feat: add OpenCode/Codex outputs and update changelog (#104)
* Add OpenCode converter coverage and specs * Add Codex target support and spec docs * Generate Codex command skills and refresh spec docs * Add global Codex install path * fix: harden plugin path loading and codex descriptions * feat: ensure codex agents block on convert/install * docs: clarify target branch usage for review * chore: prep npm package metadata and release notes * docs: mention opencode and codex in changelog * docs: update CLI usage and remove stale todos * feat: install from GitHub with global outputs
This commit is contained in:
64
src/utils/files.ts
Normal file
64
src/utils/files.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { promises as fs } from "fs"
|
||||
import path from "path"
|
||||
|
||||
export async function pathExists(filePath: string): Promise<boolean> {
|
||||
try {
|
||||
await fs.access(filePath)
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export async function ensureDir(dirPath: string): Promise<void> {
|
||||
await fs.mkdir(dirPath, { recursive: true })
|
||||
}
|
||||
|
||||
export async function readText(filePath: string): Promise<string> {
|
||||
return fs.readFile(filePath, "utf8")
|
||||
}
|
||||
|
||||
export async function readJson<T>(filePath: string): Promise<T> {
|
||||
const raw = await readText(filePath)
|
||||
return JSON.parse(raw) as T
|
||||
}
|
||||
|
||||
export async function writeText(filePath: string, content: string): Promise<void> {
|
||||
await ensureDir(path.dirname(filePath))
|
||||
await fs.writeFile(filePath, content, "utf8")
|
||||
}
|
||||
|
||||
export async function writeJson(filePath: string, data: unknown): Promise<void> {
|
||||
const content = JSON.stringify(data, null, 2)
|
||||
await writeText(filePath, content + "\n")
|
||||
}
|
||||
|
||||
export async function walkFiles(root: string): Promise<string[]> {
|
||||
const entries = await fs.readdir(root, { withFileTypes: true })
|
||||
const results: string[] = []
|
||||
for (const entry of entries) {
|
||||
const fullPath = path.join(root, entry.name)
|
||||
if (entry.isDirectory()) {
|
||||
const nested = await walkFiles(fullPath)
|
||||
results.push(...nested)
|
||||
} else if (entry.isFile()) {
|
||||
results.push(fullPath)
|
||||
}
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
export async function copyDir(sourceDir: string, targetDir: string): Promise<void> {
|
||||
await ensureDir(targetDir)
|
||||
const entries = await fs.readdir(sourceDir, { withFileTypes: true })
|
||||
for (const entry of entries) {
|
||||
const sourcePath = path.join(sourceDir, entry.name)
|
||||
const targetPath = path.join(targetDir, entry.name)
|
||||
if (entry.isDirectory()) {
|
||||
await copyDir(sourcePath, targetPath)
|
||||
} else if (entry.isFile()) {
|
||||
await ensureDir(path.dirname(targetPath))
|
||||
await fs.copyFile(sourcePath, targetPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user