spawnio 1.0.9__tar.gz → 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {spawnio-1.0.9 → spawnio-1.1.0}/PKG-INFO +40 -3
- {spawnio-1.0.9 → spawnio-1.1.0}/README.md +39 -2
- {spawnio-1.0.9 → spawnio-1.1.0}/docs/architecture.md +35 -2
- {spawnio-1.0.9 → spawnio-1.1.0}/docs/changelog.md +27 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/docs/commands.md +66 -5
- {spawnio-1.0.9 → spawnio-1.1.0}/docs/getting-started.md +3 -2
- spawnio-1.1.0/docs/inspection/inspection-contract.md +987 -0
- spawnio-1.1.0/docs/inspection/language-framework-handoff.md +57 -0
- spawnio-1.1.0/docs/inspection/safe-discovery.md +123 -0
- spawnio-1.1.0/docs/inspection/supported-technologies.md +182 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/pyproject.toml +1 -1
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/__init__.py +1 -1
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/cli/app.py +77 -2
- spawnio-1.1.0/src/spawn/cli/inspect_render.py +287 -0
- spawnio-1.1.0/src/spawn/inspection/__init__.py +69 -0
- spawnio-1.1.0/src/spawn/inspection/_reading.py +21 -0
- spawnio-1.1.0/src/spawn/inspection/base.py +68 -0
- spawnio-1.1.0/src/spawn/inspection/dependencies.py +410 -0
- spawnio-1.1.0/src/spawn/inspection/discovery.py +280 -0
- spawnio-1.1.0/src/spawn/inspection/exceptions.py +14 -0
- spawnio-1.1.0/src/spawn/inspection/frameworks.py +255 -0
- spawnio-1.1.0/src/spawn/inspection/languages.py +195 -0
- spawnio-1.1.0/src/spawn/inspection/models.py +615 -0
- spawnio-1.1.0/src/spawn/inspection/orchestrator.py +294 -0
- spawnio-1.1.0/src/spawn/inspection/serialization.py +491 -0
- spawnio-1.1.0/src/spawn/inspection/tooling.py +469 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/conftest.py +8 -0
- spawnio-1.1.0/tests/fixtures/inspection_corpus.py +175 -0
- spawnio-1.1.0/tests/fixtures/make_sample_report.py +363 -0
- spawnio-1.1.0/tests/fixtures/static/sample_report.json +316 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_app.py +15 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_boundaries.py +1 -1
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_docs.py +3 -1
- spawnio-1.1.0/tests/test_inspect_cli.py +350 -0
- spawnio-1.1.0/tests/test_inspection_dependencies.py +537 -0
- spawnio-1.1.0/tests/test_inspection_discovery.py +530 -0
- spawnio-1.1.0/tests/test_inspection_frameworks.py +327 -0
- spawnio-1.1.0/tests/test_inspection_languages.py +221 -0
- spawnio-1.1.0/tests/test_inspection_models.py +773 -0
- spawnio-1.1.0/tests/test_inspection_orchestrator.py +445 -0
- spawnio-1.1.0/tests/test_inspection_regression.py +477 -0
- spawnio-1.1.0/tests/test_inspection_sample.py +486 -0
- spawnio-1.1.0/tests/test_inspection_serialization.py +791 -0
- spawnio-1.1.0/tests/test_inspection_tooling.py +605 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/.gitignore +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/CONTRIBUTING.md +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/LICENSE +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/cli/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/cli/errors.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/cli/noninteractive.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/cli/prompts.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/core/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/core/exceptions.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/core/models.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/core/planning.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/core/project.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/core/registry.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/generators/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/generators/custom_structure.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/generators/destination.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/generators/metadata.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/generators/pipeline.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/generators/project_files.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/generators/project_generator.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/github/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/github/exceptions.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/github/publisher.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/github/validators.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/agent/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/agent/content.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/automation/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/automation/content.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/backend_api/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/backend_api/content.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/base.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/chatbot/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/chatbot/content.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/cli_application/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/cli_application/content.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/data_project/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/data_project/analysis/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/data_project/analysis/content.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/data_project/dashboard/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/data_project/dashboard/content.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/data_project/etl/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/data_project/etl/content.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/data_project/ml/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/data_project/ml/content.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/mcp_server/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/mcp_server/content.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/rag/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/rag/content.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/templates/shared_content.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/utils/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/utils/banner.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/utils/console.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/utils/doctor.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/utils/doctor_fix.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/utils/git.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/utils/redact.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/utils/success.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/utils/theme.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/utils/uv.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/src/spawn/utils/validators.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/fixtures/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/fixtures/archetypes.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/fixtures/static/broken_meta/.spawn/meta.json +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/fixtures/static/meta_unknown_intent/.spawn/meta.json +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/fixtures/static/non_spawn_python_repo/pyproject.toml +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/fixtures/static/non_spawn_python_repo/src/pkg/__init__.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/fixtures/static/non_spawn_python_repo/tests/test_x.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/fixtures/trees/agent.txt +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/fixtures/trees/automation.txt +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/fixtures/trees/backend-api.txt +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/fixtures/trees/chatbot.txt +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/fixtures/trees/cli.txt +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/fixtures/trees/custom.txt +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/fixtures/trees/data.txt +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/fixtures/trees/mcp.txt +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/fixtures/trees/rag.txt +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_agent_generator.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_agent_template.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_automation_generator.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_automation_template.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_chatbot_generator.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_chatbot_template.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_cli_application_generator.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_cli_application_template.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_console.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_create_flags.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_custom_structure.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_custom_structure_integration.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_data_project_analysis.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_data_project_dashboard.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_data_project_etl.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_data_project_gitignore.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_data_project_ml.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_destination.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_doctor.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_doctor_fix.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_errors.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_fixtures.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_generator.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_git.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_github_publisher.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_github_validators.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_mcp_server_generator.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_mcp_server_template.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_models.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_noninteractive.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_pipeline.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_planning.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_project.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_project_files.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_prompts.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_rag_generator.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_rag_template.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_registry.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_templates.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_uv.py +0 -0
- {spawnio-1.0.9 → spawnio-1.1.0}/tests/test_validators.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: spawnio
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: Spawn a ready-to-use Python project in seconds
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Requires-Python: >=3.12
|
|
@@ -89,6 +89,7 @@ It's repetitive. It's inconsistent. And you haven't written a single line of *re
|
|
|
89
89
|
| **GitHub publishing** | Connects your project to an existing GitHub repo and pushes the initial commit |
|
|
90
90
|
| **spawn doctor** | Scores your project's health out of 100, with per-category breakdowns and a prioritized next step |
|
|
91
91
|
| **spawn doctor --fix** | Fixes missing files and config automatically — never overwrites, never installs packages |
|
|
92
|
+
| **spawn inspect** | Static, read-only summary of a repository: languages, frameworks, dependencies, package managers, tooling and layout, as text or JSON |
|
|
92
93
|
|
|
93
94
|
---
|
|
94
95
|
|
|
@@ -144,12 +145,13 @@ Running `spawn` with no arguments shows the banner, the installed version, and t
|
|
|
144
145
|
|
|
145
146
|
```
|
|
146
147
|
SPAWN — scaffold your next project
|
|
147
|
-
v1.0
|
|
148
|
+
v1.1.0
|
|
148
149
|
|
|
149
150
|
Commands
|
|
150
151
|
create Scaffold a new project
|
|
151
152
|
doctor Check the health of a project directory
|
|
152
153
|
version Show the installed version
|
|
154
|
+
inspect Inspect a repository (read-only)
|
|
153
155
|
|
|
154
156
|
Run spawn COMMAND --help for details on a command.
|
|
155
157
|
```
|
|
@@ -791,8 +793,42 @@ spawn doctor --fix --license mit
|
|
|
791
793
|
|
|
792
794
|
```bash
|
|
793
795
|
spawn version
|
|
794
|
-
# → Spawn v1.0
|
|
796
|
+
# → Spawn v1.1.0
|
|
797
|
+
|
|
798
|
+
spawn --version
|
|
799
|
+
# → Spawn v1.1.0
|
|
800
|
+
```
|
|
801
|
+
|
|
802
|
+
### `spawn inspect`
|
|
803
|
+
|
|
804
|
+
Give Spawn a repository and receive a deterministic, evidence-backed summary of what it contains.
|
|
805
|
+
|
|
806
|
+
```bash
|
|
807
|
+
spawn inspect . # human-readable summary
|
|
808
|
+
spawn inspect . --json # full report on stdout, schema_version "1.0"
|
|
809
|
+
spawn inspect . --verbose # all dependencies, entries and evidence paths
|
|
810
|
+
```
|
|
811
|
+
|
|
795
812
|
```
|
|
813
|
+
⚡ SPAWN / INSPECT
|
|
814
|
+
|
|
815
|
+
demo
|
|
816
|
+
python project · 11 files · 3 directories
|
|
817
|
+
|
|
818
|
+
PROJECT OVERVIEW
|
|
819
|
+
Primary language python
|
|
820
|
+
Framework Not detected
|
|
821
|
+
Package manager Not detected
|
|
822
|
+
Origin spawn
|
|
823
|
+
|
|
824
|
+
✓ Inspection complete
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
**Scope.** 25 languages by extension and manifest; React, Next.js, Vue, Nuxt, Angular, Svelte, Express, FastAPI, Flask, Django, Starlette, Pydantic and Laravel; dependencies from `pyproject.toml`, `requirements*.txt` and `package.json`; package managers (uv, poetry, pipenv, pip, npm, yarn, pnpm, bun); tooling (ruff, black, flake8, mypy, pyright, pytest, eslint, prettier, jest, vitest, pre-commit, git), CI, containers and databases. Full matrix: [supported technologies](docs/inspection/supported-technologies.md).
|
|
828
|
+
|
|
829
|
+
**Limitations.** Detection is static and evidence-based: a finding means an indicator exists, not that the project builds or runs. Frameworks seen only in a dependency declaration are marked *inferred*; imports are matched by regex, so import-like text in comments or strings can false-positive. CI, container and pre-commit detection is presence-only. Databases are inferred from driver packages. Manifests such as `Pipfile`, `setup.py`, `Cargo.toml`, `go.mod`, `Gemfile` and `pom.xml` give no dependency findings. Directories named `build`, `dist`, `env`, `target`, `vendor` and the like are skipped at any depth.
|
|
830
|
+
|
|
831
|
+
**Safety.** `spawn inspect` is read-only: it never runs repository code, installs anything, uses the network or writes to the repository, and it does not follow symbolic links. It exits 0 for complete and partial reports and 7 for an invalid path or failed inspection. See the [command reference](docs/commands.md#spawn-inspect).
|
|
796
832
|
|
|
797
833
|
### Publish to GitHub
|
|
798
834
|
|
|
@@ -825,6 +861,7 @@ All tests should pass. If they don't, please [open an issue](https://github.com/
|
|
|
825
861
|
|
|
826
862
|
| Version | Highlight |
|
|
827
863
|
|---|---|
|
|
864
|
+
| **v1.1.0** | `spawn inspect`: static, read-only repository inspection (languages, frameworks, dependencies, package managers, tooling, layout) with human and `--json` output; `spawn --version` |
|
|
828
865
|
| **v1.0.9** | Core hardening: documented exit-code contract (generation, toolchain and publish failures exit non-zero), `--no-uv` honored for templates (file-only extras still written), path-traversal protection for custom structures, `read_project_metadata` extension boundary |
|
|
829
866
|
| **v1.0.8** | `spawn doctor --fix` (`--dry-run`, `--yes`, `--license`), `--license` flag and prompt on `create`, `CHANGELOG.md` generated for every project, `pre-commit` and `mypy` extras across all templates, Custom Structure Mypy option |
|
|
830
867
|
| **v1.0.7** | Fixed UTF-8 console crash on Windows when stdout is redirected/piped, added Windows reserved device name validation (`CON`, `PRN`, `AUX`, `NUL`, `COM1`–`9`, `LPT1`–`9`), clarified Python 3.12 requirement |
|
|
@@ -78,6 +78,7 @@ It's repetitive. It's inconsistent. And you haven't written a single line of *re
|
|
|
78
78
|
| **GitHub publishing** | Connects your project to an existing GitHub repo and pushes the initial commit |
|
|
79
79
|
| **spawn doctor** | Scores your project's health out of 100, with per-category breakdowns and a prioritized next step |
|
|
80
80
|
| **spawn doctor --fix** | Fixes missing files and config automatically — never overwrites, never installs packages |
|
|
81
|
+
| **spawn inspect** | Static, read-only summary of a repository: languages, frameworks, dependencies, package managers, tooling and layout, as text or JSON |
|
|
81
82
|
|
|
82
83
|
---
|
|
83
84
|
|
|
@@ -133,12 +134,13 @@ Running `spawn` with no arguments shows the banner, the installed version, and t
|
|
|
133
134
|
|
|
134
135
|
```
|
|
135
136
|
SPAWN — scaffold your next project
|
|
136
|
-
v1.0
|
|
137
|
+
v1.1.0
|
|
137
138
|
|
|
138
139
|
Commands
|
|
139
140
|
create Scaffold a new project
|
|
140
141
|
doctor Check the health of a project directory
|
|
141
142
|
version Show the installed version
|
|
143
|
+
inspect Inspect a repository (read-only)
|
|
142
144
|
|
|
143
145
|
Run spawn COMMAND --help for details on a command.
|
|
144
146
|
```
|
|
@@ -780,8 +782,42 @@ spawn doctor --fix --license mit
|
|
|
780
782
|
|
|
781
783
|
```bash
|
|
782
784
|
spawn version
|
|
783
|
-
# → Spawn v1.0
|
|
785
|
+
# → Spawn v1.1.0
|
|
786
|
+
|
|
787
|
+
spawn --version
|
|
788
|
+
# → Spawn v1.1.0
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
### `spawn inspect`
|
|
792
|
+
|
|
793
|
+
Give Spawn a repository and receive a deterministic, evidence-backed summary of what it contains.
|
|
794
|
+
|
|
795
|
+
```bash
|
|
796
|
+
spawn inspect . # human-readable summary
|
|
797
|
+
spawn inspect . --json # full report on stdout, schema_version "1.0"
|
|
798
|
+
spawn inspect . --verbose # all dependencies, entries and evidence paths
|
|
799
|
+
```
|
|
800
|
+
|
|
784
801
|
```
|
|
802
|
+
⚡ SPAWN / INSPECT
|
|
803
|
+
|
|
804
|
+
demo
|
|
805
|
+
python project · 11 files · 3 directories
|
|
806
|
+
|
|
807
|
+
PROJECT OVERVIEW
|
|
808
|
+
Primary language python
|
|
809
|
+
Framework Not detected
|
|
810
|
+
Package manager Not detected
|
|
811
|
+
Origin spawn
|
|
812
|
+
|
|
813
|
+
✓ Inspection complete
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
**Scope.** 25 languages by extension and manifest; React, Next.js, Vue, Nuxt, Angular, Svelte, Express, FastAPI, Flask, Django, Starlette, Pydantic and Laravel; dependencies from `pyproject.toml`, `requirements*.txt` and `package.json`; package managers (uv, poetry, pipenv, pip, npm, yarn, pnpm, bun); tooling (ruff, black, flake8, mypy, pyright, pytest, eslint, prettier, jest, vitest, pre-commit, git), CI, containers and databases. Full matrix: [supported technologies](docs/inspection/supported-technologies.md).
|
|
817
|
+
|
|
818
|
+
**Limitations.** Detection is static and evidence-based: a finding means an indicator exists, not that the project builds or runs. Frameworks seen only in a dependency declaration are marked *inferred*; imports are matched by regex, so import-like text in comments or strings can false-positive. CI, container and pre-commit detection is presence-only. Databases are inferred from driver packages. Manifests such as `Pipfile`, `setup.py`, `Cargo.toml`, `go.mod`, `Gemfile` and `pom.xml` give no dependency findings. Directories named `build`, `dist`, `env`, `target`, `vendor` and the like are skipped at any depth.
|
|
819
|
+
|
|
820
|
+
**Safety.** `spawn inspect` is read-only: it never runs repository code, installs anything, uses the network or writes to the repository, and it does not follow symbolic links. It exits 0 for complete and partial reports and 7 for an invalid path or failed inspection. See the [command reference](docs/commands.md#spawn-inspect).
|
|
785
821
|
|
|
786
822
|
### Publish to GitHub
|
|
787
823
|
|
|
@@ -814,6 +850,7 @@ All tests should pass. If they don't, please [open an issue](https://github.com/
|
|
|
814
850
|
|
|
815
851
|
| Version | Highlight |
|
|
816
852
|
|---|---|
|
|
853
|
+
| **v1.1.0** | `spawn inspect`: static, read-only repository inspection (languages, frameworks, dependencies, package managers, tooling, layout) with human and `--json` output; `spawn --version` |
|
|
817
854
|
| **v1.0.9** | Core hardening: documented exit-code contract (generation, toolchain and publish failures exit non-zero), `--no-uv` honored for templates (file-only extras still written), path-traversal protection for custom structures, `read_project_metadata` extension boundary |
|
|
818
855
|
| **v1.0.8** | `spawn doctor --fix` (`--dry-run`, `--yes`, `--license`), `--license` flag and prompt on `create`, `CHANGELOG.md` generated for every project, `pre-commit` and `mypy` extras across all templates, Custom Structure Mypy option |
|
|
819
856
|
| **v1.0.7** | Fixed UTF-8 console crash on Windows when stdout is redirected/piped, added Windows reserved device name validation (`CON`, `PRN`, `AUX`, `NUL`, `COM1`–`9`, `LPT1`–`9`), clarified Python 3.12 requirement |
|
|
@@ -23,9 +23,10 @@ Entry point: `spawn.cli.app:main` (defined in `pyproject.toml` as `[project.scri
|
|
|
23
23
|
|
|
24
24
|
```
|
|
25
25
|
src/spawn/
|
|
26
|
-
├── __init__.py # __version__ via importlib.metadata, fallback "1.0.
|
|
26
|
+
├── __init__.py # __version__ via importlib.metadata, fallback "1.1.0" (keep in sync with pyproject.toml)
|
|
27
27
|
├── cli/
|
|
28
|
-
│ ├── app.py # Typer app: create, version, doctor commands
|
|
28
|
+
│ ├── app.py # Typer app: create, version (and --version), doctor, inspect commands
|
|
29
|
+
│ ├── inspect_render.py # Rich rendering of an InspectionReport for `spawn inspect`
|
|
29
30
|
│ ├── noninteractive.py # Build config from CLI flags or JSON config file
|
|
30
31
|
│ └── prompts.py # Interactive prompts; derives menu from registry
|
|
31
32
|
├── core/
|
|
@@ -41,6 +42,18 @@ src/spawn/
|
|
|
41
42
|
│ ├── exceptions.py # GitHubPublishError
|
|
42
43
|
│ ├── publisher.py # GitHubPublisher — stages, commits, pushes
|
|
43
44
|
│ └── validators.py # GitHub URL validation
|
|
45
|
+
├── inspection/ # Read-only repository inspection (never imports spawn.cli)
|
|
46
|
+
│ ├── models.py # Report/finding/evidence/diagnostic models, SCHEMA_VERSION, validate_report
|
|
47
|
+
│ ├── base.py # Analyzer protocol
|
|
48
|
+
│ ├── discovery.py # validate_inspection_root, discover_repository (single inventory scan)
|
|
49
|
+
│ ├── languages.py # LanguageDetector
|
|
50
|
+
│ ├── frameworks.py # FrameworkDetector
|
|
51
|
+
│ ├── dependencies.py # DependencyAnalyzer (dependencies, package managers)
|
|
52
|
+
│ ├── tooling.py # ToolingAnalyzer (tools, CI, containers, databases, structure)
|
|
53
|
+
│ ├── orchestrator.py # run_inspection: runs analyzers, aggregates, builds the report
|
|
54
|
+
│ ├── serialization.py # to_json / from_json
|
|
55
|
+
│ ├── exceptions.py # InspectionError (exit code 7)
|
|
56
|
+
│ └── _reading.py # Bounded file reads
|
|
44
57
|
├── templates/
|
|
45
58
|
│ ├── base.py # BaseTemplate dataclass
|
|
46
59
|
│ ├── shared_content.py # README_CONTENT, GITIGNORE_CONTENT, CI, and tool configs
|
|
@@ -255,3 +268,23 @@ To add a template: subclass `BaseTemplate` in `templates/<slug>/` and add a `Tem
|
|
|
255
268
|
## 10. Error model
|
|
256
269
|
|
|
257
270
|
All Spawn errors derive from `SpawnError` (`core/exceptions.py`); each class carries the CLI `exit_code`. The CLI prints `❌ message` and exits with that code. See [Exit codes](commands.md#exit-codes).
|
|
271
|
+
|
|
272
|
+
## 11. Inspection pipeline
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
spawn inspect -> run_inspection -> validate root -> discover once -> analyzers -> aggregate/dedupe/sort -> InspectionReport -> human or JSON
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
| Step | Owner |
|
|
279
|
+
|---|---|
|
|
280
|
+
| CLI: argument, `--json`, exit codes | `cli/app.py::inspect_command` |
|
|
281
|
+
| Validate root (bad root raises `InspectionError`, exit 7) | `inspection/discovery.py::validate_inspection_root` |
|
|
282
|
+
| Discover once: sorted files, directories, skipped, diagnostics; symlinks never followed | `inspection/discovery.py::discover_repository` |
|
|
283
|
+
| Analyzers, fixed order: language, framework, dependency, tooling; each gets the same immutable inventory | `inspection/orchestrator.py::ANALYZERS` |
|
|
284
|
+
| Isolate: a crashing or invalid analyzer becomes a `failed` result, others continue | `orchestrator._run_one` |
|
|
285
|
+
| Aggregate: validate findings, merge by `(category, subject)`, sort; derive summary and structure | `orchestrator._aggregate`, `_summary` |
|
|
286
|
+
| Render: Rich output, or `to_json` on stdout | `cli/inspect_render.py`, `inspection/serialization.py` |
|
|
287
|
+
|
|
288
|
+
Analyzers only consume the inventory (plus bounded reads of files it lists); they do not walk the tree. Nothing is executed, installed, fetched or written. `.spawn/meta.json` is read at most once, as untrusted recorded metadata.
|
|
289
|
+
|
|
290
|
+
**Module boundary:** `inspection/` never imports `spawn.cli`; `tests/test_boundaries.py` enforces this. Statuses and semantics are in [the inspection contract](inspection/inspection-contract.md); what is detected is in [supported technologies](inspection/supported-technologies.md).
|
|
@@ -3,6 +3,33 @@
|
|
|
3
3
|
All notable changes to Spawn are documented here.
|
|
4
4
|
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
5
5
|
|
|
6
|
+
## v1.1.0 — 2026
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- **`spawn inspect [PATH] [--json] [--verbose]`** — read-only, static inspection of a repository. Prints a human summary (overview, technology, tooling, structure, diagnostics) or, with `--json`, the full report on stdout. Exits 0 for complete and partial reports and 7 for an invalid path or failed inspection (see `docs/commands.md`).
|
|
11
|
+
- **`spawn --version`** — prints the same line as `spawn version`.
|
|
12
|
+
- **Inspection contract** — `spawn.inspection` models (`InspectionReport`, `Finding`, `Evidence`, `Diagnostic`), `SCHEMA_VERSION` `"1.0"`, `validate_report`, and `to_json` / `from_json`. See `docs/inspection/inspection-contract.md`.
|
|
13
|
+
- **Safe discovery** — one sorted inventory scan; symlinks and junctions are never followed, default exclusions (`.git`, `node_modules`, `build`, `dist`, `venv`, `env`, `target`, ...) match at any depth, errors below the root become diagnostics.
|
|
14
|
+
- **Language and framework detection** — 25 languages by extension and manifest; React, Next.js, Vue, Nuxt, Angular, Svelte, Express, FastAPI, Flask, Django, Starlette, Pydantic and Laravel from manifests (inferred), imports and config files (detected).
|
|
15
|
+
- **Dependency and package-manager analyzer** — direct dependencies from `pyproject.toml`, `requirements*.txt` and `package.json`; uv, poetry, pipenv, pip, npm, yarn, pnpm and bun.
|
|
16
|
+
- **Tooling analyzer** — Python and JavaScript tools, git, CI systems, Docker and Compose, database drivers, `tests-directory`, `src-layout` and `spawn-generated` markers.
|
|
17
|
+
- **Orchestrator** — runs the analyzers in a fixed order with per-analyzer isolation, merges findings by `(category, subject)`, derives the summary and structure, and reads `.spawn/meta.json` as untrusted recorded metadata.
|
|
18
|
+
- **Test corpus** — generated fixture repositories and a regression suite (`tests/test_inspection_*.py`).
|
|
19
|
+
- Release smoke test now runs `spawn inspect . --json` against a generated project and checks it is unchanged.
|
|
20
|
+
|
|
21
|
+
### Known limitations
|
|
22
|
+
|
|
23
|
+
- Excluded directory basenames (`build`, `env`, `target`, `vendor`, `dist`, `coverage`, ...) match at any depth.
|
|
24
|
+
- `.git` is detected through discovery's skipped list only.
|
|
25
|
+
- Framework imports are regex-matched: import-like text in comments or strings can false-positive; multi-line and destructured imports are missed.
|
|
26
|
+
- Frameworks found only in a dependency declaration are inferred, and `primary_framework` may be inferred.
|
|
27
|
+
- CI, container and pre-commit detection is presence-only (no YAML parsing).
|
|
28
|
+
- Databases are inferred from driver packages only.
|
|
29
|
+
- A pip and an npm package with the same name share one finding.
|
|
30
|
+
- `Pipfile`, `setup.py`, `Cargo.toml`, `go.mod`, `Gemfile`, `composer.json`, `pom.xml` and Gradle files produce no dependency findings; Rails is not detected.
|
|
31
|
+
- `summary.name` is the directory basename.
|
|
32
|
+
|
|
6
33
|
## v1.0.9 — 2026
|
|
7
34
|
|
|
8
35
|
### Added
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
| `spawn` | Show the banner, version, and command list |
|
|
8
8
|
| `spawn create` | Scaffold a new project (interactive or non-interactive) |
|
|
9
9
|
| `spawn doctor` | Score a project directory's health out of 135 |
|
|
10
|
-
| `spawn
|
|
10
|
+
| `spawn inspect` | Inspect a repository and report what it contains (read-only) |
|
|
11
|
+
| `spawn version` | Print the installed version (also `spawn --version`) |
|
|
11
12
|
|
|
12
13
|
---
|
|
13
14
|
|
|
@@ -18,12 +19,13 @@ Running `spawn` with no arguments prints the ASCII banner, the installed version
|
|
|
18
19
|
```
|
|
19
20
|
<ASCII SPAWN banner — "scaffold your next project">
|
|
20
21
|
|
|
21
|
-
v1.0
|
|
22
|
+
v1.1.0
|
|
22
23
|
|
|
23
24
|
Commands
|
|
24
25
|
create Scaffold a new project
|
|
25
26
|
doctor Check the health of a project directory
|
|
26
27
|
version Show the installed version
|
|
28
|
+
inspect Inspect a repository (read-only)
|
|
27
29
|
|
|
28
30
|
Run spawn COMMAND --help for details on a command.
|
|
29
31
|
```
|
|
@@ -398,7 +400,7 @@ If `--claude-md` was passed (or `"claude_md": true` in the config file), a `CLAU
|
|
|
398
400
|
"intent": "backend-api",
|
|
399
401
|
"framework": "fastapi",
|
|
400
402
|
"provider": null,
|
|
401
|
-
"spawn_version": "1.0
|
|
403
|
+
"spawn_version": "1.1.0",
|
|
402
404
|
"created_at": "2026-01-01T00:00:00+00:00",
|
|
403
405
|
"generator": "blueprint",
|
|
404
406
|
"git": true,
|
|
@@ -518,13 +520,71 @@ spawn doctor --fix --license mit
|
|
|
518
520
|
|
|
519
521
|
---
|
|
520
522
|
|
|
523
|
+
## `spawn inspect`
|
|
524
|
+
|
|
525
|
+
```
|
|
526
|
+
spawn inspect [PATH] [--json] [--verbose | -v]
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
Statically inspects a repository and reports its languages, frameworks, declared dependencies, package managers, engineering tooling and layout. `PATH` defaults to `.`. Every positive finding carries repository-relative evidence.
|
|
530
|
+
|
|
531
|
+
| Option | Effect |
|
|
532
|
+
|---|---|
|
|
533
|
+
| `--json` | Print the full report as JSON on stdout (`schema_version` `"1.0"`); errors go to stderr |
|
|
534
|
+
| `--verbose`, `-v` | Show all dependencies, all top-level entries and evidence paths |
|
|
535
|
+
|
|
536
|
+
### Safety
|
|
537
|
+
|
|
538
|
+
`spawn inspect` is read-only and static. It never executes or imports repository code, installs dependencies, uses the network or writes to the repository. Symbolic links and directory junctions are listed as skipped, never followed. Files are read with a 1 MB cap. `.env` files are never read.
|
|
539
|
+
|
|
540
|
+
### Human output
|
|
541
|
+
|
|
542
|
+
Sections, in order: header, **Project overview** (primary language, framework, package manager, origin, Spawn version for Spawn-generated projects), **Technology** (languages, other frameworks, dependencies), **Tooling** (tools, CI, containers, databases), **Repository structure** (file/directory counts, top-level entries, structure markers), **Diagnostics**, and a final status line.
|
|
543
|
+
|
|
544
|
+
State markers:
|
|
545
|
+
|
|
546
|
+
| Marker (ASCII) | State | Meaning |
|
|
547
|
+
|---|---|---|
|
|
548
|
+
| `✓` (`+`) | detected | A direct static indicator exists |
|
|
549
|
+
| `~` | inferred | Indirect evidence only (for example a declared dependency without config); the detail says why |
|
|
550
|
+
| `?` | unknown | The check could not be completed |
|
|
551
|
+
| `○` (`-`) | not detected / not checked | Looked for and absent, or not looked for |
|
|
552
|
+
|
|
553
|
+
The framework line is suffixed `inferred` when the primary framework rests on a dependency declaration alone. Diagnostics list warnings and errors with a stable code (for example `discovery.permission_denied`, `framework.malformed_manifest`) and the affected path. A report with warnings ends `Inspection partial: findings may be incomplete`.
|
|
554
|
+
|
|
555
|
+
### JSON output
|
|
556
|
+
|
|
557
|
+
`--json` writes one JSON document to stdout and nothing else. `target.root` is always `"."`; no absolute path is emitted. Fields: `schema_version`, `status`, `generated_at`, `target`, `recorded_metadata`, `summary`, `structure`, `findings`, `analyzer_results`, `diagnostics`.
|
|
558
|
+
|
|
559
|
+
```bash
|
|
560
|
+
spawn inspect ./my-project --json
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### Inspect exit codes
|
|
564
|
+
|
|
565
|
+
| Code | When |
|
|
566
|
+
|---|---|
|
|
567
|
+
| 0 | Inspection complete or partial (a partial report still prints) |
|
|
568
|
+
| 7 | Path missing, not a directory or unreadable; or the repository root could not be scanned (status `failed`) |
|
|
569
|
+
| 10 | Unexpected error |
|
|
570
|
+
|
|
571
|
+
With `--json`, an invalid path prints the message to stderr, leaves stdout empty and exits 7. An unexpected error in `--json` mode also prints to stderr only (`SPAWN_DEBUG=1` raises the traceback).
|
|
572
|
+
|
|
573
|
+
### Limitations
|
|
574
|
+
|
|
575
|
+
See [Supported technologies](inspection/supported-technologies.md#limitations) for what is and is not detected.
|
|
576
|
+
|
|
577
|
+
---
|
|
578
|
+
|
|
521
579
|
## `spawn version`
|
|
522
580
|
|
|
523
|
-
Prints the installed version. No arguments or options; exit code 0; writes nothing.
|
|
581
|
+
Prints the installed version. `spawn --version` prints the same line. No other arguments or options; exit code 0; writes nothing.
|
|
524
582
|
|
|
525
583
|
```bash
|
|
526
584
|
spawn version
|
|
527
|
-
# Spawn v1.0
|
|
585
|
+
# Spawn v1.1.0
|
|
586
|
+
spawn --version
|
|
587
|
+
# Spawn v1.1.0
|
|
528
588
|
```
|
|
529
589
|
|
|
530
590
|
---
|
|
@@ -540,6 +600,7 @@ spawn version
|
|
|
540
600
|
| 4 | Toolchain error (`git` or `uv` missing or failed) |
|
|
541
601
|
| 5 | Generation / template error |
|
|
542
602
|
| 6 | Publish error (GitHub publishing failed) |
|
|
603
|
+
| 7 | Inspection error (`spawn inspect`: invalid or unreadable path, or a failed inspection) |
|
|
543
604
|
| 10 | Unexpected error (re-run with `SPAWN_DEBUG=1` for a traceback) |
|
|
544
605
|
| 130 | Cancelled (Ctrl+C, EOF, or declining the final prompt) |
|
|
545
606
|
|
|
@@ -49,19 +49,20 @@ After installation, `spawn` is available anywhere on your machine.
|
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
51
|
spawn version
|
|
52
|
-
# Spawn v1.0
|
|
52
|
+
# Spawn v1.1.0
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
Or just run `spawn` with no arguments to see the command overview:
|
|
56
56
|
|
|
57
57
|
```
|
|
58
58
|
SPAWN — scaffold your next project
|
|
59
|
-
v1.0
|
|
59
|
+
v1.1.0
|
|
60
60
|
|
|
61
61
|
Commands
|
|
62
62
|
create Scaffold a new project
|
|
63
63
|
doctor Check the health of a project directory
|
|
64
64
|
version Show the installed version
|
|
65
|
+
inspect Inspect a repository (read-only)
|
|
65
66
|
|
|
66
67
|
Run spawn COMMAND --help for details on a command.
|
|
67
68
|
```
|