mirror of
https://github.com/aphrody-labs/vu.git
synced 2026-10-15 04:39:14 +00:00
59 lines
2.3 KiB
TypeScript
59 lines
2.3 KiB
TypeScript
// SPDX-License-Identifier: Apache-2.0
|
|
// SessionStart hook: hands the session the Git state, the host reachability and the no-human-in-the-loop rule,
|
|
// then the open work (agy.md), so a cloud, WSL or VPS session resumes the plan without being told.
|
|
import { existsSync, readFileSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
|
|
const root = process.env.CLAUDE_PROJECT_DIR ?? process.cwd();
|
|
const resumePath = join(root, "agy.md");
|
|
const resume = existsSync(resumePath) ? readFileSync(resumePath, "utf8") : "(agy.md absent)";
|
|
|
|
async function git(...args: string[]): Promise<string> {
|
|
const proc = Bun.spawn(["git", ...args], { cwd: root, stdout: "pipe", stderr: "ignore" });
|
|
const out = await new Response(proc.stdout).text();
|
|
await proc.exited;
|
|
return out.trim();
|
|
}
|
|
|
|
function aliasDefined(alias: string): boolean {
|
|
const cfg = join(process.env.HOME ?? "", ".ssh/config");
|
|
return existsSync(cfg) && new RegExp(`^Host ${alias}$`, "m").test(readFileSync(cfg, "utf8"));
|
|
}
|
|
|
|
function reach(alias: string): string {
|
|
const code = Bun.spawnSync(
|
|
["ssh", "-o", "BatchMode=yes", "-o", "ConnectTimeout=5", alias, "true"],
|
|
{
|
|
stdout: "ignore",
|
|
stderr: "ignore",
|
|
},
|
|
).exitCode;
|
|
return `${alias}: ${code === 0 ? "reachable" : "unavailable"}`;
|
|
}
|
|
|
|
const [branch, head, dirty] = await Promise.all([
|
|
git("rev-parse", "--abbrev-ref", "HEAD"),
|
|
git("log", "--oneline", "-5"),
|
|
git("status", "--short"),
|
|
]);
|
|
const kind = process.env.CLAUDE_CODE_REMOTE === "true" ? "cloud" : "local";
|
|
const hosts =
|
|
["vps", "dbfr", "wsl"].filter(aliasDefined).map(reach).join(", ") || "no alias defined";
|
|
const context = [
|
|
`[aphrody] ${kind} session: full autonomy, no human in the loop.`,
|
|
"Resume the open work below end to end: code, gates, commit and push, then hosts through `aphrody infra ssh exec --host vps|dbfr` (plan before apply, see docs/operations/cloud/CLOUD-READY.md in the aphrody repository).",
|
|
`SSH: ${hosts}.`,
|
|
`Branch ${branch}. Last commits:\n${head}`,
|
|
dirty
|
|
? `Dirty tree (other agents may own it, do not touch):\n${dirty.split("\n").slice(0, 12).join("\n")}`
|
|
: "Clean tree.",
|
|
"--- OPEN WORK ---",
|
|
resume,
|
|
].join("\n");
|
|
|
|
console.log(
|
|
JSON.stringify({
|
|
hookSpecificOutput: { hookEventName: "SessionStart", additionalContext: context },
|
|
}),
|
|
);
|