@@ -249,6 +249,11 @@ async def _handle_add_dir(
249249 When false, configs are read and actions collected without starting any
250250 runners. Useful when runner environments may not exist yet (e.g. before
251251 running prepare-envs).
252+ projects: list[str] | null - optional list of project names to initialize.
253+ Projects not in this list are discovered but not config-initialized or
254+ started. Omit (or pass null) to initialize all projects.
255+ Calling add_dir again for the same dir with a different filter (or no
256+ filter) will initialize the previously skipped projects.
252257 """
253258 from finecode .wm_server .config import collect_actions , read_configs
254259 from finecode .wm_server .runner import runner_manager
@@ -257,23 +262,38 @@ async def _handle_add_dir(
257262 params = params or {}
258263 dir_path = pathlib .Path (params ["dir_path" ])
259264 start_runners : bool = params .get ("start_runners" , True )
265+ projects_filter : set [str ] | None = (
266+ set (params ["projects" ]) if params .get ("projects" ) else None
267+ )
260268 logger .trace (f"Add ws dir: { dir_path } " )
261269
262- if dir_path in ws_context .ws_dirs_paths :
263- return {"projects" : []}
270+ if dir_path not in ws_context .ws_dirs_paths :
271+ ws_context .ws_dirs_paths .append (dir_path )
272+
273+ # Discover new projects in this dir (idempotent — skips already-known ones).
274+ await read_configs .read_projects_in_dir (dir_path , ws_context )
275+
276+ # Collect all projects in this dir that haven't been config-initialized yet.
277+ # This covers both newly discovered projects and ones that were filtered out
278+ # by a previous add_dir call with a projects filter.
279+ projects_to_init = [
280+ p for p in ws_context .ws_projects .values ()
281+ if p .dir_path .is_relative_to (dir_path )
282+ and p .dir_path not in ws_context .ws_projects_raw_configs
283+ ]
264284
265- ws_context . ws_dirs_paths . append ( dir_path )
266- new_projects = await read_configs . read_projects_in_dir ( dir_path , ws_context )
285+ if projects_filter is not None :
286+ projects_to_init = [ p for p in projects_to_init if p . name in projects_filter ]
267287
268- for project in new_projects :
288+ for project in projects_to_init :
269289 await read_configs .read_project_config (
270290 project = project , ws_context = ws_context , resolve_presets = False
271291 )
272292
273293 if not start_runners :
274294 # Collect actions directly from raw config without needing runners.
275295 from finecode .wm_server .config import config_models
276- for project in new_projects :
296+ for project in projects_to_init :
277297 if project .status == domain .ProjectStatus .CONFIG_VALID :
278298 try :
279299 collect_actions .collect_actions (
@@ -283,11 +303,11 @@ async def _handle_add_dir(
283303 logger .warning (
284304 f"Failed to collect actions for { project .name } : { exc .message } "
285305 )
286- return {"projects" : [_project_to_dict (p ) for p in new_projects ]}
306+ return {"projects" : [_project_to_dict (p ) for p in projects_to_init ]}
287307
288308 try :
289309 await runner_manager .start_runners_with_presets (
290- projects = new_projects ,
310+ projects = projects_to_init ,
291311 ws_context = ws_context ,
292312 initialize_all_handlers = True ,
293313 )
@@ -300,12 +320,12 @@ async def _handle_add_dir(
300320
301321 # If config overrides were set before this addDir call (e.g. standalone CLI mode),
302322 # apply them to the newly discovered projects and push to their running runners.
303- if ws_context .handler_config_overrides and new_projects :
323+ if ws_context .handler_config_overrides and projects_to_init :
304324 action_names = list (ws_context .handler_config_overrides .keys ())
305- _apply_config_overrides_to_projects (new_projects , action_names , ws_context .handler_config_overrides )
325+ _apply_config_overrides_to_projects (projects_to_init , action_names , ws_context .handler_config_overrides )
306326 try :
307327 async with asyncio .TaskGroup () as tg :
308- for project in new_projects :
328+ for project in projects_to_init :
309329 runners = ws_context .ws_projects_extension_runners .get (project .dir_path , {})
310330 for runner in runners .values ():
311331 if runner .status == RunnerStatus .RUNNING :
@@ -320,7 +340,7 @@ async def _handle_add_dir(
320340 for exc in eg .exceptions :
321341 logger .warning (f"Failed to push config update to runner: { exc } " )
322342
323- return {"projects" : [_project_to_dict (p ) for p in new_projects ]}
343+ return {"projects" : [_project_to_dict (p ) for p in projects_to_init ]}
324344
325345
326346async def _handle_remove_dir (
0 commit comments