Skip to content

Privatize non-Cursor replays that attach new child content - #384

Merged
realtonyyoung merged 7 commits into
mainfrom
ai-1397-private-import-child-content
Jul 28, 2026
Merged

Privatize non-Cursor replays that attach new child content#384
realtonyyoung merged 7 commits into
mainfrom
ai-1397-private-import-child-content

Conversation

@realtonyyoung

@realtonyyoung realtonyyoung commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Problem

kcap import --private fails to privatize a session when the run attaches brand-new nested-child (subagent) content to a session that was already fully imported. The session keeps whatever visibility it had — public, if an earlier non-private import stamped an org default — while carrying content the --private run just added. Narrow, but a genuine privacy leak.

Mechanism

The end-of-run privatize pass unions two sets:

  • importedSessionIds — membership keyed on the call's raw ImportOutcome being Loaded/Resumed.
  • privateScopeSessionIds — the outcome-independent tracker that exists precisely so privacy doesn't depend on that classification. It was gated to vendor == "cursor".

A non-Cursor replay that attaches child content falls through both. The two vendors fail differently, which matters for the tests:

replay outcome leaks?
Antigravity hardcoded Skipped however much child content the repair attached yes — never reaches the Loaded/Resumed arm
Gemini Resumed on success, Failed if session-end fails only on the failure path

Gemini's success path was already covered, so the obvious "Gemini + new child content" test passes before the fix and proves nothing. Its real gap is that ImportSubagentsAsync posts the child transcript before session-end, so a failing session-end degrades the outcome to Failed with the child content already public.

The replayed session-start's default_visibility can't rescue either case: it is a create-time hint, and by definition an already-ingested session already exists. The old comment claimed non-Cursor vendors were covered by that stamp — they aren't, and Copilot/Gemini/Kiro/Cursor never emit one at all.

Fix

Scope the capture by a new IImportSource.AttachesChildContentOnReplay capability rather than a vendor-name check, so the source that owns the child-import pass decides and a newly-added source has to answer at compile time:

  • true — Cursor, Antigravity, Gemini (child-import pass reachable on an AlreadyLoaded replay)
  • false — Claude/Codex (chain-based, never routed), Copilot/Kiro/Pi (no child import; they still replay lifecycle), OpenCode (its ImportSessionAsync returns before any POST for AlreadyLoaded)

false claims only that the AlreadyLoaded call posts no transcript content — not that the source never posts, and not that it can never add content on New/Partial.

Cursor's behaviour is unchanged. Counting/Done-grid behaviour is unchanged — importedSessionIds still keys off the raw outcome.

Routed bookkeeping collapsed to one site

Surfaced by review: the TTY and non-TTY Parallel.ForEachAsync bodies each carried their own copy of the privatize capture, the counting resolution, the per-vendor tracker, the membership decision and the aggregate totals — so a regression in one branch was invisible to tests that exercise a single display mode. All of it now lives in RecordRoutedResultAsync; the two branches differ only in how they draw.

Tests

  • RoutedReplayPrivatizeTests (new) — the per-vendor pin: Antigravity AlreadyLoaded+new-child on the success path, Antigravity and Gemini on the session-end-failed path, plus a non-private zero-PUT guard. All three privatize assertions fail on main for the right reason and pass here.
  • RoutedPrivatizeMembershipTests (new) — pins that the counting override never feeds importedSessionIds. Needs a source that attaches child content while sitting outside the private scope, which no shipped source does, so it uses a deliberately contradictory probe. Asserts both halves (the override fired → Loaded 1; membership didn't follow → zero PUTs) so it can't pass vacuously. Mutation-verified: keying membership off resolved fails it.
  • ReplayChildContentCapabilityTests (new) — pins the capability per source, with a reflection guard so a new IImportSource must be classified rather than silently defaulting to "not captured".
  • AntigravitySkippedChildOverrideRoutedLoopTests — its Effect 4 asserted zero visibility PUTs, i.e. it pinned this leak as correct behaviour. Now asserts exactly one PUT, and its doc records that it can no longer observe membership (the private scope covers the root, so the union absorbs raw-vs-resolved — verified by mutation) and points at the test that can.

Local: integration 149/149. macOS unit failures are the flake cluster CI's own matrix comment documents (which is why CI excludes macOS) — 56 on a clean origin/main baseline worktree vs 42 here, empty regression set, none import-related.

Out of scope (observed, not fixed)

A related but distinct leak: a New/Partial import of any vendor whose lifecycle POST fails after content persisted returns Failed and is likewise excluded from the privatize set. Different shape from this issue's "attaches child content on a replay", and fixing it would widen the change to all seven routed sources — so it is deliberately left alone rather than folded in silently.

Review

Codex review flow: clean after 5 rounds (findings on the vacuous membership assertion, the uncovered TTY branch, the duplicated totals, and two overstated comments — all fixed). Qodo: 2 verbosity findings fixed; 1 README finding answered inline (the Getting started section never mentions --private and defers flags to the section that was updated).

Closes #381
Linear: AI-1397

realtonyyoung and others added 2 commits July 28, 2026 14:08
kcap import --private failed to privatize a session when the run attached
brand-new nested-child (subagent) content to a session that was already fully
imported. The session kept whatever visibility it had — public, if an earlier
non-private import stamped an org default — while carrying content the
--private run had just added.

The end-of-run privatize pass unions importedSessionIds (membership keyed on
the raw ImportOutcome being Loaded/Resumed) with privateScopeSessionIds, the
outcome-independent tracker that exists precisely so privacy does not depend on
that classification. The latter was gated to vendor == "cursor", so a non-Cursor
replay that attached child content fell through both: Antigravity's AlreadyLoaded
repair branch reports a hardcoded Skipped however much child content it attached,
and Gemini's replay posts its child content before session-end, so a failing
session-end degrades the outcome to Failed. The replayed session-start's
default_visibility cannot cover either — it is a create-time hint, and an
already-ingested session already exists.

Scope the capture by a new IImportSource.AttachesChildContentOnReplay capability
instead of a vendor-name check, so the source owning the child-import pass is
what decides and a new source has to answer at compile time. True for Cursor,
Antigravity and Gemini; false for Claude/Codex (chain-based, never routed),
Copilot/Kiro/Pi (no child import), and OpenCode (its ImportSessionAsync
early-returns Skipped for AlreadyLoaded before posting anything).

Closes #381

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The routed phase has covered every non-chain source for a long time; the
leftover Cursor-only labels are what made the privatize gate's Cursor scoping
read as intentional.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@linear-code

linear-code Bot commented Jul 28, 2026

Copy link
Copy Markdown

AI-1397

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Privatize replays that can attach child content

🐞 Bug fix 🧪 Tests 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Privatizes replayed sessions when capable sources may attach nested child content.
• Replaces Cursor-specific gating with an explicit per-import-source replay capability.
• Adds vendor coverage tests and documents --private replay semantics.
Diagram

graph TD
  A["Import sources"] --> B["Replay capability"] --> C["Replay vendor set"] --> D["Routed replay"] --> E["Private scope IDs"] --> G["Privatize union"] --> H["Visibility API"]
  D --> F["Imported IDs"] --> G
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Keep a vendor allowlist
  • ➕ Requires fewer interface changes.
  • ➕ Produces the same immediate behavior for known vendors.
  • ➖ Couples privacy behavior to vendor strings.
  • ➖ New replay-capable sources can silently reintroduce the leak.
  • ➖ Ownership of replay behavior remains outside each source implementation.
2. Return exact mutation metadata
  • ➕ Could privatize only sessions that actually attached child content.
  • ➕ May avoid unnecessary visibility requests on no-op replays.
  • ➖ Requires broader changes to import result contracts and every failure path.
  • ➖ Partial lifecycle failures must preserve accurate mutation state.
  • ➖ Does not robustly address content attached by an earlier interrupted private run.

Recommendation: Use the PR's explicit source capability. It places replay semantics with the source that owns child importing, forces new implementations to make a compile-time decision, and remains safe when raw outcomes cannot represent already-persisted child content. The added exhaustive capability table and behavioral tests appropriately control the risk of over- or under-classification.

Files changed (15) +440 / -35

Enhancement (1) +24 / -0
IImportSource.csAdd replay child-content capability contract +24/-0

Add replay child-content capability contract

• Adds 'AttachesChildContentOnReplay' to require every import source to describe whether an already-ingested replay can post nested transcript content. Documents why privacy capture cannot rely on create-time visibility or raw import outcomes.

src/Capacitor.Cli/Commands/IImportSource.cs

Bug fix (10) +51 / -24
AntigravityImportSource.csMark Antigravity replays as child-content capable +1/-0

Mark Antigravity replays as child-content capable

• Declares that Antigravity's already-loaded repair path can attach nested child content during replay.

src/Capacitor.Cli/Commands/AntigravityImportSource.cs

ClaudeImportSource.csExclude Claude from replay child capture +1/-0

Exclude Claude from replay child capture

• Declares that chain-based Claude imports cannot attach child content through the routed replay path.

src/Capacitor.Cli/Commands/ClaudeImportSource.cs

CodexImportSource.csExclude Codex from replay child capture +1/-0

Exclude Codex from replay child capture

• Declares that chain-based Codex imports never use the routed child-content replay path.

src/Capacitor.Cli/Commands/CodexImportSource.cs

CopilotImportSource.csDeclare Copilot replays child-free +1/-0

Declare Copilot replays child-free

• Marks Copilot as unable to attach nested child content during replay.

src/Capacitor.Cli/Commands/CopilotImportSource.cs

CursorImportSource.csPreserve Cursor replay privacy behavior +1/-0

Preserve Cursor replay privacy behavior

• Declares Cursor's existing ability to attach subagent lifecycle and transcript content during replay, preserving its prior outcome-independent privatization behavior.

src/Capacitor.Cli/Commands/CursorImportSource.cs

GeminiImportSource.csMark Gemini replays as child-content capable +1/-0

Mark Gemini replays as child-content capable

• Declares that Gemini can resend and attach subagent transcripts while replaying an existing session.

src/Capacitor.Cli/Commands/GeminiImportSource.cs

ImportCommand.csPrivatize replay-capable sources independently of outcomes +42/-24

Privatize replay-capable sources independently of outcomes

• Builds a vendor set from source capabilities and captures every touched routed session from those vendors during private imports. Unions that set with existing imported-session membership without changing raw-outcome counting or Done-grid behavior.

src/Capacitor.Cli/Commands/ImportCommand.cs

KiroImportSource.csDeclare Kiro replays child-free +1/-0

Declare Kiro replays child-free

• Marks Kiro as unable to import nested child content during replay.

src/Capacitor.Cli/Commands/KiroImportSource.cs

OpenCodeImportSource.csExclude OpenCode's early-return replays +1/-0

Exclude OpenCode's early-return replays

• Declares OpenCode replay-safe because already-loaded sessions return before posting descendant or lifecycle content.

src/Capacitor.Cli/Commands/OpenCodeImportSource.cs

PiImportSource.csDeclare Pi replays child-free +1/-0

Declare Pi replays child-free

• Marks Pi as unable to attach nested child content during replay.

src/Capacitor.Cli/Commands/PiImportSource.cs

Tests (3) +363 / -11
AntigravitySkippedChildOverrideRoutedLoopTests.csAssert Antigravity replay privatization +20/-11

Assert Antigravity replay privatization

• Updates the routed-loop regression test to expect exactly one visibility request for the Antigravity root. Continues verifying that counting uses the resolved outcome while imported-session membership uses the raw skipped outcome.

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

RoutedReplayPrivatizeTests.csCover non-Cursor replay privacy failure paths +252/-0

Cover non-Cursor replay privacy failure paths

• Adds integration coverage for successful and lifecycle-failed Antigravity child repairs, Gemini child persistence followed by session-end failure, and non-private replay behavior. Verifies owner-only visibility requests target the replayed root session.

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

ReplayChildContentCapabilityTests.csPin replay capability for every import source +91/-0

Pin replay capability for every import source

• Tests the expected capability value for all current vendors. Uses reflection to ensure newly added import sources cannot remain unclassified by the capability table.

test/Capacitor.Cli.Tests.Unit/Import/ReplayChildContentCapabilityTests.cs

Documentation (1) +2 / -0
README.mdDocument private replay visibility semantics +2/-0

Document private replay visibility semantics

• Explains that '--private' also privatizes revisited sessions for agents capable of attaching previously missed subagent content. Clarifies why visibility cannot depend only on new top-level content.

README.md

@qodo-code-review

qodo-code-review Bot commented Jul 28, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (1) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. AttachesChildContentOnReplay documentation is verbose ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
The new property has a 22-line comment containing implementation history, vendor classifications,
failure scenarios, and a test reference. This violates the requirement to keep source comments
concise and necessary.
Code

src/Capacitor.Cli/Commands/IImportSource.cs[R99-120]

+    /// <summary>
+    /// True if a routed <see cref="ImportSessionAsync"/> call against an ALREADY-INGESTED session
+    /// can still POST transcript lines — to a nested child/subagent stream, since the root's own
+    /// content is by definition already caught up. This is what makes the call able to add
+    /// publicly-visible content to a session that already exists, which is why <c>--private</c>
+    /// captures these sources outcome-independently (see <c>privateScopeSessionIds</c> in
+    /// <see cref="ImportCommand"/>): the replayed session-start's <c>default_visibility</c> is a
+    /// CREATE-time hint and does nothing to a session that already exists, and the call's own
+    /// <see cref="ImportOutcome"/> can't be trusted to reveal the attach (Antigravity's repair
+    /// branch reports a hardcoded <see cref="ImportOutcome.Skipped"/>; any vendor's lifecycle POST
+    /// can fail AFTER the child content persisted and report <see cref="ImportOutcome.Failed"/>).
+    ///
+    /// <para>
+    /// True for the three sources with a child-import pass reachable on a replay (Cursor,
+    /// Antigravity, Gemini). False for the chain-based sources (Claude, Codex — never routed) and
+    /// for Copilot/Kiro/Pi, which have no child import at all. Also false for OpenCode: it DOES
+    /// import descendants, but its ImportSessionAsync early-returns Skipped for AlreadyLoaded
+    /// before posting anything, so a replay cannot attach content — a contract pinned by
+    /// <c>ImportVisibilityTests.OpenCode_already_loaded_session_is_skipped_before_any_session_start</c>.
+    /// Flip this to true if that ever gains a repair pass.
+    /// </para>
+    /// </summary>
Evidence
PR Compliance ID 4 requires concise, necessary source comments. The cited property documentation
spans multiple paragraphs and includes detailed outcome scenarios, a complete vendor matrix, and a
specific test name that are not required to explain the interface contract.

CLAUDE.md: Keep Source Comments Concise and Free of Linear Issue Numbers
src/Capacitor.Cli/Commands/IImportSource.cs[99-120]

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 XML documentation for `AttachesChildContentOnReplay` is unnecessarily verbose and embeds implementation and test details.

## Issue Context
Retain a concise explanation of the capability while moving vendor-specific rationale to tests or other appropriate documentation.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/IImportSource.cs[99-120]

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


2. Getting started remains unsynchronized 📘 Rule violation ⚙ Maintainability
Description
The changed --private replay behavior is documented only in the per-command section, while the
Getting started import section remains unchanged. The checklist explicitly requires user-facing CLI
changes to update both locations.
Code

README.md[562]

+`--private` also covers sessions the run only *revisits*. Agents that record subagents (Cursor, Antigravity, Gemini) can attach a previously-missed subagent to a session that was already fully imported, so for those a `--private` re-run marks every session it touched private — not just the ones with brand-new top-level content. That is deliberate: a session's visibility can't be left to whether a re-run happened to find new content, and re-running with `--private` is the supported way to privatize sessions an earlier non-private import made visible.
Evidence
PR Compliance ID 6 requires updates to both README locations. The new explanation appears at
README.md[562-562], but the Getting started import guidance at README.md[136-160] does not
mention --private or its revised replay semantics.

CLAUDE.md: Keep README Documentation Synchronized With User-Facing CLI Changes
README.md[136-160]
README.md[550-562]

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 documents the changed `--private` replay behavior only in the detailed import-command section.

## Issue Context
PR Compliance ID 6 requires synchronized coverage in both Getting started and the applicable CLI command section for user-facing behavior changes.

## Fix Focus Areas
- README.md[136-160]
- README.md[550-562]

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


3. privateScopeSessionIds comment is verbose ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
The expanded comment adds more than twenty lines of historical and control-flow explanation before a
simple tracker declaration. This violates the requirement to favor concise comments and
self-explanatory implementation.
Code

src/Capacitor.Cli/Commands/ImportCommand.cs[R1189-1209]

+        // only gains a session id when this run did "real new work" by the
        // Loaded/Failed/AlreadyLoaded + SentChildContent accounting — but privacy must NOT
        // depend on that classification: a lifecycle POST (subagent-stop/session-end) can fail
        // AFTER a child transcript has already persisted new content (this run's own
-        // ImportSessionAsync then returns Failed), or a later retry can see the child read as
-        // already-complete (SentChildContent=false) even though a PRIOR run attached new
-        // content that was never privatized. Either way `importedSessionIds` would exclude the
-        // session and a public session would stay public. So every Cursor routed classification
-        // this run touches — regardless of its outcome — is unconditionally captured here when
-        // --private is requested, and privatized at the end independent of Loaded/Failed/
-        // AlreadyLoaded/SentChildContent. Scoped to Cursor (vendor == "cursor") because
-        // SentChildContent/this lifecycle-after-content-persisted shape is Cursor-specific;
-        // every other routed vendor's own default_visibility-on-session-start stamp already
-        // privatizes atomically and isn't exposed to this gap.
+        // ImportSessionAsync then returns Failed), a source can report a hardcoded Skipped for a
+        // repair that DID attach a child (Antigravity), or a later retry can see the child read
+        // as already-complete (SentChildContent=false) even though a PRIOR run attached new
+        // content that was never privatized. In every one of those `importedSessionIds` would
+        // exclude the session and a public session would stay public. So each routed
+        // classification this run touches for a source that can attach child content on a replay
+        // — regardless of its outcome — is unconditionally captured here when --private is
+        // requested, and privatized at the end independent of Loaded/Failed/AlreadyLoaded/
+        // SentChildContent.
+        //
+        // Scoped by IImportSource.AttachesChildContentOnReplay rather than a vendor-name check:
+        // the risk is precisely "this call can add content to a session that ALREADY EXISTS", so
+        // the source that owns that child-import pass is what decides. A source whose replay can
+        // post nothing needs no post-hoc privatize — its only reachable content path is a New
+        // session, which under --private is never stamped with a public default_visibility in the
+        // first place (server-side sessions are private by default). Note the create-time stamp
+        // is NOT what protects the sources below: it does nothing to an already-existing session.
Evidence
PR Compliance ID 4 requires source comments to remain concise. The added block narrates several
vendor outcomes, retry cases, server defaults, and design history instead of briefly stating why
replay-capable sources require outcome-independent privacy tracking.

CLAUDE.md: Keep Source Comments Concise and Free of Linear Issue Numbers
src/Capacitor.Cli/Commands/ImportCommand.cs[1189-1209]

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 preceding `privateScopeSessionIds` is unnecessarily long and repeats implementation details represented by the capability property and tests.

## Issue Context
Preserve only the essential privacy invariant and let names such as `AttachesChildContentOnReplay` explain the selection mechanism.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/ImportCommand.cs[1189-1209]

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


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment thread src/Capacitor.Cli/Commands/IImportSource.cs
Comment thread src/Capacitor.Cli/Commands/ImportCommand.cs Outdated
Comment thread README.md
realtonyyoung and others added 5 commits July 28, 2026 14:30
Address Qodo findings 1 and 2: the vendor enumeration now lives only in
ReplayChildContentCapabilityTests, which pins it, rather than being restated in
the interface doc, and the privateScopeSessionIds comment keeps the privacy
invariant while dropping the mechanism the capability name already conveys.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The flipped Effect 4 assertion did not actually guard importedSessionIds
membership. The privatize set is HashSet(importedSessionIds) unioned with
privateScopeSessionIds, and the Antigravity root is now in the private scope, so
keying membership off the resolved Loaded outcome unions the same single id and
still emits exactly one PUT. ComputePerSourceFinalCounts does not expose it
either: for routed vendors it takes the routedOutcomes early return and ignores
its imported argument.

Observing the rule needs a source that attaches child content while sitting
outside the private scope, which no shipped source does. Add a probe source that
reports Skipped + SentChildContent while declaring
AttachesChildContentOnReplay=false, and assert both that the counting override
fired (Loaded 1, the Loading line) and that no visibility PUT followed. Verified
by mutation: keying membership off resolved fails the new test and leaves the
Antigravity one green. Corrected that test's doc and comment to stop claiming a
guarantee it cannot provide.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The membership guard only covered the non-TTY branch: the TTY and non-TTY
Parallel.ForEachAsync bodies each carried their own copy of the privatize
capture, the counting resolution and the membership decision, so rewiring only
the TTY copy would have left the new test green. The two branches could drift
independently.

Extract RecordRoutedResultAsync, which performs every non-rendering effect and
returns the resolved outcome plus the raw one (the switch's null-when-Skipped
arm needs it). Both branches now differ only in how they draw, leaving exactly
one routed membership site and one privatize capture. Re-verified by mutation
against the shared routine.

Also rename the Antigravity test, whose name still carried the stays_out_of_
private_set claim that commit 5bf09ea removed from its comments.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
routedLoaded/routedExcluded/routedErrored were still incremented inside each
renderer's switch, so the claim that the branches differ only in how they draw
was false and a TTY-only drift in the totals mapping stayed invisible to the
non-TTY tests. They are non-rendering effects; fold them into
RecordRoutedResultAsync alongside the rest, leaving both switches purely
renderer-specific.

Also narrow the privacy-scope justification, which overreached: a false
capability says only that the AlreadyLoaded call posts nothing, not that the
source never posts. Copilot/Kiro/Pi/OpenCode all post on New and Partial, and
OpenCode imports descendants there — that is the separately scoped residual, so
the comment no longer erases it. The interface contract now names
ClassificationStatus.AlreadyLoaded instead of the looser already-ingested
phrasing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The narrowed contract was still literally false for three of the capability-false
sources: Copilot, Kiro and Pi have no AlreadyLoaded early-return and still replay
session-start and session-end there, so those calls do POST. Only OpenCode
returns before any POST. Since the flag is about attaching transcript/child
content, both comments now say the AlreadyLoaded call posts no transcript
content, and keep the per-source distinction rather than implying lifecycle
repair is absent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@realtonyyoung
realtonyyoung merged commit 5ca07b9 into main Jul 28, 2026
6 checks passed
@realtonyyoung
realtonyyoung deleted the ai-1397-private-import-child-content branch July 28, 2026 21:41
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.

kcap import --private doesn't privatize non-Cursor sessions that attach new child content

1 participant