This commit is contained in:
Dax Raad 2025-09-15 18:07:20 -04:00
parent d38594d34a
commit ac744a162c
8 changed files with 56 additions and 19 deletions

View file

@ -143,6 +143,7 @@
"@standard-schema/spec": "1.0.0",
"@zip.js/zip.js": "2.7.62",
"ai": "catalog:",
"chokidar": "4.0.3",
"decimal.js": "10.5.0",
"diff": "8.0.2",
"gray-matter": "4.0.3",

View file

@ -30,6 +30,10 @@ declare module "sst" {
"type": "sst.sst.Linkable"
"username": string
}
"Desktop": {
"type": "sst.cloudflare.StaticSite"
"url": string
}
"FIREWORKS_API_KEY": {
"type": "sst.sst.Secret"
"value": string

View file

@ -30,6 +30,10 @@ declare module "sst" {
"type": "sst.sst.Linkable"
"username": string
}
"Desktop": {
"type": "sst.cloudflare.StaticSite"
"url": string
}
"FIREWORKS_API_KEY": {
"type": "sst.sst.Secret"
"value": string

View file

@ -30,6 +30,10 @@ declare module "sst" {
"type": "sst.sst.Linkable"
"username": string
}
"Desktop": {
"type": "sst.cloudflare.StaticSite"
"url": string
}
"FIREWORKS_API_KEY": {
"type": "sst.sst.Secret"
"value": string

View file

@ -37,6 +37,7 @@
"@standard-schema/spec": "1.0.0",
"@zip.js/zip.js": "2.7.62",
"ai": "catalog:",
"chokidar": "4.0.3",
"decimal.js": "10.5.0",
"diff": "8.0.2",
"gray-matter": "4.0.3",

View file

@ -1,13 +1,12 @@
import z from "zod/v4"
import { Bus } from "../bus"
import fs from "fs"
import { Log } from "../util/log"
import path from "path"
import chokidar from "chokidar"
import ignore from "ignore"
import { Flag } from "../flag/flag"
import { Instance } from "../project/instance"
export namespace FileWatcher {
const log = Log.create({ service: "file.watcher" })
export const Event = {
Updated: Bus.event(
"file.watcher.updated",
@ -18,21 +17,39 @@ export namespace FileWatcher {
),
}
const state = Instance.state(
() => {
async () => {
if (Instance.project.vcs !== "git") return {}
try {
const watcher = fs.watch(Instance.directory, { recursive: true }, (event, file) => {
log.info("change", { file, event })
if (!file) return
Bus.publish(Event.Updated, {
file,
event,
})
})
return { watcher }
} catch {
return {}
const ig = ignore()
const glob = new Bun.Glob("**/.gitignore")
for await (const gitignorePath of glob.scan({
cwd: Instance.directory,
absolute: true,
onlyFiles: true,
dot: true,
})) {
const relativePath = path.relative(Instance.directory, gitignorePath)
const dir = path.dirname(relativePath)
const prefix = dir === "." ? "" : dir + "/"
const content = await Bun.file(gitignorePath).text()
const prefixed = content
.split("\n")
.map((line) => (line ? prefix + line : line))
.join("\n")
ig.add(prefixed)
}
const watcher = chokidar.watch(Instance.directory, {
ignored: (filePath) => ig.ignores(filePath),
})
watcher.on("change", (file) => {
Bus.publish(Event.Updated, { file, event: "change" })
})
watcher.on("add", (file) => {
Bus.publish(Event.Updated, { file, event: "change" })
})
watcher.on("unlink", (file) => {
Bus.publish(Event.Updated, { file, event: "change" })
})
return { watcher }
},
async (state) => {
state.watcher?.close()
@ -40,7 +57,7 @@ export namespace FileWatcher {
)
export function init() {
if (Flag.OPENCODE_DISABLE_WATCHER || true) return
if (!Flag.OPENCODE_EXPERIMENTAL_WATCHER) return
state()
}
}

View file

@ -1,6 +1,5 @@
export namespace Flag {
export const OPENCODE_AUTO_SHARE = truthy("OPENCODE_AUTO_SHARE")
export const OPENCODE_DISABLE_WATCHER = truthy("OPENCODE_DISABLE_WATCHER")
export const OPENCODE_CONFIG = process.env["OPENCODE_CONFIG"]
export const OPENCODE_CONFIG_CONTENT = process.env["OPENCODE_CONFIG_CONTENT"]
export const OPENCODE_DISABLE_AUTOUPDATE = truthy("OPENCODE_DISABLE_AUTOUPDATE")
@ -10,6 +9,9 @@ export namespace Flag {
export const OPENCODE_ENABLE_EXPERIMENTAL_MODELS = truthy("OPENCODE_ENABLE_EXPERIMENTAL_MODELS")
export const OPENCODE_DISABLE_AUTOCOMPACT = truthy("OPENCODE_DISABLE_AUTOCOMPACT")
// Experimental
export const OPENCODE_EXPERIMENTAL_WATCHER = truthy("OPENCODE_EXPERIMENTAL_WATCHER")
function truthy(key: string) {
const value = process.env[key]?.toLowerCase()
return value === "true" || value === "1"

4
sst-env.d.ts vendored
View file

@ -44,6 +44,10 @@ declare module "sst" {
"type": "sst.sst.Linkable"
"username": string
}
"Desktop": {
"type": "sst.cloudflare.StaticSite"
"url": string
}
"FIREWORKS_API_KEY": {
"type": "sst.sst.Secret"
"value": string