mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-04-01 14:52:25 +00:00
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com> Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com> Co-authored-by: rekram1-node <rekram1-node@users.noreply.github.com>
94 lines
2.3 KiB
TypeScript
94 lines
2.3 KiB
TypeScript
import z from "zod"
|
|
import { Filesystem } from "../util/filesystem"
|
|
import path from "path"
|
|
import { $ } from "bun"
|
|
import { Storage } from "../storage/storage"
|
|
import { Log } from "../util/log"
|
|
|
|
export namespace Project {
|
|
const log = Log.create({ service: "project" })
|
|
export const Info = z
|
|
.object({
|
|
id: z.string(),
|
|
worktree: z.string(),
|
|
vcs: z.literal("git").optional(),
|
|
time: z.object({
|
|
created: z.number(),
|
|
initialized: z.number().optional(),
|
|
}),
|
|
})
|
|
.meta({
|
|
ref: "Project",
|
|
})
|
|
export type Info = z.infer<typeof Info>
|
|
|
|
export async function fromDirectory(directory: string) {
|
|
log.info("fromDirectory", { directory })
|
|
const matches = Filesystem.up({ targets: [".git"], start: directory })
|
|
const git = await matches.next().then((x) => x.value)
|
|
await matches.return()
|
|
if (!git) {
|
|
const project: Info = {
|
|
id: "global",
|
|
worktree: "/",
|
|
time: {
|
|
created: Date.now(),
|
|
},
|
|
}
|
|
await Storage.write<Info>(["project", "global"], project)
|
|
return project
|
|
}
|
|
let worktree = path.dirname(git)
|
|
const [id] = await $`git rev-list --max-parents=0 --all`
|
|
.quiet()
|
|
.nothrow()
|
|
.cwd(worktree)
|
|
.text()
|
|
.then((x) =>
|
|
x
|
|
.split("\n")
|
|
.filter(Boolean)
|
|
.map((x) => x.trim())
|
|
.toSorted(),
|
|
)
|
|
if (!id) {
|
|
const project: Info = {
|
|
id: "global",
|
|
worktree: "/",
|
|
time: {
|
|
created: Date.now(),
|
|
},
|
|
}
|
|
await Storage.write<Info>(["project", "global"], project)
|
|
return project
|
|
}
|
|
worktree = await $`git rev-parse --path-format=absolute --show-toplevel`
|
|
.quiet()
|
|
.nothrow()
|
|
.cwd(worktree)
|
|
.text()
|
|
.then((x) => x.trim())
|
|
const project: Info = {
|
|
id,
|
|
worktree,
|
|
vcs: "git",
|
|
time: {
|
|
created: Date.now(),
|
|
},
|
|
}
|
|
await Storage.write<Info>(["project", id], project)
|
|
return project
|
|
}
|
|
|
|
export async function setInitialized(projectID: string) {
|
|
await Storage.update<Info>(["project", projectID], (draft) => {
|
|
draft.time.initialized = Date.now()
|
|
})
|
|
}
|
|
|
|
export async function list() {
|
|
const keys = await Storage.list(["project"])
|
|
return await Promise.all(keys.map((x) => Storage.read<Info>(x)))
|
|
}
|
|
}
|