Skip to content

Let agents read the next-work feed from the CLI - #1178

Merged
realtonyyoung merged 21 commits into
mainfrom
claude-tyoung/ai-3142-next-work
Sep 25, 2026
Merged

realtonyyoung merged 21 commits into
mainfrom
claude-tyoung/ai-3142-next-work

Conversation

@realtonyyoung

Copy link
Copy Markdown
Collaborator

Closes #1177 — AI-3142

What & why

Agents cannot see the user's next-work feed from the CLI. This adds a get_next_work tool to kcap mcp workitems over the server's GET /api/next-work, and a SessionStart emitter that renders page one from the ack's next_work field, with guidance to finish listed work first and declare loose ends at the moment of deferral. The CLI advertises next_work: "v1" so the server only runs the feed for a client that renders it; disable_nextwork_nudge opts out of both.

Where to look

Every server-supplied string is untrusted: label, because, href, evidence, arm states and error bodies go through one sanitiser and sit inside a single <next-work-data> block, with the imperative guidance outside it. The capability goes on the live post body only, never the spooled one, because a replay renders nothing.

Verification

Hostile labels, hrefs and freshness strings containing newlines, control characters and a literal closing tag render on one line inside the block with exactly one open and one close tag; removing the sanitiser from the freshness line fails its test. A 500 spools a body without the capability while the live post carried it. A release publish ran with no AOT warnings, and the published binary against a stub server listed the tool and rendered a hostile row safely.

🤖 Generated with Claude Code

realtonyyoung and others added 7 commits September 25, 2026 03:24
A copy of the server's sanitiser: rows from an older or other server may not
have been through it, and nothing inside the block may close it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The repository is resolved only when this tool is called, so the other
work-items tools still start with no git probe.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The capability rides the live post only; a spooled replay must not make the
server run the feed for rows nobody renders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A proxy or error page can put arbitrary text in a non-2xx body; the sibling
tools still echo theirs verbatim.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-next-work

# Conflicts:
#	src/Capacitor.Cli/Commands/McpWorkItemsServer.cs
@linear-code

linear-code Bot commented Sep 25, 2026

Copy link
Copy Markdown

AI-3142

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Expose ranked next work through MCP and SessionStart

✨ Enhancement ⚙️ Configuration changes 📝 Documentation 🧪 Tests 🕐 40+ Minutes

Grey Divider

AI Description

• Adds repository-aware MCP access to ranked next-work recommendations.
• Injects sanitised page-one recommendations into live SessionStart context with actionable
 guidance.
• Adds opt-out configuration and extensive hostile-input, failure, and replay coverage.
Diagram

sequenceDiagram
    actor Agent
    participant Hook as Session Hook
    participant Config as CLI Config
    participant API as Next Work API
    participant Safe as Text Sanitizer
    participant Context as Context Envelope
    participant MCP as Work Items MCP
    participant Repo as Repository Resolver

    Agent->>Hook: Start session
    Hook->>Config: Read opt-out
    Hook->>API: POST capability v1
    API-->>Hook: Ack page one
    Hook->>Safe: Sanitize rows
    Safe->>Context: Safe fragment
    Context-->>Agent: Inject recommendations
    Agent->>MCP: get_next_work
    MCP->>Repo: Resolve default hash
    MCP->>API: GET ranked feed
    API-->>MCP: Feed and freshness
    MCP->>Safe: Sanitize response
    MCP-->>Agent: Return safe feed
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. On-demand MCP only
  • ➕ Smaller SessionStart payload and integration surface
  • ➕ Avoids running the feed until an agent explicitly requests it
  • ➖ Agents may overlook existing work before proposing something new
  • ➖ Requires prompt compliance before recommendations become visible
2. Fetch feed separately at SessionStart
  • ➕ Decouples feed retrieval from the SessionStart acknowledgement schema
  • ➕ Could reuse the same endpoint and response format as MCP
  • ➖ Adds another network request to a latency-sensitive hook
  • ➖ Introduces an additional failure path and request budget concern

Recommendation: Keep the PR's dual delivery model: the acknowledgement provides low-latency proactive guidance, while MCP supports refreshed and larger on-demand results. Advertising the capability only on live requests avoids wasted server work and undeliverable replay output; client-side sanitisation appropriately provides defense in depth against older or compromised servers.

Files changed (16) +937 / -57

Enhancement (4) +323 / -34
NextWorkUntrustedText.csCentralise safe rendering of next-work text +26/-0

Centralise safe rendering of next-work text

• Introduces a shared sanitiser that collapses whitespace and control characters, neutralises angle brackets, caps lengths, and preserves surrogate-pair boundaries.

src/Capacitor.Cli.Core/WorkItems/NextWorkUntrustedText.cs

ClaudeHookCommand.csAdvertise and render next work at SessionStart +15/-20

Advertise and render next work at SessionStart

• Adds the v1 next-work capability only to live request bodies, preserving capability-free spool payloads. Renders returned recommendations into the shared context envelope unless disabled.

src/Capacitor.Cli/Commands/Harness/ClaudeHookCommand.cs

McpWorkItemsServer.csExpose get_next_work through the work-items MCP server +161/-14

Expose get_next_work through the work-items MCP server

• Adds repository-aware GET /api/next-work dispatch, result and error handling, safe feed rendering, evidence and freshness output, and tool metadata. Repository detection remains lazy and is skipped when an explicit hash is supplied.

src/Capacitor.Cli/Commands/McpWorkItemsServer.cs

NextWorkEmitter.csRender safe next-work SessionStart fragments +121/-0

Render safe next-work SessionStart fragments

• Builds a delimited, sanitised recommendation block from the SessionStart acknowledgement. Keeps imperative guidance and freshness metadata outside the untrusted data block and fails open for absent or malformed input.

src/Capacitor.Cli/NextWorkEmitter.cs

Tests (6) +564 / -5
NextWorkUntrustedTextTests.csVerify untrusted-text sanitisation boundaries +59/-0

Verify untrusted-text sanitisation boundaries

• Covers hostile delimiters, control characters, whitespace normalisation, length caps, surrogate pairs, and empty inputs.

test/Capacitor.Cli.Core.Tests.Unit/WorkItems/NextWorkUntrustedTextTests.cs

ConfigCommandTests.csTest next-work opt-out configuration +33/-0

Test next-work opt-out configuration

• Verifies true and false updates, invalid-value rejection, and snake_case JSON round-tripping.

test/Capacitor.Cli.Tests.Unit/Commands/ConfigCommandTests.cs

ClaudeHookCommandTests.csTest live next-work capability delivery +63/-0

Test live next-work capability delivery

• Verifies capability advertisement and context ordering, complete opt-out behavior, and exclusion of the capability from failed-request spool bodies.

test/Capacitor.Cli.Tests.Unit/Commands/Harness/ClaudeHookCommandTests.cs

McpWorkItemsNextWorkTests.csCover next-work MCP retrieval and safe rendering +252/-0

Cover next-work MCP retrieval and safe rendering

• Tests feed formatting, evidence selection, freshness states, hostile content, errors, URL construction, lazy repository defaults, and unavailable-server behavior.

test/Capacitor.Cli.Tests.Unit/Commands/McpWorkItemsNextWorkTests.cs

McpWorkItemsServerTests.csExtend work-items MCP surface tests +24/-5

Extend work-items MCP surface tests

• Updates server construction for lazy repository resolution and verifies get_next_work registration, schema, and agent instructions.

test/Capacitor.Cli.Tests.Unit/Commands/McpWorkItemsServerTests.cs

NextWorkEmitterTests.csTest SessionStart next-work rendering +133/-0

Test SessionStart next-work rendering

• Covers complete fragments, guidance, freshness, hostile fields, single-block integrity, opt-out behavior, empty responses, and malformed acknowledgements.

test/Capacitor.Cli.Tests.Unit/NextWorkEmitterTests.cs

Documentation (4) +42 / -18
README.mdDocument SessionStart next-work delivery and MCP tool +3/-1

Document SessionStart next-work delivery and MCP tool

• Documents live capability advertisement, sanitised page-one injection, agent guidance, replay exclusions, and the opt-out. Expands the work-items MCP reference from ten to eleven tools.

README.md

SKILL.mdTeach agents to consult and maintain next work +31/-15

Teach agents to consult and maintain next work

• Directs agents to call get_next_work before recommending work and to cite its ranking rationale. Moves loose-end declaration guidance to the moment work is deferred.

kcap/skills/work-items/SKILL.md

help-config.txtList the next-work opt-out +1/-0

List the next-work opt-out

• Adds disable_nextwork_nudge to configuration help output.

src/Capacitor.Cli.Core/Resources/help-config.txt

help-mcp.txtDescribe the eleventh work-items MCP tool +7/-2

Describe the eleventh work-items MCP tool

• Updates work-items MCP help to include ranked next-work retrieval, repository defaults, and result limits.

src/Capacitor.Cli.Core/Resources/help-mcp.txt

Other (2) +8 / -0
ProfileConfig.csAdd next-work nudge profile setting +5/-0

Add next-work nudge profile setting

• Adds the nullable disable_nextwork_nudge profile property, independently controlling capability advertisement and SessionStart injection.

src/Capacitor.Cli.Core/Config/ProfileConfig.cs

ConfigCommand.csSupport setting the next-work opt-out +3/-0

Support setting the next-work opt-out

• Parses and validates disable_nextwork_nudge through kcap config set and includes it in command usage.

src/Capacitor.Cli/Commands/ConfigCommand.cs

@qodo-code-review

qodo-code-review Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (2) 🔗 Cross-repo conflicts (1) 📜 Skill insights (0)

Grey Divider


Action required

1. A slow feed stalls every work tool ✓ Resolved 🐞 Bug ☼ Reliability
Description
HandleGetNextWorkAsync switches to headers-only completion and then passes
CancellationToken.None into BoundedHttpContent.ReadAsync, leaving response-body reads without a
deadline. If the server returns headers and trickles fewer than 256 KiB indefinitely, the sequential
MCP dispatch loop remains blocked and cannot process any later work-items calls.
Code

src/Capacitor.Cli/Commands/McpWorkItemsServer.cs[255]

+            var bytes = await BoundedHttpContent.ReadAsync(httpResponse.Content, NextWorkMaxResponseBytes, CancellationToken.None);
Relevance

●●● Strong

The team repeatedly accepts fixes preventing serial MCP dispatch from blocking on unbounded network
work.

PR-#1135
PR-#480

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new request returns after headers and explicitly disables cancellation for the subsequent
bounded stream read. BoundedHttpContent waits on each read using only the supplied token, while
the work-items server awaits each tool dispatch before reading the next request, so a body that
never completes blocks the entire protocol loop.

src/Capacitor.Cli/Commands/McpWorkItemsServer.cs[248-255]
src/Capacitor.Cli/BoundedHttpContent.cs[7-16]
src/Capacitor.Cli/Commands/McpWorkItemsServer.cs[88-116]
src/Capacitor.Cli.Core/Http/CapacitorHttpServices.cs[44-66]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The next-work response body is streamed with no cancellation deadline, so a trickling response can block the sequential work-items MCP server indefinitely.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/McpWorkItemsServer.cs[248-255]
- src/Capacitor.Cli/BoundedHttpContent.cs[7-16]

## Recommended Fix
Create a bounded cancellation token for the complete next-work request, pass it to both `GetAsync` and `BoundedHttpContent.ReadAsync`, and convert timeout cancellation into the existing next-work timeout tool error. Add a test using a response stream that stalls after returning headers.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Large feed responses can exhaust the agent process ✓ Resolved 🐞 Bug ☼ Reliability
Description
HandleGetNextWorkAsync reads the complete HTTP response with ReadAsStringAsync before
RenderNextWorkResult truncates the text that reaches the agent. A proxy, malfunctioning server, or
oversized successful feed therefore allocates and buffers its entire body in the long-lived MCP
process, so the 300-character rendering cap does not prevent memory pressure or termination.
Code

src/Capacitor.Cli/Commands/McpWorkItemsServer.cs[R243-244]

+            using var httpResponse = await client.GetAsync(BuildNextWorkUrl(baseUrl, arguments, repoHash, sessionId));
+            var body = await httpResponse.Content.ReadAsStringAsync();
Relevance

●●● Strong

Historical reliability reviews accept bounded reads to prevent large untrusted inputs from consuming
long-lived process resources.

PR-#291
PR-#1135

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The endpoint response is fully materialized before status handling or the untrusted-text cap
executes. The only cap is applied later while constructing the agent-facing error string, after the
large body has already been read.

src/Capacitor.Cli/Commands/McpWorkItemsServer.cs[236-250]
src/Capacitor.Cli/Commands/McpWorkItemsServer.cs[275-280]
src/Capacitor.Cli.Core/WorkItems/NextWorkUntrustedText.cs[15-24]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

Issue description
The new next-work request buffers the entire response body before applying the renderer's output caps, allowing an oversized response to consume unbounded memory in the MCP process.

Fix Focus Areas
- src/Capacitor.Cli/Commands/McpWorkItemsServer.cs[243-244]
- src/Capacitor.Cli/Commands/McpWorkItemsServer.cs[275-280]

Recommended Fix
Send the request with response-headers completion and read the content through a bounded reader. Apply a conservative byte limit to successful feed payloads and a smaller limit to error bodies, returning a clean tool error when either limit is exceeded before parsing or rendering.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Failed requests can instruct the agent ✓ Resolved 🐞 Bug ⛨ Security
Description
RenderNextWorkResult interpolates a sanitized non-success response body directly into trusted tool
text, without enclosing or labeling that server-controlled body as data. A proxy or error page
containing ordinary imperative prose survives NextWorkUntrustedText.Render, so any non-success
response except the two coded cases can deliver instructions to the agent.
Code

src/Capacitor.Cli/Commands/McpWorkItemsServer.cs[R275-276]

+        if ((int)status is < 200 or > 299)
+            return BuildToolResult(id, $"Error: HTTP {(int)status} — {NextWorkUntrustedText.Render(body, NextWorkEmitter.FieldCap)}", isError: true);
Relevance

●●● Strong

Untrusted server text reaching agent-facing output without containment matches accepted
injection-hardening precedents.

PR-#408
PR-#344

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The generic non-success branch concatenates the response body directly after a static error prefix.
The sanitizer removes newlines and angle brackets but preserves the demonstrated `ignore previous
instructions` text, and the corresponding test confirms that this imperative content is returned
without any data delimiter.

src/Capacitor.Cli/Commands/McpWorkItemsServer.cs[268-280]
src/Capacitor.Cli.Core/WorkItems/NextWorkUntrustedText.cs[15-24]
test/Capacitor.Cli.Tests.Unit/Commands/McpWorkItemsNextWorkTests.cs[171-180]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Arbitrary non-success HTTP response bodies are returned as ordinary MCP tool text, allowing imperative content from a server or proxy error page to reach the agent outside a data boundary.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/McpWorkItemsServer.cs[268-280]
- test/Capacitor.Cli.Tests.Unit/Commands/McpWorkItemsNextWorkTests.cs[171-180]

## Recommended Fix
Keep the static status description outside the boundary, but place the sanitized response-body excerpt inside an explicitly labeled data block such as `<next-work-error-data>`. Update the hostile error-body test to verify exactly one opening and closing delimiter and that all server-controlled text remains between them.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View high (1)
4. Feed metadata can instruct the agent ✓ Resolved 🐞 Bug ⛨ Security
Description
BuildFragment and RenderNextWorkFeed append FreshnessLine after closing <next-work-data>,
even though the line includes server-controlled timestamps, arm names, states, and error codes. A
hostile freshness value therefore follows trusted guidance as ordinary context, and
NextWorkUntrustedText.Render preserves imperative prose such as obey me while only flattening
controls and angle brackets.
Code

src/Capacitor.Cli/NextWorkEmitter.cs[R67-72]

+        var freshness = FreshnessLine(
+            asOf: null,
+            ReadString(nextWork, "tracker_state_as_of"),
+            ReadInt(nextWork, "tracker_state_unknown_rows"),
+            ReadStrings(nextWork, "arms_not_current"));
+        if (freshness is not null) Line(sb, freshness);
Relevance

●●● Strong

Team accepts sanitizing and containing server-controlled metadata when it can influence agent-facing
context.

PR-#408
PR-#1015

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Both renderers place the shared freshness output after the closing data tag, while the sanitizer
only normalizes characters rather than removing commands. The added test directly demonstrates
hostile values producing obey me and run this after the trusted guidance and outside the block.

src/Capacitor.Cli/NextWorkEmitter.cs[56-72]
src/Capacitor.Cli/Commands/McpWorkItemsServer.cs[326-349]
src/Capacitor.Cli.Core/WorkItems/NextWorkUntrustedText.cs[15-24]
test/Capacitor.Cli.Tests.Unit/NextWorkEmitterTests.cs[98-110]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Untrusted freshness metadata is emitted outside `<next-work-data>`, where imperative text can be interpreted as agent guidance.

## Fix Focus Areas
- src/Capacitor.Cli/NextWorkEmitter.cs[56-72]
- src/Capacitor.Cli/Commands/McpWorkItemsServer.cs[326-349]

## Recommended Fix
Render all server-controlled freshness values inside the existing `<next-work-data>` block, or place them in a separate explicitly marked data block. Keep only static CLI-authored guidance outside those boundaries, and update hostile-input tests to assert that freshness instructions remain inside a data delimiter.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

5. Arm limit comment states wrong count 📘 Rule violation ⚙ Maintainability ⭐ New
Description
MaxArmEntries is set to 10 while its new summary says the feed has eight arms and allows “no
more.” A later change can rely on the stated eight-entry invariant even though nine or ten distinct
arms are deliberately accepted and rendered.
Code

src/Capacitor.Cli/NextWorkEmitter.cs[R40-41]

+    /// <summary>The feed has eight arms; room for all of them and no more.</summary>
+    internal const int MaxArmEntries = 10;
Relevance

●●● Strong

Recent precedents accept correcting inaccurate constraint comments and hard-coded counts that can
drift from behavior.

PR-#675
PR-#1097

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Compliance rule 2762993 requires comments to remain true and document non-obvious constraints. The
cited summary states an eight-entry maximum directly above a constant whose value is ten.

Rule 2762993: Restrict comments to documenting non-obvious, behavior‑critical constraints
src/Capacitor.Cli/NextWorkEmitter.cs[40-41]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The summary for `MaxArmEntries` claims that only eight arm entries are allowed, but the constant permits ten, leaving maintainers with conflicting guidance.

## Fix Focus Areas
- src/Capacitor.Cli/NextWorkEmitter.cs[40-41]

## Recommended Fix
Remove the redundant summary, or rewrite it to explain the actual non-obvious reason the limit is ten without claiming that eight is the maximum.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. A test summary mirrors its test name ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
The summary above without_the_workitems_mcp_server_next_work_is_neither_requested_nor_rendered
repeats the absence condition and the two outcomes already stated by the method name. A later change
to that scenario would require maintaining duplicate prose without giving the reader an additional
invariant or rationale.
Code

test/Capacitor.Cli.Tests.Unit/Commands/Harness/ClaudeHookCommandTests.cs[R668-669]

+    /// <summary>The same ack that renders above renders nothing, and neither field is sent, when
+    /// Claude has no kcap-workitems server to call the tools the guidance names.</summary>
Relevance

●●● Strong

Recent comment-compliance precedents accept shortening test comments that duplicate names or obvious
behavior.

PR-#1138
PR-#785

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Compliance rule 2762993 rejects comments that merely restate adjacent code or signature information.
The cited summary and test name both say that no next-work capability is requested or rendered when
the Claude work-items server is absent.

Rule 2762993: Restrict comments to documenting non-obvious, behavior‑critical constraints
test/Capacitor.Cli.Tests.Unit/Commands/Harness/ClaudeHookCommandTests.cs[668-671]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test summary repeats the test method's complete scenario and expected behavior without documenting a non-obvious constraint.

## Fix Focus Areas
- test/Capacitor.Cli.Tests.Unit/Commands/Harness/ClaudeHookCommandTests.cs[668-671]

## Recommended Fix
Delete the redundant XML summary and retain the descriptive test method name.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


7. Slow setup drops the next-work feed ✓ Resolved 🐞 Bug ☼ Reliability
Description
ClaudeHookCommand computes next_work_budget_ms from budget.Remaining before starting the
memory-index task, but later takes a smaller snapshot for the POST timeout. When synchronous memory
lease or provider setup consumes part of the reserved interval, the server receives a stale feed
allowance and the POST can time out and spool instead of returning the feed.
Code

src/Capacitor.Cli/Commands/Harness/ClaudeHookCommand.cs[R697-700]

+                        if (!nextWorkDisabled && NextWorkEmitter.FeedBudgetMs(budget.Remaining) is { } feedBudgetMs) {
+                            node["next_work"]           = AotJsonString(NextWorkEmitter.CapabilityVersion);
+                            node["next_work_budget_ms"] = feedBudgetMs;
+                        }
Relevance

●●● Strong

Recent hook-budget precedents accept fixes ensuring synchronous setup and network work respect
remaining deadlines.

PR-#790
PR-#187

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The capability budget is calculated at line 697, then memory orchestration is started before
budget.Remaining is read again for PostOnceAsync. HookBudget.Remaining decreases with elapsed
time, and StartMemoryIndexTask performs store and provider setup before its first incomplete
await, so the two values can diverge.

src/Capacitor.Cli/Commands/Harness/ClaudeHookCommand.cs[697-731]
src/Capacitor.Cli/Commands/Harness/ClaudeHookCommand.cs[1142-1161]
src/Capacitor.Cli/Commands/HookBudget.cs[13-18]
src/Capacitor.Cli/NextWorkEmitter.cs[24-33]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The advertised feed budget is calculated before additional setup work, so it can exceed what the eventual SessionStart POST can safely accommodate.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/Harness/ClaudeHookCommand.cs[696-700]
- src/Capacitor.Cli/NextWorkEmitter.cs[24-33]

## Recommended Fix
Start the memory task first, then capture one remaining-time snapshot immediately before constructing and sending the POST. Derive both `next_work_budget_ms` and the POST timeout from that same snapshot so intervening setup cannot consume the feed reserve; add a clock-controlled test where memory setup advances time.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View medium (6)
8. Timestamp summary adds no constraint ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
Timestamp is preceded by a summary that merely narrates its visible UTC-formatting and null-return
behavior. If accepted formats or output precision change, this duplicate prose can become stale
without preserving any non-obvious invariant.
Code

src/Capacitor.Cli/NextWorkEmitter.cs[145]

+    /// <summary>The value re-formatted as ISO 8601 UTC, or null when it is not a timestamp.</summary>
Relevance

●●● Strong

Recent comment-compliance precedents accept removing summaries that merely restate straightforward
method behavior.

PR-#1138
PR-#749

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Compliance rule 2762993 permits comments only when they document non-obvious, behavior-critical
constraints. The cited summary restates the adjacent one-expression method's formatting and null
behavior.

Rule 2762993: Restrict comments to documenting non-obvious, behavior‑critical constraints
src/Capacitor.Cli/NextWorkEmitter.cs[145-149]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The `Timestamp` documentation repeats behavior that is immediately apparent from the method implementation and records no non-obvious constraint.

## Fix Focus Areas
- src/Capacitor.Cli/NextWorkEmitter.cs[145-149]

## Recommended Fix
Remove the summary above `Timestamp`, or replace it only if there is a behavior-critical parsing or formatting constraint that the implementation does not make evident.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


9. Three tests bypass temp injection ✓ Resolved 📘 Rule violation ▣ Testability
Description
absent is initialized with new TempDir() in each of the three added session-start tests instead
of using a public required property annotated with [TempDir]. These methods therefore own separate
directory lifecycles, so later fixture changes must account for locally managed state rather than
the test framework's injected lifecycle.
Code

test/Capacitor.Cli.Tests.Unit/Commands/Harness/ClaudeHookCommandTests.cs[573]

+        using var absent = new TempDir();
Relevance

●●● Strong

The rule explicitly mandates injected TempDir lifecycle; replacing manual construction is a
deterministic test-maintainability fix.

PR-#877
PR-#645

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 2808173 expressly prohibits new TempDir() calls in test classes and requires a public
required [TempDir] property. The changed test methods create manually managed instances at lines
573, 596, and 614.

Rule 2808173: Use injected [TempDir] public required property in test classes instead of manual fields
test/Capacitor.Cli.Tests.Unit/Commands/Harness/ClaudeHookCommandTests.cs[573-573]
test/Capacitor.Cli.Tests.Unit/Commands/Harness/ClaudeHookCommandTests.cs[596-596]
test/Capacitor.Cli.Tests.Unit/Commands/Harness/ClaudeHookCommandTests.cs[614-614]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Three added session-start tests manually construct and dispose `TempDir` instances even though test classes must use framework-injected temporary directories.

## Fix Focus Areas
- test/Capacitor.Cli.Tests.Unit/Commands/Harness/ClaudeHookCommandTests.cs[573-614]

## Recommended Fix
Add or reuse a public required `TempDir` property annotated with `[TempDir]`, replace each local `new TempDir()` with that injected instance, and remove the corresponding local disposal declarations.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


10. Oversized session feeds flood agent context ✓ Resolved 🐞 Bug ☼ Reliability
Description
NextWorkEmitter.BuildFragment iterates every acknowledgement row and appends each valid row to the
injected context without enforcing the advertised page-one maximum of three. If a server returns
more rows than the expected page, all of them are emitted, so a malformed or older server response
can consume the agent's context and bury the intended SessionStart guidance.
Code

src/Capacitor.Cli/NextWorkEmitter.cs[R38-51]

+        var lines = new List<string>();
+        foreach (var node in rows) {
+            if (node is not JsonObject row) continue;
+
+            var label = NextWorkUntrustedText.Render(ReadString(row, "label"), FieldCap);
+            if (label.Length == 0) continue;
+
+            var because = NextWorkUntrustedText.Render(ReadString(row, "because"), FieldCap);
+            var href    = NextWorkUntrustedText.Render(ReadString(row, "href"), FieldCap);
+
+            var line = new StringBuilder($"{lines.Count + 1}. {label}");
+            if (because.Length > 0) line.Append($" — {because}");
+            if (href.Length > 0) line.Append($"  {href}");
+            lines.Add(line.ToString());
Relevance

●●● Strong

The documented three-row page limit is explicit, and enforcing cumulative output bounds is a
straightforward reliability fix.

PR-#1131
PR-#173

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The feature documentation defines the SessionStart payload as page one with up to three rows, but
the renderer has no count guard and adds every valid row. Per-field caps only bound an individual
row and do not bound the cumulative injected fragment.

src/Capacitor.Cli/NextWorkEmitter.cs[35-54]
src/Capacitor.Cli/NextWorkEmitter.cs[18-24]
README.md[295-295]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

Issue description
The SessionStart renderer trusts the acknowledgement's row count even though page one is defined as at most three rows, allowing an oversized response to inject arbitrary numbers of capped-but-accumulated lines into agent context.

Fix Focus Areas
- src/Capacitor.Cli/NextWorkEmitter.cs[38-52]
- README.md[295-295]

Recommended Fix
Stop processing after three accepted rows, rather than after three raw array entries, so malformed entries do not reduce the displayed page size. Keep the existing per-field sanitisation and return no fragment only when no accepted rows remain.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


11. Agents are told to use unavailable tools ✓ Resolved 🐞 Bug ≡ Correctness
Description
ClaudeHookCommand calls NextWorkEmitter.BuildFragment whenever the server returns next_work,
without checking whether kcap-workitems is registered for the Claude harness. A hook can be
installed while that MCP server is absent, and unlike WorkItemsNudgeEmitter.Resolve, this path
then injects guidance requiring declare_loose_end and get_next_work that the agent cannot
invoke.
Code

src/Capacitor.Cli/Commands/Harness/ClaudeHookCommand.cs[784]

+                    var nextWorkFragment = NextWorkEmitter.BuildFragment(responseNode, nextWorkDisabled);
Relevance

●●● Strong

Capability availability gating is consistently accepted for preventing agents being directed to
unavailable tools.

PR-#1015
PR-#609

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new call renders the fragment based only on the response and opt-out state. The established
work-items nudge explicitly treats MCP registration as a fail-closed availability gate before
referring agents to work-items tools.

src/Capacitor.Cli/Commands/Harness/ClaudeHookCommand.cs[780-812]
src/Capacitor.Cli/WorkItemsNudgeEmitter.cs[30-45]
src/Capacitor.Cli/NextWorkEmitter.cs[26-30]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

Issue description
The SessionStart next-work fragment is rendered without verifying that `kcap-workitems` is available to the Claude harness, so its mandatory guidance can point agents at MCP tools that are not registered.

Fix Focus Areas
- src/Capacitor.Cli/Commands/Harness/ClaudeHookCommand.cs[784-784]
- src/Capacitor.Cli/WorkItemsNudgeEmitter.cs[40-45]

Recommended Fix
Use the same `McpServerNudgeAvailability.IsRegisteredFor` availability check used by the work-items nudge before advertising the next-work capability and before rendering its fragment. When the server is unavailable, omit the capability and fragment so the server does not compute an unreadable feed.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


12. Configured feeds outlast session starts 🔗 Cross-repo conflict ☼ Reliability
Description
ClaudeHookCommand sends next_work_budget_ms, but kcap-server's SessionStartHook has no
matching field and its handler always uses the configured SessionStartBudgetMs. When that server
setting exceeds the CLI's remaining advertised budget, the feed can consume the POST deadline, so
the live session-start response may arrive too late to render.
Code

src/Capacitor.Cli/Commands/Harness/ClaudeHookCommand.cs[R697-699]

+                        if (!nextWorkDisabled && NextWorkEmitter.FeedBudgetMs(budget.Remaining) is { } feedBudgetMs) {
+                            node["next_work"]           = AotJsonString(NextWorkEmitter.CapabilityVersion);
+                            node["next_work_budget_ms"] = feedBudgetMs;
Relevance

●● Moderate

Cross-repository budget coordination is plausible, but no closely matching acceptance or rejection
precedent appeared.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The PR calculates a deadline-derived budget and sends it beside the capability, while the pinned
server request DTO defines only the capability and the handler passes its own configurable budget
directly to the feed. The server permits that independent budget to reach 5000 ms, proving it can
exceed the CLI's advertised allowance.

kcap-cli -> kcap-server
src/Capacitor.Cli/Commands/Harness/ClaudeHookCommand.cs[696-700]
src/Capacitor.Cli/NextWorkEmitter.cs[20-33]
External repo: kurrent-io/kcap-server, src/Capacitor.Api.Public.Abstractions/Hooks/SessionStartHook.cs [66-70]
External repo: kurrent-io/kcap-server, src/Capacitor.Server/Hooks/SessionHookHandlers.cs [455-467]
External repo: kurrent-io/kcap-server, src/Capacitor.Server/NextWork/NextWorkOptions.cs [19-20]
External repo: kurrent-io/kcap-server, src/Capacitor.Server/NextWork/NextWorkOptions.cs [34-51]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The CLI sends a per-request `next_work_budget_ms`, but the pinned kcap-server request model ignores it and uses only its independently configurable session-start budget. A server configured above the CLI's available time can therefore overrun the live hook deadline.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/Harness/ClaudeHookCommand.cs[697-699]
- /cross_repos/kcap-server/src/Capacitor.Api.Public.Abstractions/Hooks/SessionStartHook.cs[66-70]
- /cross_repos/kcap-server/src/Capacitor.Server/Hooks/SessionHookHandlers.cs[463-467]

## Recommended Fix
Add an optional `next_work_budget_ms` field to the server request contract, validate and clamp it, and run the feed with the minimum of that request budget and `SessionStartBudgetMs`. Coordinate deployment so the server understands the field before the CLI relies on it; otherwise withhold the capability unless the remaining deadline can accommodate the server's maximum supported configured budget.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


13. Freshness metadata floods agent context ✓ Resolved 🐞 Bug ➹ Performance
Description
FreshnessLine materializes and joins every syntactically valid arm entry without a count or
aggregate-length limit. A server response containing many valid or duplicate entries therefore
creates an arbitrarily long SessionStart line and can consume nearly the full 256 KiB MCP response
allowance despite the feed rows themselves being capped.
Code

src/Capacitor.Cli/NextWorkEmitter.cs[R130-131]

+            .Select(a => a.Code is null ? $"{a.Arm}: {a.State}" : $"{a.Arm}: {a.State} ({a.Code})")
+            .ToList();
Relevance

●● Moderate

The unbounded freshness aggregation concern is technically specific, but no closely matching
precedent appeared.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Validation limits each individual arm, state, and code but ToList and string.Join retain every
accepted entry. Both the SessionStart acknowledgement and MCP feed feed their complete freshness
collections into this method, whereas only feed rows have an explicit small display limit.

src/Capacitor.Cli/NextWorkEmitter.cs[126-134]
src/Capacitor.Cli/Commands/McpWorkItemsServer.cs[338-351]
src/Capacitor.Cli/NextWorkEmitter.cs[37-38]
src/Capacitor.Cli/Commands/McpWorkItemsServer.cs[234-237]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Freshness rendering accepts every valid arm entry, allowing duplicate or excessive metadata to consume agent context despite the row limits.

## Fix Focus Areas
- src/Capacitor.Cli/NextWorkEmitter.cs[126-132]
- src/Capacitor.Cli/Commands/McpWorkItemsServer.cs[338-346]

## Recommended Fix
Deduplicate validated freshness entries and enforce a small maximum count or aggregate rendered-length limit before materializing them. Apply the bound centrally in `FreshnessLine` so both SessionStart and MCP output are protected, and add tests with many duplicate and distinct valid entries.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

14. New vendor logic sits in wrong folder 📘 Rule violation ⌂ Architecture
Description
ClaudeHookCommand adds Claude-specific next-work capability gating under Commands/Harness
instead of the required Harness/Claude directory. Because this branch extends vendor-specific hook
behavior at that site, subsequent Claude harness changes and discovery must continue to account for
code outside the prescribed vendor boundary.
Code

src/Capacitor.Cli/Commands/Harness/ClaudeHookCommand.cs[R689-690]

+            var nextWorkDisabled            = activeProfile?.DisableNextWorkNudge is true
+                                           || !WorkItemsNudgeEmitter.ToolsRegisteredFor(HarnessId.Claude, harnesses);
Relevance

● Weak

Recent precedent rejected moving vendor-specific hook logic from Commands/Harness into
Harness/Vendor.

PR-#877

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Compliance rule 2762984 requires vendor-specific CLI harness commands and logic to reside under
Capacitor.Cli/Harness/<Vendor>/. The cited branch code adds behavior specifically for
HarnessId.Claude while remaining under Commands/Harness.

Rule 2762984: Place vendor-specific harness code only in the correct Harness/&lt;Vendor&gt;/ assembly and directory
src/Capacitor.Cli/Commands/Harness/ClaudeHookCommand.cs[683-690]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The newly added Claude-specific capability logic resides outside the required `Harness/Claude` directory.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/Harness/ClaudeHookCommand.cs[689-690]

## Recommended Fix
Move the Claude harness command and its vendor-specific behavior under `src/Capacitor.Cli/Harness/Claude/`, update its namespace to match that directory, and adjust imports and tests accordingly.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


15. A test heading repeats test names ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
The SessionStart next-work lane comment only categorizes the following tests by repeating their
capability-advertising and response-rendering behavior. Because the adjacent method names already
describe that behavior, the comment supplies no invariant or rationale for a later reader to
preserve.
Code

test/Capacitor.Cli.Tests.Unit/Commands/Harness/ClaudeHookCommandTests.cs[566]

+    // ── SessionStart next-work lane: capability advertise + response render ───────────────────
Relevance

● Weak

A closely matching Claude test comment cleanup was explicitly rejected as unnecessary despite
similar redundancy concerns.

PR-#768

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 2762993 requires comments to capture non-obvious, behavior-critical constraints and
specifically rejects comments that restate clear code. The changed heading labels capability
advertisement and response rendering, which the immediately following test name already states.

Rule 2762993: Restrict comments to documenting non-obvious, behavior‑critical constraints
test/Capacitor.Cli.Tests.Unit/Commands/Harness/ClaudeHookCommandTests.cs[566-572]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The added section heading merely summarizes the test names below it and documents no non-obvious behavioral constraint.

## Fix Focus Areas
- test/Capacitor.Cli.Tests.Unit/Commands/Harness/ClaudeHookCommandTests.cs[566-566]

## Recommended Fix
Remove the redundant section comment, leaving the descriptive test names to communicate the covered behavior.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 64 rules
✅ Cross-repo context — repo relationships
  Explored: repo: kurrent-io/kcap-server (sha: 0da3ec5b) — View relationship
Review mode: ⚖️ Balanced: The push changes timeout/cancellation behavior, capability advertisement timing, and feed rendering across multiple runtime paths, creating real correctness risk but not enough independent logic to warrant extended review.

Grey Divider

Tip of the day
💡 Did you know, you can enable the Remediation agent and Qodo fixes findings in a dedicated fix PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread test/Capacitor.Cli.Tests.Unit/Commands/Harness/ClaudeHookCommandTests.cs Outdated
Comment thread src/Capacitor.Cli/NextWorkEmitter.cs
Comment thread src/Capacitor.Cli/Commands/McpWorkItemsServer.cs Outdated
Comment thread src/Capacitor.Cli/Commands/Harness/ClaudeHookCommand.cs
Comment thread src/Capacitor.Cli/Commands/McpWorkItemsServer.cs Outdated
Comment thread src/Capacitor.Cli/NextWorkEmitter.cs
realtonyyoung and others added 8 commits September 25, 2026 16:21
The server runs the feed before acking, so the capability is sent only when the
time left, less a reserve for the POST itself, fits at least the server's default
feed budget; a server that predates next_work_budget_ms spends that default anyway.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Under NativeAOT a string assigned into a JsonObject throws, and the catch around the capability block would silently drop every capability.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The body is read from the stream at headers-read time, so an oversized reply is refused
without being buffered.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The line sits outside the data block, so a timestamp, arm, state or code that fails to parse
is dropped rather than sanitised and shown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Any other body text is server or proxy prose that would reach the agent outside the data block.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Its guidance tells the agent to call declare_loose_end and get_next_work, so without the
server the feed is neither requested nor rendered.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@realtonyyoung

Copy link
Copy Markdown
Collaborator Author

/agentic_review

Comment thread src/Capacitor.Cli/NextWorkEmitter.cs Outdated
Comment thread test/Capacitor.Cli.Tests.Unit/Commands/Harness/ClaudeHookCommandTests.cs Outdated
Comment thread src/Capacitor.Cli/Commands/McpWorkItemsServer.cs Outdated
Comment thread src/Capacitor.Cli/NextWorkEmitter.cs
Comment thread src/Capacitor.Cli/Commands/Harness/ClaudeHookCommand.cs Outdated
Comment on lines +697 to +699
if (!nextWorkDisabled && NextWorkEmitter.FeedBudgetMs(budget.Remaining) is { } feedBudgetMs) {
node["next_work"] = AotJsonString(NextWorkEmitter.CapabilityVersion);
node["next_work_budget_ms"] = feedBudgetMs;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

9. Configured feeds outlast session starts 🔗 Cross-repo conflict ☼ Reliability

ClaudeHookCommand sends next_work_budget_ms, but kcap-server's SessionStartHook has no
matching field and its handler always uses the configured SessionStartBudgetMs. When that server
setting exceeds the CLI's remaining advertised budget, the feed can consume the POST deadline, so
the live session-start response may arrive too late to render.
Agent Prompt
## Issue description
The CLI sends a per-request `next_work_budget_ms`, but the pinned kcap-server request model ignores it and uses only its independently configurable session-start budget. A server configured above the CLI's available time can therefore overrun the live hook deadline.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/Harness/ClaudeHookCommand.cs[697-699]
- /cross_repos/kcap-server/src/Capacitor.Api.Public.Abstractions/Hooks/SessionStartHook.cs[66-70]
- /cross_repos/kcap-server/src/Capacitor.Server/Hooks/SessionHookHandlers.cs[463-467]

## Recommended Fix
Add an optional `next_work_budget_ms` field to the server request contract, validate and clamp it, and run the feed with the minimum of that request budget and `SessionStartBudgetMs`. Coordinate deployment so the server understands the field before the CLI relies on it; otherwise withhold the capability unless the remaining deadline can accommodate the server's maximum supported configured budget.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed on the server side in kurrent-io/kcap-server#2070: SessionStartHook gains next_work_budget_ms and the handler spends the smaller of it and NextWork:SessionStartBudgetMs, skipping the feed below the 200 ms floor. Until that server ships, this CLI advertises next_work only when the remaining time covers the server's 1500 ms default plus the POST reserve, so a server at its default budget cannot outlast the deadline either way.

In .NET `$` also matches before a final newline, which let a code or arm name carry a newline outside the data block.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit da87247

@realtonyyoung

Copy link
Copy Markdown
Collaborator Author

/agentic_review

@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit a5bf022

realtonyyoung and others added 4 commits September 25, 2026 17:06
A headers-read request is otherwise unbounded while the body trickles in, and the stdio
loop serves one call at a time, so a stalled body would hang every later tool call.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The memory-index setup runs between the two reads, so an earlier read could promise the
server more time than the POST would wait.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entries are deduplicated by arm and limited in number, and trailing ones are dropped until
the line fits its length cap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@realtonyyoung

Copy link
Copy Markdown
Collaborator Author

On the one summary-only finding without an inline thread, "New vendor logic sits in wrong folder": declining. ClaudeHookCommand already lives under Commands/Harness, alongside every other harness hook command; this PR edits that existing file rather than adding vendor code in a new place. Moving the Claude hook command under Harness/Claude is a relocation of pre-existing code and belongs in its own change, not in this feature PR.

@realtonyyoung

Copy link
Copy Markdown
Collaborator Author

/agentic_review

Comment on lines +40 to +41
/// <summary>The feed has eight arms; room for all of them and no more.</summary>
internal const int MaxArmEntries = 10;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

5. Arm limit comment states wrong count 📘 Rule violation ⚙ Maintainability

MaxArmEntries is set to 10 while its new summary says the feed has eight arms and allows “no
more.” A later change can rely on the stated eight-entry invariant even though nine or ten distinct
arms are deliberately accepted and rendered.
Agent Prompt
## Issue description
The summary for `MaxArmEntries` claims that only eight arm entries are allowed, but the constant permits ten, leaving maintainers with conflicting guidance.

## Fix Focus Areas
- src/Capacitor.Cli/NextWorkEmitter.cs[40-41]

## Recommended Fix
Remove the redundant summary, or rewrite it to explain the actual non-obvious reason the limit is ten without claiming that eight is the maximum.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit c67a629

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Let agents read the next-work feed from the CLI

1 participant