Summary
DevForge currently manages repositories, project lifecycle, and Docker — but lacks capabilities that help LLMs and developers quickly understand, diagnose, and bootstrap projects. This issue proposes four new commands that make DevForge a tool LLMs can invoke to reason about codebases.
This was identified by comparing DevForge with Lino, a .NET-specific scaffolding CLI. While Lino's code generation features are too framework-specific to port, the gap in project introspection and structured output for machine consumption is clear. All four commands support a --json flag for LLM-consumable structured output.
Motivation
- LLM-friendliness: An LLM working on a codebase can run
dev project explain . --json to instantly understand architecture, entry points, dependencies, and patterns — without reading dozens of files.
- Developer onboarding:
dev project doctor and dev project explain reduce the time to understand a new project from minutes to seconds.
- Project bootstrapping:
dev project scaffold brings the existing Claude Code scaffolding skills into the CLI, making them available to any LLM or automation.
- Environment debugging:
dev env info --json gives an LLM (or developer) a complete picture of installed tools and auth status in one command.
Implementation Order and Dependencies
Feature 1: dev env info (simplest, introduces --json output pattern)
│
v
Feature 2: dev project doctor (reuses JSON pattern, introduces ProjectChecker interface)
│
v
Feature 3: dev project explain (reuses ProjectChecker, adds architecture analysis)
│
v
Feature 4: dev project scaffold (most complex, uses embedded templates)
Features 1 and 2 are mostly independent and could be implemented in parallel. Feature 3 reuses ProjectChecker from Feature 2. Feature 4 is fully independent but benefits from patterns established by the first three.
Feature 1: dev env info
Purpose: Dump all installed tooling versions, Git provider auth status, and shell info in one structured output. An LLM debugging "why won't this build" can run this first.
Usage
dev env info # human-readable output
dev env info --json # structured JSON for LLM consumption
Example JSON Output
{
"devforge_version": "0.5.0",
"tools": [
{"name": "go", "version": "1.23.0", "installed": true},
{"name": "node", "version": "20.11.0", "installed": true},
{"name": "python3", "version": "3.12.1", "installed": true},
{"name": "java", "version": "", "installed": false},
{"name": "docker", "version": "24.0.7", "installed": true},
{"name": "git", "version": "2.43.0", "installed": true},
{"name": "make", "version": "4.4.1", "installed": true},
{"name": "terraform", "version": "", "installed": false}
],
"auth": [
{"provider": "github", "env_var": "GH_TOKEN", "set": true},
{"provider": "azuredevops", "env_var": "AZURE_DEVOPS_EXT_PAT", "set": false},
{"provider": "gitlab", "env_var": "GITLAB_TOKEN", "set": false}
],
"shell": "/bin/zsh"
}
New Files
| File |
Purpose |
internal/env/runner.go |
ToolRunner interface + DefaultToolRunner (wraps exec.Command for version checks) |
internal/env/info.go |
RunInfo function, InfoConfig, EnvReport, ToolStatus, AuthStatus types |
internal/env/info_test.go |
BDD parallel tests |
internal/testutil/doubles/tool_runner_stub.go |
Test double for ToolRunner |
Key Interfaces
// ToolRunner abstracts external tool version detection for testability.
type ToolRunner interface {
Version(tool string, args ...string) (string, error)
EnvVar(name string) string
}
Design Details
- Mapper from tool name to version-check arguments (no switch/case):
var toolVersionArgs = map[string][]string{
"go": {"version"}, "node": {"--version"}, "python3": {"--version"},
"java": {"-version"}, "docker": {"--version"}, "git": {"--version"},
"make": {"--version"}, "terraform": {"version"},
}
- Auth token check uses env vars:
GH_TOKEN, AZURE_DEVOPS_EXT_PAT, GITLAB_TOKEN
- CLI wiring: new
envCmd command group in main.go with newEnvInfoCmd() factory
Feature 2: dev project doctor [path]
Purpose: Run project health diagnostics with structured pass/warn/fail results. An LLM can parse the output to identify and fix issues automatically.
Usage
dev project doctor . # human-readable with status symbols
dev project doctor . --json # structured JSON
Example JSON Output
{
"language": "go",
"checks": [
{"category": "sdk", "name": "SDK installed", "status": "pass", "detail": "go 1.23.0"},
{"category": "tools", "name": "make", "status": "pass"},
{"category": "tools", "name": "docker", "status": "pass"},
{"category": "tools", "name": "git", "status": "pass"},
{"category": "makefile", "name": "target: lint", "status": "pass"},
{"category": "makefile", "name": "target: test", "status": "pass"},
{"category": "makefile", "name": "target: sast", "status": "warn", "detail": "target not found in Makefile"},
{"category": "docs", "name": "README.md", "status": "pass"},
{"category": "docs", "name": "CHANGELOG.md", "status": "pass"},
{"category": "docs", "name": "CONTRIBUTING.md", "status": "fail", "detail": "file not found"},
{"category": "ci", "name": "CI/CD config", "status": "pass", "detail": ".github/workflows/"}
],
"summary": {"pass": 9, "warn": 1, "fail": 1}
}
New Files
| File |
Purpose |
internal/project/checker.go |
ProjectChecker interface + DefaultProjectChecker |
internal/project/doctor.go |
RunDoctor function, DoctorConfig, CheckResult, DoctorReport types |
internal/project/doctor_test.go |
BDD parallel tests |
internal/testutil/doubles/project_checker_stub.go |
Test double for ProjectChecker |
Key Interfaces
// ProjectChecker abstracts filesystem checks for testability.
type ProjectChecker interface {
FileExists(path string) bool
ReadFile(path string) (string, error)
ToolExists(name string) bool
}
Health Checks (mapper pattern — slice of check functions, no switch/case)
| Check |
Category |
Logic |
| SDK installed |
sdk |
info.CurrentVersion != "" |
| Required tools |
tools |
checker.ToolExists("make"), "docker", "git" |
| Makefile targets |
makefile |
Read Makefile, regex for lint:, test:, sast:, build: |
| Documentation |
docs |
checker.FileExists("README.md"), CHANGELOG.md, CONTRIBUTING.md |
| CI/CD config |
ci |
Check .github/workflows/ or .gitlab-ci.yml or azure-pipelines.yml |
Feature 3: dev project explain [path]
Purpose: Machine-readable project analysis. This is the highest-value LLM feature — an LLM runs this to instantly understand a codebase's architecture, entry points, dependencies, and patterns before making changes.
Usage
dev project explain . # human-readable sections
dev project explain . --json # structured JSON for LLM consumption
Example JSON Output
{
"language": "go",
"sdk_version": "1.23.0",
"required_version": "1.23",
"dependencies": [
{"name": "github.com/spf13/cobra", "version": "v1.8.0", "source_file": "go.mod"},
{"name": "github.com/sirupsen/logrus", "version": "v1.9.3", "source_file": "go.mod"},
{"name": "github.com/rios0rios0/langforge", "version": "v0.3.0", "source_file": "go.mod"},
{"name": "github.com/rios0rios0/gitforge", "version": "v0.2.0", "source_file": "go.mod"}
],
"structure": {
"layers": [
{"name": "cmd", "path": "cmd/devforge", "type": "cmd"},
{"name": "repo", "path": "internal/repo", "type": "internal"},
{"name": "project", "path": "internal/project", "type": "internal"},
{"name": "docker", "path": "internal/docker", "type": "internal"},
{"name": "testutil", "path": "internal/testutil", "type": "test"}
],
"entry_points": ["cmd/devforge/main.go"],
"patterns": ["Clean Architecture", "Dependency Injection", "Mapper Pattern"],
"file_tree": [
{"path": "cmd/devforge", "is_dir": true, "layer": "cmd"},
{"path": "internal/repo", "is_dir": true, "layer": "internal"},
{"path": "internal/project", "is_dir": true, "layer": "internal"},
{"path": "internal/docker", "is_dir": true, "layer": "internal"},
{"path": "internal/testutil/doubles", "is_dir": true, "layer": "test"},
{"path": "internal/testutil/builders", "is_dir": true, "layer": "test"}
]
}
}
New Files
| File |
Purpose |
internal/project/analyzer.go |
ProjectAnalyzer interface + DefaultProjectAnalyzer |
internal/project/explain.go |
RunExplain function, ExplainConfig, ExplainReport, DependencyInfo types |
internal/project/explain_test.go |
BDD parallel tests |
internal/project/analyzer_test.go |
Tests for analysis logic |
internal/testutil/doubles/project_analyzer_stub.go |
Test double for ProjectAnalyzer |
Key Interfaces
// ProjectAnalyzer abstracts project structure analysis for testability.
type ProjectAnalyzer interface {
Analyze(repoPath string) (*ProjectStructure, error)
}
Analysis Logic
- Layer detection (mapper):
{"domain": "domain", "infrastructure": "infrastructure", "cmd": "cmd", "internal": "internal", "test": "test", "pkg": "pkg", "src": "src", "lib": "lib"}
- Pattern detection: Clean Architecture =
domain/ + infrastructure/ present; DDD = entities/ + commands/ inside domain; CQRS = separate command/query directories
- Entry points (mapper per language):
{"go": ["main.go"], "node": ["index.ts", "index.js"], "python": ["main.py", "__main__.py", "app.py"]}
- Dependencies: parse
go.mod require block, package.json dependencies, pyproject.toml dependencies
- File tree: walk directory (max depth 3), annotate each dir with its detected layer
Feature 4: dev project scaffold [language] [path]
Purpose: Language-agnostic project scaffolding following Clean Architecture. Brings the existing Claude Code scaffolding skills into the CLI so any LLM or automation can bootstrap projects.
Usage
dev project scaffold go ./my-project --name my-project --module github.com/org/my-project
dev project scaffold python ./my-api --name my-api
dev project scaffold node ./my-app --name my-app
Supported Languages
| Language |
Aliases |
Generated Structure |
| Go |
go |
cmd/<name>/main.go, internal/domain/{entities,commands,repositories}/, internal/infrastructure/{controllers,repositories}/, Makefile, go.mod |
| Python |
python |
src/<name>/domain/{entities,commands,repositories}/, src/<name>/infrastructure/{controllers,repositories}/, tests/, pyproject.toml, Makefile |
| Node/TS |
node, ts, typescript |
src/domain/{entities,commands,repositories}/, src/infrastructure/{controllers,repositories}/, tests/, package.json, tsconfig.json, Makefile |
All languages also get: README.md, CHANGELOG.md, CONTRIBUTING.md, .gitignore, .editorconfig
New Files
| File |
Purpose |
internal/project/scaffold.go |
RunScaffold function, ScaffoldConfig type |
internal/project/templates.go |
TemplateRenderer interface + DefaultTemplateRenderer using embed.FS |
internal/project/templates/go/** |
Go project template files |
internal/project/templates/python/** |
Python project template files |
internal/project/templates/node/** |
Node/TypeScript project template files |
internal/project/templates/common/** |
Shared templates (README, CHANGELOG, etc.) |
internal/project/scaffold_test.go |
BDD parallel tests |
internal/testutil/doubles/template_renderer_stub.go |
Test double for TemplateRenderer |
Key Interfaces
type TemplateRenderer interface {
Render(templatePath string, data TemplateData) (string, error)
ListTemplates(language string) ([]string, error)
}
Design Details
- Language dispatch via mapper (no switch/case):
{"go": "go", "python": "python", "node": "node", "ts": "node", "typescript": "node"}
- Embedded templates via
//go:embed templates/* + Go text/template
- Generates Clean Architecture structure (domain/infrastructure split)
- Target dir must be empty or non-existent;
--force flag to override
- CLI flags:
--name (project name), --module (module path, e.g., Go module or npm scope)
Files Modified
| File |
Change |
cmd/devforge/main.go |
Add envCmd group + 4 new command factory functions (newEnvInfoCmd, newProjectDoctorCmd, newProjectExplainCmd, newProjectScaffoldCmd) |
CHANGELOG.md |
Add 4 entries under [Unreleased] > Added |
CLAUDE.md |
Update Usage and Architecture sections |
README.md |
Add new commands to usage section |
Design Constraints
These constraints come from the existing codebase patterns:
- Interface-driven testability: all external operations behind interfaces, stubs in
internal/testutil/doubles/ using the fluent builder pattern (NewStub().WithError(err))
- No switch/case: all dispatch uses mapper pattern (maps of string → value/function)
- BDD tests:
// given, // when, // then blocks, parallel via t.Parallel() + t.Run()
- Output convention: status/log to
cfg.Output (stderr) via logf(), machine output to stdout
- Config structs: each operation gets a config struct with injected dependencies (see
project.Config pattern)
Verification Checklist
After each feature:
Final integration:
Summary
DevForge currently manages repositories, project lifecycle, and Docker — but lacks capabilities that help LLMs and developers quickly understand, diagnose, and bootstrap projects. This issue proposes four new commands that make DevForge a tool LLMs can invoke to reason about codebases.
This was identified by comparing DevForge with Lino, a .NET-specific scaffolding CLI. While Lino's code generation features are too framework-specific to port, the gap in project introspection and structured output for machine consumption is clear. All four commands support a
--jsonflag for LLM-consumable structured output.Motivation
dev project explain . --jsonto instantly understand architecture, entry points, dependencies, and patterns — without reading dozens of files.dev project doctoranddev project explainreduce the time to understand a new project from minutes to seconds.dev project scaffoldbrings the existing Claude Code scaffolding skills into the CLI, making them available to any LLM or automation.dev env info --jsongives an LLM (or developer) a complete picture of installed tools and auth status in one command.Implementation Order and Dependencies
Features 1 and 2 are mostly independent and could be implemented in parallel. Feature 3 reuses
ProjectCheckerfrom Feature 2. Feature 4 is fully independent but benefits from patterns established by the first three.Feature 1:
dev env infoPurpose: Dump all installed tooling versions, Git provider auth status, and shell info in one structured output. An LLM debugging "why won't this build" can run this first.
Usage
Example JSON Output
{ "devforge_version": "0.5.0", "tools": [ {"name": "go", "version": "1.23.0", "installed": true}, {"name": "node", "version": "20.11.0", "installed": true}, {"name": "python3", "version": "3.12.1", "installed": true}, {"name": "java", "version": "", "installed": false}, {"name": "docker", "version": "24.0.7", "installed": true}, {"name": "git", "version": "2.43.0", "installed": true}, {"name": "make", "version": "4.4.1", "installed": true}, {"name": "terraform", "version": "", "installed": false} ], "auth": [ {"provider": "github", "env_var": "GH_TOKEN", "set": true}, {"provider": "azuredevops", "env_var": "AZURE_DEVOPS_EXT_PAT", "set": false}, {"provider": "gitlab", "env_var": "GITLAB_TOKEN", "set": false} ], "shell": "/bin/zsh" }New Files
internal/env/runner.goToolRunnerinterface +DefaultToolRunner(wrapsexec.Commandfor version checks)internal/env/info.goRunInfofunction,InfoConfig,EnvReport,ToolStatus,AuthStatustypesinternal/env/info_test.gointernal/testutil/doubles/tool_runner_stub.goToolRunnerKey Interfaces
Design Details
GH_TOKEN,AZURE_DEVOPS_EXT_PAT,GITLAB_TOKENenvCmdcommand group inmain.gowithnewEnvInfoCmd()factoryFeature 2:
dev project doctor [path]Purpose: Run project health diagnostics with structured pass/warn/fail results. An LLM can parse the output to identify and fix issues automatically.
Usage
Example JSON Output
{ "language": "go", "checks": [ {"category": "sdk", "name": "SDK installed", "status": "pass", "detail": "go 1.23.0"}, {"category": "tools", "name": "make", "status": "pass"}, {"category": "tools", "name": "docker", "status": "pass"}, {"category": "tools", "name": "git", "status": "pass"}, {"category": "makefile", "name": "target: lint", "status": "pass"}, {"category": "makefile", "name": "target: test", "status": "pass"}, {"category": "makefile", "name": "target: sast", "status": "warn", "detail": "target not found in Makefile"}, {"category": "docs", "name": "README.md", "status": "pass"}, {"category": "docs", "name": "CHANGELOG.md", "status": "pass"}, {"category": "docs", "name": "CONTRIBUTING.md", "status": "fail", "detail": "file not found"}, {"category": "ci", "name": "CI/CD config", "status": "pass", "detail": ".github/workflows/"} ], "summary": {"pass": 9, "warn": 1, "fail": 1} }New Files
internal/project/checker.goProjectCheckerinterface +DefaultProjectCheckerinternal/project/doctor.goRunDoctorfunction,DoctorConfig,CheckResult,DoctorReporttypesinternal/project/doctor_test.gointernal/testutil/doubles/project_checker_stub.goProjectCheckerKey Interfaces
Health Checks (mapper pattern — slice of check functions, no switch/case)
sdkinfo.CurrentVersion != ""toolschecker.ToolExists("make"),"docker","git"makefilelint:,test:,sast:,build:docschecker.FileExists("README.md"),CHANGELOG.md,CONTRIBUTING.mdci.github/workflows/or.gitlab-ci.ymlorazure-pipelines.ymlFeature 3:
dev project explain [path]Purpose: Machine-readable project analysis. This is the highest-value LLM feature — an LLM runs this to instantly understand a codebase's architecture, entry points, dependencies, and patterns before making changes.
Usage
Example JSON Output
{ "language": "go", "sdk_version": "1.23.0", "required_version": "1.23", "dependencies": [ {"name": "github.com/spf13/cobra", "version": "v1.8.0", "source_file": "go.mod"}, {"name": "github.com/sirupsen/logrus", "version": "v1.9.3", "source_file": "go.mod"}, {"name": "github.com/rios0rios0/langforge", "version": "v0.3.0", "source_file": "go.mod"}, {"name": "github.com/rios0rios0/gitforge", "version": "v0.2.0", "source_file": "go.mod"} ], "structure": { "layers": [ {"name": "cmd", "path": "cmd/devforge", "type": "cmd"}, {"name": "repo", "path": "internal/repo", "type": "internal"}, {"name": "project", "path": "internal/project", "type": "internal"}, {"name": "docker", "path": "internal/docker", "type": "internal"}, {"name": "testutil", "path": "internal/testutil", "type": "test"} ], "entry_points": ["cmd/devforge/main.go"], "patterns": ["Clean Architecture", "Dependency Injection", "Mapper Pattern"], "file_tree": [ {"path": "cmd/devforge", "is_dir": true, "layer": "cmd"}, {"path": "internal/repo", "is_dir": true, "layer": "internal"}, {"path": "internal/project", "is_dir": true, "layer": "internal"}, {"path": "internal/docker", "is_dir": true, "layer": "internal"}, {"path": "internal/testutil/doubles", "is_dir": true, "layer": "test"}, {"path": "internal/testutil/builders", "is_dir": true, "layer": "test"} ] } }New Files
internal/project/analyzer.goProjectAnalyzerinterface +DefaultProjectAnalyzerinternal/project/explain.goRunExplainfunction,ExplainConfig,ExplainReport,DependencyInfotypesinternal/project/explain_test.gointernal/project/analyzer_test.gointernal/testutil/doubles/project_analyzer_stub.goProjectAnalyzerKey Interfaces
Analysis Logic
{"domain": "domain", "infrastructure": "infrastructure", "cmd": "cmd", "internal": "internal", "test": "test", "pkg": "pkg", "src": "src", "lib": "lib"}domain/+infrastructure/present; DDD =entities/+commands/inside domain; CQRS = separate command/query directories{"go": ["main.go"], "node": ["index.ts", "index.js"], "python": ["main.py", "__main__.py", "app.py"]}go.modrequire block,package.jsondependencies,pyproject.tomldependenciesFeature 4:
dev project scaffold [language] [path]Purpose: Language-agnostic project scaffolding following Clean Architecture. Brings the existing Claude Code scaffolding skills into the CLI so any LLM or automation can bootstrap projects.
Usage
Supported Languages
gocmd/<name>/main.go,internal/domain/{entities,commands,repositories}/,internal/infrastructure/{controllers,repositories}/,Makefile,go.modpythonsrc/<name>/domain/{entities,commands,repositories}/,src/<name>/infrastructure/{controllers,repositories}/,tests/,pyproject.toml,Makefilenode,ts,typescriptsrc/domain/{entities,commands,repositories}/,src/infrastructure/{controllers,repositories}/,tests/,package.json,tsconfig.json,MakefileAll languages also get:
README.md,CHANGELOG.md,CONTRIBUTING.md,.gitignore,.editorconfigNew Files
internal/project/scaffold.goRunScaffoldfunction,ScaffoldConfigtypeinternal/project/templates.goTemplateRendererinterface +DefaultTemplateRendererusingembed.FSinternal/project/templates/go/**internal/project/templates/python/**internal/project/templates/node/**internal/project/templates/common/**internal/project/scaffold_test.gointernal/testutil/doubles/template_renderer_stub.goTemplateRendererKey Interfaces
Design Details
{"go": "go", "python": "python", "node": "node", "ts": "node", "typescript": "node"}//go:embed templates/*+ Gotext/template--forceflag to override--name(project name),--module(module path, e.g., Go module or npm scope)Files Modified
cmd/devforge/main.goenvCmdgroup + 4 new command factory functions (newEnvInfoCmd,newProjectDoctorCmd,newProjectExplainCmd,newProjectScaffoldCmd)CHANGELOG.md[Unreleased] > AddedCLAUDE.mdREADME.mdDesign Constraints
These constraints come from the existing codebase patterns:
internal/testutil/doubles/using the fluent builder pattern (NewStub().WithError(err))// given,// when,// thenblocks, parallel viat.Parallel()+t.Run()cfg.Output(stderr) vialogf(), machine output to stdoutproject.Configpattern)Verification Checklist
After each feature:
make build— binary compilesmake test— all tests pass (new + existing)make lint— no lint errors--jsonoutput is valid JSON (parseable byjq)Final integration:
dev env info --json | jq .worksdev project doctor . --json | jq .worksdev project explain . --json | jq .worksdev project scaffold go /tmp/test-project --name test-project --module github.com/test/test-projectcreates expected files