Skip to content

Post Codex, Cursor and Antigravity store titles on import - #1237

Merged
realtonyyoung merged 7 commits into
mainfrom
claude-tyoung/ai-3335-import-store-titles
Sep 30, 2026
Merged

realtonyyoung merged 7 commits into
mainfrom
claude-tyoung/ai-3335-import-store-titles

Conversation

@realtonyyoung

Copy link
Copy Markdown
Collaborator

Refs #1229 — AI-3335

What & why

kcap import posted the harness's own session title for Copilot, Kiro and OpenCode only. Codex, Cursor and Antigravity imports now do the same through the existing store readers: Codex's session_index.jsonl thread name as a rename with Codex's own change time, Cursor's chat/composer name as a rename, and Antigravity's summary title as an auto title.

Where to look

  • Codex sessions import through the chain worker in ImportCommand, so the post lives there; LLM titling is skipped only when the server accepted the title through /hooks/harness-title (a legacy set-title fallback still titles).
  • On cancellation, Codex and Cursor skip the title post so session-end still runs.

Verification

  • New tests assert the /hooks/harness-title request, its kind and changed_at, the Codex skip-LLM-title rule and its legacy-route counterpart, the Cursor IDE composer path, and no post when a store has no title.
  • dotnet publish -c Release for kcap: no IL warnings.

🤖 Generated with Claude Code

realtonyyoung and others added 2 commits September 30, 2026 09:06
Codex still generates a title unless /hooks/harness-title itself took the
native one: an older server's set-title fallback only fills an untitled session.

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

linear-code Bot commented Sep 30, 2026

Copy link
Copy Markdown

AI-3335

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Import native titles for Codex, Cursor, and Antigravity sessions

✨ Enhancement 🧪 Tests 🕐 40+ Minutes

Grey Divider

AI Description

• Import native session titles for Codex, Cursor, and Antigravity through the existing title hook.
• Preserve Codex title generation unless the server accepts its native title through the
 harness-title route.
• Cover title metadata, missing titles, legacy servers, and Cursor IDE composer titles.
Diagram

graph TD
    Chain["Codex chain"] --> Stores[("Native title stores")] --> Helper["Import title helper"] --> Client["Title client"] --> Hooks["Title endpoints"]
    Routed["Routed importers"] --> Stores
    Chain -->|"title not accepted"| Generated["Generated title"]
    Chain --> End["Session end"]
    Routed --> End
Loading
High-Level Assessment

Reuse the existing store readers and title client while posting from each vendor's established import path. Moving Codex into the routed import pipeline solely to unify title posting would broaden this change substantially without a clear benefit.

Files changed (9) +328 / -9

Enhancement (4) +76 / -6
ImportCommand.csPost Codex index titles during chain imports +30/-1

Post Codex index titles during chain imports

• Posts the Codex store title before session-end for new and resumed imports. A new import skips generated titling only when the harness-title route accepts the native title; cancellation of the title attempt does not prevent session-end.

src/Capacitor.Cli/Commands/ImportCommand.cs

AntigravityImportSource.csPost Antigravity summary titles before session-end +8/-0

Post Antigravity summary titles before session-end

• Reads and posts the summary title on both regular imports and already-loaded reimports. Stores without a title send no title request.

src/Capacitor.Cli/Harness/Antigravity/AntigravityImportSource.cs

CursorImportSource.csImport Cursor chat and composer titles +15/-1

Import Cursor chat and composer titles

• Optionally reads Cursor's chat title or IDE composer name and posts it before session-end. Cancellation of the title attempt is skipped so lifecycle finalization can continue.

src/Capacitor.Cli/Harness/Cursor/CursorImportSource.cs

ImportHarnessTitle.csPost titles directly from stores and return the server outcome +23/-4

Post titles directly from stores and return the server outcome

• Adds a shared store-reading entry point that sends title kind and recorded change time when available. Posting now returns its outcome, allowing Codex to distinguish harness-title acceptance from legacy fallback.

src/Capacitor.Cli/Harness/Titles/ImportHarnessTitle.cs

Refactor (1) +2 / -2
HarnessTitleStores.csExpose the existing Cursor title-store selector +2/-2

Expose the existing Cursor title-store selector

• Makes the chat-first, composer-fallback store selector available to Cursor imports without duplicating title lookup logic.

src/Capacitor.Cli/Harness/Titles/HarnessTitleStores.cs

Tests (3) +249 / -0
AntigravityImportTests.csVerify Antigravity summary-title import behavior +72/-0

Verify Antigravity summary-title import behavior

• Tests that a summary becomes an untimed auto title before session-end and that a blank summary sends no title.

test/Capacitor.Cli.Tests.Integration/AntigravityImportTests.cs

ImportChainsTests.csVerify Codex title metadata and generation precedence +82/-0

Verify Codex title metadata and generation precedence

• Tests the index title's rename kind and change time, suppression of generated titling after harness-title acceptance, continued generation after legacy fallback, and absence of a post when the index has no title.

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

CursorImportSourceTests.csVerify Cursor chat and IDE composer title imports +95/-0

Verify Cursor chat and IDE composer title imports

• Tests chat-title ordering and rename metadata, IDE composer fallback, and omission of default or missing titles. Composer database cases are excluded on Windows because its state path is not redirected by the test home.

test/Capacitor.Cli.Tests.Unit/Harness/Cursor/CursorImportSourceTests.cs

Other (1) +1 / -1
SetupCommand.csProvide Cursor title paths to its import source +1/-1

Provide Cursor title paths to its import source

• Passes the existing Cursor paths into the import source so it can locate chat and IDE composer title stores.

src/Capacitor.Cli/Commands/SetupCommand.cs

@qodo-code-review

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

Copy link
Copy Markdown

Code Review by Qodo

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

Grey Divider


Remediation recommended

1. A test helper comment repeats its behavior ✓ Resolved
Description
The summary above CancelOnHarnessTitle says that other requests reach the stub server except when
session-end is configured to fail, which the handler’s conditions already show. A reader changing
this test helper gets no additional constraint or rationale from that line, leaving a redundant
description to keep in sync.
Code

test/Capacitor.Cli.Tests.Unit/Commands/ImportChainsTests.cs[515]

+    /// through to the stub server — except session-end, which fails outright when asked to.</summary>
Relevance

●●● Strong

Recent tests accepted removal of summaries that merely duplicate descriptive test names and
behavior.

PR-#1178

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 2762993 disallows comments that merely restate what the code does. The added summary describes
the same request routing and conditional failure implemented immediately below it.

Rule 2762993: Restrict comments to documenting non-obvious, behavior‑critical constraints
test/Capacitor.Cli.Tests.Unit/Commands/ImportChainsTests.cs[514-521]

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 helper summary repeats behavior visible in its request handler.

## Fix Focus Areas
- test/Capacitor.Cli.Tests.Unit/Commands/ImportChainsTests.cs[514-520]

## Recommended Fix
Remove the summary, or replace it with a non-obvious constraint that explains why this handler is needed.

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


2. The Codex parser bypasses the JSON helper ✓ Resolved
Description
Parse checks root.ValueKind directly instead of using the available root.IsObject extension
property. Every line read from Codex’s session index passes through this check, leaving the new
parser out of step with the project’s JSON-shape convention.
Code

src/Capacitor.Cli.Core/Harness/Codex/CodexSessionIndexTitle.cs[87]

+            if (root.ValueKind != JsonValueKind.Object) return (null, null);
Relevance

●●● Strong

Recent repository precedents explicitly accept replacing direct JsonValueKind checks with shared
JSON helpers.

PR-#1232
PR-#1016

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The changed parser directly compares ValueKind to JsonValueKind.Object; the existing JSON
extension defines IsObject for that check.

Rule 2270023: Use JsonElementExtensions helpers instead of direct JsonValueKind comparisons
src/Capacitor.Cli.Core/Harness/Codex/CodexSessionIndexTitle.cs[83-89]
src/Capacitor.Models.Transcripts/JsonElementExtensions.cs[5-10]

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 Codex index parser compares `JsonElement.ValueKind` directly even though `IsObject` is available.

## Fix Focus Areas
- src/Capacitor.Cli.Core/Harness/Codex/CodexSessionIndexTitle.cs[87-87]

## Recommended Fix
Replace the direct comparison with `!root.IsObject`.

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


3. Import guide misstates which titles appear ✓ Resolved
Description
kcap import now posts Codex, Cursor, and Antigravity store titles, but the README still says Codex
titles are generated, Cursor titles come from transcripts, and Antigravity titles are left to the
server. Users reading the historical-import section are given the old behavior for all three agents,
including what to expect from the title-generation opt-out.
Code

src/Capacitor.Cli/Commands/ImportCommand.cs[3410]

+        var harnessTitled = await PostCodexHarnessTitleAsync(httpClient, baseUrl, session, perSessionProgress, ct);
Relevance

●●● Strong

Recent history consistently accepts README updates for user-facing CLI behavior changes.

PR-#191
PR-#629
PR-#318

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Checklist 2270057 requires README updates when an existing CLI command's default behavior changes.
The changed import paths post the three agents' store titles, while the README's historical-import
title paragraph describes their previous behavior.

Rule 2270057: Keep CLI documentation in README.md in sync with user-facing CLI changes
README.md[984-984]
src/Capacitor.Cli/Commands/ImportCommand.cs[3410-3410]
src/Capacitor.Cli/Harness/Cursor/CursorImportSource.cs[620-627]
src/Capacitor.Cli/Harness/Antigravity/AntigravityImportSource.cs[551-554]

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 README's historical-import section describes the old title behavior for Codex, Cursor, and Antigravity.

## Fix Focus Areas
- README.md[984-984]
- src/Capacitor.Cli/Commands/ImportCommand.cs[3410-3410]
- src/Capacitor.Cli/Harness/Cursor/CursorImportSource.cs[623-625]
- src/Capacitor.Cli/Harness/Antigravity/AntigravityImportSource.cs[552-554]

## Recommended Fix
Update the README's title paragraph to describe which store title each agent imports, when Codex still generates a title, and the effect of `--skip-title`.

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


View medium (5)
4. Codex imports repeatedly scan the index ✓ Resolved
Description
PostCodexHarnessTitleAsync constructs a fresh CodexSessionIndexTitle for every session, so the
reader's per-instance cache cannot avoid a full scan of the shared session_index.jsonl. Importing
many Codex sessions therefore rereads the entire index once per session, increasing import work with
both the session count and index size.
Code

src/Capacitor.Cli/Commands/ImportCommand.cs[R3465-3467]

+            var outcome = await ImportHarnessTitle.PostFromStoreAsync(
+                new CodexSessionIndexTitle(harnesses.Of<CodexHarness>().Paths.Home, session.SessionId),
+                httpClient, time, baseUrl, session.SessionId, progress, ct);
Relevance

●●● Strong

Recent performance findings accept redundant full-file scans and per-session repeated reads.

PR-#186
PR-#204
PR-#291

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The added call creates a reader for each session. The reader's cache starts empty on construction
and its first Read() calls Scan, which traverses every line of the shared index; the title-post
helper calls Read() for each import.

src/Capacitor.Cli/Commands/ImportCommand.cs[3462-3467]
src/Capacitor.Cli.Core/Harness/Codex/CodexSessionIndexTitle.cs[12-18]
src/Capacitor.Cli.Core/Harness/Codex/CodexSessionIndexTitle.cs[23-58]
src/Capacitor.Cli/Harness/Titles/ImportHarnessTitle.cs[30-43]

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

## Issue description
Codex imports construct a new index reader per session and scan the same shared file repeatedly.
## Fix Focus Areas
- src/Capacitor.Cli/Commands/ImportCommand.cs[3455-3467]
- src/Capacitor.Cli.Core/Harness/Codex/CodexSessionIndexTitle.cs[23-58]
## Recommended Fix
Read the shared index once per import run into a session-ID-to-title lookup, or share an index cache across sessions while preserving the ability to observe index changes.

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


5. A cancelled Codex import still reports Loaded ✓ Resolved
Description
PostCodexHarnessTitleAsync catches OperationCanceledException from the import token and returns
false instead of propagating cancellation. If cancellation occurs during a New-path title request,
session-end is attempted with the same canceled token and its failure is swallowed, then
OnTitleTaskReady queues an LLM title task without a token and the import returns
SessionImportOutcome.Loaded.
Code

src/Capacitor.Cli/Commands/ImportCommand.cs[R3470-3472]

+        } catch (OperationCanceledException) {
+            return false;
+        }
Relevance

●●● Strong

Recent reliability precedents accept findings involving swallowed cancellation and abandoned
asynchronous work.

PR-#357
PR-#187
PR-#136

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The title request and its backoff delays use the import token, but PostCodexHarnessTitleAsync
converts cancellation into false. The subsequent session-end call uses that same token inside a
catch-all handler, allowing execution to reach OnTitleTaskReady, which queues a Task.Run without
a token, and then the Loaded return.

src/Capacitor.Cli/Commands/ImportCommand.cs[3410-3449]
src/Capacitor.Cli/Commands/ImportCommand.cs[1403-1432]
src/Capacitor.Cli/Harness/Titles/ImportHarnessTitle.cs[60-79]
src/Capacitor.Cli.Core/Http/HarnessTitleClient.cs[25-51]
src/Capacitor.Cli/Commands/ImportCommand.cs[3410-3414]
src/Capacitor.Cli/Commands/ImportCommand.cs[3430-3449]
src/Capacitor.Cli/Commands/ImportCommand.cs[3464-3472]

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

## Issue description
Cancellation during a New-path Codex title request is swallowed, allowing the import to report `Loaded` and schedule background title work even though session-end may not have been sent.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/ImportCommand.cs[3410-3449]
- src/Capacitor.Cli/Commands/ImportCommand.cs[3464-3472]
- src/Capacitor.Cli/Harness/Cursor/CursorImportSource.cs[620-627]

## Recommended Fix
Make `PostCodexHarnessTitleAsync` propagate cancellation of the import token rather than returning `false`: remove the catch or restrict it to `catch (OperationCanceledException) when (!ct.IsCancellationRequested)`, consistent with the Partial path. When the import token is canceled, attempt the required session-end with a separately bounded token before propagating cancellation; do not queue background title work or return `Loaded`. Apply the same cancellation-handling change to the Cursor catch.

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


6. A parser comment repeats its return value ✓ Resolved
Description
The comment above Parse says that lines without a session or title produce nulls, which the
adjacent guards and return statements already show. A reader maintaining the parser gains no
constraint or rationale from it, so it adds another statement to keep aligned with the
implementation.
Code

src/Capacitor.Cli.Core/Harness/Codex/CodexSessionIndexTitle.cs[81]

+    // A line naming no session or no title parses to nulls.
Relevance

●● Moderate

Evidence is mixed: redundant-comment removal was rejected once, while later comment-focused cleanup
was accepted.

PR-#767
PR-#1159

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The newly added comment describes the null returns immediately below it rather than a
behavior-critical constraint.

Rule 2762993: Restrict comments to documenting non-obvious, behavior‑critical constraints
src/Capacitor.Cli.Core/Harness/Codex/CodexSessionIndexTitle.cs[81-98]

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 comment above `Parse` restates behavior visible in its return statements without documenting a non-obvious constraint.

## Fix Focus Areas
- src/Capacitor.Cli.Core/Harness/Codex/CodexSessionIndexTitle.cs[81-82]

## Recommended Fix
Remove the comment and leave the parser behavior expressed by its guards and returns.

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


7. Loaded Codex renames fail silently ✓ Resolved
Description
PostAlreadyLoadedCodexTitlesAsync passes null progress to PostCodexHarnessTitleAsync and
discards its result. If the server refuses a title, the request fails, or the session remains
unrecognized after retries, the import finishes without the warning emitted for new and resumed
sessions.
Code

src/Capacitor.Cli/Commands/ImportCommand.cs[3514]

+            async (session, token) => await PostCodexHarnessTitleAsync(httpClient, baseUrl, session, null, token));
Relevance

●● Moderate

The warning-loss concern is plausible, but no closely matching precedent confirms acceptance for
loaded-session progress callbacks.

PR-#675
PR-#192

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The loaded-session pass supplies null progress and discards the posting result.
ImportHarnessTitle.PostAsync reports refused, failed, and exhausted session-not-found outcomes
only through progress; the new and resumed chain paths supply a per-session callback that forwards
those warnings.

src/Capacitor.Cli/Commands/ImportCommand.cs[3502-3515]
src/Capacitor.Cli/Harness/Titles/ImportHarnessTitle.cs[55-75]
src/Capacitor.Cli/Commands/ImportCommand.cs[3232-3245]
src/Capacitor.Cli/Commands/ImportCommand.cs[3261-3261]

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 title-only pass for already-loaded Codex sessions suppresses title-post failures because it supplies no progress callback and ignores the result.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/ImportCommand.cs[1742-1750]
- src/Capacitor.Cli/Commands/ImportCommand.cs[3502-3515]

## Recommended Fix
Pass a progress callback from `HandleImport` into the title-only pass and surface `ImportTitleNotRecorded` through the existing session-warning display path. Preserve the pass's title-only behavior.

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


8. Generated Codex titles never appear ✓ Resolved
Description
PostCodexHarnessTitleAsync falls back to /hooks/set-title when /hooks/harness-title is
unavailable, then returns false so OnTitleTaskReady queues a generated title. On a kcap-server
that accepts the fallback for an untitled session, that first write is hook-title; the later
/hooks/session-title write is initial and cannot replace it.
Code

src/Capacitor.Cli/Commands/ImportCommand.cs[3446]

+        if (!harnessTitled) events.OnTitleTaskReady((session.SessionId, session.FilePath, session.PreviousSessionId, session.Vendor));
Relevance

●● Moderate

The behavior is semantically risky, but the PR explicitly documents and tests this legacy fallback
contract.

PR-#1230

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The PR queues generation unless the new route accepted the Codex title, while its title client posts
to the legacy route on a route-missing response. The server assigns the legacy write hook-title,
maps a generated request without a source to initial, and only allows that initial write to fill
an empty title.

kcap-cli -> kcap-server
src/Capacitor.Cli/Commands/ImportCommand.cs[3446-3469]
src/Capacitor.Cli.Core/Http/HarnessTitleClient.cs[49-70]
src/Capacitor.Cli/Commands/ImportCommand.cs[3027-3041]
External repo: kurrent-io/kcap-server, src/Capacitor.Api.Public/Hooks/SessionActivityHookHandlers.cs [382-399]
External repo: kurrent-io/kcap-server, src/Capacitor.Api.Public/Hooks/SessionActivityHookHandlers.cs [312-349]
External repo: kurrent-io/kcap-server, src/Capacitor.Server.Services/ReadModels/SessionTitleLadder.cs [26-39]
External repo: kurrent-io/kcap-server, docs/superpowers/specs/2026-09-29-ai3335-harness-native-session-titles-design.md [177-178]

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

## Issue description
Codex imports queue a generated title after the legacy set-title fallback, but the server does not let that generated title replace the fallback.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/ImportCommand.cs[3446-3446]
- src/Capacitor.Cli/Commands/ImportCommand.cs[3465-3469]
- src/Capacitor.Cli/Harness/Titles/ImportHarnessTitle.cs[39-43]

## Recommended Fix
When Codex will generate a title on a server without the harness-title route, avoid writing the legacy title first. Keep other imports' fallback behavior unchanged, and add a test that verifies the server-visible title after both requests rather than only checking that generation was queued.

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



Informational

9. Every import re-posts titles for loaded sessions ✗ Dismissed
Description
Cursor and Antigravity send a harness-title post whatever the classification status, including for
AlreadyLoaded sessions. ImportCommand routes AlreadyLoaded sessions on every run, so each
historical session gets another title request, which is an untimed rename for Cursor.
Code

src/Capacitor.Cli/Harness/Cursor/CursorImportSource.cs[R621-625]

+        if (_titlePaths is not null) {
+            try {
+                await ImportHarnessTitle.PostFromStoreAsync(
+                    HarnessTitleStores.Cursor(_titlePaths, transcriptPath),
+                    ctx.HttpClient, _time, ctx.BaseUrl, classification.SessionId, ctx.Progress, ct);
Relevance

●●● Strong

Recent import precedent accepts repairs on AlreadyLoaded sessions to restore missing lifecycle or
related state.

PR-#262
PR-#675

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The routed filter in ImportCommand includes AlreadyLoaded sessions, and the new title post in Cursor
has no status guard. Antigravity's AlreadyLoaded repair branch calls PostHarnessTitleAsync
explicitly.

src/Capacitor.Cli/Commands/ImportCommand.cs[1312-1326]
src/Capacitor.Cli/Harness/Antigravity/AntigravityImportSource.cs[239-270]

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

## Issue description
AlreadyLoaded repair runs re-post harness titles for every previously imported Cursor or Antigravity session on each import.

## Fix Focus Areas
- src/Capacitor.Cli/Harness/Cursor/CursorImportSource.cs[620-627]
- src/Capacitor.Cli/Harness/Antigravity/AntigravityImportSource.cs[263-263]

## Recommended Fix
Guard the title post with `classification.Status is New or Partial`, or with the session actually having sent content. If re-asserting titles on repair runs is intended, document it.

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


10. Shared title posting breaks folder layout 📘 Rule violation ⌂ Architecture
Description
PostFromStoreAsync adds a cross-vendor import-posting operation to
Harness/Titles/ImportHarnessTitle.cs, a directory under Harness/ that is not a vendor directory.
Codex, Cursor, and Antigravity import paths all call it, so the newly added shared behavior remains
inside the area reserved for vendor-specific code.
Code

src/Capacitor.Cli/Harness/Titles/ImportHarnessTitle.cs[30]

+    public static async Task<HarnessTitleOutcome?> PostFromStoreAsync(
Relevance

● Weak

Recent precedent rejects architecture findings requiring shared logic to move out of Harness
directories.

PR-#877
PR-#1178

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Checklist 2762984 requires cross-vendor shared code to live outside any Harness/ directory. The
added PostFromStoreAsync method is in Harness/Titles/, and the three changed vendor import paths
call it.

Rule 2762984: Place vendor-specific harness code only in the correct Harness/&lt;Vendor&gt;/ assembly and directory
src/Capacitor.Cli/Harness/Titles/ImportHarnessTitle.cs[28-44]
src/Capacitor.Cli/Commands/ImportCommand.cs[3464-3469]
src/Capacitor.Cli/Harness/Cursor/CursorImportSource.cs[621-626]
src/Capacitor.Cli/Harness/Antigravity/AntigravityImportSource.cs[551-554]

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 title-posting operation is shared across vendors but is located beneath the vendor harness directory.

## Fix Focus Areas
- src/Capacitor.Cli/Harness/Titles/ImportHarnessTitle.cs[28-44]

## Recommended Fix
Place cross-vendor title-posting code in a shared CLI directory outside Harness, then update its callers and namespace.

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

Dismiss ↗ | View ↗


11. Codex import helper breaks vendor layout ✓ Resolved
Description
PostCodexHarnessTitleAsync puts Codex-specific store selection and posting in
Commands/ImportCommand.cs rather than the CLI's Harness/Codex/ directory. Both the new-import
and resumed-import branches call this helper, extending vendor-specific logic in the shared command
instead of confining it to the designated harness location.
Code

src/Capacitor.Cli/Commands/ImportCommand.cs[R3465-3467]

+            var outcome = await ImportHarnessTitle.PostFromStoreAsync(
+                new CodexSessionIndexTitle(harnesses.Of<CodexHarness>().Paths.Home, session.SessionId),
+                httpClient, time, baseUrl, session.SessionId, progress, ct);
Relevance

● Weak

Recent repository precedent rejects moving vendor-specific behavior solely to satisfy prescribed
directory placement.

PR-#877
PR-#1178

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Checklist 2762984 places vendor-specific CLI harness logic under Harness/<Vendor>/. The added
method selects CodexHarness and constructs CodexSessionIndexTitle inside
Commands/ImportCommand.cs.

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

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 Codex title-posting helper lives in a shared CLI command rather than the designated Codex harness directory.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/ImportCommand.cs[3452-3473]

## Recommended Fix
Move the Codex-specific store selection and posting logic into the CLI's Harness/Codex directory and have the import command call that vendor-specific component.

ⓘ 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: 54891e9c) — View relationship
Review mode: 🚀 Fast: The push makes a small, localized change to propagate Codex title-post warnings and replaces an equivalent JSON kind check, with no broad or high-risk behavior changes.

Grey Divider

Tip of the day
💡 Did you know, you can route each severity your way: inline, summary, both, or drop

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread src/Capacitor.Cli/Commands/ImportCommand.cs Outdated
Comment thread src/Capacitor.Cli/Commands/ImportCommand.cs Outdated
Comment thread src/Capacitor.Cli/Commands/ImportCommand.cs Outdated
Comment thread src/Capacitor.Cli/Harness/Cursor/CursorImportSource.cs
Comment thread src/Capacitor.Cli/Commands/ImportCommand.cs
realtonyyoung and others added 3 commits September 30, 2026 09:17
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>
@realtonyyoung

Copy link
Copy Markdown
Collaborator Author

Qodo findings without an inline thread:

6. Shared title posting breaks folder layout — Not changed in this PR: Harness/Titles/ (in both Capacitor.Cli and Capacitor.Cli.Core) was established by the already-merged harness-title change; this PR only adds a method beside its sibling in an existing file. Relocating both assemblies' shared title directories (and their test mirrors) out of Harness/ is a separate layout refactor, not something to fold into a behaviour change.

7. Codex import helper breaks vendor layout — Fixed in c734ac7: the Codex index read and title posting now live in src/Capacitor.Cli/Harness/Codex/CodexImportTitles.cs; ImportCommand only routes a Codex session to it.

🤖 Addressed by Claude Code

@realtonyyoung

Copy link
Copy Markdown
Collaborator Author

/agentic_review

@qodo-code-review

Copy link
Copy Markdown

Qodo findings without an inline thread:

6. Shared title posting breaks folder layout — Not changed in this PR: Harness/Titles/ (in both Capacitor.Cli and Capacitor.Cli.Core) was established by the already-merged harness-title change; this PR only adds a method beside its sibling in an existing file. Relocating both assemblies' shared title directories (and their test mirrors) out of Harness/ is a separate layout refactor, not something to fold into a behaviour change.

7. Codex import helper breaks vendor layout — Fixed in c734ac7: the Codex index read and title posting now live in src/Capacitor.Cli/Harness/Codex/CodexImportTitles.cs; ImportCommand only routes a Codex session to it.

🤖 Addressed by Claude Code

Understood:

  • finding 6 remains active because the shared Harness/Titles/ layout predates this PR and is out of scope for this behavior change.
  • finding 7 is addressed by c734ac76; the Codex-specific logic now resides in src/Capacitor.Cli/Harness/Codex/CodexImportTitles.cs.

No action was taken on either finding.

Comment thread src/Capacitor.Cli.Core/Harness/Codex/CodexSessionIndexTitle.cs Outdated
Comment thread src/Capacitor.Cli.Core/Harness/Codex/CodexSessionIndexTitle.cs Outdated
Comment thread src/Capacitor.Cli/Commands/ImportCommand.cs Outdated
@qodo-code-review

Copy link
Copy Markdown

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

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

Copy link
Copy Markdown
Collaborator Author

/agentic_review

Comment thread test/Capacitor.Cli.Tests.Unit/Commands/ImportChainsTests.cs Outdated
@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 9e66964

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@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 8cb9239

@realtonyyoung
realtonyyoung merged commit 4211d30 into main Sep 30, 2026
8 checks passed
@realtonyyoung
realtonyyoung deleted the claude-tyoung/ai-3335-import-store-titles branch September 30, 2026 14:03
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.

1 participant