MCPcopy Create free account
hub / github.com/SethGammon/Citadel / detectRuntime

Function detectRuntime

core/runtime/detect-runtime.js:12–73  ·  view source on GitHub ↗
(projectRoot)

Source from the content-addressed store, hash-verified

10const VALID_RUNTIMES = listRuntimeIds();
11
12function detectRuntime(projectRoot) {
13 const root = projectRoot || process.env.CLAUDE_PROJECT_DIR || process.cwd();
14
15 const envRuntime = process.env.CITADEL_RUNTIME;
16 if (envRuntime && VALID_RUNTIMES.includes(envRuntime)) {
17 return { runtime: envRuntime, method: 'env' };
18 }
19
20 try {
21 const isWin = process.platform === 'win32';
22 let parentInfo = '';
23 if (isWin) {
24 try {
25 parentInfo = execSync(
26 `wmic process where "ProcessId=${process.ppid}" get CommandLine /format:list`,
27 { encoding: 'utf8', timeout: 3000, stdio: ['pipe', 'pipe', 'pipe'] }
28 ).toLowerCase();
29 } catch {
30 parentInfo = execSync(
31 `tasklist /FI "PID eq ${process.ppid}" /FO CSV /NH`,
32 { encoding: 'utf8', timeout: 3000, stdio: ['pipe', 'pipe', 'pipe'] }
33 ).toLowerCase();
34 }
35 } else {
36 parentInfo = execSync(
37 `ps -p ${process.ppid} -o command= 2>/dev/null || true`,
38 { encoding: 'utf8', timeout: 3000, stdio: ['pipe', 'pipe', 'pipe'] }
39 ).toLowerCase();
40 }
41
42 if (parentInfo.includes('codex')) {
43 return { runtime: 'codex', method: 'process-tree' };
44 }
45 if (parentInfo.includes('claude')) {
46 return { runtime: 'claude-code', method: 'process-tree' };
47 }
48 } catch {
49 // Ignore and continue to directory markers.
50 }
51
52 const hasClaudeDir = fs.existsSync(path.join(root, '.claude'));
53 const hasCodexDir = fs.existsSync(path.join(root, '.codex'));
54
55 if (hasCodexDir && !hasClaudeDir) {
56 return { runtime: 'codex', method: 'directory-marker' };
57 }
58 if (hasClaudeDir && !hasCodexDir) {
59 return { runtime: 'claude-code', method: 'directory-marker' };
60 }
61 if (hasClaudeDir && hasCodexDir) {
62 try {
63 const claudeStat = fs.statSync(path.join(root, '.claude'));
64 const codexStat = fs.statSync(path.join(root, '.codex'));
65 const runtime = codexStat.mtimeMs > claudeStat.mtimeMs ? 'codex' : 'claude-code';
66 return { runtime, method: 'directory-marker-recency' };
67 } catch {
68 return { runtime: 'claude-code', method: 'directory-marker-fallback' };
69 }

Callers 3

detect-runtime.jsFile · 0.85
mainFunction · 0.85
runFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected