@@ -58,7 +58,7 @@ public function __construct()
5858 * - Quoted args are respected: "--path=\"my path\""
5959 * - Placeholder tokens like [name] are ignored if passed literally.
6060 */
61- public static function call (string $ input ): int
61+ public static function call (string $ input )
6262 {
6363 // Tokenize input and drop placeholder tokens like [name]
6464 $ tokens = self ::tokenizeCommand ($ input );
@@ -164,8 +164,11 @@ public function registerAll(array $commands): void
164164
165165 /**
166166 * Handle argv input and dispatch
167+ *
168+ * When running in console, returns an int exit code.
169+ * When running from web (non-console), returns the command's result if available; otherwise, the exit code.
167170 */
168- public function run (array $ argv ): int
171+ public function run (array $ argv )
169172 {
170173 // In PHP CLI, $argv[0] is the script name (tame), so command starts at index 1
171174 $ commandInput = $ argv [1 ] ?? 'list ' ;
@@ -176,6 +179,7 @@ public function run(array $argv): int
176179
177180 if ($ commandInput === 'list ' ) {
178181 $ this ->renderList ();
182+ // For web context, nothing to return; keep consistent exit code 0
179183 return 0 ;
180184 }
181185
@@ -199,6 +203,7 @@ public function run(array $argv): int
199203
200204 $ exitCode = 0 ;
201205 $ handled = false ;
206+ $ firstResult = null ; // capture first non-null non-int result
202207
203208 // Resolve primary once and track unresolved flags across providers
204209 $ primaryMethod = $ sub ?: 'handle ' ;
@@ -214,8 +219,11 @@ public function run(array $argv): int
214219 continue ;
215220 }
216221
217- $ result = (int ) ($ this ->invokeCommandMethod ($ instance , $ primaryMethod , $ positionals , $ options ) ?? 0 );
218- $ exitCode = max ($ exitCode , $ result );
222+ $ raw = $ this ->invokeCommandMethod ($ instance , $ primaryMethod , $ positionals , $ options );
223+ $ exitCode = max ($ exitCode , is_numeric ($ raw ) ? (int )$ raw : 0 );
224+ if ($ firstResult === null && $ raw !== null && !is_int ($ raw )) {
225+ $ firstResult = $ raw ;
226+ }
219227 $ handled = true ;
220228
221229 // Route flags as methods on the same instance and mark them as resolved
@@ -237,8 +245,11 @@ public function run(array $argv): int
237245 // Fallback: callable handler (no subcommands/flags routing)
238246 if (isset ($ entry ['handler ' ]) && \is_callable ($ entry ['handler ' ])) {
239247 $ handler = $ entry ['handler ' ];
240- $ result = (int ) ($ handler ($ rawArgs ) ?? 0 );
241- $ exitCode = max ($ exitCode , $ result );
248+ $ raw = $ handler ($ rawArgs );
249+ $ exitCode = max ($ exitCode , is_numeric ($ raw ) ? (int )$ raw : 0 );
250+ if ($ firstResult === null && $ raw !== null && !is_int ($ raw )) {
251+ $ firstResult = $ raw ;
252+ }
242253 $ handled = true ;
243254 continue ;
244255 }
@@ -254,8 +265,9 @@ public function run(array $argv): int
254265 }
255266 return max ($ exitCode , 1 );
256267 }
257-
258- return $ exitCode ;
268+
269+ // prefer returning the first meaningful result or exit code
270+ return $ firstResult !== null ? $ firstResult : $ exitCode ;
259271 }
260272
261273 /**
0 commit comments