### Build and Setup GrotTrack from Source Source: https://m7kni.io/grotTrack Commands to clone the repository, install the task runner, and initialize the project environment. ```bash brew install just git clone https://github.com/rknightion/grotTrack.git cd grotTrack just setup open GrotTrack.xcodeproj ``` -------------------------------- ### Install just via Homebrew Source: https://m7kni.io/grotTrack/building Prerequisite installation command for the `just` command runner, required for the build tasks. ```sh brew install just ``` -------------------------------- ### Build from command line Source: https://m7kni.io/grotTrack/building Builds the app from the command line using the `just build` recipe. ```sh just build ``` -------------------------------- ### Build and package the extension with just commands Source: https://m7kni.io/grotTrack/extension Commands to build the extension for unpacked output and create an upload-ready zip. The unpacked output is placed in grot-track-extension/.output/chrome-mv3/ and the zip in grot-track-extension/.output/. ```sh just build-extension # unpacked output: grot-track-extension/.output/chrome-mv3/ just extension-zip # upload-ready zip in grot-track-extension/.output/ ``` -------------------------------- ### Project directory structure Source: https://m7kni.io/grotTrack/contributing Overview of the GrotTrack repository layout, including Swift source directories, the native host CLI, test suites, and the Chrome extension. ```text GrotTrack/ Main app source ├── Models/ SwiftData @Model classes ├── ViewModels/ @Observable view models ├── Services/ Core services (tracking, screenshots, native messaging, ...) ├── Views/ SwiftUI views, grouped by feature area └── Utilities/ Extensions, shared constants, the Chrome host installer GrotTrackNativeHost/ Native messaging host CLI entry point GrotTrackTests/ Unit tests (XCTest, run against the app as test host) grot-track-extension/ Chrome extension (WXT / TypeScript) project.yml XcodeGen project definition — regenerate after editing arch.txt Hand-maintained architecture document ``` -------------------------------- ### Lint the codebase Source: https://m7kni.io/grotTrack/building Runs the strict lint recipe. CI treats a lint failure as a failed build. ```sh just lint ``` -------------------------------- ### Run all tests Source: https://m7kni.io/grotTrack/building Runs the test suite with `just test`. ```sh just test ``` -------------------------------- ### Storage directory layout Source: https://m7kni.io/grotTrack/architecture Shows the directory structure under ~/Library/Application Support/GrotTrack/ with the SwiftData database, screenshots, thumbnails, and exports. ```plaintext GrotTrack.store — SwiftData database (SQLite-backed) Screenshots/YYYY-MM-DD/ — full-resolution WebP screenshots Thumbnails/YYYY-MM-DD/ — WebP thumbnails Exports/ — exported reports and LLM evidence bundles ``` -------------------------------- ### Generate and open Xcode project Source: https://m7kni.io/grotTrack/building Generates the Xcode project from `project.yml` and opens it. Re-run after `project.yml` changes or when files are added/removed under a target's `sources`. ```sh just xcodeproj open GrotTrack.xcodeproj ``` -------------------------------- ### Run a single test class or method Source: https://m7kni.io/grotTrack/building Runs a specific test class or method by adding `-only-testing` to the `just test` command. ```sh just test GrotTrackTests/ActivityTrackerTests ``` -------------------------------- ### ChromeHostManifest JSON for GrotTrack native messaging host Source: https://m7kni.io/grotTrack/native-messaging The manifest file written by ChromeExtensionInstaller with prettyPrinted and sortedKeys JSON encoding. It specifies the allowed extension origin, host name, path to the native host binary, and the stdio transport type. The name must match the identifier passed to chrome.runtime.connectNative in background.ts. ```json { "allowed_origins": ["chrome-extension:///"], "description": "GrotTrack native messaging host for browser tab tracking", "name": "com.grottrack.tabtracker", "path": "/Applications/GrotTrack.app/Contents/MacOS/GrotTrackNativeHost", "type": "stdio" } ``` -------------------------------- ### Define TabMessage interface and Swift BrowserTabMessage struct Source: https://m7kni.io/grotTrack/native-messaging Defines the message shape exchanged between the extension and the native host. The TypeScript interface is built by background.ts and sent via port.postMessage(message); the Swift struct decodes the same JSON with title and url required and the rest optional. ```ts interface TabMessage { type: 'activeTab'; title: string; url: string; tabId: number; windowId: number; timestamp: number; // Date.now(), i.e. milliseconds since epoch } ``` ```swift struct BrowserTabMessage: Codable, Sendable { let type: String? let title: String let url: String let tabId: Int? let windowId: Int? let timestamp: Double? } ``` -------------------------------- ### Broadcast tab data with NSDistributedNotificationCenter Source: https://m7kni.io/grotTrack/native-messaging The NativeMessageHost uses this call to broadcast decoded tab data to the main application via a same-machine IPC mechanism. ```swift DistributedNotificationCenter.default().postNotificationName( NSNotification.Name(GrotTrackIPC.browserTabNotification), object: nil, userInfo: userInfo as [AnyHashable: Any], deliverImmediately: true ) ``` -------------------------------- ### Chrome native messaging wire format Source: https://m7kni.io/grotTrack/native-messaging Chrome's native messaging framing: a 4-byte little-endian UInt32 length prefix followed by that many bytes of UTF-8 JSON. NativeMessageHost.readMessage() implements this protocol, rejecting lengths of 0 or >= 1,000,000 and treating short reads as stdinClosed or incompleteRead. ```text [4 bytes: little-endian UInt32 length][N bytes: UTF-8 JSON payload] ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.