Skip to content

Commit 21d1555

Browse files
authored
feat(core): add OpenCode AI agent detection (#34072)
## Current Behavior Nx's AI agent detection currently identifies Claude Code, Repl.it, and Cursor AI agents via environment variables, but does not detect OpenCode. ## Expected Behavior Nx should also detect when running under OpenCode AI agent by checking for the `OPENCODE` environment variable, which OpenCode sets to `1` when active. ## Related Issue(s) N/A - Feature addition to improve AI agent detection coverage. ## Changes - Added `is_opencode_ai()` function in `packages/nx/src/native/utils/ai.rs` - Updated `is_ai_agent()` to include OpenCode detection - Added corresponding unit tests
1 parent 1b12b39 commit 21d1555

1 file changed

Lines changed: 33 additions & 1 deletion

File tree

  • packages/nx/src/native/utils

packages/nx/src/native/utils/ai.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,21 @@ fn is_cursor_ai() -> bool {
4242
is_cursor
4343
}
4444

45+
/// Detects if the current process is being run by OpenCode
46+
fn is_opencode_ai() -> bool {
47+
match env::var("OPENCODE") {
48+
Ok(_) => {
49+
debug!("OpenCode AI detected via OPENCODE environment variable");
50+
true
51+
}
52+
Err(_) => false,
53+
}
54+
}
55+
4556
/// Detects if the current process is being run by an AI agent
4657
#[napi]
4758
pub fn is_ai_agent() -> bool {
48-
let is_ai = is_claude_ai() || is_replit_ai() || is_cursor_ai();
59+
let is_ai = is_claude_ai() || is_replit_ai() || is_cursor_ai() || is_opencode_ai();
4960

5061
if is_ai {
5162
debug!("AI agent detected");
@@ -65,6 +76,7 @@ mod tests {
6576
"PAGER",
6677
"CURSOR_TRACE_ID",
6778
"COMPOSER_NO_INTERACTION",
79+
"OPENCODE",
6880
];
6981
for var in &ai_vars {
7082
unsafe {
@@ -81,6 +93,7 @@ mod tests {
8193
let original_pager = env::var("PAGER").ok();
8294
let original_cursor_trace_id = env::var("CURSOR_TRACE_ID").ok();
8395
let original_composer_no_interaction = env::var("COMPOSER_NO_INTERACTION").ok();
96+
let original_opencode = env::var("OPENCODE").ok();
8497

8598
// Start with clean environment
8699
clear_ai_env_vars();
@@ -98,6 +111,10 @@ mod tests {
98111
!is_cursor_ai(),
99112
"Should not detect Cursor AI without all variables"
100113
);
114+
assert!(
115+
!is_opencode_ai(),
116+
"Should not detect OpenCode AI without OPENCODE"
117+
);
101118
assert!(!is_ai_agent(), "Should not detect any AI agent");
102119

103120
// Test Claude AI detection
@@ -120,6 +137,16 @@ mod tests {
120137
env::remove_var("REPL_ID");
121138
}
122139

140+
// Test OpenCode AI detection
141+
unsafe {
142+
env::set_var("OPENCODE", "1");
143+
}
144+
assert!(is_opencode_ai(), "Should detect OpenCode AI with OPENCODE");
145+
assert!(is_ai_agent(), "Main function should detect OpenCode AI");
146+
unsafe {
147+
env::remove_var("OPENCODE");
148+
}
149+
123150
// Test Cursor AI detection with wrong PAGER
124151
unsafe {
125152
env::set_var("PAGER", "wrong-value");
@@ -179,5 +206,10 @@ mod tests {
179206
env::set_var("COMPOSER_NO_INTERACTION", val);
180207
}
181208
}
209+
if let Some(val) = original_opencode {
210+
unsafe {
211+
env::set_var("OPENCODE", val);
212+
}
213+
}
182214
}
183215
}

0 commit comments

Comments
 (0)