From 05efee30376d9bd1d8bcd02f106fd00276060876 Mon Sep 17 00:00:00 2001 From: Thomas Spader Date: Tue, 24 Mar 2026 14:53:41 -0400 Subject: [PATCH] windows: add --- .github/workflows/build.yml | 5 ++++- .gitignore | 2 ++ src/core/config.ts | 7 ++++++- test/core/config.test.ts | 10 ++++++++-- test/fixture.ts | 11 +++++++++-- tsconfig.json | 11 +++++------ 6 files changed, 34 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 853f9b5..01dffcf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,10 @@ on: branches: [main] jobs: build: - runs-on: ubuntu-24.04 + strategy: + matrix: + os: [ubuntu-24.04, windows-latest, macos-latest] + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v6 - uses: oven-sh/setup-bun@v2 diff --git a/.gitignore b/.gitignore index 15b8a3f..83c7d32 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .llm/reference node_modules .build +/mutagen.yml +/mutagen.yml.lock diff --git a/src/core/config.ts b/src/core/config.ts index 70dfbf7..6e6f3d7 100644 --- a/src/core/config.ts +++ b/src/core/config.ts @@ -1,4 +1,5 @@ import fs from "fs"; +import os from "os"; import path from "path"; import { z } from "zod"; @@ -7,7 +8,11 @@ const LOCAL_FILE = path.join(LOCAL_DIR, "dotllm.json"); const REF_DIR = path.join(LOCAL_DIR, "reference"); function home(): string { - return path.join(process.env.HOME ?? "", ".local", "share", "dotllm"); + if (process.platform === "win32") { + const appData = process.env.LOCALAPPDATA ?? path.join(os.homedir(), "AppData", "Local"); + return path.join(appData, "dotllm"); + } + return path.join(process.env.HOME ?? os.homedir(), ".local", "share", "dotllm"); } const RepoEntry = z.object({ diff --git a/test/core/config.test.ts b/test/core/config.test.ts index c86b308..243997c 100644 --- a/test/core/config.test.ts +++ b/test/core/config.test.ts @@ -7,8 +7,14 @@ import { Config, type RepoEntry } from "@spader/dotllm/core/config" const foo: RepoEntry = { kind: "file", name: "foo", uri: "/mock/foo", description: "foo lib" } const bar: RepoEntry = { kind: "url", name: "bar", uri: "https://example.com/bar", description: "" } +function globalDir(root: string): string { + return process.platform === "win32" + ? path.join(root, "dotllm") + : path.join(root, ".local", "share", "dotllm") +} + function seedGlobal(root: string, content: string): void { - const dir = path.join(root, ".local", "share", "dotllm") + const dir = globalDir(root) fs.mkdirSync(dir, { recursive: true }) fs.writeFileSync(path.join(dir, "dotllm.json"), content) } @@ -130,7 +136,7 @@ test("local read returns default on schema-invalid JSON", async () => { test("storeDir returns path under HOME", async () => { await using env = await fixture() - expect(Config.storeDir()).toBe(path.join(env.path, ".local", "share", "dotllm", "store")) + expect(Config.storeDir()).toBe(path.join(globalDir(env.path), "store")) }) test("refDir returns .llm/reference", () => { diff --git a/test/fixture.ts b/test/fixture.ts index 1c39ece..a3205ed 100644 --- a/test/fixture.ts +++ b/test/fixture.ts @@ -24,9 +24,13 @@ type Env = { export async function fixture(state: State = {}): Promise { const root = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), "dotllm-"))) - const prev = process.env.HOME + const prevHome = process.env.HOME + const prevAppData = process.env.LOCALAPPDATA const cwd = process.cwd() process.env.HOME = root + if (process.platform === "win32") { + process.env.LOCALAPPDATA = root + } process.chdir(root) const git = { stdout: "pipe" as const, stderr: "pipe" as const } @@ -81,7 +85,10 @@ export async function fixture(state: State = {}): Promise { path: root, dir(name: string) { return path.join(root, name) }, async [Symbol.asyncDispose]() { - process.env.HOME = prev + process.env.HOME = prevHome + if (process.platform === "win32") { + process.env.LOCALAPPDATA = prevAppData + } process.chdir(cwd) fs.rmSync(root, { recursive: true, force: true }) }, diff --git a/tsconfig.json b/tsconfig.json index 22480c6..e0558ef 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,13 +10,12 @@ "esModuleInterop": true, "allowImportingTsExtensions": true, "verbatimModuleSyntax": true, - "baseUrl": ".", "paths": { - "@spader/dotllm/cli": ["src/cli/index.ts"], - "@spader/dotllm/cli/*": ["src/cli/*"], - "@spader/dotllm/core": ["src/core/index.ts"], - "@spader/dotllm/core/*": ["src/core/*"], - "#tools/*": ["tools/*"] + "@spader/dotllm/cli": ["./src/cli/index.ts"], + "@spader/dotllm/cli/*": ["./src/cli/*"], + "@spader/dotllm/core": ["./src/core/index.ts"], + "@spader/dotllm/core/*": ["./src/core/*"], + "#tools/*": ["./tools/*"] } }, "include": ["src/**/*.ts", "test/**/*.ts"]