Skip to content

LOU-D3: loushy init scaffolds a runnable project in one command - #61

Merged
LinuxDevil merged 4 commits into
mainfrom
lou-d3-loushy-init
Oct 1, 2026
Merged

LinuxDevil merged 4 commits into
mainfrom
lou-d3-loushy-init

Conversation

@LinuxDevil

Copy link
Copy Markdown
Owner

What

loushy init [dir] [--provider openai|anthropic|openrouter|ollama] [--template minimal|tools|yaml] [--yes] [--no-install] [--no-git] [--package-manager npm|pnpm|yarn|bun] [--force] [--sdk-path <dir|tarball>] scaffolds a runnable project in one command, installs dependencies and runs git init.

Generated project (ESM, TypeScript strict): package.json (scripts dev, test, typecheck, doctor), tsconfig.json, .gitignore, .env.example with the chosen provider's key name, a README with the next 3 commands, src/agent.ts (createAgent({ model, instructions }) plus defineTool example tool(s)), src/agent.test.ts (uses mockModel from /testing, passes offline), src/index.ts (terminal chat for npm run dev). The yaml template ships agent.yaml instead (and dev is loushy dev agent.yaml). Next steps (cd, set the key, npm run dev) are printed at the end.

  • No flags on a TTY: prompts only for what is missing (directory, provider, template), reusing prompts. --yes or no TTY: defaults (minimal, provider auto-detected from the API key env var via providerSpec.ts, else openai).
  • Non-empty target directory is refused with a clear message unless --force.
  • Package manager from --package-manager, else npm_config_user_agent, else npm.
  • The SDK dependency is a caret range of the generating SDK's own version (read from its package.json at runtime). --sdk-path <checkout|.tgz> / LOUSHY_SDK_PATH is the documented local-dev escape hatch: a checkout is npm packed, a tarball is copied, and the project depends on file:./<tarball>. findSdkRoot() is gone.
  • Generated projects depend only on the chosen provider's package (providers load lazily now that LOU-D10/D19 landed).

Why / design choice

One generator, two front doors. The logic lives in the SDK (src/cli/init.ts + src/cli/init/), because the SDK ships bin/ + dist/, so npx loushy init works from the published SDK with no sibling checkout. create-loushy-agent is now a ~25-line wrapper that depends on @loushy/build-ai-agent (same version line) and spawns its loushy init with the same args, so npm create loushy-agent works from the published scaffolder with zero duplicated code. The alternative (SDK importing the scaffolder's build) would make the SDK depend on a package that depends on it, and the SDK's files would not include the scaffolder. Trade-off: npm create loushy-agent now pulls the SDK as a dependency.

How verified (merged origin/main 995f649 immediately before; all re-run on the merged result)

  • npx tsc --noEmit: clean
  • npm run lint: 0 errors (433 warnings, none from the new files)
  • npm run build and npm run build --workspace=packages/create-loushy-agent: success
  • npm run test:coverage: Test Files 120 passed (120), Tests 1722 passed, 4 skipped; thresholds met. Includes the rewritten e2e (about 50s): scaffolds into a temp dir with --sdk-path (packs the local SDK), init runs the real npm install, then npm run typecheck and the generated npm test (2 passed) run offline with provider env vars stripped.
  • npm run fallow: exit 0, no issues, no duplication
  • npm run docs:verify-snippets: all 57 snippets type-check; npm run test:types: no errors; npm run docs:llms:check: ok (llms files regenerated)
  • Also checked by hand: a generated yaml project's test passes.

Notes for reviewer

  • Files outside the obvious scope: root package.json adds prompts (dependency) and @types/prompts (devDependency) because prompts.ts moved into the SDK; package-lock.json updated accordingly. packages/create-loushy-agent/package.json: dropped prompts/@types/prompts/stale templates in files, added the @loushy/build-ai-agent dependency. bin/loushy.js (new init command), tsup.config.ts (entry cli/init), .fallowrc.json (entry glob), src/providers/providerSpec.ts (adds defaultModel to ProviderInfo and detectProviderFromEnv()).
  • Intentional deletions vs main: packages/create-loushy-agent/src/{prompts,template}.ts and prompts.test.ts moved to src/cli/init/ (template.ts became sdkDependency.ts); cli.integration.test.ts and template.env.test.ts replaced by src/cli/init.test.ts and packages/create-loushy-agent/src/index.test.ts. The old create-loushy-agent flags (--name, --dir, --tools) are replaced by init's positional dir and --template; the package was never published.
  • Docs: docs/quick-start.md leads with "Start a new project", README Quickstart/CLI and docs/installation.md updated; nothing claims the package is published and no badges added. Note a bare npx loushy init only resolves the SDK's bin once the SDK is installed (an unrelated loushy package may exist on the registry), so the quick start also gives npx @loushy/build-ai-agent init my-agent.
  • Known leftover (not mine): README still carries the "Current limitation: all provider packages must be installed" note that LOU-D10 made obsolete.
  • packages/create-loushy-agent/package-lock.json is stale (pre-existing, unused by the workspace install); left untouched.

🤖 Generated with Claude Code

LinuxDevil and others added 4 commits October 1, 2026 10:17
Move the generator into the SDK (src/cli/init.ts + src/cli/init/) and add
it to the loushy CLI. create-loushy-agent becomes a thin wrapper that runs
the installed SDK's loushy init, so there is one generator behind both
npx loushy init and npm create loushy-agent.

The generated project depends on @loushy/build-ai-agent by caret range of
the generating SDK version (read from its own package.json); --sdk-path /
LOUSHY_SDK_PATH keeps local development and the e2e test on a packed tarball.
Templates: minimal, tools, yaml. Flags: --provider, --template, --yes,
--no-install, --no-git, --package-manager, --force.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Resolve providerSpec.ts (keep detectProviderFromEnv and main's
peerInstallCommand); with provider packages now loaded lazily, generated
projects depend only on the chosen provider's package.
@LinuxDevil
LinuxDevil merged commit 10f2d24 into main Oct 1, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant