feat: Claude Code Monitor — lanes, pipelines and a merged workspace
Internal SmartGift build of a Claude Code monitoring dashboard. Lanes: a durable unit of parallel agent work, one per working directory, tracked across session restarts. Managed lanes are git worktrees the dashboard provisions and can reset or remove behind a three-check destroy guard and a counted preflight; adopted lanes are directories you already own and are never destroyable. Pipelines: a lane moves through pipeline stages. A stage the agent declares with evidence renders green; a stage inferred from the tool-event stream renders dashed amber and never counts as done. Detection is forward-only within a 30-minute window, and never writes the declared stage. Workspace: one page at /run with a lane grid, the selected lane's pipeline, and a full Claude console behind a disclosure.
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* @file Archive extraction and install-dir discovery for cross-platform binaries.
|
||||
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
||||
*/
|
||||
const fs = require("node:fs");
|
||||
const path = require("node:path");
|
||||
const { pipeline } = require("node:stream/promises");
|
||||
const { Readable } = require("node:stream");
|
||||
const tar = require("tar");
|
||||
const AdmZip = require("adm-zip");
|
||||
const { isWindows } = require("./paths");
|
||||
|
||||
async function downloadFile(url, dest) {
|
||||
const response = await fetch(url, { redirect: "follow" });
|
||||
if (!response.ok) {
|
||||
throw new Error(`Download failed (${response.status}): ${url}`);
|
||||
}
|
||||
if (!response.body) {
|
||||
throw new Error(`Empty response body: ${url}`);
|
||||
}
|
||||
await fs.promises.mkdir(path.dirname(dest), { recursive: true });
|
||||
await pipeline(Readable.fromWeb(response.body), fs.createWriteStream(dest));
|
||||
}
|
||||
|
||||
async function extractTar(archivePath, destDir) {
|
||||
await fs.promises.mkdir(destDir, { recursive: true });
|
||||
await tar.x({ file: archivePath, cwd: destDir });
|
||||
}
|
||||
|
||||
async function extractZip(archivePath, destDir) {
|
||||
await fs.promises.mkdir(destDir, { recursive: true });
|
||||
const zip = new AdmZip(archivePath);
|
||||
zip.extractAllTo(destDir, true);
|
||||
}
|
||||
|
||||
async function extractArchive(archivePath, destDir) {
|
||||
if (archivePath.endsWith(".zip")) {
|
||||
await extractZip(archivePath, destDir);
|
||||
return;
|
||||
}
|
||||
await extractTar(archivePath, destDir);
|
||||
}
|
||||
|
||||
async function listChildDirs(parent) {
|
||||
const entries = await fs.promises.readdir(parent, { withFileTypes: true });
|
||||
return entries.filter((e) => e.isDirectory()).map((e) => path.join(parent, e.name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Locate a single top-level directory after extraction. Official archives ship
|
||||
* one root folder; this also tolerates minor naming differences across OS builds.
|
||||
*/
|
||||
async function findExtractedRoot(extractRoot, preferredNames, containsFile) {
|
||||
for (const name of preferredNames) {
|
||||
const candidate = path.join(extractRoot, name);
|
||||
if (fs.existsSync(path.join(candidate, containsFile))) return candidate;
|
||||
}
|
||||
|
||||
const dirs = await listChildDirs(extractRoot);
|
||||
const matches = [];
|
||||
for (const dir of dirs) {
|
||||
if (fs.existsSync(path.join(dir, containsFile))) matches.push(dir);
|
||||
}
|
||||
if (matches.length === 1) return matches[0];
|
||||
if (matches.length > 1) {
|
||||
throw new Error(
|
||||
`Multiple install directories matched in ${extractRoot}: ${matches.map(path.basename).join(", ")}`
|
||||
);
|
||||
}
|
||||
throw new Error(
|
||||
`Could not find install directory under ${extractRoot} (expected ${containsFile}).`
|
||||
);
|
||||
}
|
||||
|
||||
async function replaceDir(target, source) {
|
||||
await fs.promises.rm(target, { recursive: true, force: true });
|
||||
await fs.promises.mkdir(path.dirname(target), { recursive: true });
|
||||
await fs.promises.cp(source, target, { recursive: true });
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
downloadFile,
|
||||
extractArchive,
|
||||
findExtractedRoot,
|
||||
replaceDir,
|
||||
prometheusContainsFile: isWindows() ? "prometheus.exe" : "prometheus",
|
||||
grafanaContainsFile: path.join("bin", isWindows() ? "grafana.exe" : "grafana"),
|
||||
};
|
||||
Reference in New Issue
Block a user