Skip to content

feat(parser): migrate CLI/JSONL providers#878

Open
mariusvniekerk wants to merge 9 commits into
fam/source-set-frameworkfrom
fam/cli-jsonl
Open

feat(parser): migrate CLI/JSONL providers#878
mariusvniekerk wants to merge 9 commits into
fam/source-set-frameworkfrom
fam/cli-jsonl

Conversation

@mariusvniekerk

@mariusvniekerk mariusvniekerk commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

Migrates the directory-JSONL providers — commandcode, iflow, gptme, deepseek-tui, amp, zencoder, pi, kimi, cortex, workbuddy — onto concrete facade providers. Each folds its discovery, raw-session lookup, fingerprinting, and parse normalization onto the provider and drops the legacy sync dispatch, becoming provider-authoritative. Symlinked project-root discovery and existing parse output are preserved.

Where to look: the per-agent *_provider.go files and their source sets.

Command Code and iFlow both fit the directory JSONL source shape, so moving them together proves the helper against real providers without mixing in nested layouts like Qwen or composite providers like WorkBuddy.

The providers keep source discovery, changed-path classification, persisted lookup, fingerprinting, and parse normalization behind concrete facade implementations while preserving the legacy parser functions for current runtime callers.

fix(parser): preserve JSONL provider symlink discovery

Command Code and iFlow legacy discovery followed symlinked project directories. The migrated providers should keep that behavior so users with linked project roots do not silently lose discovery or raw-session lookup after moving onto the provider facade.

test(parser): opt commandcode iflow into provider shadow

CommandCode and iFlow now have concrete facade providers on this branch, so keeping them legacy-only would let the migration branch remain additive instead of exercised by the shared provider harness.

This makes the migration manifest fail closed for the providers introduced here while leaving unrelated providers for their own stack branches.

Validation: go test -tags "fts5" ./internal/parser -run TestProviderMigrationModes -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; git diff --check

test(sync): compare commandcode iflow shadow parity

Command Code and iFlow now opt into shadow comparison, so their provider branch should prove more than provider-local parsing. Add source-level migration tests that run ObserveProviderSource and compare the normalized provider output against the legacy parser functions for both agents.

Validation: go fmt ./...; go test -tags "fts5" ./internal/parser ./internal/sync -count=1; go vet ./...; git diff --check; ./custom-gcl run --config .golangci.nilaway.yml ./internal/parser/... ./internal/sync/...

refactor(parser): fold commandcode and iflow into provider

Move Command Code and iFlow parse ownership onto their concrete
providers and delete the package-level discover/find/parse entrypoints
plus the legacy sync dispatch for both agents. Both agents become
provider-authoritative so runtime sync routes through provider
changed-path classification and processProviderFile instead of the
removed processCommandCode/processIflow methods.

Command Code:
- parseSession moves onto the provider; DiscoverCommandCodeSessions,
  FindCommandCodeSourceFile, and ParseCommandCodeSession are removed.
- The provider reproduces the legacy .meta.json companion behavior:
  WatchPlan includes *.meta.json, SourcesForChangedPath remaps a
  changed .meta.json back to its .jsonl transcript, the composite
  Fingerprint folds the companion size, mtime, and content into the
  freshness identity, and Parse overrides File.Size/File.Mtime with the
  combined transcript+meta effective info. commandCodeEffectiveInfo
  stays in the engine for the SourceMtime watcher fallback.

iFlow:
- parseSession moves onto the provider; DiscoverIflowProjects,
  FindIflowSourceFile, and ParseIflowSession are removed.
- Parse mirrors the legacy sync path: it resolves the project from the
  recorded cwd and git branch (falling back to GetProjectName of the
  project directory), applies InferRelationshipTypes to derive
  continuation/subagent links, and enables source content hashing so
  File.Hash matches the legacy ComputeFileHash value.

Tests move from the deleted free functions to provider API coverage,
add guard tests asserting the legacy entrypoints stay gone, drop the
shadow comparison test, and remove both provider files from the
pending-shim scan list.

fix(parser): preserve commandcode file hash parity

Command Code needs a composite provider fingerprint so metadata-only edits invalidate freshness, but that value should not replace the persisted transcript content hash. The legacy sync path stored the SHA-256 of the transcript file in file_hash, and changing that semantic would make metadata-only edits look like transcript content changes.\n\nKeep the composite value scoped to SourceFingerprint and recompute Session.File.Hash from the transcript during provider parse. The provider test now exercises Fingerprint -> Parse with a .meta.json companion to prove the two hashes remain distinct.\n\nValidation: go test -tags "fts5" ./internal/parser -run TestCommandCodeProvider -count=1; go test -tags "fts5" ./internal/parser -count=1; go test -tags "fts5" ./internal/sync -run 'Test.*CommandCode|Test.*Iflow' -count=1; go vet ./...; git diff --check

fix(parser): thread ctx through commandcode and iflow source lookups
The facade needs at least one real provider implementation before caller migration can prove the contract. Gptme is a narrow first target because it has a single-session JSONL source layout and an existing parser path that can be wrapped without changing runtime sync dispatch.

This keeps gptme source behavior explicit: the provider composes JSONLSourceSet for filesystem mechanics, filters to the legacy one-level conversation.jsonl layout, and returns complete current parse outcomes while the rest of the registry remains on legacy adapters.

fix(parser): preserve gptme provider source parity

The gptme provider is intended to be a no-behavior-change facade migration, so it needs to preserve the legacy source semantics before sync callers can safely move to it. Symlinked session directories, deleted source events, and persisted lookup hints are all observable through the current discovery and session lookup paths.

This keeps provider-backed gptme discovery and changed-path classification compatible with those legacy expectations while leaving runtime dispatch unchanged.

test(parser): opt gptme into provider shadow

Gptme now has a concrete facade provider on this branch, so the migration manifest should force it through the shared shadow-compare harness instead of leaving the provider implementation additive and unexercised.

Lower branch opt-ins remain inherited and later provider families stay legacy-only until their own branches introduce concrete providers.

Validation: go test -tags "fts5" ./internal/parser -run TestProviderMigrationModes -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; git diff --check

test(sync): compare gptme shadow parity

GPTMe is marked shadow-compare on this branch, so add the shared source-level migration proof beside the concrete provider. The test runs ObserveProviderSource and compares normalized provider output with ParseGptmeSession while preserving the provider-computed content hash.

Validation: go fmt ./...; go test -tags "fts5" ./internal/parser ./internal/sync -count=1; go vet ./...; git diff --check; ./custom-gcl run --config .golangci.nilaway.yml ./internal/parser/... ./internal/sync/...

refactor(parser): fold gptme into provider

GPTMe should be a migrated provider on this branch, not a provider wrapper around exported legacy parser entrypoints. Keeping DiscoverGptmeSessions, FindGptmeSourceFile, ParseGptmeSession, and the engine processGptme path made the stack additive and left two public shapes to maintain.

Move GPTMe parsing behind the concrete provider, make GPTMe provider-authoritative at this branch, remove its legacy AgentDef hooks and engine dispatch, and replace shadow-baseline tests with provider API coverage plus a guard that the legacy symbols stay gone.

Validation: go test -tags "fts5" ./internal/parser ./internal/sync ./cmd/agentsview -count=1; go vet ./...; git diff --check

fix(parser): thread ctx through gptme source lookups
DeepSeek TUI has a shallow one-file-per-session JSON layout, so moving it next keeps the provider migration incremental while exercising the JSON source helper with non-JSONL extensions.

The provider preserves legacy discovery filters for latest and offline queue files, raw/full ID lookup, changed-path classification, fingerprint propagation, and parse normalization without changing runtime sync dispatch.

fix(parser): preserve deepseek tui symlink files

DeepSeek TUI legacy lookup and parsing followed direct symlinks to session JSON files, so the facade provider needs an explicit way to preserve that source shape instead of silently dropping linked archives.

The JSONL source helper keeps symlink-file following opt-in, DeepSeek TUI enables it, and the branch manifest opts the concrete provider into shadow comparison so the migration is exercised rather than additive.

Validation: go test -tags "fts5" ./internal/parser -run 'Test(DeepSeekTUIProvider|JSONLSourceSet|ProviderMigrationModes)' -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; git diff --check

test(parser): skip deepseek symlink test when unsupported

Some test environments deny symlink creation even though the provider behavior is valid when links are available. The regression should skip in that environment instead of failing for host permissions.

Validation: go test -tags "fts5" ./internal/parser -run 'Test(DeepSeekTUIProvider|ProviderMigrationModes)' -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; git diff --check

test(sync): compare deepseek tui shadow parity

DeepSeek TUI is shadow-compared on this branch, so add the shared source-level proof that provider observation matches the existing ParseDeepSeekTUISession output. This keeps the branch review focused on an actual migration surface rather than only provider-local parser tests.

Validation: go fmt ./...; go test -tags "fts5" ./internal/parser ./internal/sync -count=1; go vet ./...; git diff --check; ./custom-gcl run --config .golangci.nilaway.yml ./internal/parser/... ./internal/sync/...

refactor(parser): fold deepseek tui into provider

DeepSeek TUI should have one maintained parser shape on this branch. Leaving exported discover, lookup, and parse functions beside the concrete provider kept the migration additive and forced sync to preserve a second dispatch path.

Make the concrete provider authoritative, move parsing onto the provider, remove the AgentDef legacy hooks and engine dispatch, and replace shadow-baseline tests with provider API coverage plus a guard that the old symbols stay gone.

Validation: go test -tags "fts5" ./internal/parser ./internal/sync ./cmd/agentsview -count=1; go vet ./...; git diff --check

fix(parser): preserve deepseek tui file hash

DeepSeek TUI legacy sync stored the transcript content hash, but the migrated provider source set did not request hashing, so provider-authoritative Parse left Session.File.Hash empty when using the real Fingerprint path.\n\nEnable source hashing for DeepSeek TUI and make the provider parse test use Fingerprint -> Parse to assert the persisted file_hash value comes from the session JSON content.\n\nValidation: go test -tags "fts5" ./internal/parser -run TestDeepSeekTUIProvider -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; git diff --check
Amp and Zencoder both use shallow session-file roots, so migrating them together keeps the provider stack moving without introducing another source helper.

The concrete providers preserve legacy filename filters, raw/full ID lookup, deleted-path classification, fingerprint propagation, and parse normalization while continuing to compose the shared JSON source mechanics explicitly.

fix(parser): preserve JSONL symlink file sources

Migrated providers are intended to preserve legacy source discovery while moving behind the provider facade. Several legacy JSON/JSONL discoveries accepted matching symlinked session files and the parsers read through those symlink targets, so the shared source helper needs an explicit opt-in for that source shape instead of treating every symlink as non-regular metadata.

This keeps the default helper behavior strict while allowing shallow and directory JSONL providers to opt into the compatibility path they already had before the migration.

Validation: go test -tags "fts5" ./internal/parser -run 'Test(Amp|Zencoder)ProviderSourceMethodsFollowSymlinkedSessionFile' -count=1; go test -tags "fts5" ./internal/parser -run 'Test(Amp|Zencoder|DeepSeekTUI)ProviderSourceMethodsFollowSymlinkedSessionFile|Test(CommandCode|Iflow)ProviderDiscoversSymlinkedProjectDirectory|TestGptmeProvider' -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; make test-short; make nilaway; git diff --check

test(parser): opt amp zencoder into provider shadow

Amp and Zencoder now have concrete facade providers on this branch, so their migration modes should fail closed through the shared shadow-compare harness instead of leaving those implementations additive.

Earlier provider opt-ins stay inherited from lower stack branches, and later provider families remain legacy-only until their own branches introduce concrete providers.

Validation: go test -tags "fts5" ./internal/parser -run TestProviderMigrationModes -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; git diff --check

test(sync): compare amp zencoder shadow parity

Amp and Zencoder are shadow-compared on this branch, so add source-level migration tests that run ObserveProviderSource and compare provider output to the legacy ParseAmpSession and ParseZencoderSession functions.

Validation: go fmt ./...; go test -tags "fts5" ./internal/parser ./internal/sync -count=1; go vet ./...; git diff --check; ./custom-gcl run --config .golangci.nilaway.yml ./internal/parser/... ./internal/sync/...

refactor(parser): fold amp zencoder into providers

Amp and Zencoder should stop carrying two public parser shapes once their concrete providers exist. Keeping exported parser entrypoints and legacy sync dispatch made this branch additive instead of a real migration.

Make both providers authoritative, move parsing behind provider methods, remove source callbacks and engine dispatch, and replace shadow-baseline tests with provider API coverage plus guards that the old symbols stay gone.

Validation: go test -tags "fts5" ./internal/parser ./internal/sync ./cmd/agentsview -count=1; go vet ./...; git diff --check

fix(parser): preserve amp zencoder file hashes

Amp and Zencoder legacy sync stored the source content hash, but the migrated providers did not request hashed source fingerprints. Provider-authoritative writes would therefore clear file_hash when running through the real provider path.\n\nEnable source hashing for both providers and update their provider tests to exercise Fingerprint -> Parse instead of passing manually injected hashes.\n\nValidation: go test -tags "fts5" ./internal/parser -run 'Test(Amp|Zencoder)ProviderParse' -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; git diff --check
Pi is the next JSONL-shaped parser that can move behind the provider facade without introducing a new source framework. Its source layout is still simple enough to compose the directory JSONL helper, but it needs provider-owned filtering because legacy discovery validates the session header while raw session lookup only checks the expected filename under encoded-cwd directories.

This keeps that discovery-versus-lookup asymmetry explicit in the provider and preserves symlinked encoded-cwd directory support while parse output continues to come from the existing Pi parser.

Validation: go test -tags "fts5" ./internal/parser -run TestPiProvider -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; make test-short; git diff --check

fix(parser): preserve pi header-based discovery

Pi discovery has historically treated the filename as source shape only: any one-level JSONL file under an encoded-cwd directory can be a session if its header has type=session. The provider migration accidentally applied raw session ID filename validation before header validation, which would drop valid files whose session ID comes from the header instead of the filename.

Raw-ID lookup still validates the requested ID before reconstructing <id>.jsonl, so the legacy discovery-versus-lookup asymmetry remains explicit without broadening lookup inputs.

Validation: go test -tags "fts5" ./internal/parser -run TestPiProviderDiscoveryAcceptsSessionHeaderInNonSessionIDFilename -count=1; go test -tags "fts5" ./internal/parser -run 'TestPiProvider(DiscoveryAcceptsSessionHeaderInNonSessionIDFilename|SourceMethods|Parse|DiscoversSymlinkedCWDDirectory|FactoryReplacesLegacyAdapter)' -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; make test-short; git diff --check

test(parser): opt pi into provider shadow

Pi now has a concrete facade provider on this branch, so its migration mode should enter the shared shadow-compare harness instead of remaining an additive implementation behind legacy-only dispatch.

The stack keeps lower provider opt-ins inherited and leaves later provider branches legacy-only until their own migrations land.

Validation: go test -tags "fts5" ./internal/parser -run TestProviderMigrationModes -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; git diff --check

test(sync): compare pi shadow parity

Pi is shadow-compared on this branch, so add the shared source-level proof that provider observation matches ParsePiSession output for a representative session file.

Validation: go fmt ./...; go test -tags "fts5" ./internal/parser ./internal/sync -count=1; go vet ./...; git diff --check; ./custom-gcl run --config .golangci.nilaway.yml ./internal/parser/... ./internal/sync/...

refactor(parser): fold pi into provider

Pi should not keep exported parser and source callback APIs after its concrete provider exists. Removing those hooks also exposed that full sync and single-session lookup still assumed AgentDef callbacks, so provider-authoritative agents were not actually runnable without legacy callbacks.

Move Pi parsing behind the provider, remove its legacy discovery and sync dispatch, add provider discovery and provider lookup to the sync root path, and replace shadow-baseline coverage with provider API tests plus a guard that the old symbols stay gone.

Validation: go test -tags "fts5" ./internal/parser ./internal/sync ./cmd/agentsview -count=1; go vet ./...; git diff --check

fix(parser): preserve pi family provider capabilities

OMP shared the Pi on-disk format but was left legacy-only after the legacy registry hooks were removed, so full sync and changed-path sync could no longer reach it through the migrated provider path. Parse-diff had the same shape of regression for provider-authoritative agents because it only trusted AgentDef discovery callbacks.\n\nFold OMP into the concrete Pi-family provider, derive parse identity from the provider definition, and teach parse-diff plus CLI validation to accept provider-authoritative on-disk sources. This keeps the branch as an actual migration rather than a shim around removed legacy functions.\n\nValidation: go test -tags "fts5" ./internal/parser -count=1; go test -tags "fts5" ./cmd/agentsview -run 'TestParseDiff' -count=1; go test -tags "fts5" ./internal/sync -run 'Test(ParseDiff|OMPSyncAllAndChangedPathUseProvider)' -count=1; go test -tags "fts5" ./internal/sync -count=1; go vet ./...; git diff --check

fix(parser): thread ctx through pi source lookups
WorkBuddy is still JSONL-backed, but its source layout has two valid shapes: project-level session files and nested subagent files. Moving it behind a concrete provider keeps that provider-specific shape explicit while continuing to reuse the shared JSONL filesystem mechanics.

The provider preserves legacy discovery and lookup behavior, including symlinked project directories and files, compound subagent raw IDs, deleted-path classification, source fingerprinting, and existing parser normalization for parent/subagent relationships.

Validation: go fmt ./...; go test -tags "fts5" ./internal/parser -run TestWorkBuddyProvider -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; make test-short; git diff --check

test(parser): document workbuddy subagent discovery

WorkBuddy legacy discovery accepts any JSONL filename under a valid parent session's subagents directory, while raw subagent lookup still validates the requested ID. The provider migration intentionally preserves that asymmetry rather than tightening discovery and dropping sources that older code would import.

Validation: go fmt ./...; go test -tags "fts5" ./internal/parser -run TestWorkBuddyProviderSourceMethods -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; git diff --check; make nilaway

test(parser): opt workbuddy into provider shadow

WorkBuddy now has a concrete facade provider on this branch, so its migration mode should enter the shared shadow-compare harness rather than remaining legacy-only and additive.

Lower provider opt-ins stay inherited and later provider branches remain responsible for their own concrete providers.

Validation: go test -tags "fts5" ./internal/parser -run TestProviderMigrationModes -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; git diff --check

test(sync): compare workbuddy shadow parity

WorkBuddy is shadow-compared on this branch, so add source-level migration coverage that compares provider observation with ParseWorkBuddySession.

The test covers both the main session file and nested subagent file shape so parent relationship parity stays visible while the stack migrates provider by provider.

Validation: go test -tags "fts5" ./internal/parser ./internal/sync -run 'TestObserveProviderSourceMatchesWorkBuddyLegacyParser|TestWorkBuddyProvider|TestParseWorkBuddy' -count=1; go test -tags "fts5" ./internal/parser ./internal/sync -count=1; go fmt ./...; go vet ./...; ./custom-gcl run --config .golangci.nilaway.yml ./internal/parser/... ./internal/sync/...; git diff --check; go test -tags "fts5" ./internal/sync -run TestObserveProviderSourceMatchesWorkBuddyLegacyParser -count=1

refactor(parser): fold workbuddy into provider

WorkBuddy already had a concrete provider, but it still depended on exported legacy parser/source functions and legacy sync dispatch. That kept the branch additive and let the old shape remain authoritative.\n\nMove parsing and composite subagent source lookup behind the provider, remove registry callbacks and sync dispatch, and convert the WorkBuddy tests to provider-backed helpers plus a guard that the old entrypoints stay gone.\n\nValidation: go test -tags "fts5" ./internal/parser ./internal/sync -run 'TestWorkBuddy|TestDiscoverWorkBuddy|TestParseWorkBuddy|TestFindWorkBuddy|TestEngineClassifyWorkBuddy|TestWorkBuddyRegistry' -count=1 -v; go test -tags "fts5" ./internal/parser ./internal/sync ./cmd/agentsview -count=1; go vet ./...; git diff --check

fix(parser): preserve workbuddy file hashes

WorkBuddy legacy sync stored the transcript content hash for both main sessions and subagent transcripts. The provider migration kept copying Fingerprint.Hash into Session.File.Hash, but the recursive source set did not request hashed fingerprints, so provider-authoritative writes would clear file_hash.\n\nEnable source hashing and make the provider parse test exercise Fingerprint -> Parse for both main and subagent sources.\n\nValidation: go test -tags "fts5" ./internal/parser -run TestWorkBuddyProvider -count=1; go test -tags "fts5" ./internal/parser -count=1; go test -tags "fts5" ./internal/sync -run 'Test.*WorkBuddy' -count=1; go vet ./...; git diff --check

fix(parser): thread ctx through workbuddy source lookups
Cortex has a shallow metadata-file source shape, with optional companion history JSONL handled inside the existing parser. Moving it behind a concrete provider keeps source discovery and lookup explicit without adding a new source abstraction.

The provider preserves the legacy Cortex session-file predicate, backup/history companion exclusions, symlinked file behavior, deleted-path classification, source fingerprinting, and parse normalization for session names, cwd, and tool content.

Validation: go fmt ./...; go test -tags "fts5" ./internal/parser -run TestCortexProvider -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; make test-short; git diff --check

fix(parser): include cortex history companions

Cortex split-history sessions parse messages from a sibling .history.jsonl file, so provider-backed live sync has to treat that companion as part of the same source. Otherwise a history-only append can be watched but never mapped back to the metadata session, or can keep the same freshness identity and skip reparsing.

This keeps the persisted source key on the .json metadata file while adding companion watch classification and a composite fingerprint over the metadata and history files when the companion exists.

Validation: go fmt ./...; go test -tags "fts5" ./internal/parser -run TestCortexProviderClassifiesAndFingerprintsHistoryCompanion -count=1; go test -tags "fts5" ./internal/parser -run TestCortexProvider -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; make test-short; git diff --check; make nilaway

test(parser): opt cortex into provider shadow

Cortex now has a concrete facade provider on this branch, so its migration mode should enter shadow comparison instead of staying legacy-only and additive.

Lower provider opt-ins stay inherited and later provider branches own their own manifest changes.

Validation: go test -tags "fts5" ./internal/parser -run TestProviderMigrationModes -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; git diff --check

test(sync): compare cortex shadow parity

Cortex is shadow-compared on this branch, so add source-level migration coverage that compares provider observation with ParseCortexSession.

The fixture uses Cortex's split metadata/history format so the test proves the provider path preserves companion-history parse behavior while still planning the primary session ID.

Validation: go test -tags "fts5" ./internal/parser ./internal/sync -run 'TestObserveProviderSourceMatchesCortexLegacyParser|TestCortexProvider|TestParseCortex' -count=1; go test -tags "fts5" ./internal/parser ./internal/sync -count=1; go fmt ./...; go vet ./...; git diff --check; ./custom-gcl run --config .golangci.nilaway.yml ./internal/parser/... ./internal/sync/...

refactor(parser): fold cortex into provider

Move Cortex parse ownership onto the concrete provider and remove the package-level discover/find/parse entrypoints. Route Cortex sync classification and processing through provider changed-path handling so this branch migrates the provider instead of adding another shim.

fix(sync): include cortex companion mtimes in quick sync

Provider-authoritative Cortex discovery emits the metadata JSON as the source, but its freshness identity also includes the split .history.jsonl companion. SyncAllSince was still filtering on the metadata file mtime before provider fingerprinting, so history-only updates could be dropped during quick sync.\n\nUse provider fingerprint mtimes for provider-process discovered files before applying the since cutoff, falling back to the existing per-agent stat logic when the provider has no mtime. Cortex full parses now replace messages as well, because split history rewrites can change existing ordinals rather than only append.\n\nValidation: go test -tags "fts5" ./internal/sync -run TestSyncAllSinceCortexHistoryUpdateTriggersResync -count=1; go test -tags "fts5" ./internal/parser -run Cortex -count=1; go test -tags "fts5" ./internal/sync -run 'Cortex|TestClassifyOnePath_Cortex|TestSyncAllSinceCortexHistoryUpdateTriggersResync' -count=1; go test -tags "fts5" ./internal/sync -count=1; go fmt ./...; go vet ./...; git diff --check

fix(parser): thread ctx through cortex source lookups
Kimi uses two wire.jsonl layouts whose raw IDs include colon-delimited path components, so it cannot rely entirely on the generic JSONL raw-ID lookup. Moving it behind a concrete provider keeps discovery and source classification on the shared JSONL helper while preserving Kimi-specific layout validation and lookup semantics.\n\nThe provider keeps legacy support for both the .kimi project/session layout and the .kimi-code workdir/session/agents layout, including symlinked directories, invalid component filtering, project hints, deleted-path classification, and parser output normalization.

test(parser): cover kimi new-layout provider parse

The roborev design review questioned whether the provider-backed Kimi migration proved the newer .kimi-code layout could round-trip through lookup and parsing. The existing parser and lookup code already handled that raw ID shape, but the provider tests only parsed the legacy layout.\n\nThis adds provider-level coverage for the .kimi-code workdir/session/agents layout so the branch itself documents the persisted session ID, project hint, source path, machine, hash propagation, and message output expected from that source shape.

test(parser): opt kimi into provider shadow

Kimi now has a concrete facade provider on this branch, so its migration mode should enter shadow comparison instead of remaining legacy-only and additive.

Lower provider opt-ins stay inherited and later branches own their provider modes.

Validation: go test -tags "fts5" ./internal/parser -run TestProviderMigrationModes -count=1; go test -tags "fts5" ./internal/parser -count=1; go vet ./...; git diff --check

test(sync): compare kimi shadow parity

Kimi is shadow-compared on this branch, so add source-level migration coverage that compares provider observation with ParseKimiSession.

The test covers both the legacy project/session wire.jsonl layout and the newer .kimi-code agents layout, keeping the fragile path-derived ID and project behavior visible during review.

Validation: go test -tags "fts5" ./internal/parser ./internal/sync -run 'TestObserveProviderSourceMatchesKimiLegacyParser|TestKimiProvider|TestParseKimi|TestSyncPathsAndSingleSession_KimiNewLayout|TestClassifyOnePath_Kimi' -count=1; go test -tags "fts5" ./internal/parser ./internal/sync -count=1; go fmt ./...; go vet ./...; git diff --check; ./custom-gcl run --config .golangci.nilaway.yml ./internal/parser/... ./internal/sync/...; make nilaway

refactor(parser): fold kimi into provider

Move Kimi parse and raw-ID source lookup onto the concrete provider and remove package-level discover/find/parse entrypoints. Route Kimi sync classification and processing through provider changed-path handling so the branch migrates the provider instead of preserving legacy dispatch.
Update the cli-jsonl provider call sites to the exported source-set framework API (WithRecursive, NewJSONLSourceSet, etc.) renamed on the source-set-framework branch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant