@@ -53,6 +53,7 @@ func init() {
5353// ── 1. Flag Parsing ─────────────────────────────────────────────────
5454
5555func TestSubagent_GoalFlag (t * testing.T ) {
56+ skipIfNoBinary (t )
5657 cmd := exec .Command (kodeBinary , "subagent" , "--goal" , "test goal" )
5758 cmd .Stderr = & bytes.Buffer {}
5859 out , err := cmd .Output ()
@@ -72,6 +73,7 @@ func TestSubagent_GoalFlag(t *testing.T) {
7273}
7374
7475func TestSubagent_ContextFlag (t * testing.T ) {
76+ skipIfNoBinary (t )
7577 cmd := exec .Command (kodeBinary , "subagent" ,
7678 "--goal" , "test" ,
7779 "--context" , "important background" ,
@@ -88,6 +90,7 @@ func TestSubagent_ContextFlag(t *testing.T) {
8890}
8991
9092func TestSubagent_TaskFileFlag (t * testing.T ) {
93+ skipIfNoBinary (t )
9194 taskFile := filepath .Join (t .TempDir (), "task.json" )
9295 taskData := map [string ]string {
9396 "goal" : "build auth middleware" ,
@@ -109,6 +112,7 @@ func TestSubagent_TaskFileFlag(t *testing.T) {
109112}
110113
111114func TestSubagent_TimeoutFlag (t * testing.T ) {
115+ skipIfNoBinary (t )
112116 cmd := exec .Command (kodeBinary , "subagent" ,
113117 "--goal" , "test" ,
114118 "--timeout" , "30" ,
@@ -125,6 +129,7 @@ func TestSubagent_TimeoutFlag(t *testing.T) {
125129}
126130
127131func TestSubagent_MaxIterFlag (t * testing.T ) {
132+ skipIfNoBinary (t )
128133 cmd := exec .Command (kodeBinary , "subagent" ,
129134 "--goal" , "test" ,
130135 "--max-iter" , "5" ,
@@ -156,6 +161,7 @@ func TestSubagent_QuietFlag(t *testing.T) {
156161}
157162
158163func TestSubagent_ParentSessionFlag (t * testing.T ) {
164+ skipIfNoBinary (t )
159165 cmd := exec .Command (kodeBinary , "subagent" ,
160166 "--goal" , "test" ,
161167 "--parent-session" , "20260519-test123" ,
@@ -172,6 +178,7 @@ func TestSubagent_ParentSessionFlag(t *testing.T) {
172178}
173179
174180func TestSubagent_RejectsGoalAndTaskTogether (t * testing.T ) {
181+ skipIfNoBinary (t )
175182 taskFile := filepath .Join (t .TempDir (), "task.json" )
176183 os .WriteFile (taskFile , []byte (`{"goal":"test"}` ), 0644 )
177184
@@ -187,6 +194,7 @@ func TestSubagent_RejectsGoalAndTaskTogether(t *testing.T) {
187194}
188195
189196func TestSubagent_RejectsNoGoalOrTask (t * testing.T ) {
197+ skipIfNoBinary (t )
190198 cmd := exec .Command (kodeBinary , "subagent" )
191199 out , err := cmd .CombinedOutput ()
192200
@@ -201,6 +209,7 @@ func TestSubagent_RejectsNoGoalOrTask(t *testing.T) {
201209// ── 2. Stdout Contract ──────────────────────────────────────────────
202210
203211func TestSubagent_StdoutIsJSON (t * testing.T ) {
212+ skipIfNoBinary (t )
204213 cmd := exec .Command (kodeBinary , "subagent" , "--goal" , "test" )
205214 out , err := cmd .Output ()
206215
@@ -286,6 +295,7 @@ func TestSubagent_ExitCodeOne(t *testing.T) {}
286295func TestSubagent_ExitCodeTwo (t * testing.T ) {}
287296
288297func TestSubagent_ExitCodeThree (t * testing.T ) {
298+ skipIfNoBinary (t )
289299 cmd := exec .Command (kodeBinary , "subagent" )
290300 _ , err := cmd .CombinedOutput ()
291301
@@ -697,6 +707,15 @@ func TestDelegateTasks_PipesStderr(t *testing.T) {
697707
698708// ── Helpers ────────────────────────────────────────────────────────
699709
710+ // skipIfNoBinary skips tests that need a real kode binary.
711+ // These tests run as part of the E2E suite (KODE_E2E=true).
712+ func skipIfNoBinary (t * testing.T ) {
713+ t .Helper ()
714+ if kodeBinary == "" {
715+ t .Skip ("kode binary not found — set KODE_E2E=true or build first" )
716+ }
717+ }
718+
700719func isFlagParseError (err error ) bool {
701720 if err == nil {
702721 return false
0 commit comments