Interactive Flow
1) Profiles (optional)
- What you see: Choose to load a saved profile or continue without one.
- What happens: Loads prior selections or proceeds to fresh prompts; at end you can save a profile.
- Files written/updated:
.shikamaru-profiles/profiles.json
in the current working directory when saving.
- Code:
this.profilesPath = path.join(this.config.profilesDir, "profiles.json");
fs.writeFileSync(this.profilesPath, JSON.stringify(profiles, null, 2));
2) Repo discovery
- What you see: No prompt; the tool scans
projectsDir
for repos containing .env.example
.
- What happens: Repos collected; metadata cached for labels (Dockerfile, language).
- Files: None.
- Code:
.readdirSync(this.config.projectsDir)
.filter((f) => fs.statSync(p).isDirectory() && fs.existsSync(path.join(p, ".env.example")))
3) Repo selection (multi-select)
- What you see: Searchable multi-select with fuzzy search; badges like 🐳 and language.
- What happens: Selected repos become the working set.
- Files: None.
- Code:
promptConfig.searchable = true; promptConfig.highlight = true;
const Fuse = (await import("fuse.js")).default;
return this.toChoices(results);
4) Cloud & install options
- What you see: Confirm to skip cloud env and/or dependency installation.
- What happens: Applies
skipCloud
→ skipAzure
, and skipInstall
in runtime config.
- Files: None.
- Code:
const { skipCloud, skipInstall } = await inquirer.default.prompt([...])
5) Execution mode
- What you see: Select Local / Docker / Hybrid. Hybrid/local offer per-repo overrides and optional custom commands.
- What happens: Sets
globalMode
and per-repo configs; may parse Dockerfile to infer commands.
- Files: None.
- Code:
type: "list", name: "globalMode", choices: [Local, Docker, Hybrid]
6) Ports management
- What you see: Confirm whether to reuse existing ports.
- What happens: Loads or generates port assignments (host typically 4000–5000).
- Files written/updated:
ports-map.json
in projectsDir
.
- Code:
await this.writeFileAtomic(content);
7) Logging interface
- What you see: Choose Web or Terminal logs.
- What happens: Sets
loggingConfig.mode
and starts API/UI for web mode.
- Files: None.
8) Environment files
- What you see: No prompt;
.env
generated for each selected repo.
- What happens: Merges
global.env
/ global.frontend.env
and .env.example
.
- Files written/updated:
[repo]/.env
next to each .env.example
.
- Code:
await this.getFileWriter().writeFileAtomic(envPath, resolvedContent);
9) Docker compose (if needed)
- What you see: No explicit prompt; based on mode and infra detection.
- What happens: Generates infra compose and unified compose files.
- Files written/updated:
docker-compose.infra.yml
docker-compose.unified.yml
- Code:
fs.writeFileSync(composePath, composeContent);
fs.writeFileSync(unifiedComposePath, composeContent, "utf-8");
10) Save profile (optional)
- What you see: Prompt to save the current configuration.
- What happens: Persists consolidated
promptSteps
including repos, unified config, skips, logging, and port reuse.
- Files written/updated:
.shikamaru-profiles/profiles.json
.
- Code:
await this.saveProfile(name, description, selectedRepos, unifiedConfig, cloudProviders, loggingConfig, portReusePreference);
projectsDir
: Base directory for repo discovery.
global.env
and global.frontend.env
: Optional root-level env inputs.
.env.example
: Required per selected repo for .env
generation.
Artifacts summary
.shikamaru-profiles/profiles.json
ports-map.json
[repo]/.env
docker-compose.infra.yml
docker-compose.unified.yml