Skip to content

feat(source): add loopback CDP cookie source - #121

Open
keithah wants to merge 5 commits into
mvanhorn:mainfrom
keithah:feat/cdp-source
Open

feat(source): add loopback CDP cookie source#121
keithah wants to merge 5 commits into
mvanhorn:mainfrom
keithah:feat/cdp-source

Conversation

@keithah

@keithah keithah commented Sep 7, 2026

Copy link
Copy Markdown

Summary

  • add an explicit loopback-only cdp_source mode for reading an existing Chromium cookie jar through CDP
  • preserve the existing blocklist, DBSC classification, and paired encrypted transport
  • prevent CDP sources from reading SQLite, Local Storage, IndexedDB, or machine-wide secrets; scope source metadata to the selected config directory

Verified

  • go build ./...
  • go vet ./...
  • focused and race-enabled CDP/config/source tests
  • read-only live probe against an existing Linux Chromium CDP endpoint: 119 allowlisted cookies, 0 secrets; values were not logged
  • go test ./... remains blocked by the pre-existing host-sensitive internal/cli TestCheckDaemonBinaryPath failure, reproduced on clean base and branch; all other packages pass

Notes

  • Adds cdp_source.enabled and cdp_source.endpoint to source.yaml.
  • The endpoint accepts only a bare loopback HTTP origin. source --watch polls every 10 seconds because CDP has no cookie-change event.
  • CDP-source mode is intentionally cookies-only and does not fall back to browser-profile files or secrets bus state.

@greptile-apps

greptile-apps Bot commented Sep 7, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds a loopback-only CDP cookie source and subsequently integrates it with multi-sink fan-out, per-sink state, local commands, inspection commands, and wizard configuration.

  • Validates CDP endpoints as literal loopback HTTP origins and reads browser-scoped cookies through CDP.
  • Reuses the existing cookie policy, DBSC classification, encryption, and source-to-sink transport.
  • Adds multi-sink configuration, per-peer sealing, failure isolation, state reporting, and additive wizard pairing.
  • Keeps CDP source mode cookies-only, avoiding SQLite, browser storage directories, and machine-wide secrets discovery.
  • The two previous review findings are fixed, but the additive wizard currently drops CDP configuration when rewriting the source file.

Confidence Score: 4/5

The PR is not yet safe to merge because adding a sink to a CDP-backed source silently rewrites it into a SQLite-backed source.

The additive wizard does not preserve cdp_source, so a documented operation can change the source mode and make a Linux CDP-only installation unusable or read a different browser profile. The remaining findings concern misleading health and status reporting. Both previous review findings are fully fixed: CDP-aware local commands now use the configured reader, and CDP source health readers use the writer’s config-scoped path.

Files Needing Attention: internal/cli/wizard.go, internal/cli/source.go, internal/cli/status.go

Important Files Changed

Filename Overview
internal/cdpsource/source.go Adds a loopback-restricted CDP reader and maps CDP cookie fields into the existing Chrome cookie model.
internal/cli/source.go Integrates CDP reads and multi-sink encrypted fan-out, but successful empty cycles no longer update source health.
internal/cli/wizard.go Adds additive sink pairing and config migration, but its renderer drops cdp_source and silently changes the selected source mode.
internal/config/config.go Adds mutually exclusive CDP source configuration and backward-compatible effective sink resolution.
internal/cli/status.go Reads config-scoped CDP state and reports per-sink results, while its configuration header still assumes the legacy scalar sink.
internal/cli/doctor.go Aligns CDP source-state lookup with the writer and adds multi-sink failure details.
internal/state/state.go Adds backward-compatible per-sink push-state records keyed by peer identity.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
    C[Source configuration] --> M{Source mode}
    M -->|CDP| D[Loopback CDP cookie jar]
    M -->|File| S[Chrome SQLite and browser storage]
    D --> F[Fresh cookie policy and DBSC filtering]
    S --> F
    F --> E[Build one sync envelope]
    E --> K1[Seal with sink A key]
    E --> K2[Seal with sink B key]
    K1 --> A[Configured sink A]
    K2 --> B[Configured sink B]
    A --> H[Per-sink source health]
    B --> H
    H --> O[status and doctor]
Loading

Comments Outside Diff (2)

  1. internal/cli/source.go, line 337-355 (link)

    P2 Empty Pushes Look Stale

    A successful cycle with no eligible cookies and no secrets returns no sink results, so this loop does not update LastPush or TotalPushes. The command succeeds, but status and doctor can continue reporting that an active source has never pushed or is stale. Successful empty cycles should still update source health.

    Knowledge Base Used:

    Fix in Codex Fix in Claude Code Fix in Cursor Fix in Conductor

  2. internal/cli/status.go, line 107-109 (link)

    P2 Multi-Sink Status Is Blank

    Human-readable status prints only the legacy SourceConfig.Sink.URL. A valid configuration using the authoritative sinks: list therefore displays a blank source -> target, even though effective destinations are configured. This makes status misleading during setup and diagnosis; it should show the resolved sink list.

    Knowledge Base Used:

    Fix in Codex Fix in Claude Code Fix in Cursor Fix in Conductor

Fix all with Greploop Fix All in Codex Fix All in Claude Code Fix All in Cursor Fix All in Conductor

Reviews (5): Last reviewed commit: "test: isolate daemon path check from hos..." | Re-trigger Greptile

Comment thread internal/config/config.go
Comment on lines +221 to +225
if cfg.CDPSource.Enabled {
if err := cdpsource.ValidateEndpoint(cfg.CDPSource.Endpoint); err != nil {
return fmt.Errorf("%s: %w", path, err)
}
return nil

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 CDP Config Breaks Local Commands

When cdp_source is enabled, this branch returns before resolving the normal Chrome database path. However, export, agent-sync, and cmux-sync use this loader and still unconditionally read from SQLite through cfg.Chrome.DBPath. A valid CDP-enabled source.yaml therefore leaves the path empty and causes these existing commands to fail instead of reading the configured source. Either these commands need to support CDP, or their configuration load must still resolve the file-based source.

Knowledge Base Used: Agentcookie CLI workflows

Fix in Codex Fix in Claude Code Fix in Cursor Fix in Conductor

Comment thread internal/cli/source.go
Comment on lines +220 to +224
func sourceStatePath(cdpSource bool, configDir, home string) string {
if cdpSource {
return filepath.Join(configDir, "state", "source-state.json")
}
return state.SourcePath(home)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Source Health Becomes Invisible

CDP source health is written under <config-dir>/state/source-state.json, but both status and doctor still read only ~/.agentcookie/source-state.json. After a successful CDP-source push, status omits the source health and doctor can incorrectly report that the daemon has never pushed. The readers and writer need to use the same state path.

Knowledge Base Used: CLI configuration and local state

Fix in Codex Fix in Claude Code Fix in Cursor Fix in Conductor

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