shikamaru

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 skipCloudskipAzure, 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);

Default inputs

  • 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

MIT © 2025 — shikamaru

Made with love