diff --git a/.forum/src/install_hooks.ts b/.forum/src/install_hooks.ts index dd34eb5..c15d54c 100644 --- a/.forum/src/install_hooks.ts +++ b/.forum/src/install_hooks.ts @@ -41,63 +41,78 @@ async function runCommand( } } +const REQUIRED_TOOLS = [ + { name: "git", command: "git", args: ["--version"], required: true, failMsg: "Git is not installed or not in PATH." }, + { name: "Deno", command: "deno", args: ["--version"], required: true, failMsg: "Deno is not installed or not in PATH." }, + { name: "Node.js / npm", command: "npm", args: ["--version"], required: true, failMsg: "npm is not installed or not in PATH." }, + { name: "tree-sitter", command: "tree-sitter", args: ["--version"], required: false, warnMsg: "SCIP/AST generation may be limited." }, + { name: "semgrep", command: "semgrep", args: ["--version"], required: false, warnMsg: "Security analysis payloads may be skipped." }, + { name: "scip-typescript", command: "scip-typescript", args: ["--version"], required: false, warnMsg: "TypeScript SCIP indexing may be skipped." }, + { name: "madge", command: "madge", args: ["--version"], required: false, warnMsg: "Dependency graphing may be skipped." }, + { name: "stryker", command: "stryker", args: ["--version"], required: false, warnMsg: "Mutation testing may be skipped." } +]; + async function checkDependencies() { console.log("Checking dependencies..."); - // Git - const gitCheck = await runCommand("git", ["--version"]); - if (gitCheck.code !== 0) { - console.error("❌ Git is not installed or not in PATH."); - Deno.exit(1); - } - console.log(`✅ ${gitCheck.stdout}`); - - // Deno - const denoCheck = await runCommand("deno", ["--version"]); - if (denoCheck.code !== 0) { - console.error("❌ Deno is not installed or not in PATH."); - Deno.exit(1); - } - console.log(`✅ Deno installed`); - - // Optional: Tree-sitter - const treeSitterCheck = await runCommand("tree-sitter", ["--version"]); - if (treeSitterCheck.code === 0) { - console.log(`✅ tree-sitter found: ${treeSitterCheck.stdout}`); - } else { - console.log( - "⚠️ tree-sitter not found. SCIP/AST generation may be limited.", - ); - } - - // Optional: Semgrep - const semgrepCheck = await runCommand("semgrep", ["--version"]); - if (semgrepCheck.code === 0) { - console.log(`✅ semgrep found: ${semgrepCheck.stdout}`); - } else { - console.log( - "⚠️ semgrep not found. Security analysis payloads may be skipped.", - ); + for (const tool of REQUIRED_TOOLS) { + const check = await runCommand(tool.command, tool.args); + if (check.code !== 0) { + if (tool.required) { + console.error(`[!] Missing: ${tool.name} - ${tool.failMsg}`); + Deno.exit(1); + } else { + console.log(`[!] Warning: ${tool.name} not found. ${tool.warnMsg}`); + } + } else { + // For tools like npm or tree-sitter that might output multiline or noisy versions, + // we take just the first line for a cleaner log. + const versionStr = check.stdout.split('\n')[0].substring(0, 30); + console.log(`[✓] Found: ${tool.name} (${versionStr})`); + } } } async function initializeMetaStateBranch() { console.log("\nInitializing 'meta-state' orphan branch..."); + const dirs = ["tasks", "ontologies", "vectors"]; + // Check if branch exists const checkBranch = await runCommand("git", [ "show-ref", "--verify", "refs/heads/meta-state", ]); + if (checkBranch.code === 0) { console.log( - "✅ 'meta-state' branch already exists. Preserving existing data.", + "[ Already Exists ] 'meta-state' branch found. Checking existing structure...", ); + + // Check which directories exist on the meta-state branch + const lsTree = await runCommand("git", ["ls-tree", "refs/heads/meta-state"]); + if (lsTree.code === 0) { + const existingItems = lsTree.stdout.split('\n').map(line => line.split('\t')[1]); + for (const d of dirs) { + if (existingItems.includes(d)) { + console.log(`[✓] Found directory: ${d}/`); + } else { + console.log(`[!] Missing directory in meta-state: ${d}/`); + } + } + if (existingItems.includes("transitions.json")) { + console.log(`[✓] Found file: transitions.json`); + } else { + console.log(`[!] Missing file in meta-state: transitions.json`); + } + } + + console.log("[~] Preserving existing data. (If missing items are needed, you may need to add them manually to the meta-state branch)"); return; } - console.log("Creating 'meta-state' orphan branch..."); + console.log("[+] Creating 'meta-state' orphan branch..."); // Save current branch name (not strictly needed since we use plumbing, but kept for context if needed later) const currentBranchRes = await runCommand("git", [ @@ -111,7 +126,6 @@ async function initializeMetaStateBranch() { const tempDir = await Deno.makeTempDir(); // Create structure - const dirs = ["tasks", "ontologies", "vectors"]; for (const d of dirs) { await Deno.mkdir(join(tempDir, d), { recursive: true }); // Add a .gitkeep so git tracks the directory @@ -220,7 +234,7 @@ async function initializeMetaStateBranch() { } console.log( - "✅ 'meta-state' branch initialized successfully without modifying working tree.", + "[+] 'meta-state' branch freshly initialized successfully without modifying working tree.", ); } @@ -229,7 +243,7 @@ async function installHooks() { if (!existsSync(GIT_DIR)) { console.error( - "❌ .git directory not found. Must be run from the root of a git repository.", + "[!] Error: .git directory not found. Must be run from the root of a git repository.", ); Deno.exit(1); } @@ -238,13 +252,13 @@ async function installHooks() { const preCommitTarget = join(HOOKS_DIR, "pre-commit"); if (!existsSync(preCommitSource)) { - console.error(`❌ Hook template not found at ${preCommitSource}`); + console.error(`[!] Error: Hook template not found at ${preCommitSource}`); Deno.exit(1); } if (existsSync(preCommitTarget)) { - console.log("⚠️ An existing pre-commit hook was found."); - console.log("Moving existing hook to pre-commit.backup..."); + console.log("[~] An existing pre-commit hook was found."); + console.log("[~] Replaced: Moving existing hook to pre-commit.backup..."); await Deno.rename(preCommitTarget, join(HOOKS_DIR, "pre-commit.backup")); } @@ -255,7 +269,7 @@ async function installHooks() { await runCommand("chmod", ["+x", preCommitTarget]); } - console.log("✅ pre-commit hook installed successfully."); + console.log("[+] Freshly Initialized: pre-commit hook installed successfully."); } async function main() {