Skip to content

Commit 6ad405b

Browse files
test(sync): compare cowork shadow parity
Cowork is a sidecar-backed Claude transcript provider, so add source-level migration coverage that compares provider observation with ParseCoworkSession. The fixture includes local-agent metadata plus the nested Claude transcript and verifies session, messages, usage, excluded IDs, and data-version planning parity while preserving provider-computed hashes. Validation: go test -tags "fts5" ./internal/parser ./internal/sync -run 'TestObserveProviderSourceMatchesCoworkLegacyParser|TestCoworkProvider|TestParseCowork|TestClassifyCoworkPath' -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
1 parent 0f7cc1b commit 6ad405b

1 file changed

Lines changed: 94 additions & 0 deletions

File tree

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package sync
2+
3+
import (
4+
"context"
5+
"path/filepath"
6+
"strings"
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
"github.com/stretchr/testify/require"
11+
12+
"go.kenn.io/agentsview/internal/parser"
13+
)
14+
15+
func TestObserveProviderSourceMatchesCoworkLegacyParser(t *testing.T) {
16+
root := t.TempDir()
17+
cli := "c0000000-0000-4000-8000-000000000201"
18+
sessionUUID := "50000000-0000-4000-8000-000000000201"
19+
workspaceDir := filepath.Join(root, "org", "workspace")
20+
sessionDir := filepath.Join(workspaceDir, "local_"+sessionUUID)
21+
metaPath := sessionDir + ".json"
22+
transcriptPath := filepath.Join(
23+
sessionDir,
24+
".claude",
25+
"projects",
26+
"-Users-dev-code-demo",
27+
cli+".jsonl",
28+
)
29+
writeProviderShadowSourceFile(t, metaPath, coworkShadowMeta(sessionUUID, cli))
30+
writeProviderShadowSourceFile(
31+
t,
32+
transcriptPath,
33+
strings.Join(coworkShadowTranscript(cli), "\n")+"\n",
34+
)
35+
36+
provider, ok := parser.NewProvider(parser.AgentCowork, parser.ProviderConfig{
37+
Roots: []string{root},
38+
Machine: "devbox",
39+
})
40+
require.True(t, ok)
41+
sources, err := provider.Discover(context.Background())
42+
require.NoError(t, err)
43+
require.Len(t, sources, 1)
44+
45+
legacyResults, legacyExcluded, err := parser.ParseCoworkSession(
46+
transcriptPath,
47+
"devbox",
48+
)
49+
require.NoError(t, err)
50+
require.Len(t, legacyResults, 1)
51+
52+
observation, err := ObserveProviderSource(context.Background(), provider, ProviderObserveRequest{
53+
Source: sources[0],
54+
Machine: "devbox",
55+
})
56+
require.NoError(t, err)
57+
require.Len(t, observation.Results, 1)
58+
legacyResults[0].Session.File.Hash = observation.Fingerprint.Hash
59+
60+
assert.Equal(t, legacyResults[0].Session, observation.Results[0].Session)
61+
assert.Equal(t, legacyResults[0].Messages, observation.Results[0].Messages)
62+
assert.Equal(t, legacyResults[0].UsageEvents, observation.Results[0].UsageEvents)
63+
assert.Equal(t, legacyExcluded, observation.ExcludedSessionIDs)
64+
assert.Equal(t, []string{legacyResults[0].Session.ID}, observation.Planned.DataVersionSessionIDs())
65+
assert.Empty(t, observation.Planned.Diagnostics)
66+
}
67+
68+
func coworkShadowMeta(sessionUUID, cli string) string {
69+
return `{"sessionId":"local_` + sessionUUID + `",` +
70+
`"cliSessionId":"` + cli + `",` +
71+
`"title":"Provider title",` +
72+
`"userSelectedFolders":["/Users/dev/code/demo"],` +
73+
`"createdAt":1772373600000,` +
74+
`"lastActivityAt":1772373605000}`
75+
}
76+
77+
func coworkShadowTranscript(cli string) []string {
78+
return []string{
79+
`{"type":"ai-title","aiTitle":"Auto title","sessionId":"` + cli + `"}`,
80+
`{"type":"user","uuid":"u1","parentUuid":null,` +
81+
`"sessionId":"` + cli + `","cwd":"/Users/dev/code/demo",` +
82+
`"gitBranch":"main","version":"2.1.119",` +
83+
`"timestamp":"2026-03-01T10:00:00.000Z",` +
84+
`"message":{"role":"user","content":"provider question"}}`,
85+
`{"type":"assistant","uuid":"a1","parentUuid":"u1",` +
86+
`"sessionId":"` + cli + `","requestId":"req_1",` +
87+
`"timestamp":"2026-03-01T10:00:05.000Z",` +
88+
`"message":{"role":"assistant","id":"msg_1",` +
89+
`"model":"claude-sonnet-4-6","stop_reason":"end_turn",` +
90+
`"content":[{"type":"text","text":"Done."}],` +
91+
`"usage":{"input_tokens":10,"cache_read_input_tokens":2,` +
92+
`"output_tokens":5}}}`,
93+
}
94+
}

0 commit comments

Comments
 (0)