@@ -175,14 +175,14 @@ async function main() {
175175 const prompt = positionals . join ( " " ) . trim ( ) ;
176176 const harness = new Harness ( cfg ) ;
177177
178- if ( values [ "no-tui" ] ) {
179- if ( ! prompt ) {
180- console . error ( "Headless mode requires a prompt." ) ;
181- process . exit ( 1 ) ;
182- }
178+ // Fallback to non-TUI mode if terminal is not a TTY or if requested
179+ const isTTY = ! ! ( process . stdout . isTTY && process . stdin . isTTY ) ;
180+ const useNoTui = ! ! ( values [ "no-tui" ] || ! isTTY ) ;
181+
182+ if ( useNoTui || prompt !== "" ) {
183183 harness . events . on ( ( e ) => {
184184 if ( e . type === "phase" )
185- console . log ( `[phase] ${ e . phase } ${ e . detail || "" } ` ) ;
185+ console . log ( `\n [phase] ${ e . phase . toUpperCase ( ) } ${ e . detail || "" } ` ) ;
186186 else if ( e . type === "agent_log" && e . line . kind !== "say" )
187187 console . log ( `[${ e . agent } ] ${ e . line . kind } : ${ e . line . text } ` ) ;
188188 else if ( e . type === "agent_log" && e . line . kind === "say" )
@@ -192,30 +192,94 @@ async function main() {
192192 `[bus] ${ e . message . from } -> ${ e . message . to } [${ e . message . kind } ] ${ e . message . title } ` ,
193193 ) ;
194194 else if ( e . type === "system" ) console . log ( `[system] ${ e . text } ` ) ;
195- else if ( e . type === "plan" )
196- console . log ( `[plan] ${ e . plan . title } \n${ e . plan . summary } ` ) ;
197- else if ( e . type === "questions" )
198- console . log (
199- `[questions]\n${ e . questions . map ( ( q , i ) => `${ i + 1 } . ${ q . question } ` ) . join ( "\n" ) } ` ,
200- ) ;
201- else if ( e . type === "final" ) console . log ( "\n=== READY ===\n" + e . text ) ;
195+ else if ( e . type === "plan" ) {
196+ console . log ( `\n=================== PLAN ===================` ) ;
197+ console . log ( `Title: ${ e . plan . title } ` ) ;
198+ console . log ( `Summary: ${ e . plan . summary } ` ) ;
199+ console . log ( `============================================\n` ) ;
200+ } else if ( e . type === "questions" ) {
201+ console . log ( `\n================= QUESTIONS =================` ) ;
202+ console . log ( e . questions . map ( ( q , i ) => `${ i + 1 } . ${ q . question } ` ) . join ( "\n" ) ) ;
203+ console . log ( `=============================================\n` ) ;
204+ } else if ( e . type === "final" ) console . log ( "\n=== READY ===\n" + e . text ) ;
202205 else if ( e . type === "swarm" )
203206 console . log ( `[swarm] ${ e . action } ${ e . workerId } active=${ e . active } ` ) ;
204207 else if ( e . type === "approval_request" ) {
205208 if ( cfg . autoApprove ) harness . resolveApproval ( e . id , true ) ;
206209 else {
207- console . log ( `[approval] denied (use -y): ${ e . agent } ${ e . tool } ` ) ;
210+ console . log ( `[approval] denied (use -y/--yolo or autoApprove ): ${ e . agent } ${ e . tool } ` ) ;
208211 harness . resolveApproval ( e . id , false ) ;
209212 }
210213 }
211214 } ) ;
212- await harness . startPlan ( prompt ) ;
213- if ( harness . plan ) {
214- console . log ( "\n[headless] auto /confirm" ) ;
215- await harness . confirmAndExecute ( ) ;
215+
216+ if ( prompt ) {
217+ await harness . startPlan ( prompt ) ;
218+ if ( harness . plan ) {
219+ console . log ( "\n[headless] auto /confirm" ) ;
220+ await harness . confirmAndExecute ( ) ;
221+ }
222+ console . log ( "\n[metrics]" , harness . metricsLine ( ) ) ;
223+ process . exit ( 0 ) ;
224+ } else {
225+ // CLI Interactive Session (like Claude Code)
226+ const readline = await import ( "node:readline" ) ;
227+ const rl = readline . createInterface ( {
228+ input : process . stdin ,
229+ output : process . stdout ,
230+ } ) ;
231+
232+ console . log ( "\n================================================================" ) ;
233+ console . log ( " /\\" ) ;
234+ console . log ( " / \\ ARROWCODE Interactive CLI" ) ;
235+ console . log ( " / /\\ \\ swarm coding harness" ) ;
236+ console . log ( " /______\\ ORCH · FE · BE · QA" ) ;
237+ console . log ( "================================================================\n" ) ;
238+ console . log ( " Welcome! You are in the interactive CLI mode (similar to Claude Code)." ) ;
239+ console . log ( " - Type standard prompt to chat with the agents." ) ;
240+ console . log ( " - Use /plan <goal> to propose a new plan." ) ;
241+ console . log ( " - Use /confirm to approve and execute the current plan." ) ;
242+ console . log ( " - Use /accept to finish and save changes." ) ;
243+ console . log ( " - Use /help to see all available commands." ) ;
244+ console . log ( " - Type /exit or /quit to quit.\n" ) ;
245+
246+ const promptUser = ( ) => {
247+ rl . question ( "arrowcode> " , async ( answer ) => {
248+ const line = answer . trim ( ) ;
249+ if ( ! line ) {
250+ promptUser ( ) ;
251+ return ;
252+ }
253+ if ( line === "/exit" || line === "/quit" ) {
254+ rl . close ( ) ;
255+ process . exit ( 0 ) ;
256+ }
257+
258+ if ( line . startsWith ( "/" ) ) {
259+ // Dispatch command
260+ const [ cmd , ..._rest ] = line . slice ( 1 ) . split ( / \s + / ) ;
261+ const { dispatchCommand } = await import ( "./commands/registry" ) ;
262+ const res = await dispatchCommand ( line , {
263+ harness,
264+ setYolo : ( ) => { } ,
265+ getYolo : ( ) => false ,
266+ } ) ;
267+ if ( res . type === "exit" ) {
268+ rl . close ( ) ;
269+ process . exit ( 0 ) ;
270+ }
271+ if ( res && "message" in res && res . message ) {
272+ console . log ( `[system] ${ res . message } ` ) ;
273+ }
274+ } else {
275+ await harness . chat ( line ) ;
276+ }
277+ promptUser ( ) ;
278+ } ) ;
279+ } ;
280+ promptUser ( ) ;
281+ return ;
216282 }
217- console . log ( "\n[metrics]" , harness . metricsLine ( ) ) ;
218- process . exit ( 0 ) ;
219283 }
220284
221285 const { waitUntilExit } = render (
0 commit comments