diff --git a/.github/workflows/ci-rust.yml b/.github/workflows/ci-rust.yml index d0d7ec2..f99736f 100644 --- a/.github/workflows/ci-rust.yml +++ b/.github/workflows/ci-rust.yml @@ -7,7 +7,8 @@ on: - "Cargo.toml" - "Cargo.lock" - "rust-toolchain.toml" - - "crates/**" + - "implementations/rust/**" + - "contracts/**" - ".github/workflows/ci-rust.yml" pull_request: branches: [main] @@ -15,7 +16,8 @@ on: - "Cargo.toml" - "Cargo.lock" - "rust-toolchain.toml" - - "crates/**" + - "implementations/rust/**" + - "contracts/**" - ".github/workflows/ci-rust.yml" jobs: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci-swift.yml similarity index 71% rename from .github/workflows/ci.yml rename to .github/workflows/ci-swift.yml index 3dc1be9..b0159bc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci-swift.yml @@ -1,9 +1,19 @@ -name: CI +name: CI (Swift) on: push: branches: [main] + paths: + - "Package.swift" + - "implementations/swift/**" + - "contracts/**" + - ".github/workflows/ci-swift.yml" pull_request: + paths: + - "Package.swift" + - "implementations/swift/**" + - "contracts/**" + - ".github/workflows/ci-swift.yml" workflow_dispatch: concurrency: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8365687..fd5fcdf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,7 +42,7 @@ jobs: echo "tag=${TAG}" >> "$GITHUB_OUTPUT" echo "Tag: ${TAG}" - INFO="Sources/AgentSessionKit/AgentSessionKitInfo.swift" + INFO="implementations/swift/Sources/AgentSessionKit/AgentSessionKitInfo.swift" if [ ! -f "$INFO" ]; then echo "::error::${INFO} is missing; the version constant is the release contract." exit 1 diff --git a/AGENTS.md b/AGENTS.md index fb09ba5..d550f70 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -21,8 +21,16 @@ own mapping as an extension in its own module. ```text . ├── Package.swift # swift-tools-version 6.2, macOS 26 +├── Cargo.toml # Cargo workspace root ├── RELEASING.md # semver policy + how a tag is cut -├── Sources/ +├── contracts/ # Facts both lanes are tested against +│ └── storage/ +│ └── session-index-v5.sql # Canonical index DDL + user_version +├── implementations/rust/ +│ └── crates/ +│ └── agent-session-core/ # macOS / Linux / Windows, read-only +└── implementations/swift/ + ├── Sources/ │ ├── AgentSessionKit/ # Swift 5 language mode (migration pending) │ │ ├── AgentSessionKitInfo.swift # version, repository URL, release-notes URL │ │ ├── Harness/ @@ -57,12 +65,22 @@ own mapping as an extension in its own module. │ │ ├── MCPArguments.swift # Typed tools/call argument decoding │ │ ├── MCPSocketServer.swift # AF_UNIX listener, 0600 │ │ └── MCPStdioBridge.swift # Byte pump for spawn-a-command clients -│ └── AgentSessionLive/ # Swift 6 language mode. Placeholder. -└── Tests/ - ├── AgentSessionKitTests/ - └── AgentSessionLiveTests/ + │ └── AgentSessionLive/ # Swift 6 language mode. Placeholder. + └── Tests/ + ├── AgentSessionKitTests/ + └── AgentSessionLiveTests/ ``` +The two implementation lanes are peers. Neither is generated from the other, +so anything that must hold in both languages goes in `contracts/` with a test +on each side — `SessionIndexContractTests` in Swift and `index::contract_tests` +in Rust both read `contracts/storage/session-index-v5.sql`. Changing a shared +fact means changing the contract, both lanes, and the kit minor version in one +pull request. + +Both manifests stay at the repository root and reach into `implementations/` +with explicit paths, so consumers' git URLs, pins, and imports never move. + Boundary rule: `AgentSessionKit` answers "what is on disk right now" — one pass, one snapshot, no observers. Anything that watches, debounces, or tails belongs in `AgentSessionLive`. diff --git a/CHANGELOG.md b/CHANGELOG.md index 580a78b..dd24843 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,38 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +## [0.7.0] - 2026-08-31 + +Swift and Rust become peer implementation lanes. The repository now says out +loud what it had already become when the Rust crate landed: one set of +session-reading semantics with two implementations, neither generated from +the other, and a `contracts/` directory holding the facts both must honour. + +### Changed +- **Layout: `implementations/swift/` and `implementations/rust/`.** The Swift + sources and tests moved out of the repository root, and the Rust crates + moved out of `crates/`. Both manifests stay at the root and reach in with + explicit paths, so **no consumer changes anything**: the git URL, the + `exact:` pin, `import AgentSessionKit`, and both product names are + unaffected. `crates/` at the root became `implementations/rust/crates/`, + which does move the Cargo path for anyone depending on the crate by path + rather than by git. +- `ci.yml` is now `ci-swift.yml`, and both lane workflows are scoped to their + own paths plus `contracts/`. + +### Added +- **`contracts/storage/session-index-v5.sql`** — the canonical index DDL and + `user_version`, extracted from the Swift writer that had been its only + definition. Both lanes are now tested against it: `SessionIndexContractTests` + checks that Swift creates exactly the objects the contract names, and + `index::contract_tests` builds a database from the file and opens it with the + Rust reader. A schema change in either lane alone now fails CI. + +### Fixed +- `AgentSessionKitInfoTests` resolved the repository root by walking three + directories up from `#filePath`, which the new layout broke. It is five now, + and the failure was real: the test could not find `CHANGELOG.md`. + ### Fixed - **Rust discovery/search/transcript parity.** The first Rust session-core slice now mirrors Swift's default title/user/assistant search scopes, diff --git a/Cargo.lock b/Cargo.lock index 9ff68e0..103f766 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 4 [[package]] name = "agent-session-core" -version = "0.1.0" +version = "0.7.0" dependencies = [ "rusqlite", "serde", diff --git a/Cargo.toml b/Cargo.toml index 058e1c7..ec04159 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,9 @@ [workspace] resolver = "2" -members = ["crates/agent-session-core"] +members = ["implementations/rust/crates/agent-session-core"] -# Rust implementation lane of agent-session-kit. The Swift package rooted at -# Package.swift and this Cargo workspace are peer implementations of the same -# session-reading semantics; contracts and fixtures are shared. The Swift -# sources are untouched by this workspace. +# Rust implementation lane of agent-session-kit. This workspace and the +# SwiftPM package rooted at Package.swift are peer implementations of the +# same session-reading semantics, living side by side under +# implementations/. Both manifests stay at the repository root so neither +# language's tooling needs a non-default working directory. diff --git a/Package.swift b/Package.swift index 29b4596..7686587 100644 --- a/Package.swift +++ b/Package.swift @@ -10,6 +10,10 @@ let package = Package( .library(name: "AgentSessionKit", targets: ["AgentSessionKit"]), .library(name: "AgentSessionLive", targets: ["AgentSessionLive"]) ], + // Swift and Rust are peer implementation lanes under implementations/. + // Explicit paths keep this manifest at the repository root so every + // consumer's git URL, exact pin, and `import AgentSessionKit` are + // unchanged by the layout. targets: [ // Discovery, parsing, indexing, and the MCP transport. Extracted // from Vibe Bar, where this code grew up inside the app target; @@ -17,6 +21,7 @@ let package = Package( // were written against it. Migrating is its own change. .target( name: "AgentSessionKit", + path: "implementations/swift/Sources/AgentSessionKit", swiftSettings: [.swiftLanguageMode(.v5)] ), // Live views over the same stores — file-system watching and @@ -24,11 +29,13 @@ let package = Package( // because nothing here predates strict concurrency. .target( name: "AgentSessionLive", - dependencies: ["AgentSessionKit"] + dependencies: ["AgentSessionKit"], + path: "implementations/swift/Sources/AgentSessionLive" ), .testTarget( name: "AgentSessionKitTests", dependencies: ["AgentSessionKit"], + path: "implementations/swift/Tests/AgentSessionKitTests", swiftSettings: [.swiftLanguageMode(.v5)] ), // `Fixtures/` holds sample source records, one directory per @@ -38,6 +45,7 @@ let package = Package( .testTarget( name: "AgentSessionLiveTests", dependencies: ["AgentSessionLive"], + path: "implementations/swift/Tests/AgentSessionLiveTests", resources: [.copy("Fixtures")] ) ] diff --git a/README.md b/README.md index f8235a3..0fa22bd 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,72 @@ # agent-session-kit -A Swift package that reads the session stores AI coding agents leave on your -Mac, and serves them over MCP. +Reads the session stores AI coding agents leave on your machine, and serves +them over MCP. **Two implementations, one set of semantics:** a Swift package +for macOS hosts and a Rust crate for cross-platform ones. Every coding agent keeps a local record of what you asked it — Codex writes rollout JSONL, Claude Code writes transcript JSONL, Cursor and AntiGravity write SQLite databases another process holds open. Each one has its own layout, its own idea of a "session id", and its own way of spelling a -timestamp. This package hides all of that behind one adapter protocol, a +timestamp. This repository hides all of that behind one adapter protocol, a searchable index, and a local MCP transport. -No third-party dependencies. Foundation, Darwin, and the system SQLite. +No third-party dependencies in either lane beyond the system SQLite. ```swift -.package(url: "https://github.com/AstroQore/agent-session-kit", exact: "0.3.0") +// Swift — macOS 26, Swift 6.2 +.package(url: "https://github.com/AstroQore/agent-session-kit", exact: "0.7.0") +``` + +```toml +# Rust — macOS, Linux, Windows +agent-session-core = { git = "https://github.com/AstroQore/agent-session-kit", tag = "0.7.0" } ``` `exact:` while the package is `0.x` — see [Versioning and releases](#versioning-and-releases). -## Targets +## Layout + +```text +Package.swift SwiftPM entry point +Cargo.toml Cargo workspace entry point +contracts/ Semantics both lanes are checked against +implementations/swift/ Sources/ + Tests/ +implementations/rust/ crates/ +``` + +Both manifests stay at the repository root, so a consumer's git URL, pin, and +`import AgentSessionKit` are unaffected by the layout — and neither language's +tooling needs a non-default working directory. + +The two lanes are peers, not a primary and a port. Neither is generated from +the other, which is why anything they must agree on lives in `contracts/` with +a test on each side. Today that is the session index schema +(`contracts/storage/session-index-v5.sql`): the Swift writer is checked to +create exactly those objects, and the Rust reader is checked to open a database +built from that file. Add to `contracts/` whenever a new fact has to hold in +both languages; a change there is a coordinated change plus a kit minor bump. + +## What each lane provides + +**Swift** (`implementations/swift`, macOS 26, Swift 6.2) | Target | What it is | | ------ | ---------- | | `AgentSessionKit` | Discovery, parsing, deletion planning, the FTS5 session index, and the MCP Unix-socket / stdio transport. | | `AgentSessionLive` | Live views over the same stores — the unified event model, the state reducer, and the tailing protocols. | -Requires macOS 26 and Swift 6.2. +**Rust** (`implementations/rust`, macOS / Linux / Windows) + +| Crate | What it is | +| ----- | ---------- | +| `agent-session-core` | Read-only session index access, lightweight Codex and Claude Code discovery, tolerant JSONL transcript paging, and the resume command builder. | + +The Rust lane is deliberately the smaller of the two: it covers what a +cross-platform host needs to render sessions without the Swift runtime. It +never writes the index — schema mismatch is refused, never rebuilt — because +the writer is the host that owns the file. ## Architecture @@ -544,7 +584,7 @@ package is `0.x`, a **minor** bump carries anything a caller could trip over storage key) and a **patch** carries fixes and internals only. Pin `exact:`. ```swift -.package(url: "https://github.com/AstroQore/agent-session-kit", exact: "0.3.0") +.package(url: "https://github.com/AstroQore/agent-session-kit", exact: "0.7.0") ``` Every build knows which version it is: @@ -552,8 +592,8 @@ Every build knows which version it is: ```swift import AgentSessionKit -AgentSessionKitInfo.version // "0.3.0" -AgentSessionKitInfo.bundledReleaseNotesURL // .../releases/tag/0.3.0 +AgentSessionKitInfo.version // "0.7.0" +AgentSessionKitInfo.bundledReleaseNotesURL // .../releases/tag/0.7.0 AgentSessionKitInfo.repositoryURL ``` diff --git a/RELEASING.md b/RELEASING.md index 3dc4040..272cfee 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -26,7 +26,7 @@ Nothing here is `1.0` yet, so `exact:` is the pin a host should use. See ## The version constant -`Sources/AgentSessionKit/AgentSessionKitInfo.swift` holds +`implementations/swift/Sources/AgentSessionKit/AgentSessionKitInfo.swift` holds `AgentSessionKitInfo.version`. This package is linked *statically* by its hosts: once it is compiled in there is no bundle, no `Info.plist`, and no dylib for anyone to read a version off. The constant is the only answer to diff --git a/contracts/storage/session-index-v5.sql b/contracts/storage/session-index-v5.sql new file mode 100644 index 0000000..3d1cec2 --- /dev/null +++ b/contracts/storage/session-index-v5.sql @@ -0,0 +1,76 @@ +-- Session index, schema version 5. +-- +-- Canonical DDL for `session_index.sqlite3`. Both implementation lanes are +-- checked against this file: the Swift writer creates exactly these objects, +-- and the Rust reader refuses any database whose `PRAGMA user_version` is not +-- 5 rather than rebuilding it. +-- +-- The index is derived data. A host may delete the file and pay a re-scan, so +-- a version bump is a re-index, never a migration. Changing anything here is +-- therefore a coordinated change across both lanes plus a kit minor version. + +PRAGMA user_version = 5; + +CREATE TABLE IF NOT EXISTS session_index_meta ( + key TEXT PRIMARY KEY, + value TEXT NOT NULL +); +CREATE TABLE IF NOT EXISTS sessions ( + id INTEGER PRIMARY KEY, + provider TEXT NOT NULL, + session_id TEXT NOT NULL, + provider_variant TEXT, + harness TEXT, + model TEXT, + title TEXT, + summary TEXT, + project_dir TEXT, + created_at INTEGER, + last_active_at INTEGER, + source_path TEXT NOT NULL, + size_bytes INTEGER NOT NULL DEFAULT 0, + message_count INTEGER NOT NULL DEFAULT -1, + UNIQUE(provider, session_id, source_path) +); +CREATE INDEX IF NOT EXISTS sessions_last_active_idx + ON sessions(last_active_at DESC); +CREATE INDEX IF NOT EXISTS sessions_effective_active_idx + ON sessions(COALESCE(last_active_at, created_at) DESC, id DESC); +CREATE INDEX IF NOT EXISTS sessions_provider_effective_active_idx + ON sessions(provider, COALESCE(last_active_at, created_at) DESC, id DESC); +CREATE INDEX IF NOT EXISTS sessions_provider_project_idx + ON sessions(provider, project_dir); +CREATE INDEX IF NOT EXISTS sessions_harness_effective_active_idx + ON sessions(harness, COALESCE(last_active_at, created_at) DESC, id DESC); +CREATE TABLE IF NOT EXISTS session_files ( + path_hash TEXT PRIMARY KEY, + path TEXT NOT NULL, + provider TEXT NOT NULL, + mtime_ns INTEGER NOT NULL, + size INTEGER NOT NULL, + session_row INTEGER REFERENCES sessions(id) ON DELETE CASCADE +); +CREATE TABLE IF NOT EXISTS session_messages ( + id INTEGER PRIMARY KEY, + session_row INTEGER NOT NULL REFERENCES sessions(id) ON DELETE CASCADE, + seq INTEGER NOT NULL, + role TEXT NOT NULL, + excerpt TEXT NOT NULL +); +CREATE INDEX IF NOT EXISTS session_messages_row_idx + ON session_messages(session_row, seq); +CREATE VIRTUAL TABLE IF NOT EXISTS session_fts USING fts5( + excerpt, + content='session_messages', + content_rowid='id', + tokenize='trigram' +); +CREATE TRIGGER IF NOT EXISTS session_messages_ai +AFTER INSERT ON session_messages BEGIN + INSERT INTO session_fts(rowid, excerpt) VALUES (new.id, new.excerpt); +END; +CREATE TRIGGER IF NOT EXISTS session_messages_ad +AFTER DELETE ON session_messages BEGIN + INSERT INTO session_fts(session_fts, rowid, excerpt) + VALUES('delete', old.id, old.excerpt); +END; diff --git a/crates/agent-session-core/Cargo.toml b/implementations/rust/crates/agent-session-core/Cargo.toml similarity index 96% rename from crates/agent-session-core/Cargo.toml rename to implementations/rust/crates/agent-session-core/Cargo.toml index 4640eb2..6191de5 100644 --- a/crates/agent-session-core/Cargo.toml +++ b/implementations/rust/crates/agent-session-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "agent-session-core" -version = "0.1.0" +version = "0.7.0" edition = "2021" license = "AGPL-3.0-only" description = "Cross-platform Rust implementation of agent-session-kit's session reading: index queries, lightweight discovery, transcripts, and resume commands." diff --git a/crates/agent-session-core/README.md b/implementations/rust/crates/agent-session-core/README.md similarity index 100% rename from crates/agent-session-core/README.md rename to implementations/rust/crates/agent-session-core/README.md diff --git a/crates/agent-session-core/examples/smoke.rs b/implementations/rust/crates/agent-session-core/examples/smoke.rs similarity index 100% rename from crates/agent-session-core/examples/smoke.rs rename to implementations/rust/crates/agent-session-core/examples/smoke.rs diff --git a/crates/agent-session-core/src/discovery.rs b/implementations/rust/crates/agent-session-core/src/discovery.rs similarity index 100% rename from crates/agent-session-core/src/discovery.rs rename to implementations/rust/crates/agent-session-core/src/discovery.rs diff --git a/crates/agent-session-core/src/error.rs b/implementations/rust/crates/agent-session-core/src/error.rs similarity index 100% rename from crates/agent-session-core/src/error.rs rename to implementations/rust/crates/agent-session-core/src/error.rs diff --git a/crates/agent-session-core/src/index.rs b/implementations/rust/crates/agent-session-core/src/index.rs similarity index 96% rename from crates/agent-session-core/src/index.rs rename to implementations/rust/crates/agent-session-core/src/index.rs index b2d3991..515dfe8 100644 --- a/crates/agent-session-core/src/index.rs +++ b/implementations/rust/crates/agent-session-core/src/index.rs @@ -1513,3 +1513,55 @@ mod tests { )); } } + +#[cfg(test)] +mod contract_tests { + use super::*; + + /// The canonical DDL lives in `contracts/storage/session-index-v5.sql` and + /// is shared with the Swift lane. Building a database from it and opening + /// that database with this reader proves the two agree on the schema this + /// crate refuses to rebuild — a drift in either direction fails here. + #[test] + fn reader_accepts_a_database_built_from_the_shared_contract() { + let sql = include_str!("../../../../../contracts/storage/session-index-v5.sql"); + let dir = tempfile::tempdir().unwrap(); + let path = dir.path().join("session_index.sqlite3"); + let conn = Connection::open(&path).unwrap(); + conn.execute_batch(sql).unwrap(); + drop(conn); + + let reader = SessionIndexReader::open(&path).expect("contract schema must be readable"); + assert_eq!(reader.session_count().unwrap(), 0); + // Every query path must work against the contract's own objects. + assert!(reader + .list(&SessionListFilter { + limit: 5, + ..Default::default() + }) + .unwrap() + .is_empty()); + assert!(reader + .search( + "anything", + &SessionListFilter { + limit: 5, + ..Default::default() + } + ) + .unwrap() + .is_empty()); + } + + /// The version this crate enforces is the version the contract declares. + #[test] + fn supported_version_matches_the_contract_pragma() { + let sql = include_str!("../../../../../contracts/storage/session-index-v5.sql"); + let declared = sql + .lines() + .find_map(|line| line.trim().strip_prefix("PRAGMA user_version = ")) + .and_then(|rest| rest.trim_end_matches(';').trim().parse::().ok()) + .expect("contract declares a user_version"); + assert_eq!(declared, SUPPORTED_SCHEMA_VERSION); + } +} diff --git a/crates/agent-session-core/src/jsonl.rs b/implementations/rust/crates/agent-session-core/src/jsonl.rs similarity index 100% rename from crates/agent-session-core/src/jsonl.rs rename to implementations/rust/crates/agent-session-core/src/jsonl.rs diff --git a/crates/agent-session-core/src/lib.rs b/implementations/rust/crates/agent-session-core/src/lib.rs similarity index 100% rename from crates/agent-session-core/src/lib.rs rename to implementations/rust/crates/agent-session-core/src/lib.rs diff --git a/crates/agent-session-core/src/provider.rs b/implementations/rust/crates/agent-session-core/src/provider.rs similarity index 100% rename from crates/agent-session-core/src/provider.rs rename to implementations/rust/crates/agent-session-core/src/provider.rs diff --git a/crates/agent-session-core/src/resume.rs b/implementations/rust/crates/agent-session-core/src/resume.rs similarity index 100% rename from crates/agent-session-core/src/resume.rs rename to implementations/rust/crates/agent-session-core/src/resume.rs diff --git a/crates/agent-session-core/src/transcript.rs b/implementations/rust/crates/agent-session-core/src/transcript.rs similarity index 100% rename from crates/agent-session-core/src/transcript.rs rename to implementations/rust/crates/agent-session-core/src/transcript.rs diff --git a/Sources/AgentSessionKit/AgentSessionKitInfo.swift b/implementations/swift/Sources/AgentSessionKit/AgentSessionKitInfo.swift similarity index 98% rename from Sources/AgentSessionKit/AgentSessionKitInfo.swift rename to implementations/swift/Sources/AgentSessionKit/AgentSessionKitInfo.swift index f748e69..99e5e5f 100644 --- a/Sources/AgentSessionKit/AgentSessionKitInfo.swift +++ b/implementations/swift/Sources/AgentSessionKit/AgentSessionKitInfo.swift @@ -19,7 +19,7 @@ public enum AgentSessionKitInfo { /// /// Semver, bare — no `v` prefix, matching the tags. Bumping it is part /// of the release commit; see `RELEASING.md`. - public static let version = "0.6.3" + public static let version = "0.7.0" /// Where the package lives. Public because a host that shows the /// version usually wants somewhere to send the reader. diff --git a/Sources/AgentSessionKit/Antigravity/AntigravityGenMetadataReader.swift b/implementations/swift/Sources/AgentSessionKit/Antigravity/AntigravityGenMetadataReader.swift similarity index 100% rename from Sources/AgentSessionKit/Antigravity/AntigravityGenMetadataReader.swift rename to implementations/swift/Sources/AgentSessionKit/Antigravity/AntigravityGenMetadataReader.swift diff --git a/Sources/AgentSessionKit/Harness/Harness.swift b/implementations/swift/Sources/AgentSessionKit/Harness/Harness.swift similarity index 100% rename from Sources/AgentSessionKit/Harness/Harness.swift rename to implementations/swift/Sources/AgentSessionKit/Harness/Harness.swift diff --git a/Sources/AgentSessionKit/MCP/MCPArguments.swift b/implementations/swift/Sources/AgentSessionKit/MCP/MCPArguments.swift similarity index 100% rename from Sources/AgentSessionKit/MCP/MCPArguments.swift rename to implementations/swift/Sources/AgentSessionKit/MCP/MCPArguments.swift diff --git a/Sources/AgentSessionKit/MCP/MCPDescriptors.swift b/implementations/swift/Sources/AgentSessionKit/MCP/MCPDescriptors.swift similarity index 100% rename from Sources/AgentSessionKit/MCP/MCPDescriptors.swift rename to implementations/swift/Sources/AgentSessionKit/MCP/MCPDescriptors.swift diff --git a/Sources/AgentSessionKit/MCP/MCPJSONRPC.swift b/implementations/swift/Sources/AgentSessionKit/MCP/MCPJSONRPC.swift similarity index 100% rename from Sources/AgentSessionKit/MCP/MCPJSONRPC.swift rename to implementations/swift/Sources/AgentSessionKit/MCP/MCPJSONRPC.swift diff --git a/Sources/AgentSessionKit/MCP/MCPSocketServer.swift b/implementations/swift/Sources/AgentSessionKit/MCP/MCPSocketServer.swift similarity index 100% rename from Sources/AgentSessionKit/MCP/MCPSocketServer.swift rename to implementations/swift/Sources/AgentSessionKit/MCP/MCPSocketServer.swift diff --git a/Sources/AgentSessionKit/MCP/MCPStdioBridge.swift b/implementations/swift/Sources/AgentSessionKit/MCP/MCPStdioBridge.swift similarity index 100% rename from Sources/AgentSessionKit/MCP/MCPStdioBridge.swift rename to implementations/swift/Sources/AgentSessionKit/MCP/MCPStdioBridge.swift diff --git a/Sources/AgentSessionKit/Sessions/AntigravityConversationIndex.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/AntigravityConversationIndex.swift similarity index 100% rename from Sources/AgentSessionKit/Sessions/AntigravityConversationIndex.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/AntigravityConversationIndex.swift diff --git a/Sources/AgentSessionKit/Sessions/AntigravitySessionAdapter.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/AntigravitySessionAdapter.swift similarity index 100% rename from Sources/AgentSessionKit/Sessions/AntigravitySessionAdapter.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/AntigravitySessionAdapter.swift diff --git a/Sources/AgentSessionKit/Sessions/ClaudeCoworkSessionAdapter.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/ClaudeCoworkSessionAdapter.swift similarity index 100% rename from Sources/AgentSessionKit/Sessions/ClaudeCoworkSessionAdapter.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/ClaudeCoworkSessionAdapter.swift diff --git a/Sources/AgentSessionKit/Sessions/ClaudeSessionAdapter.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/ClaudeSessionAdapter.swift similarity index 100% rename from Sources/AgentSessionKit/Sessions/ClaudeSessionAdapter.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/ClaudeSessionAdapter.swift diff --git a/Sources/AgentSessionKit/Sessions/CodexSessionAdapter.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/CodexSessionAdapter.swift similarity index 100% rename from Sources/AgentSessionKit/Sessions/CodexSessionAdapter.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/CodexSessionAdapter.swift diff --git a/Sources/AgentSessionKit/Sessions/CodexTitleHydrator.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/CodexTitleHydrator.swift similarity index 100% rename from Sources/AgentSessionKit/Sessions/CodexTitleHydrator.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/CodexTitleHydrator.swift diff --git a/Sources/AgentSessionKit/Sessions/CursorSessionAdapter.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/CursorSessionAdapter.swift similarity index 100% rename from Sources/AgentSessionKit/Sessions/CursorSessionAdapter.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/CursorSessionAdapter.swift diff --git a/Sources/AgentSessionKit/Sessions/GeminiSessionAdapter.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/GeminiSessionAdapter.swift similarity index 100% rename from Sources/AgentSessionKit/Sessions/GeminiSessionAdapter.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/GeminiSessionAdapter.swift diff --git a/Sources/AgentSessionKit/Sessions/GrokBotSessionAdapter.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/GrokBotSessionAdapter.swift similarity index 100% rename from Sources/AgentSessionKit/Sessions/GrokBotSessionAdapter.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/GrokBotSessionAdapter.swift diff --git a/Sources/AgentSessionKit/Sessions/GrokSessionAdapter.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/GrokSessionAdapter.swift similarity index 100% rename from Sources/AgentSessionKit/Sessions/GrokSessionAdapter.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/GrokSessionAdapter.swift diff --git a/Sources/AgentSessionKit/Sessions/LiveSQLiteReader.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/LiveSQLiteReader.swift similarity index 100% rename from Sources/AgentSessionKit/Sessions/LiveSQLiteReader.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/LiveSQLiteReader.swift diff --git a/Sources/AgentSessionKit/Sessions/ProtobufWireReader.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/ProtobufWireReader.swift similarity index 100% rename from Sources/AgentSessionKit/Sessions/ProtobufWireReader.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/ProtobufWireReader.swift diff --git a/Sources/AgentSessionKit/Sessions/SessionDeleter.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/SessionDeleter.swift similarity index 100% rename from Sources/AgentSessionKit/Sessions/SessionDeleter.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/SessionDeleter.swift diff --git a/Sources/AgentSessionKit/Sessions/SessionIndexService.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/SessionIndexService.swift similarity index 100% rename from Sources/AgentSessionKit/Sessions/SessionIndexService.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/SessionIndexService.swift diff --git a/Sources/AgentSessionKit/Sessions/SessionIndexStore.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/SessionIndexStore.swift similarity index 99% rename from Sources/AgentSessionKit/Sessions/SessionIndexStore.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/SessionIndexStore.swift index f297f2a..739c280 100644 --- a/Sources/AgentSessionKit/Sessions/SessionIndexStore.swift +++ b/implementations/swift/Sources/AgentSessionKit/Sessions/SessionIndexStore.swift @@ -160,6 +160,10 @@ public actor SessionIndexStore { DROP TABLE IF EXISTS session_index_meta; """ + /// Exposed for `SessionIndexContractTests`, which compares the objects + /// created here against `contracts/storage/session-index-v5.sql`. + static var schemaSQLForContractTests: String { schemaSQL } + private static let schemaSQL = """ CREATE TABLE IF NOT EXISTS session_index_meta ( key TEXT PRIMARY KEY, diff --git a/Sources/AgentSessionKit/Sessions/SessionModels.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/SessionModels.swift similarity index 100% rename from Sources/AgentSessionKit/Sessions/SessionModels.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/SessionModels.swift diff --git a/Sources/AgentSessionKit/Sessions/SessionParsing.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/SessionParsing.swift similarity index 100% rename from Sources/AgentSessionKit/Sessions/SessionParsing.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/SessionParsing.swift diff --git a/Sources/AgentSessionKit/Sessions/SessionProviderAdapter.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/SessionProviderAdapter.swift similarity index 100% rename from Sources/AgentSessionKit/Sessions/SessionProviderAdapter.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/SessionProviderAdapter.swift diff --git a/Sources/AgentSessionKit/Sessions/SessionResumeCommandBuilder.swift b/implementations/swift/Sources/AgentSessionKit/Sessions/SessionResumeCommandBuilder.swift similarity index 100% rename from Sources/AgentSessionKit/Sessions/SessionResumeCommandBuilder.swift rename to implementations/swift/Sources/AgentSessionKit/Sessions/SessionResumeCommandBuilder.swift diff --git a/Sources/AgentSessionKit/Utilities/Base32.swift b/implementations/swift/Sources/AgentSessionKit/Utilities/Base32.swift similarity index 100% rename from Sources/AgentSessionKit/Utilities/Base32.swift rename to implementations/swift/Sources/AgentSessionKit/Utilities/Base32.swift diff --git a/Sources/AgentSessionKit/Utilities/ClaudeCoworkPaths.swift b/implementations/swift/Sources/AgentSessionKit/Utilities/ClaudeCoworkPaths.swift similarity index 100% rename from Sources/AgentSessionKit/Utilities/ClaudeCoworkPaths.swift rename to implementations/swift/Sources/AgentSessionKit/Utilities/ClaudeCoworkPaths.swift diff --git a/Sources/AgentSessionKit/Utilities/CodexOriginator.swift b/implementations/swift/Sources/AgentSessionKit/Utilities/CodexOriginator.swift similarity index 100% rename from Sources/AgentSessionKit/Utilities/CodexOriginator.swift rename to implementations/swift/Sources/AgentSessionKit/Utilities/CodexOriginator.swift diff --git a/Sources/AgentSessionKit/Utilities/HumanPromptText.swift b/implementations/swift/Sources/AgentSessionKit/Utilities/HumanPromptText.swift similarity index 100% rename from Sources/AgentSessionKit/Utilities/HumanPromptText.swift rename to implementations/swift/Sources/AgentSessionKit/Utilities/HumanPromptText.swift diff --git a/Sources/AgentSessionKit/Utilities/JSONLHeadTail.swift b/implementations/swift/Sources/AgentSessionKit/Utilities/JSONLHeadTail.swift similarity index 100% rename from Sources/AgentSessionKit/Utilities/JSONLHeadTail.swift rename to implementations/swift/Sources/AgentSessionKit/Utilities/JSONLHeadTail.swift diff --git a/Sources/AgentSessionKit/Utilities/JSONLLineScanner.swift b/implementations/swift/Sources/AgentSessionKit/Utilities/JSONLLineScanner.swift similarity index 100% rename from Sources/AgentSessionKit/Utilities/JSONLLineScanner.swift rename to implementations/swift/Sources/AgentSessionKit/Utilities/JSONLLineScanner.swift diff --git a/Sources/AgentSessionKit/Utilities/KitLog.swift b/implementations/swift/Sources/AgentSessionKit/Utilities/KitLog.swift similarity index 100% rename from Sources/AgentSessionKit/Utilities/KitLog.swift rename to implementations/swift/Sources/AgentSessionKit/Utilities/KitLog.swift diff --git a/Sources/AgentSessionKit/Utilities/PrivacyPreservingHash.swift b/implementations/swift/Sources/AgentSessionKit/Utilities/PrivacyPreservingHash.swift similarity index 100% rename from Sources/AgentSessionKit/Utilities/PrivacyPreservingHash.swift rename to implementations/swift/Sources/AgentSessionKit/Utilities/PrivacyPreservingHash.swift diff --git a/Sources/AgentSessionKit/Utilities/RealHomeDirectory.swift b/implementations/swift/Sources/AgentSessionKit/Utilities/RealHomeDirectory.swift similarity index 100% rename from Sources/AgentSessionKit/Utilities/RealHomeDirectory.swift rename to implementations/swift/Sources/AgentSessionKit/Utilities/RealHomeDirectory.swift diff --git a/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityConversationReader.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityConversationReader.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Antigravity/AntigravityConversationReader.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityConversationReader.swift diff --git a/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityConversationRegistry.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityConversationRegistry.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Antigravity/AntigravityConversationRegistry.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityConversationRegistry.swift diff --git a/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityConversationTailer.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityConversationTailer.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Antigravity/AntigravityConversationTailer.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityConversationTailer.swift diff --git a/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityLiveAdapter.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityLiveAdapter.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Antigravity/AntigravityLiveAdapter.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityLiveAdapter.swift diff --git a/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityStepMapper.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityStepMapper.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Antigravity/AntigravityStepMapper.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityStepMapper.swift diff --git a/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityStepPayload.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityStepPayload.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Antigravity/AntigravityStepPayload.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityStepPayload.swift diff --git a/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityStepStatus.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityStepStatus.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Antigravity/AntigravityStepStatus.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityStepStatus.swift diff --git a/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityStepType.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityStepType.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Antigravity/AntigravityStepType.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityStepType.swift diff --git a/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityWorkspaceIndex.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityWorkspaceIndex.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Antigravity/AntigravityWorkspaceIndex.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Antigravity/AntigravityWorkspaceIndex.swift diff --git a/Sources/AgentSessionLive/Adapters/Claude/ClaudeCoworkLiveAdapter.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Claude/ClaudeCoworkLiveAdapter.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Claude/ClaudeCoworkLiveAdapter.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Claude/ClaudeCoworkLiveAdapter.swift diff --git a/Sources/AgentSessionLive/Adapters/Claude/ClaudeLiveAdapter.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Claude/ClaudeLiveAdapter.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Claude/ClaudeLiveAdapter.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Claude/ClaudeLiveAdapter.swift diff --git a/Sources/AgentSessionLive/Adapters/Claude/ClaudeProjectPath.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Claude/ClaudeProjectPath.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Claude/ClaudeProjectPath.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Claude/ClaudeProjectPath.swift diff --git a/Sources/AgentSessionLive/Adapters/Claude/ClaudeRecordMapper.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Claude/ClaudeRecordMapper.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Claude/ClaudeRecordMapper.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Claude/ClaudeRecordMapper.swift diff --git a/Sources/AgentSessionLive/Adapters/Claude/ClaudeSessionsDirectory.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Claude/ClaudeSessionsDirectory.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Claude/ClaudeSessionsDirectory.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Claude/ClaudeSessionsDirectory.swift diff --git a/Sources/AgentSessionLive/Adapters/Claude/ClaudeSourceBuilder.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Claude/ClaudeSourceBuilder.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Claude/ClaudeSourceBuilder.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Claude/ClaudeSourceBuilder.swift diff --git a/Sources/AgentSessionLive/Adapters/Claude/ClaudeSubagentLinker.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Claude/ClaudeSubagentLinker.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Claude/ClaudeSubagentLinker.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Claude/ClaudeSubagentLinker.swift diff --git a/Sources/AgentSessionLive/Adapters/Claude/ClaudeTranscriptRecord.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Claude/ClaudeTranscriptRecord.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Claude/ClaudeTranscriptRecord.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Claude/ClaudeTranscriptRecord.swift diff --git a/Sources/AgentSessionLive/Adapters/Codex/CodexLiveAdapter.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Codex/CodexLiveAdapter.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Codex/CodexLiveAdapter.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Codex/CodexLiveAdapter.swift diff --git a/Sources/AgentSessionLive/Adapters/Codex/CodexRecordMapper.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Codex/CodexRecordMapper.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Codex/CodexRecordMapper.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Codex/CodexRecordMapper.swift diff --git a/Sources/AgentSessionLive/Adapters/Codex/CodexRolloutRecord.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Codex/CodexRolloutRecord.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Codex/CodexRolloutRecord.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Codex/CodexRolloutRecord.swift diff --git a/Sources/AgentSessionLive/Adapters/Codex/CodexSubagentLinker.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Codex/CodexSubagentLinker.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Codex/CodexSubagentLinker.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Codex/CodexSubagentLinker.swift diff --git a/Sources/AgentSessionLive/Adapters/Codex/CodexToolCall.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Codex/CodexToolCall.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Codex/CodexToolCall.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Codex/CodexToolCall.swift diff --git a/Sources/AgentSessionLive/Adapters/Cursor/CursorLiveAdapter.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Cursor/CursorLiveAdapter.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Cursor/CursorLiveAdapter.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Cursor/CursorLiveAdapter.swift diff --git a/Sources/AgentSessionLive/Adapters/Cursor/CursorMessage.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Cursor/CursorMessage.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Cursor/CursorMessage.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Cursor/CursorMessage.swift diff --git a/Sources/AgentSessionLive/Adapters/Cursor/CursorMessageMapper.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Cursor/CursorMessageMapper.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Cursor/CursorMessageMapper.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Cursor/CursorMessageMapper.swift diff --git a/Sources/AgentSessionLive/Adapters/Cursor/CursorPaths.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Cursor/CursorPaths.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Cursor/CursorPaths.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Cursor/CursorPaths.swift diff --git a/Sources/AgentSessionLive/Adapters/Cursor/CursorSessionTailer.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Cursor/CursorSessionTailer.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Cursor/CursorSessionTailer.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Cursor/CursorSessionTailer.swift diff --git a/Sources/AgentSessionLive/Adapters/Cursor/CursorStoreMeta.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Cursor/CursorStoreMeta.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Cursor/CursorStoreMeta.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Cursor/CursorStoreMeta.swift diff --git a/Sources/AgentSessionLive/Adapters/Cursor/CursorStoreReader.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Cursor/CursorStoreReader.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Cursor/CursorStoreReader.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Cursor/CursorStoreReader.swift diff --git a/Sources/AgentSessionLive/Adapters/Cursor/CursorThinTranscriptMapper.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Cursor/CursorThinTranscriptMapper.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Cursor/CursorThinTranscriptMapper.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Cursor/CursorThinTranscriptMapper.swift diff --git a/Sources/AgentSessionLive/Adapters/Cursor/CursorWorkerProbe.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Cursor/CursorWorkerProbe.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Cursor/CursorWorkerProbe.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Cursor/CursorWorkerProbe.swift diff --git a/Sources/AgentSessionLive/Adapters/Grok/GrokLiveAdapter.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Grok/GrokLiveAdapter.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Grok/GrokLiveAdapter.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Grok/GrokLiveAdapter.swift diff --git a/Sources/AgentSessionLive/Adapters/Grok/GrokRecordMapper.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Grok/GrokRecordMapper.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Grok/GrokRecordMapper.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Grok/GrokRecordMapper.swift diff --git a/Sources/AgentSessionLive/Adapters/Grok/GrokRecords.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Grok/GrokRecords.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Grok/GrokRecords.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Grok/GrokRecords.swift diff --git a/Sources/AgentSessionLive/Adapters/Grok/GrokSessionsPath.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Grok/GrokSessionsPath.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Grok/GrokSessionsPath.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Grok/GrokSessionsPath.swift diff --git a/Sources/AgentSessionLive/Adapters/Grok/GrokSignalsReader.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Grok/GrokSignalsReader.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Grok/GrokSignalsReader.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Grok/GrokSignalsReader.swift diff --git a/Sources/AgentSessionLive/Adapters/Grok/GrokToolCall.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/Grok/GrokToolCall.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/Grok/GrokToolCall.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/Grok/GrokToolCall.swift diff --git a/Sources/AgentSessionLive/Adapters/GrokBot/GrokBotEntry.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/GrokBot/GrokBotEntry.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/GrokBot/GrokBotEntry.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/GrokBot/GrokBotEntry.swift diff --git a/Sources/AgentSessionLive/Adapters/GrokBot/GrokBotEntryMapper.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/GrokBot/GrokBotEntryMapper.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/GrokBot/GrokBotEntryMapper.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/GrokBot/GrokBotEntryMapper.swift diff --git a/Sources/AgentSessionLive/Adapters/GrokBot/GrokBotLiveAdapter.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/GrokBot/GrokBotLiveAdapter.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/GrokBot/GrokBotLiveAdapter.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/GrokBot/GrokBotLiveAdapter.swift diff --git a/Sources/AgentSessionLive/Adapters/GrokBot/GrokBotStore.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/GrokBot/GrokBotStore.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/GrokBot/GrokBotStore.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/GrokBot/GrokBotStore.swift diff --git a/Sources/AgentSessionLive/Adapters/GrokBot/GrokBotTranscriptTailer.swift b/implementations/swift/Sources/AgentSessionLive/Adapters/GrokBot/GrokBotTranscriptTailer.swift similarity index 100% rename from Sources/AgentSessionLive/Adapters/GrokBot/GrokBotTranscriptTailer.swift rename to implementations/swift/Sources/AgentSessionLive/Adapters/GrokBot/GrokBotTranscriptTailer.swift diff --git a/Sources/AgentSessionLive/AgentSessionLive.swift b/implementations/swift/Sources/AgentSessionLive/AgentSessionLive.swift similarity index 100% rename from Sources/AgentSessionLive/AgentSessionLive.swift rename to implementations/swift/Sources/AgentSessionLive/AgentSessionLive.swift diff --git a/Sources/AgentSessionLive/Events/AgentEvent.swift b/implementations/swift/Sources/AgentSessionLive/Events/AgentEvent.swift similarity index 100% rename from Sources/AgentSessionLive/Events/AgentEvent.swift rename to implementations/swift/Sources/AgentSessionLive/Events/AgentEvent.swift diff --git a/Sources/AgentSessionLive/Events/ContextUsage.swift b/implementations/swift/Sources/AgentSessionLive/Events/ContextUsage.swift similarity index 100% rename from Sources/AgentSessionLive/Events/ContextUsage.swift rename to implementations/swift/Sources/AgentSessionLive/Events/ContextUsage.swift diff --git a/Sources/AgentSessionLive/Events/SessionBrief.swift b/implementations/swift/Sources/AgentSessionLive/Events/SessionBrief.swift similarity index 100% rename from Sources/AgentSessionLive/Events/SessionBrief.swift rename to implementations/swift/Sources/AgentSessionLive/Events/SessionBrief.swift diff --git a/Sources/AgentSessionLive/Events/SessionIdentity.swift b/implementations/swift/Sources/AgentSessionLive/Events/SessionIdentity.swift similarity index 100% rename from Sources/AgentSessionLive/Events/SessionIdentity.swift rename to implementations/swift/Sources/AgentSessionLive/Events/SessionIdentity.swift diff --git a/Sources/AgentSessionLive/Events/SessionKey.swift b/implementations/swift/Sources/AgentSessionLive/Events/SessionKey.swift similarity index 100% rename from Sources/AgentSessionLive/Events/SessionKey.swift rename to implementations/swift/Sources/AgentSessionLive/Events/SessionKey.swift diff --git a/Sources/AgentSessionLive/Events/SessionResume.swift b/implementations/swift/Sources/AgentSessionLive/Events/SessionResume.swift similarity index 100% rename from Sources/AgentSessionLive/Events/SessionResume.swift rename to implementations/swift/Sources/AgentSessionLive/Events/SessionResume.swift diff --git a/Sources/AgentSessionLive/Events/SessionSnapshot.swift b/implementations/swift/Sources/AgentSessionLive/Events/SessionSnapshot.swift similarity index 100% rename from Sources/AgentSessionLive/Events/SessionSnapshot.swift rename to implementations/swift/Sources/AgentSessionLive/Events/SessionSnapshot.swift diff --git a/Sources/AgentSessionLive/Events/SessionState.swift b/implementations/swift/Sources/AgentSessionLive/Events/SessionState.swift similarity index 100% rename from Sources/AgentSessionLive/Events/SessionState.swift rename to implementations/swift/Sources/AgentSessionLive/Events/SessionState.swift diff --git a/Sources/AgentSessionLive/Events/SessionStateReducer.swift b/implementations/swift/Sources/AgentSessionLive/Events/SessionStateReducer.swift similarity index 100% rename from Sources/AgentSessionLive/Events/SessionStateReducer.swift rename to implementations/swift/Sources/AgentSessionLive/Events/SessionStateReducer.swift diff --git a/Sources/AgentSessionLive/Liveness/LivenessResolver.swift b/implementations/swift/Sources/AgentSessionLive/Liveness/LivenessResolver.swift similarity index 100% rename from Sources/AgentSessionLive/Liveness/LivenessResolver.swift rename to implementations/swift/Sources/AgentSessionLive/Liveness/LivenessResolver.swift diff --git a/Sources/AgentSessionLive/Liveness/LockFileProbe.swift b/implementations/swift/Sources/AgentSessionLive/Liveness/LockFileProbe.swift similarity index 100% rename from Sources/AgentSessionLive/Liveness/LockFileProbe.swift rename to implementations/swift/Sources/AgentSessionLive/Liveness/LockFileProbe.swift diff --git a/Sources/AgentSessionLive/Liveness/ProcessLinker.swift b/implementations/swift/Sources/AgentSessionLive/Liveness/ProcessLinker.swift similarity index 100% rename from Sources/AgentSessionLive/Liveness/ProcessLinker.swift rename to implementations/swift/Sources/AgentSessionLive/Liveness/ProcessLinker.swift diff --git a/Sources/AgentSessionLive/Liveness/ProcessTable.swift b/implementations/swift/Sources/AgentSessionLive/Liveness/ProcessTable.swift similarity index 100% rename from Sources/AgentSessionLive/Liveness/ProcessTable.swift rename to implementations/swift/Sources/AgentSessionLive/Liveness/ProcessTable.swift diff --git a/Sources/AgentSessionLive/Liveness/ProcessTableReading.swift b/implementations/swift/Sources/AgentSessionLive/Liveness/ProcessTableReading.swift similarity index 100% rename from Sources/AgentSessionLive/Liveness/ProcessTableReading.swift rename to implementations/swift/Sources/AgentSessionLive/Liveness/ProcessTableReading.swift diff --git a/Sources/AgentSessionLive/Liveness/RegistrySnapshot.swift b/implementations/swift/Sources/AgentSessionLive/Liveness/RegistrySnapshot.swift similarity index 100% rename from Sources/AgentSessionLive/Liveness/RegistrySnapshot.swift rename to implementations/swift/Sources/AgentSessionLive/Liveness/RegistrySnapshot.swift diff --git a/Sources/AgentSessionLive/Liveness/SessionEnvironmentVariables.swift b/implementations/swift/Sources/AgentSessionLive/Liveness/SessionEnvironmentVariables.swift similarity index 100% rename from Sources/AgentSessionLive/Liveness/SessionEnvironmentVariables.swift rename to implementations/swift/Sources/AgentSessionLive/Liveness/SessionEnvironmentVariables.swift diff --git a/Sources/AgentSessionLive/Sources/DiscoveryCache.swift b/implementations/swift/Sources/AgentSessionLive/Sources/DiscoveryCache.swift similarity index 100% rename from Sources/AgentSessionLive/Sources/DiscoveryCache.swift rename to implementations/swift/Sources/AgentSessionLive/Sources/DiscoveryCache.swift diff --git a/Sources/AgentSessionLive/Sources/DiscoveryIO.swift b/implementations/swift/Sources/AgentSessionLive/Sources/DiscoveryIO.swift similarity index 100% rename from Sources/AgentSessionLive/Sources/DiscoveryIO.swift rename to implementations/swift/Sources/AgentSessionLive/Sources/DiscoveryIO.swift diff --git a/Sources/AgentSessionLive/Sources/LivenessHint.swift b/implementations/swift/Sources/AgentSessionLive/Sources/LivenessHint.swift similarity index 100% rename from Sources/AgentSessionLive/Sources/LivenessHint.swift rename to implementations/swift/Sources/AgentSessionLive/Sources/LivenessHint.swift diff --git a/Sources/AgentSessionLive/Sources/SessionSource.swift b/implementations/swift/Sources/AgentSessionLive/Sources/SessionSource.swift similarity index 100% rename from Sources/AgentSessionLive/Sources/SessionSource.swift rename to implementations/swift/Sources/AgentSessionLive/Sources/SessionSource.swift diff --git a/Sources/AgentSessionLive/Sources/SessionTailer.swift b/implementations/swift/Sources/AgentSessionLive/Sources/SessionTailer.swift similarity index 100% rename from Sources/AgentSessionLive/Sources/SessionTailer.swift rename to implementations/swift/Sources/AgentSessionLive/Sources/SessionTailer.swift diff --git a/Sources/AgentSessionLive/Sources/SourceAdapter.swift b/implementations/swift/Sources/AgentSessionLive/Sources/SourceAdapter.swift similarity index 100% rename from Sources/AgentSessionLive/Sources/SourceAdapter.swift rename to implementations/swift/Sources/AgentSessionLive/Sources/SourceAdapter.swift diff --git a/Sources/AgentSessionLive/Sources/SourceCursor.swift b/implementations/swift/Sources/AgentSessionLive/Sources/SourceCursor.swift similarity index 100% rename from Sources/AgentSessionLive/Sources/SourceCursor.swift rename to implementations/swift/Sources/AgentSessionLive/Sources/SourceCursor.swift diff --git a/Sources/AgentSessionLive/Tailing/FSEventsWatcher.swift b/implementations/swift/Sources/AgentSessionLive/Tailing/FSEventsWatcher.swift similarity index 100% rename from Sources/AgentSessionLive/Tailing/FSEventsWatcher.swift rename to implementations/swift/Sources/AgentSessionLive/Tailing/FSEventsWatcher.swift diff --git a/Sources/AgentSessionLive/Tailing/FileStamp.swift b/implementations/swift/Sources/AgentSessionLive/Tailing/FileStamp.swift similarity index 100% rename from Sources/AgentSessionLive/Tailing/FileStamp.swift rename to implementations/swift/Sources/AgentSessionLive/Tailing/FileStamp.swift diff --git a/Sources/AgentSessionLive/Tailing/IngestCoordinator.swift b/implementations/swift/Sources/AgentSessionLive/Tailing/IngestCoordinator.swift similarity index 100% rename from Sources/AgentSessionLive/Tailing/IngestCoordinator.swift rename to implementations/swift/Sources/AgentSessionLive/Tailing/IngestCoordinator.swift diff --git a/Sources/AgentSessionLive/Tailing/JSONLTailer.swift b/implementations/swift/Sources/AgentSessionLive/Tailing/JSONLTailer.swift similarity index 100% rename from Sources/AgentSessionLive/Tailing/JSONLTailer.swift rename to implementations/swift/Sources/AgentSessionLive/Tailing/JSONLTailer.swift diff --git a/Sources/AgentSessionLive/Tailing/SQLiteChangeWatcher.swift b/implementations/swift/Sources/AgentSessionLive/Tailing/SQLiteChangeWatcher.swift similarity index 100% rename from Sources/AgentSessionLive/Tailing/SQLiteChangeWatcher.swift rename to implementations/swift/Sources/AgentSessionLive/Tailing/SQLiteChangeWatcher.swift diff --git a/Sources/AgentSessionLive/Tailing/SourceCursorStore.swift b/implementations/swift/Sources/AgentSessionLive/Tailing/SourceCursorStore.swift similarity index 100% rename from Sources/AgentSessionLive/Tailing/SourceCursorStore.swift rename to implementations/swift/Sources/AgentSessionLive/Tailing/SourceCursorStore.swift diff --git a/Sources/AgentSessionLive/Tailing/TailerBackpressure.swift b/implementations/swift/Sources/AgentSessionLive/Tailing/TailerBackpressure.swift similarity index 100% rename from Sources/AgentSessionLive/Tailing/TailerBackpressure.swift rename to implementations/swift/Sources/AgentSessionLive/Tailing/TailerBackpressure.swift diff --git a/Sources/AgentSessionLive/Utilities/ArgvSanitizer.swift b/implementations/swift/Sources/AgentSessionLive/Utilities/ArgvSanitizer.swift similarity index 100% rename from Sources/AgentSessionLive/Utilities/ArgvSanitizer.swift rename to implementations/swift/Sources/AgentSessionLive/Utilities/ArgvSanitizer.swift diff --git a/Sources/AgentSessionLive/Utilities/EventText.swift b/implementations/swift/Sources/AgentSessionLive/Utilities/EventText.swift similarity index 100% rename from Sources/AgentSessionLive/Utilities/EventText.swift rename to implementations/swift/Sources/AgentSessionLive/Utilities/EventText.swift diff --git a/Tests/AgentSessionKitTests/AgentSessionKitInfoTests.swift b/implementations/swift/Tests/AgentSessionKitTests/AgentSessionKitInfoTests.swift similarity index 96% rename from Tests/AgentSessionKitTests/AgentSessionKitInfoTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/AgentSessionKitInfoTests.swift index 31f5c5e..339a422 100644 --- a/Tests/AgentSessionKitTests/AgentSessionKitInfoTests.swift +++ b/implementations/swift/Tests/AgentSessionKitTests/AgentSessionKitInfoTests.swift @@ -12,11 +12,14 @@ final class AgentSessionKitInfoTests: XCTestCase { /// The repository root, resolved from this file rather than from the /// working directory: `swift test` can be invoked from anywhere, and /// the package deliberately ships no test resource for this. - /// `Tests/AgentSessionKitTests/` → three levels up. + /// `implementations/swift/Tests/AgentSessionKitTests/` → + /// five levels up. private var repositoryRoot: URL { URL(fileURLWithPath: #filePath) .deletingLastPathComponent() // AgentSessionKitTests .deletingLastPathComponent() // Tests + .deletingLastPathComponent() // swift + .deletingLastPathComponent() // implementations .deletingLastPathComponent() // repository root } diff --git a/Tests/AgentSessionKitTests/AntigravityElapsedDateTests.swift b/implementations/swift/Tests/AgentSessionKitTests/AntigravityElapsedDateTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/AntigravityElapsedDateTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/AntigravityElapsedDateTests.swift diff --git a/Tests/AgentSessionKitTests/AntigravitySessionAdapterTests.swift b/implementations/swift/Tests/AgentSessionKitTests/AntigravitySessionAdapterTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/AntigravitySessionAdapterTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/AntigravitySessionAdapterTests.swift diff --git a/Tests/AgentSessionKitTests/Base32Tests.swift b/implementations/swift/Tests/AgentSessionKitTests/Base32Tests.swift similarity index 100% rename from Tests/AgentSessionKitTests/Base32Tests.swift rename to implementations/swift/Tests/AgentSessionKitTests/Base32Tests.swift diff --git a/Tests/AgentSessionKitTests/ClaudeCoworkSessionAdapterTests.swift b/implementations/swift/Tests/AgentSessionKitTests/ClaudeCoworkSessionAdapterTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/ClaudeCoworkSessionAdapterTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/ClaudeCoworkSessionAdapterTests.swift diff --git a/Tests/AgentSessionKitTests/ClaudeSessionAdapterTests.swift b/implementations/swift/Tests/AgentSessionKitTests/ClaudeSessionAdapterTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/ClaudeSessionAdapterTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/ClaudeSessionAdapterTests.swift diff --git a/Tests/AgentSessionKitTests/CodexSessionAdapterTests.swift b/implementations/swift/Tests/AgentSessionKitTests/CodexSessionAdapterTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/CodexSessionAdapterTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/CodexSessionAdapterTests.swift diff --git a/Tests/AgentSessionKitTests/CodexTitleHydratorTests.swift b/implementations/swift/Tests/AgentSessionKitTests/CodexTitleHydratorTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/CodexTitleHydratorTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/CodexTitleHydratorTests.swift diff --git a/Tests/AgentSessionKitTests/CursorSessionAdapterTests.swift b/implementations/swift/Tests/AgentSessionKitTests/CursorSessionAdapterTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/CursorSessionAdapterTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/CursorSessionAdapterTests.swift diff --git a/Tests/AgentSessionKitTests/GeminiSessionAdapterTests.swift b/implementations/swift/Tests/AgentSessionKitTests/GeminiSessionAdapterTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/GeminiSessionAdapterTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/GeminiSessionAdapterTests.swift diff --git a/Tests/AgentSessionKitTests/GrokBotSessionAdapterTests.swift b/implementations/swift/Tests/AgentSessionKitTests/GrokBotSessionAdapterTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/GrokBotSessionAdapterTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/GrokBotSessionAdapterTests.swift diff --git a/Tests/AgentSessionKitTests/GrokSessionAdapterTests.swift b/implementations/swift/Tests/AgentSessionKitTests/GrokSessionAdapterTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/GrokSessionAdapterTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/GrokSessionAdapterTests.swift diff --git a/Tests/AgentSessionKitTests/HarnessNamingTests.swift b/implementations/swift/Tests/AgentSessionKitTests/HarnessNamingTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/HarnessNamingTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/HarnessNamingTests.swift diff --git a/Tests/AgentSessionKitTests/HumanPromptTextTests.swift b/implementations/swift/Tests/AgentSessionKitTests/HumanPromptTextTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/HumanPromptTextTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/HumanPromptTextTests.swift diff --git a/Tests/AgentSessionKitTests/JSONLHeadTailTests.swift b/implementations/swift/Tests/AgentSessionKitTests/JSONLHeadTailTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/JSONLHeadTailTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/JSONLHeadTailTests.swift diff --git a/Tests/AgentSessionKitTests/MCPJSONRPCTests.swift b/implementations/swift/Tests/AgentSessionKitTests/MCPJSONRPCTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/MCPJSONRPCTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/MCPJSONRPCTests.swift diff --git a/Tests/AgentSessionKitTests/MCPSocketServerTests.swift b/implementations/swift/Tests/AgentSessionKitTests/MCPSocketServerTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/MCPSocketServerTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/MCPSocketServerTests.swift diff --git a/Tests/AgentSessionKitTests/MCPStdioBridgeTests.swift b/implementations/swift/Tests/AgentSessionKitTests/MCPStdioBridgeTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/MCPStdioBridgeTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/MCPStdioBridgeTests.swift diff --git a/Tests/AgentSessionKitTests/PrivacyPreservingHashTests.swift b/implementations/swift/Tests/AgentSessionKitTests/PrivacyPreservingHashTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/PrivacyPreservingHashTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/PrivacyPreservingHashTests.swift diff --git a/Tests/AgentSessionKitTests/ProtobufWireReaderTests.swift b/implementations/swift/Tests/AgentSessionKitTests/ProtobufWireReaderTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/ProtobufWireReaderTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/ProtobufWireReaderTests.swift diff --git a/Tests/AgentSessionKitTests/SessionDeleterTests.swift b/implementations/swift/Tests/AgentSessionKitTests/SessionDeleterTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/SessionDeleterTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/SessionDeleterTests.swift diff --git a/implementations/swift/Tests/AgentSessionKitTests/SessionIndexContractTests.swift b/implementations/swift/Tests/AgentSessionKitTests/SessionIndexContractTests.swift new file mode 100644 index 0000000..9a4e39e --- /dev/null +++ b/implementations/swift/Tests/AgentSessionKitTests/SessionIndexContractTests.swift @@ -0,0 +1,83 @@ +import XCTest +@testable import AgentSessionKit + +/// The session index schema is shared with the Rust lane through +/// `contracts/storage/session-index-v5.sql`. Nothing generates one lane from +/// the other, so without a check the two drift silently: a column added in +/// Swift would simply be invisible to a Rust reader that still believes it +/// understands version 5. +/// +/// The Rust lane has the mirror of this test — it builds a database straight +/// from the contract file and opens it with its reader. +final class SessionIndexContractTests: XCTestCase { + /// `implementations/swift/Tests/AgentSessionKitTests/` → + /// five levels up. + private var repositoryRoot: URL { + URL(fileURLWithPath: #filePath) + .deletingLastPathComponent() + .deletingLastPathComponent() + .deletingLastPathComponent() + .deletingLastPathComponent() + .deletingLastPathComponent() + } + + private func contractSQL() throws -> String { + try String( + contentsOf: repositoryRoot + .appendingPathComponent("contracts/storage/session-index-v5.sql"), + encoding: .utf8 + ) + } + + /// The version this lane stamps is the version the contract declares. + func testSchemaVersionMatchesTheContract() throws { + let sql = try contractSQL() + let declared = sql + .split(separator: "\n") + .compactMap { line -> Int? in + let trimmed = line.trimmingCharacters(in: .whitespaces) + guard trimmed.hasPrefix("PRAGMA user_version = ") else { return nil } + return Int( + trimmed + .dropFirst("PRAGMA user_version = ".count) + .trimmingCharacters(in: CharacterSet(charactersIn: "; ")) + ) + } + .first + XCTAssertEqual(declared, SessionIndexStore.schemaVersion) + } + + /// Every statement this lane creates appears in the contract, and every + /// statement the contract declares is created by this lane — compared as + /// whole normalised definitions, so a changed column type, constraint, + /// index expression, FTS tokenizer, or trigger body fails here too. + /// + /// Normalisation collapses whitespace and drops `IF NOT EXISTS`, because + /// those differ between a file meant to be run once and a writer that + /// re-runs on every open. Nothing semantic is normalised away. + func testCreatedStatementsMatchTheContract() throws { + let contract = Self.createStatements(in: try contractSQL()) + let swift = Self.createStatements(in: SessionIndexStore.schemaSQLForContractTests) + XCTAssertFalse(contract.isEmpty, "contract declares no statements") + XCTAssertEqual( + swift, + contract, + "session index schema drifted from contracts/storage/session-index-v5.sql" + ) + } + + /// Whole `CREATE …;` statements, normalised and sorted. + private static func createStatements(in sql: String) -> [String] { + sql + .split(separator: ";") + .map { statement in + statement + .split(whereSeparator: \.isWhitespace) + .joined(separator: " ") + .replacingOccurrences(of: "IF NOT EXISTS ", with: "") + .trimmingCharacters(in: .whitespaces) + } + .filter { $0.uppercased().hasPrefix("CREATE ") } + .sorted() + } +} diff --git a/Tests/AgentSessionKitTests/SessionIndexServiceTests.swift b/implementations/swift/Tests/AgentSessionKitTests/SessionIndexServiceTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/SessionIndexServiceTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/SessionIndexServiceTests.swift diff --git a/Tests/AgentSessionKitTests/SessionIndexStoreTests.swift b/implementations/swift/Tests/AgentSessionKitTests/SessionIndexStoreTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/SessionIndexStoreTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/SessionIndexStoreTests.swift diff --git a/Tests/AgentSessionKitTests/SessionResumeCommandBuilderTests.swift b/implementations/swift/Tests/AgentSessionKitTests/SessionResumeCommandBuilderTests.swift similarity index 100% rename from Tests/AgentSessionKitTests/SessionResumeCommandBuilderTests.swift rename to implementations/swift/Tests/AgentSessionKitTests/SessionResumeCommandBuilderTests.swift diff --git a/Tests/AgentSessionLiveTests/Adapters/AntigravityFixtureSupport.swift b/implementations/swift/Tests/AgentSessionLiveTests/Adapters/AntigravityFixtureSupport.swift similarity index 100% rename from Tests/AgentSessionLiveTests/Adapters/AntigravityFixtureSupport.swift rename to implementations/swift/Tests/AgentSessionLiveTests/Adapters/AntigravityFixtureSupport.swift diff --git a/Tests/AgentSessionLiveTests/Adapters/AntigravityLiveAdapterTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/Adapters/AntigravityLiveAdapterTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/Adapters/AntigravityLiveAdapterTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/Adapters/AntigravityLiveAdapterTests.swift diff --git a/Tests/AgentSessionLiveTests/Adapters/ClaudeCoworkLiveAdapterTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/Adapters/ClaudeCoworkLiveAdapterTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/Adapters/ClaudeCoworkLiveAdapterTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/Adapters/ClaudeCoworkLiveAdapterTests.swift diff --git a/Tests/AgentSessionLiveTests/Adapters/ClaudeFixtureSupport.swift b/implementations/swift/Tests/AgentSessionLiveTests/Adapters/ClaudeFixtureSupport.swift similarity index 100% rename from Tests/AgentSessionLiveTests/Adapters/ClaudeFixtureSupport.swift rename to implementations/swift/Tests/AgentSessionLiveTests/Adapters/ClaudeFixtureSupport.swift diff --git a/Tests/AgentSessionLiveTests/Adapters/ClaudeLiveAdapterTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/Adapters/ClaudeLiveAdapterTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/Adapters/ClaudeLiveAdapterTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/Adapters/ClaudeLiveAdapterTests.swift diff --git a/Tests/AgentSessionLiveTests/Adapters/ClaudeRecordMapperTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/Adapters/ClaudeRecordMapperTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/Adapters/ClaudeRecordMapperTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/Adapters/ClaudeRecordMapperTests.swift diff --git a/Tests/AgentSessionLiveTests/Adapters/CodexLiveAdapterTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/Adapters/CodexLiveAdapterTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/Adapters/CodexLiveAdapterTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/Adapters/CodexLiveAdapterTests.swift diff --git a/Tests/AgentSessionLiveTests/Adapters/CursorFixtureSupport.swift b/implementations/swift/Tests/AgentSessionLiveTests/Adapters/CursorFixtureSupport.swift similarity index 100% rename from Tests/AgentSessionLiveTests/Adapters/CursorFixtureSupport.swift rename to implementations/swift/Tests/AgentSessionLiveTests/Adapters/CursorFixtureSupport.swift diff --git a/Tests/AgentSessionLiveTests/Adapters/CursorLiveAdapterTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/Adapters/CursorLiveAdapterTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/Adapters/CursorLiveAdapterTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/Adapters/CursorLiveAdapterTests.swift diff --git a/Tests/AgentSessionLiveTests/Adapters/GrokBotFixtureSupport.swift b/implementations/swift/Tests/AgentSessionLiveTests/Adapters/GrokBotFixtureSupport.swift similarity index 100% rename from Tests/AgentSessionLiveTests/Adapters/GrokBotFixtureSupport.swift rename to implementations/swift/Tests/AgentSessionLiveTests/Adapters/GrokBotFixtureSupport.swift diff --git a/Tests/AgentSessionLiveTests/Adapters/GrokBotLiveAdapterTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/Adapters/GrokBotLiveAdapterTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/Adapters/GrokBotLiveAdapterTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/Adapters/GrokBotLiveAdapterTests.swift diff --git a/Tests/AgentSessionLiveTests/Adapters/GrokLiveAdapterTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/Adapters/GrokLiveAdapterTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/Adapters/GrokLiveAdapterTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/Adapters/GrokLiveAdapterTests.swift diff --git a/Tests/AgentSessionLiveTests/ArgvSanitizerTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/ArgvSanitizerTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/ArgvSanitizerTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/ArgvSanitizerTests.swift diff --git a/Tests/AgentSessionLiveTests/ContextUsageTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/ContextUsageTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/ContextUsageTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/ContextUsageTests.swift diff --git a/Tests/AgentSessionLiveTests/CursorPersistenceTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/CursorPersistenceTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/CursorPersistenceTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/CursorPersistenceTests.swift diff --git a/Tests/AgentSessionLiveTests/DiscoveryCostTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/DiscoveryCostTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/DiscoveryCostTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/DiscoveryCostTests.swift diff --git a/Tests/AgentSessionLiveTests/DiscoveryRoutingTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/DiscoveryRoutingTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/DiscoveryRoutingTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/DiscoveryRoutingTests.swift diff --git a/Tests/AgentSessionLiveTests/EventCodableTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/EventCodableTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/EventCodableTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/EventCodableTests.swift diff --git a/Tests/AgentSessionLiveTests/EventTextTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/EventTextTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/EventTextTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/EventTextTests.swift diff --git a/Tests/AgentSessionLiveTests/FSEventsWatcherTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/FSEventsWatcherTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/FSEventsWatcherTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/FSEventsWatcherTests.swift diff --git a/Tests/AgentSessionLiveTests/Fixtures/README.md b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/README.md similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/README.md rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/README.md diff --git a/Tests/AgentSessionLiveTests/Fixtures/antigravity/.gitkeep b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/antigravity/.gitkeep similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/antigravity/.gitkeep rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/antigravity/.gitkeep diff --git a/Tests/AgentSessionLiveTests/Fixtures/claude/.gitkeep b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/claude/.gitkeep similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/claude/.gitkeep rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/claude/.gitkeep diff --git a/Tests/AgentSessionLiveTests/Fixtures/claude/README.md b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/claude/README.md similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/claude/README.md rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/claude/README.md diff --git a/Tests/AgentSessionLiveTests/Fixtures/claude/session-pid.json b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/claude/session-pid.json similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/claude/session-pid.json rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/claude/session-pid.json diff --git a/Tests/AgentSessionLiveTests/Fixtures/claude/session.jsonl b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/claude/session.jsonl similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/claude/session.jsonl rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/claude/session.jsonl diff --git a/Tests/AgentSessionLiveTests/Fixtures/claude/subagent.jsonl b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/claude/subagent.jsonl similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/claude/subagent.jsonl rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/claude/subagent.jsonl diff --git a/Tests/AgentSessionLiveTests/Fixtures/claude/subagent.meta.json b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/claude/subagent.meta.json similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/claude/subagent.meta.json rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/claude/subagent.meta.json diff --git a/Tests/AgentSessionLiveTests/Fixtures/codex/.gitkeep b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/codex/.gitkeep similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/codex/.gitkeep rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/codex/.gitkeep diff --git a/Tests/AgentSessionLiveTests/Fixtures/codex/cli-shapes.jsonl b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/codex/cli-shapes.jsonl similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/codex/cli-shapes.jsonl rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/codex/cli-shapes.jsonl diff --git a/Tests/AgentSessionLiveTests/Fixtures/codex/events-sampler.jsonl b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/codex/events-sampler.jsonl similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/codex/events-sampler.jsonl rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/codex/events-sampler.jsonl diff --git a/Tests/AgentSessionLiveTests/Fixtures/codex/rollout.jsonl b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/codex/rollout.jsonl similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/codex/rollout.jsonl rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/codex/rollout.jsonl diff --git a/Tests/AgentSessionLiveTests/Fixtures/cursor/.gitkeep b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/cursor/.gitkeep similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/cursor/.gitkeep rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/cursor/.gitkeep diff --git a/Tests/AgentSessionLiveTests/Fixtures/cursor/thin-transcript.jsonl b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/cursor/thin-transcript.jsonl similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/cursor/thin-transcript.jsonl rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/cursor/thin-transcript.jsonl diff --git a/Tests/AgentSessionLiveTests/Fixtures/grok/.gitkeep b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/grok/.gitkeep similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/grok/.gitkeep rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/grok/.gitkeep diff --git a/Tests/AgentSessionLiveTests/Fixtures/grok/README.md b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/grok/README.md similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/grok/README.md rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/grok/README.md diff --git a/Tests/AgentSessionLiveTests/Fixtures/grok/session/chat_history.jsonl b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/grok/session/chat_history.jsonl similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/grok/session/chat_history.jsonl rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/grok/session/chat_history.jsonl diff --git a/Tests/AgentSessionLiveTests/Fixtures/grok/session/events.jsonl b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/grok/session/events.jsonl similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/grok/session/events.jsonl rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/grok/session/events.jsonl diff --git a/Tests/AgentSessionLiveTests/Fixtures/grok/session/signals.json b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/grok/session/signals.json similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/grok/session/signals.json rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/grok/session/signals.json diff --git a/Tests/AgentSessionLiveTests/Fixtures/grok/session/summary.json b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/grok/session/summary.json similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/grok/session/summary.json rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/grok/session/summary.json diff --git a/Tests/AgentSessionLiveTests/Fixtures/grok/session/updates.jsonl b/implementations/swift/Tests/AgentSessionLiveTests/Fixtures/grok/session/updates.jsonl similarity index 100% rename from Tests/AgentSessionLiveTests/Fixtures/grok/session/updates.jsonl rename to implementations/swift/Tests/AgentSessionLiveTests/Fixtures/grok/session/updates.jsonl diff --git a/Tests/AgentSessionLiveTests/IngestCoordinatorTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/IngestCoordinatorTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/IngestCoordinatorTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/IngestCoordinatorTests.swift diff --git a/Tests/AgentSessionLiveTests/JSONLTailerTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/JSONLTailerTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/JSONLTailerTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/JSONLTailerTests.swift diff --git a/Tests/AgentSessionLiveTests/LiveTestSupport.swift b/implementations/swift/Tests/AgentSessionLiveTests/LiveTestSupport.swift similarity index 100% rename from Tests/AgentSessionLiveTests/LiveTestSupport.swift rename to implementations/swift/Tests/AgentSessionLiveTests/LiveTestSupport.swift diff --git a/Tests/AgentSessionLiveTests/LivenessResolverTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/LivenessResolverTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/LivenessResolverTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/LivenessResolverTests.swift diff --git a/Tests/AgentSessionLiveTests/LockFileProbeTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/LockFileProbeTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/LockFileProbeTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/LockFileProbeTests.swift diff --git a/Tests/AgentSessionLiveTests/PipelineCostTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/PipelineCostTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/PipelineCostTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/PipelineCostTests.swift diff --git a/Tests/AgentSessionLiveTests/ProcessLinkerTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/ProcessLinkerTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/ProcessLinkerTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/ProcessLinkerTests.swift diff --git a/Tests/AgentSessionLiveTests/ProcessTableTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/ProcessTableTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/ProcessTableTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/ProcessTableTests.swift diff --git a/Tests/AgentSessionLiveTests/RegistrySnapshotTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/RegistrySnapshotTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/RegistrySnapshotTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/RegistrySnapshotTests.swift diff --git a/Tests/AgentSessionLiveTests/SessionBriefFixtureTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/SessionBriefFixtureTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/SessionBriefFixtureTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/SessionBriefFixtureTests.swift diff --git a/Tests/AgentSessionLiveTests/SessionBriefTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/SessionBriefTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/SessionBriefTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/SessionBriefTests.swift diff --git a/Tests/AgentSessionLiveTests/SessionKeyTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/SessionKeyTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/SessionKeyTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/SessionKeyTests.swift diff --git a/Tests/AgentSessionLiveTests/SessionResumeTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/SessionResumeTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/SessionResumeTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/SessionResumeTests.swift diff --git a/Tests/AgentSessionLiveTests/SessionStateReducerTests.swift b/implementations/swift/Tests/AgentSessionLiveTests/SessionStateReducerTests.swift similarity index 100% rename from Tests/AgentSessionLiveTests/SessionStateReducerTests.swift rename to implementations/swift/Tests/AgentSessionLiveTests/SessionStateReducerTests.swift diff --git a/Tests/AgentSessionLiveTests/TestSupport.swift b/implementations/swift/Tests/AgentSessionLiveTests/TestSupport.swift similarity index 100% rename from Tests/AgentSessionLiveTests/TestSupport.swift rename to implementations/swift/Tests/AgentSessionLiveTests/TestSupport.swift