---
phase: 01-foundation-build-system
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - plugins/claude-tts-companion/Package.swift
  - plugins/claude-tts-companion/Sources/CSherpaOnnx/include/module.modulemap
  - plugins/claude-tts-companion/Sources/CSherpaOnnx/include/shim.h
  - plugins/claude-tts-companion/Sources/CSherpaOnnx/include/sherpa-onnx/c-api/c-api.h
  - plugins/claude-tts-companion/Sources/CSherpaOnnx/empty.c
  - plugins/claude-tts-companion/Sources/claude-tts-companion/Config.swift
autonomous: true
requirements:
  - BUILD-02
  - BUILD-03
must_haves:
  truths:
    - "CSherpaOnnx module can be imported from Swift code via `import CSherpaOnnx`"
    - "Package.swift resolves swift-telegram-sdk v4.5.0 and links sherpa-onnx static libraries"
    - "Vendored c-api.h header matches the installed sherpa-onnx header exactly"
  artifacts:
    - path: "plugins/claude-tts-companion/Package.swift"
      provides: "SwiftPM manifest with all dependencies and linker settings"
      contains: "swift-telegram-sdk"
    - path: "plugins/claude-tts-companion/Sources/CSherpaOnnx/include/module.modulemap"
      provides: "C module map for sherpa-onnx headers"
      contains: "module CSherpaOnnx"
    - path: "plugins/claude-tts-companion/Sources/CSherpaOnnx/include/shim.h"
      provides: "Umbrella header for sherpa-onnx C API"
      contains: "CSHERPAONNX_SHIM_H"
    - path: "plugins/claude-tts-companion/Sources/CSherpaOnnx/include/sherpa-onnx/c-api/c-api.h"
      provides: "Vendored sherpa-onnx C API header"
      contains: "SherpaOnnxGetVersion"
    - path: "plugins/claude-tts-companion/Sources/claude-tts-companion/Config.swift"
      provides: "Centralized path and configuration constants"
      contains: "enum Config"
  key_links:
    - from: "Package.swift"
      to: "CSherpaOnnx target"
      via: '.target(name: "CSherpaOnnx")'
      pattern: "name:.*CSherpaOnnx"
    - from: "Package.swift"
      to: "sherpa-onnx static libs"
      via: "linkerSettings unsafeFlags -L path"
      pattern: "fork-tools/sherpa-onnx/build-swift-macos/install"
---

<objective>
Create the SwiftPM project scaffold for claude-tts-companion: Package.swift with all dependencies (swift-telegram-sdk v4.5.0, swift-log, CSherpaOnnx), the CSherpaOnnx C module map target with vendored headers, and a Config.swift for centralized path constants.

Purpose: Establish the build system foundation that all subsequent phases depend on. Without a working Package.swift and C interop module, nothing else can compile.
Output: A `plugins/claude-tts-companion/` directory with Package.swift, CSherpaOnnx target, and Config.swift.
</objective>

<execution_context>
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
@$HOME/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/01-foundation-build-system/01-RESEARCH.md
</context>

<tasks>

<task type="auto">
  <name>Task 1: Create CSherpaOnnx C module target with vendored headers</name>
  <files>
    plugins/claude-tts-companion/Sources/CSherpaOnnx/include/module.modulemap
    plugins/claude-tts-companion/Sources/CSherpaOnnx/include/shim.h
    plugins/claude-tts-companion/Sources/CSherpaOnnx/include/sherpa-onnx/c-api/c-api.h
    plugins/claude-tts-companion/Sources/CSherpaOnnx/empty.c
  </files>
  <read_first>
    ~/fork-tools/sherpa-onnx/build-swift-macos/install/include/sherpa-onnx/c-api/c-api.h
    .planning/phases/01-foundation-build-system/01-RESEARCH.md
  </read_first>
  <action>
Create the CSherpaOnnx C target directory structure under `plugins/claude-tts-companion/Sources/CSherpaOnnx/`.

1. Create `include/module.modulemap` with this exact content:

```
module CSherpaOnnx {
    header "shim.h"
    link "sherpa-onnx"
    link "onnxruntime"
    export *
}
```

1. Create `include/shim.h` with this exact content:

```c
#ifndef CSHERPAONNX_SHIM_H
#define CSHERPAONNX_SHIM_H

// sherpa-onnx C API
#include "sherpa-onnx/c-api/c-api.h"

#endif /* CSHERPAONNX_SHIM_H */
```

1. Vendor the c-api.h header by copying `~/fork-tools/sherpa-onnx/build-swift-macos/install/include/sherpa-onnx/c-api/c-api.h` to `include/sherpa-onnx/c-api/c-api.h`. This is a ~1990 line header file -- copy it exactly, do not truncate or modify.

2. Create `empty.c` with a single comment:

```c
// Required by SwiftPM to recognize this as a C target.
```

This is the CSherpaOnnx module map approach (not `-import-objc-header` unsafeFlags) per research recommendation. Vendoring the header avoids path fragility.
</action>
<verify>
<automated>test -f plugins/claude-tts-companion/Sources/CSherpaOnnx/include/module.modulemap && grep -q "module CSherpaOnnx" plugins/claude-tts-companion/Sources/CSherpaOnnx/include/module.modulemap && test -f plugins/claude-tts-companion/Sources/CSherpaOnnx/include/shim.h && test -f plugins/claude-tts-companion/Sources/CSherpaOnnx/include/sherpa-onnx/c-api/c-api.h && grep -q "SherpaOnnxGetVersion" plugins/claude-tts-companion/Sources/CSherpaOnnx/include/sherpa-onnx/c-api/c-api.h && test -f plugins/claude-tts-companion/Sources/CSherpaOnnx/empty.c && echo "PASS" || echo "FAIL"</automated>
</verify>
<acceptance_criteria> - `module.modulemap` contains `module CSherpaOnnx` with `header "shim.h"`, `link "sherpa-onnx"`, `link "onnxruntime"`, `export *` - `shim.h` includes `sherpa-onnx/c-api/c-api.h` with include guard `CSHERPAONNX_SHIM_H` - `c-api.h` is an exact copy of `~/fork-tools/sherpa-onnx/build-swift-macos/install/include/sherpa-onnx/c-api/c-api.h` (contains `SherpaOnnxGetVersion`) - `empty.c` exists (SwiftPM needs at least one .c file to recognize C target)
</acceptance_criteria>
<done>CSherpaOnnx C module target directory exists with module.modulemap, shim.h, vendored c-api.h, and empty.c</done>
</task>

<task type="auto">
  <name>Task 2: Create Package.swift and Config.swift</name>
  <files>
    plugins/claude-tts-companion/Package.swift
    plugins/claude-tts-companion/Sources/claude-tts-companion/Config.swift
  </files>
  <read_first>
    .planning/phases/01-foundation-build-system/01-RESEARCH.md
    plugins/claude-tts-companion/Sources/CSherpaOnnx/include/module.modulemap
  </read_first>
  <action>
1. Create `plugins/claude-tts-companion/Package.swift` with this exact content:

```swift
// swift-tools-version: 6.0
import PackageDescription

let home = ProcessInfo.processInfo.environment["HOME"] ?? "/Users/terryli"
let sherpaOnnxPath = ProcessInfo.processInfo.environment["SHERPA_ONNX_PATH"]
    ?? "\(home)/fork-tools/sherpa-onnx/build-swift-macos/install"

let package = Package(
    name: "claude-tts-companion",
    platforms: [.macOS(.v14)],
    dependencies: [
        .package(url: "https://github.com/nerzh/swift-telegram-sdk", from: "4.5.0"),
        .package(url: "https://github.com/apple/swift-log", from: "1.6.0"),
    ],
    targets: [
        .target(
            name: "CSherpaOnnx",
            path: "Sources/CSherpaOnnx",
            cSettings: [
                .headerSearchPath("include"),
            ]
        ),
        .executableTarget(
            name: "claude-tts-companion",
            dependencies: [
                "CSherpaOnnx",
                .product(name: "SwiftTelegramSdk", package: "swift-telegram-sdk"),
                .product(name: "Logging", package: "swift-log"),
            ],
            linkerSettings: [
                .unsafeFlags([
                    "-L\(sherpaOnnxPath)/lib",
                ]),
                .linkedLibrary("sherpa-onnx"),
                .linkedLibrary("onnxruntime"),
                .linkedLibrary("c++"),
                .linkedFramework("AppKit"),
                .linkedFramework("Foundation"),
            ]
        ),
    ]
)
```

Key decisions:

- `swift-tools-version: 6.0` per research (compatible with Swift 6.2.4)
- `.macOS(.v14)` deployment target required by swift-telegram-sdk v4 concurrency
- `SHERPA_ONNX_PATH` env var with fallback to `~/fork-tools/...` avoids hardcoded path fragility (Pitfall 1)
- CSherpaOnnx is a `.target` (not `.systemLibrary`) so vendored headers work without pkg-config
- Start with combined `-lsherpa-onnx` archive. If linking fails with undefined symbols, switch to individual libs per Pitfall 2

1. Create `plugins/claude-tts-companion/Sources/claude-tts-companion/Config.swift`:

```swift
import Foundation

/// Centralized configuration constants for claude-tts-companion.
/// Paths use environment variable overrides with sensible defaults.
enum Config {
    /// Path to sherpa-onnx installation directory
    static let sherpaOnnxPath: String = {
        let home = ProcessInfo.processInfo.environment["HOME"] ?? "/Users/terryli"
        return ProcessInfo.processInfo.environment["SHERPA_ONNX_PATH"]
            ?? "\(home)/fork-tools/sherpa-onnx/build-swift-macos/install"
    }()

    /// Path to Kokoro int8 TTS model directory
    /// Note: canonical path is ~/.local/share/kokoro/models/kokoro-int8-en-v0_19/
    /// but current location differs. Model copy is a Phase 10 concern.
    static let kokoroModelPath: String = {
        let home = ProcessInfo.processInfo.environment["HOME"] ?? "/Users/terryli"
        return ProcessInfo.processInfo.environment["KOKORO_MODEL_PATH"]
            ?? "\(home)/tmp/subtitle-spikes-7aqa/03-textream/models-int8/kokoro-int8-en-v0_19"
    }()

    /// Application name for logging and service identification
    static let appName = "claude-tts-companion"

    /// Launchd service label
    static let serviceLabel = "com.terryli.claude-tts-companion"
}
```

  </action>
  <verify>
    <automated>grep -q 'swift-tools-version: 6.0' plugins/claude-tts-companion/Package.swift && grep -q 'swift-telegram-sdk.*4.5.0' plugins/claude-tts-companion/Package.swift && grep -q 'CSherpaOnnx' plugins/claude-tts-companion/Package.swift && grep -q 'sherpa-onnx' plugins/claude-tts-companion/Package.swift && grep -q 'enum Config' plugins/claude-tts-companion/Sources/claude-tts-companion/Config.swift && echo "PASS" || echo "FAIL"</automated>
  </verify>
  <acceptance_criteria>
    - Package.swift has `swift-tools-version: 6.0`
    - Package.swift declares dependency `swift-telegram-sdk` from `4.5.0`
    - Package.swift declares dependency `swift-log` from `1.6.0`
    - Package.swift has CSherpaOnnx `.target` with `path: "Sources/CSherpaOnnx"`
    - Package.swift has executable target `claude-tts-companion` depending on CSherpaOnnx, SwiftTelegramSdk, Logging
    - Package.swift linkerSettings include `-L` path to sherpa-onnx libs, `-lsherpa-onnx`, `-lonnxruntime`, `-lc++`
    - Package.swift uses `SHERPA_ONNX_PATH` env var with `~/fork-tools/...` fallback
    - Config.swift defines `enum Config` with `sherpaOnnxPath`, `kokoroModelPath`, `appName`, `serviceLabel`
    - Config.swift model path points to actual location `~/tmp/subtitle-spikes-7aqa/03-textream/models-int8/kokoro-int8-en-v0_19`
  </acceptance_criteria>
  <done>Package.swift resolves all dependencies and Config.swift provides centralized path configuration with env var overrides</done>
</task>

</tasks>

<verification>
- `swift package resolve` succeeds in `plugins/claude-tts-companion/` (dependency resolution)
- All 4 CSherpaOnnx target files exist with correct content
- Package.swift references swift-telegram-sdk v4.5.0 and sherpa-onnx linker settings
</verification>

<success_criteria>

- CSherpaOnnx module target exists with vendored c-api.h header
- Package.swift compiles dependency graph (swift-telegram-sdk v4.5.0, swift-log, CSherpaOnnx)
- Config.swift centralizes all path constants with env var overrides
- `swift package resolve` succeeds without errors
  </success_criteria>

<output>
After completion, create `.planning/phases/01-foundation-build-system/01-01-SUMMARY.md`
</output>
