intake-ai-cli 0.1.0__tar.gz → 0.2.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.
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/.gitignore +1 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/CHANGELOG.md +94 -0
- intake_ai_cli-0.2.0/LICENSE +21 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/PKG-INFO +68 -16
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/README.md +56 -15
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/SEGUIMIENTO-V0.md +305 -9
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/README.md +18 -4
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/arquitectura.md +97 -20
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/buenas-practicas.md +82 -3
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/configuracion.md +39 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/exportacion.md +14 -2
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/formatos-entrada.md +148 -9
- intake_ai_cli-0.2.0/docs/github-notes/v0.2.0.md +317 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/guia-cli.md +162 -7
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/pipeline.md +72 -23
- intake_ai_cli-0.2.0/docs/plugins.md +297 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/solucion-problemas.md +109 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/pyproject.toml +35 -1
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/__init__.py +1 -1
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/analyzer.py +1 -4
- intake_ai_cli-0.2.0/src/intake/analyze/complexity.py +165 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/dedup.py +2 -6
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/extraction.py +1 -3
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/models.py +1 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/cli.py +449 -65
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/config/loader.py +1 -3
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/config/presets.py +1 -3
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/config/schema.py +34 -6
- intake_ai_cli-0.2.0/src/intake/connectors/__init__.py +11 -0
- intake_ai_cli-0.2.0/src/intake/connectors/base.py +129 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/diff/differ.py +56 -48
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/doctor/checks.py +17 -13
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/export/__init__.py +5 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/export/architect.py +13 -8
- intake_ai_cli-0.2.0/src/intake/export/registry.py +140 -0
- intake_ai_cli-0.2.0/src/intake/generate/adaptive.py +206 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/generate/spec_builder.py +1 -3
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/__init__.py +4 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/base.py +1 -4
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/confluence.py +8 -8
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/docx.py +15 -11
- intake_ai_cli-0.2.0/src/intake/ingest/github_issues.py +319 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/image.py +1 -3
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/jira.py +22 -19
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/markdown.py +8 -5
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/pdf.py +7 -5
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/plaintext.py +6 -4
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/registry.py +117 -12
- intake_ai_cli-0.2.0/src/intake/ingest/slack.py +258 -0
- intake_ai_cli-0.2.0/src/intake/ingest/url.py +233 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/yaml_input.py +7 -7
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/llm/adapter.py +3 -9
- intake_ai_cli-0.2.0/src/intake/plugins/__init__.py +32 -0
- intake_ai_cli-0.2.0/src/intake/plugins/discovery.py +304 -0
- intake_ai_cli-0.2.0/src/intake/plugins/hooks.py +87 -0
- intake_ai_cli-0.2.0/src/intake/plugins/protocols.py +256 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/templates/tasks.md.j2 +4 -3
- intake_ai_cli-0.2.0/src/intake/utils/source_uri.py +162 -0
- intake_ai_cli-0.2.0/src/intake/utils/task_state.py +333 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/verify/engine.py +2 -3
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/verify/reporter.py +7 -3
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/conftest.py +18 -0
- intake_ai_cli-0.2.0/tests/fixtures/github_issues.json +82 -0
- intake_ai_cli-0.2.0/tests/fixtures/sample_webpage.html +62 -0
- intake_ai_cli-0.2.0/tests/fixtures/slack_export.json +65 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_analyze/test_analyzer.py +1 -2
- intake_ai_cli-0.2.0/tests/test_analyze/test_complexity.py +169 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_analyze/test_extraction.py +1 -2
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_analyze/test_llm_adapter.py +2 -1
- intake_ai_cli-0.2.0/tests/test_cli.py +482 -0
- intake_ai_cli-0.2.0/tests/test_connectors/test_base.py +139 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_diff/test_differ.py +26 -15
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_doctor/test_checks.py +3 -2
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_export/test_architect.py +23 -25
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_export/test_generic.py +22 -20
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_export/test_registry.py +20 -0
- intake_ai_cli-0.2.0/tests/test_generate/test_adaptive.py +369 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_generate/test_lock.py +2 -6
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_ingest/test_confluence.py +2 -6
- intake_ai_cli-0.2.0/tests/test_ingest/test_github_issues.py +135 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_ingest/test_hardening.py +13 -7
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_ingest/test_image.py +1 -3
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_ingest/test_jira.py +9 -27
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_ingest/test_markdown.py +1 -3
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_ingest/test_plaintext.py +3 -6
- intake_ai_cli-0.2.0/tests/test_ingest/test_registry.py +222 -0
- intake_ai_cli-0.2.0/tests/test_ingest/test_slack.py +96 -0
- intake_ai_cli-0.2.0/tests/test_ingest/test_url.py +145 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_ingest/test_yaml_input.py +4 -12
- intake_ai_cli-0.2.0/tests/test_plugins/test_discovery.py +118 -0
- intake_ai_cli-0.2.0/tests/test_plugins/test_hooks.py +68 -0
- intake_ai_cli-0.2.0/tests/test_plugins/test_protocols.py +183 -0
- intake_ai_cli-0.2.0/tests/test_utils/__init__.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_utils/test_file_detect.py +16 -2
- intake_ai_cli-0.2.0/tests/test_utils/test_source_uri.py +109 -0
- intake_ai_cli-0.2.0/tests/test_utils/test_task_state.py +247 -0
- intake_ai_cli-0.2.0/tests/test_verify/__init__.py +0 -0
- intake_ai_cli-0.1.0/src/intake/export/registry.py +0 -70
- intake_ai_cli-0.1.0/tests/test_cli.py +0 -256
- intake_ai_cli-0.1.0/tests/test_ingest/test_registry.py +0 -107
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/.intake.yaml.example +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/github-notes/v0.1.0.md +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/verificacion.md +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/from-jira/README.md +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/from-jira/jira-export.json +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/from-markdown/README.md +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/from-markdown/requirements.md +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/from-scratch/README.md +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/from-scratch/idea.txt +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/multi-source/README.md +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/multi-source/api-decisions.json +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/multi-source/notes.txt +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/multi-source/user-stories.md +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/__main__.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/__init__.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/conflicts.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/design.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/prompts.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/questions.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/risks.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/config/__init__.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/config/defaults.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/diff/__init__.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/doctor/__init__.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/export/base.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/export/generic.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/generate/__init__.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/generate/lock.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/llm/__init__.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/templates/acceptance.yaml.j2 +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/templates/context.md.j2 +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/templates/design.md.j2 +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/templates/requirements.md.j2 +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/templates/sources.md.j2 +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/utils/__init__.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/utils/cost.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/utils/file_detect.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/utils/logging.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/utils/project_detect.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/verify/__init__.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/__init__.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/fixtures/confluence_page.html +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/fixtures/jira_export.json +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/fixtures/jira_export_multi.json +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/fixtures/simple_spec.md +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/fixtures/slack_thread.txt +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/fixtures/structured_reqs.yaml +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/fixtures/wireframe.png +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_analyze/__init__.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_analyze/test_conflicts.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_analyze/test_dedup.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_analyze/test_design.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_analyze/test_risks.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_config/__init__.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_config/test_loader.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_config/test_presets.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_config/test_schema.py +0 -0
- {intake_ai_cli-0.1.0/tests/test_diff → intake_ai_cli-0.2.0/tests/test_connectors}/__init__.py +0 -0
- {intake_ai_cli-0.1.0/tests/test_doctor → intake_ai_cli-0.2.0/tests/test_diff}/__init__.py +0 -0
- {intake_ai_cli-0.1.0/tests/test_export → intake_ai_cli-0.2.0/tests/test_doctor}/__init__.py +0 -0
- {intake_ai_cli-0.1.0/tests/test_generate → intake_ai_cli-0.2.0/tests/test_export}/__init__.py +0 -0
- {intake_ai_cli-0.1.0/tests/test_ingest → intake_ai_cli-0.2.0/tests/test_generate}/__init__.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_generate/test_spec_builder.py +0 -0
- {intake_ai_cli-0.1.0/tests/test_utils → intake_ai_cli-0.2.0/tests/test_ingest}/__init__.py +0 -0
- {intake_ai_cli-0.1.0/tests/test_verify → intake_ai_cli-0.2.0/tests/test_plugins}/__init__.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_utils/test_cost.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_utils/test_project_detect.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_verify/test_engine.py +0 -0
- {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_verify/test_reporter.py +0 -0
|
@@ -5,6 +5,84 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.2.0] - 2026-03-03
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
#### Plugin system (extensible architecture)
|
|
13
|
+
|
|
14
|
+
- **Plugin protocols** (`plugins/protocols.py`): V2 extension contracts — `ParserPlugin`, `ExporterPlugin`, `ConnectorPlugin` protocols with `@runtime_checkable`. Supporting dataclasses: `PluginMeta`, `ExportResult`, `FetchedSource`. Exceptions: `PluginError`, `PluginLoadError`.
|
|
15
|
+
- **Plugin discovery** (`plugins/discovery.py`): Automatic plugin loading via `importlib.metadata.entry_points()` (PEP 621). `PluginRegistry` with `discover_all()`, `discover_group()`, `get_parsers()`, `get_exporters()`, `get_connectors()`, `list_plugins()`, `check_compatibility()`. Three entry point groups: `intake.parsers`, `intake.exporters`, `intake.connectors`.
|
|
16
|
+
- **Pipeline hooks** (`plugins/hooks.py`): `HookManager` with `register()`, `emit()`, `registered_events`. Callbacks are called in order; exceptions are caught and logged without blocking other callbacks. Ready for Phase 2 event wiring.
|
|
17
|
+
- **Entry points in `pyproject.toml`**: 11 parsers + 2 exporters registered as `[project.entry-points]`. All discoverable via `intake plugins list`.
|
|
18
|
+
|
|
19
|
+
#### Registry refactoring
|
|
20
|
+
|
|
21
|
+
- **Parser registry** (`ingest/registry.py`): `ParserRegistry` now accepts an optional `PluginRegistry` and attempts plugin-based discovery before falling back to manual registration. New `discover_parsers()` method. JSON subtype detection expanded: Jira → GitHub Issues → Slack → generic YAML.
|
|
22
|
+
- **Exporter registry** (`export/registry.py`): Same plugin-first pattern. `ExporterRegistry` with optional `PluginRegistry`, `discover_exporters()` method, plugin-first `create_default_registry()`.
|
|
23
|
+
|
|
24
|
+
#### 3 new parsers (11 total)
|
|
25
|
+
|
|
26
|
+
- **UrlParser** (`ingest/url.py`): Fetches HTTP/HTTPS URLs via `httpx` (sync), converts HTML to Markdown via BeautifulSoup4 + markdownify. Extracts page title, heading-based sections. Auto-detects source type (confluence, jira, github) from URL patterns. Handles connection errors, timeouts, and HTTP errors with user-friendly `ParseError`.
|
|
27
|
+
- **SlackParser** (`ingest/slack.py`): Parses Slack workspace export JSON format (array of message objects with `type`, `user`, `text`, `ts`, `thread_ts`, `reactions`). Groups messages by thread. Detects decisions via reactions (thumbsup, white_check_mark) and keywords. Detects action items via keywords (TODO, action item, etc.). Metadata: message_count, thread_count, decision_count, action_item_count.
|
|
28
|
+
- **GithubIssuesParser** (`ingest/github_issues.py`): Parses GitHub Issues JSON (single object or array). Extracts labels, assignees, milestones, state, html_url, comments. Detects `#NNN` cross-references as relations. Supports both array and single-issue formats.
|
|
29
|
+
|
|
30
|
+
#### Source URI parsing
|
|
31
|
+
|
|
32
|
+
- **Source URI parser** (`utils/source_uri.py`): `SourceURI` dataclass and `parse_source()` function. Detection order: stdin (`-`) → scheme URIs (`jira://`, `confluence://`, `github://`) → HTTP(S) URLs → existing files → file extensions → free text fallback. `SCHEME_PATTERNS` dict with compiled regexes.
|
|
33
|
+
|
|
34
|
+
#### Connector infrastructure
|
|
35
|
+
|
|
36
|
+
- **Connector base** (`connectors/base.py`): `ConnectorRegistry` with `register()`, `find_for_uri()`, async `fetch()`, `validate_all()`, `available_schemes`. Exceptions: `ConnectorError`, `ConnectorNotFoundError`. No concrete connectors yet (Phase 2).
|
|
37
|
+
|
|
38
|
+
#### Complexity classification and adaptive generation
|
|
39
|
+
|
|
40
|
+
- **Complexity classifier** (`analyze/complexity.py`): `ComplexityAssessment` dataclass and `classify_complexity()` function. Three modes: quick (<500 words, 1 source, no structure), standard (default), enterprise (4+ sources OR >5000 words). Heuristic-based, no LLM dependency.
|
|
41
|
+
- **Adaptive spec builder** (`generate/adaptive.py`): `GenerationPlan` dataclass and `AdaptiveSpecBuilder` class. Wraps standard `SpecBuilder` and filters files by mode: quick generates only `context.md` + `tasks.md`, standard generates all 6, enterprise generates all 6 with detailed risks. `create_generation_plan()` respects user config overrides.
|
|
42
|
+
|
|
43
|
+
#### Task state tracking
|
|
44
|
+
|
|
45
|
+
- **TaskStateManager** (`utils/task_state.py`): Reads and updates `tasks.md` in a spec directory. `list_tasks()` with optional status filter, `get_task()`, `update_task()` with persistence. Supports statuses: pending, in_progress, done, blocked. `TaskStatus` dataclass, `TaskStateError` exception.
|
|
46
|
+
- **TaskItem.status field** added to `analyze/models.py` (default: `"pending"`).
|
|
47
|
+
- **tasks.md.j2 template** updated with Status column in summary table and `**Status:**` field in detail sections.
|
|
48
|
+
|
|
49
|
+
#### New CLI commands
|
|
50
|
+
|
|
51
|
+
- **`intake plugins list`**: Shows table of all discovered plugins with name, group, version, V2 status, built-in status. Verbose mode (`-v`) adds module and error columns.
|
|
52
|
+
- **`intake plugins check`**: Validates compatibility of all discovered plugins. Reports OK or FAIL per plugin.
|
|
53
|
+
- **`intake task list <spec_dir>`**: Lists tasks from a spec with current status. Supports `--status` filter (repeatable). Shows progress summary.
|
|
54
|
+
- **`intake task update <spec_dir> <task_id> <status>`**: Updates task status in tasks.md. Supports `--note` for annotations.
|
|
55
|
+
- **`intake init --mode`**: New `--mode quick|standard|enterprise` option. When omitted and `spec.auto_mode` is True, auto-classifies complexity from sources.
|
|
56
|
+
|
|
57
|
+
#### init command enhancements
|
|
58
|
+
|
|
59
|
+
- Source URI resolution via `parse_source()` — detects file, URL, stdin, and scheme URIs.
|
|
60
|
+
- Scheme URIs (`jira://`, `confluence://`, `github://`) display "connector not available yet" warning.
|
|
61
|
+
- HTTP/HTTPS URLs routed to UrlParser automatically.
|
|
62
|
+
- Complexity classification + adaptive generation when `--mode` not specified.
|
|
63
|
+
- `AdaptiveSpecBuilder` replaces `SpecBuilder` for mode-aware file selection.
|
|
64
|
+
|
|
65
|
+
#### Configuration schema updates
|
|
66
|
+
|
|
67
|
+
- `SpecConfig.auto_mode: bool = True` — enables automatic complexity classification.
|
|
68
|
+
- `ConnectorsConfig` with `JiraConnectorConfig`, `ConfluenceConnectorConfig`, `GithubConnectorConfig` sub-models (Phase 2 preparation).
|
|
69
|
+
- `IntakeConfig.connectors` field added.
|
|
70
|
+
|
|
71
|
+
#### Optional dependencies in pyproject.toml
|
|
72
|
+
|
|
73
|
+
- `connectors = ["atlassian-python-api>=3.40", "PyGithub>=2.0"]`
|
|
74
|
+
- `watch = ["watchfiles>=0.21"]`
|
|
75
|
+
- `mcp = ["mcp>=1.0"]`
|
|
76
|
+
- `respx>=0.21` added to dev dependencies.
|
|
77
|
+
|
|
78
|
+
#### Test suite
|
|
79
|
+
|
|
80
|
+
- **492 tests** (up from 313), **0 failures**. 179 new tests added.
|
|
81
|
+
- 13 new test files: test_protocols, test_discovery, test_hooks, test_base (connectors), test_source_uri, test_task_state, test_url, test_slack, test_github_issues, test_complexity, test_adaptive.
|
|
82
|
+
- 3 new fixture files: `sample_webpage.html`, `slack_export.json`, `github_issues.json`.
|
|
83
|
+
- Plugin discovery tests added to `test_ingest/test_registry.py` and `test_export/test_registry.py`.
|
|
84
|
+
- CLI tests for plugins, task, and init --mode commands added to `test_cli.py`.
|
|
85
|
+
|
|
8
86
|
## [0.1.0] - 2026-03-02
|
|
9
87
|
|
|
10
88
|
### Added
|
|
@@ -112,9 +190,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
112
190
|
- **0 ruff errors**: Fixed 88 lint issues (TC001/TC003, F401, I001, SIM103, RUF022, E501, SIM117, RUF043).
|
|
113
191
|
- **0 mypy --strict errors**: Fixed 26 type errors across 12 files. Proper isinstance narrowing, type-safe dict extraction, correct bool return types.
|
|
114
192
|
|
|
193
|
+
#### Documentation
|
|
194
|
+
|
|
195
|
+
- **`docs/` directory** fully updated with v0.2.0 content: architecture, pipeline, formats, CLI guide, configuration, best practices, troubleshooting.
|
|
196
|
+
- **`docs/plugins.md`** (NEW): Complete plugin system documentation — discovery mechanism, built-in plugins table, V1 vs V2 protocols, how to create external plugins, HookManager, PluginRegistry API.
|
|
197
|
+
- **`docs/github-notes/v0.2.0.md`** (NEW): Full release notes with highlights, migration guide, quality metrics.
|
|
198
|
+
|
|
115
199
|
### Fixed
|
|
116
200
|
|
|
117
201
|
- **structlog test isolation**: Replaced `StringIO` sink with persistent `_NullWriter` class and yield-based autouse fixture. Fixed `cache_logger_on_first_use=True` in `setup_logging()` that caused "I/O operation on closed file" errors when CLI tests ran before module tests.
|
|
118
202
|
- **`_get_list` type safety**: Split into `_get_list` (for dict lists) and `_get_str_list` (for string lists) to fix mypy --strict without breaking acceptance criteria extraction.
|
|
119
203
|
- **bs4 `find()` kwargs**: Changed `**selector` to `attrs=selector` in Confluence parser for correct BeautifulSoup4 type narrowing.
|
|
120
204
|
|
|
205
|
+
### QA Audit
|
|
206
|
+
|
|
207
|
+
Full QA audit completed with 105 issues found and resolved:
|
|
208
|
+
|
|
209
|
+
- **51 ruff lint errors** fixed: TC001 (8), RUF002 (2), N817 (2), E501 (4), F841 (2), TC003 (2), F401/I001 (30 auto-fixed), RUF100 (1).
|
|
210
|
+
- **54 ruff format issues** fixed: Auto-formatted with `ruff format`.
|
|
211
|
+
- **4 mypy --strict errors** fixed: `Returning Any` in `github_issues.py`, unused `type: ignore` in `discovery.py`, `list[object]` vs `list[ParsedContent]` in `cli.py`.
|
|
212
|
+
- **0 security issues**: No hardcoded credentials, no sensitive data in logs.
|
|
213
|
+
- **Coverage**: 86% overall (target: 65%). All modules above their individual targets.
|
|
214
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Diego303
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: intake-ai-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: From requirements in any format to verified implementation
|
|
5
|
+
Project-URL: Homepage, https://diego303.github.io/intake-docs/
|
|
6
|
+
Project-URL: Repository, https://github.com/Diego303/intake-cli
|
|
5
7
|
Author: intake contributors
|
|
6
8
|
License: MIT
|
|
9
|
+
License-File: LICENSE
|
|
7
10
|
Keywords: ai,automation,cli,requirements,spec-driven
|
|
8
11
|
Classifier: Development Status :: 3 - Alpha
|
|
9
12
|
Classifier: Environment :: Console
|
|
@@ -25,14 +28,22 @@ Requires-Dist: python-docx>=1.1
|
|
|
25
28
|
Requires-Dist: pyyaml>=6.0
|
|
26
29
|
Requires-Dist: rich>=13.0
|
|
27
30
|
Requires-Dist: structlog>=24.0
|
|
31
|
+
Provides-Extra: connectors
|
|
32
|
+
Requires-Dist: atlassian-python-api>=3.40; extra == 'connectors'
|
|
33
|
+
Requires-Dist: pygithub>=2.0; extra == 'connectors'
|
|
28
34
|
Provides-Extra: dev
|
|
29
35
|
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
30
36
|
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
31
37
|
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
32
38
|
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: respx>=0.21; extra == 'dev'
|
|
33
40
|
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
34
41
|
Requires-Dist: types-beautifulsoup4>=4.12; extra == 'dev'
|
|
35
42
|
Requires-Dist: types-pyyaml>=6.0; extra == 'dev'
|
|
43
|
+
Provides-Extra: mcp
|
|
44
|
+
Requires-Dist: mcp>=1.0; extra == 'mcp'
|
|
45
|
+
Provides-Extra: watch
|
|
46
|
+
Requires-Dist: watchfiles>=0.21; extra == 'watch'
|
|
36
47
|
Description-Content-Type: text/markdown
|
|
37
48
|
|
|
38
49
|
# intake
|
|
@@ -114,13 +125,26 @@ intake init "API gateway" -s reqs.yaml --preset enterprise
|
|
|
114
125
|
|
|
115
126
|
# Export for a specific agent
|
|
116
127
|
intake init "User endpoint" -s reqs.pdf --format architect
|
|
128
|
+
|
|
129
|
+
# Quick mode for simple tasks (only context.md + tasks.md)
|
|
130
|
+
intake init "Fix login bug" -s notes.txt --mode quick
|
|
131
|
+
|
|
132
|
+
# Fetch requirements from a URL
|
|
133
|
+
intake init "API review" -s https://wiki.company.com/rfc/auth
|
|
134
|
+
|
|
135
|
+
# List discovered plugins
|
|
136
|
+
intake plugins list
|
|
137
|
+
|
|
138
|
+
# Track task progress
|
|
139
|
+
intake task list ./specs/auth-oauth2
|
|
140
|
+
intake task update ./specs/auth-oauth2 1 done --note "Implemented and tested"
|
|
117
141
|
```
|
|
118
142
|
|
|
119
143
|
---
|
|
120
144
|
|
|
121
145
|
## Supported Input Formats
|
|
122
146
|
|
|
123
|
-
| Format | Extensions | Parser |
|
|
147
|
+
| Format | Extensions / Source | Parser |
|
|
124
148
|
|--------|-----------|--------|
|
|
125
149
|
| Markdown | `.md` | Front matter, heading-based sections |
|
|
126
150
|
| Plain text | `.txt`, stdin (`-`) | Paragraph sections, Slack dumps |
|
|
@@ -130,8 +154,11 @@ intake init "User endpoint" -s reqs.pdf --format architect
|
|
|
130
154
|
| Jira export | `.json` (auto-detected) | Issues, comments, links, priorities |
|
|
131
155
|
| Confluence export | `.html` (auto-detected) | Clean Markdown via BS4 + markdownify |
|
|
132
156
|
| Images | `.png`, `.jpg`, `.webp`, `.gif` | LLM vision analysis |
|
|
157
|
+
| URLs | `http://`, `https://` | Fetches page, converts HTML → Markdown |
|
|
158
|
+
| Slack export | `.json` (auto-detected) | Messages, threads, decisions, action items |
|
|
159
|
+
| GitHub Issues | `.json` (auto-detected) | Issues, labels, comments, cross-references |
|
|
133
160
|
|
|
134
|
-
Format is auto-detected by file extension and content inspection. Jira
|
|
161
|
+
Format is auto-detected by file extension and content inspection. Jira, Slack, and GitHub Issues JSON exports are distinguished automatically from generic JSON files. Confluence HTML is distinguished from generic HTML.
|
|
135
162
|
|
|
136
163
|
---
|
|
137
164
|
|
|
@@ -148,6 +175,10 @@ Format is auto-detected by file extension and content inspection. Jira JSON expo
|
|
|
148
175
|
| `intake diff` | Compare two spec versions | **Available** |
|
|
149
176
|
| `intake doctor` | Check environment and configuration health | **Available** |
|
|
150
177
|
| `intake doctor --fix` | Auto-fix environment issues (install deps, create config) | **Available** |
|
|
178
|
+
| `intake plugins list` | List all discovered plugins (parsers, exporters) | **Available** |
|
|
179
|
+
| `intake plugins check` | Validate plugin compatibility | **Available** |
|
|
180
|
+
| `intake task list` | List tasks from a spec with current status | **Available** |
|
|
181
|
+
| `intake task update` | Update a task's status (pending/in_progress/done/blocked) | **Available** |
|
|
151
182
|
|
|
152
183
|
---
|
|
153
184
|
|
|
@@ -171,6 +202,7 @@ spec:
|
|
|
171
202
|
design_depth: moderate # minimal | moderate | detailed
|
|
172
203
|
task_granularity: medium # coarse | medium | fine
|
|
173
204
|
risk_assessment: true
|
|
205
|
+
auto_mode: true # auto-detect quick/standard/enterprise
|
|
174
206
|
|
|
175
207
|
export:
|
|
176
208
|
default_format: generic # architect | claude-code | cursor | kiro | generic
|
|
@@ -213,13 +245,19 @@ See the [`examples/`](examples/) directory for ready-to-run scenarios:
|
|
|
213
245
|
src/intake/
|
|
214
246
|
├── cli.py # Click CLI — thin adapter, no logic
|
|
215
247
|
├── config/ # Pydantic v2 models, presets, layered loader
|
|
216
|
-
│ ├── schema.py #
|
|
248
|
+
│ ├── schema.py # 7 config models (LLM, Project, Spec, Verification, Export, Security, Connectors)
|
|
217
249
|
│ ├── presets.py # minimal / standard / enterprise presets
|
|
218
250
|
│ ├── loader.py # Layered merge: defaults → preset → YAML → CLI
|
|
219
251
|
│ └── defaults.py # Centralized constants
|
|
220
|
-
├──
|
|
252
|
+
├── plugins/ # Plugin system (v0.2.0)
|
|
253
|
+
│ ├── protocols.py # V2 protocols: ParserPlugin, ExporterPlugin, ConnectorPlugin
|
|
254
|
+
│ ├── discovery.py # Entry point scanning via importlib.metadata
|
|
255
|
+
│ └── hooks.py # Pipeline hook system (HookManager)
|
|
256
|
+
├── connectors/ # Connector infrastructure (Phase 2 prep)
|
|
257
|
+
│ └── base.py # ConnectorRegistry, ConnectorError
|
|
258
|
+
├── ingest/ # Phase 1 — 11 parsers, registry, auto-detection
|
|
221
259
|
│ ├── base.py # ParsedContent dataclass + Parser Protocol
|
|
222
|
-
│ ├── registry.py # Auto-detection + parser dispatch
|
|
260
|
+
│ ├── registry.py # Auto-detection + plugin discovery + parser dispatch
|
|
223
261
|
│ ├── markdown.py # .md with YAML front matter
|
|
224
262
|
│ ├── plaintext.py # .txt, stdin, Slack dumps
|
|
225
263
|
│ ├── yaml_input.py # .yaml/.yml/.json structured input
|
|
@@ -227,11 +265,15 @@ src/intake/
|
|
|
227
265
|
│ ├── docx.py # .docx via python-docx
|
|
228
266
|
│ ├── jira.py # Jira JSON exports (API + list format)
|
|
229
267
|
│ ├── confluence.py # Confluence HTML via BS4 + markdownify
|
|
230
|
-
│
|
|
268
|
+
│ ├── image.py # Image analysis via LLM vision
|
|
269
|
+
│ ├── url.py # HTTP/HTTPS URLs via httpx + markdownify
|
|
270
|
+
│ ├── slack.py # Slack workspace export JSON
|
|
271
|
+
│ └── github_issues.py # GitHub Issues JSON
|
|
231
272
|
├── analyze/ # Phase 2 — LLM orchestration (async)
|
|
232
273
|
│ ├── analyzer.py # Orchestrator: extraction → dedup → risk → design
|
|
233
274
|
│ ├── prompts.py # 3 system prompts (extraction, risk, design)
|
|
234
275
|
│ ├── models.py # 10 dataclasses for analysis pipeline
|
|
276
|
+
│ ├── complexity.py # Heuristic complexity classification (quick/standard/enterprise)
|
|
235
277
|
│ ├── extraction.py # LLM JSON → typed AnalysisResult
|
|
236
278
|
│ ├── dedup.py # Jaccard word similarity deduplication
|
|
237
279
|
│ ├── conflicts.py # Conflict validation
|
|
@@ -240,13 +282,14 @@ src/intake/
|
|
|
240
282
|
│ └── design.py # Design output parsing (tasks, checks)
|
|
241
283
|
├── generate/ # Phase 3 — Jinja2 template rendering
|
|
242
284
|
│ ├── spec_builder.py # Orchestrates 6 spec files + lock
|
|
285
|
+
│ ├── adaptive.py # AdaptiveSpecBuilder — mode-aware file selection
|
|
243
286
|
│ └── lock.py # spec.lock.yaml for reproducibility
|
|
244
287
|
├── verify/ # Phase 4 — Acceptance check engine
|
|
245
288
|
│ ├── engine.py # 4 check types: command, files_exist, pattern_*
|
|
246
289
|
│ └── reporter.py # Terminal (Rich), JSON, JUnit XML reporters
|
|
247
290
|
├── export/ # Phase 5 — Agent-ready output
|
|
248
291
|
│ ├── base.py # Exporter Protocol
|
|
249
|
-
│ ├── registry.py #
|
|
292
|
+
│ ├── registry.py # Plugin discovery + format-based dispatch
|
|
250
293
|
│ ├── architect.py # pipeline.yaml generation
|
|
251
294
|
│ └── generic.py # SPEC.md + verify.sh generation
|
|
252
295
|
├── diff/ # Spec comparison
|
|
@@ -258,13 +301,15 @@ src/intake/
|
|
|
258
301
|
├── templates/ # Jinja2 templates for spec generation
|
|
259
302
|
│ ├── requirements.md.j2 # FR, NFR, conflicts, open questions
|
|
260
303
|
│ ├── design.md.j2 # Components, files, tech decisions
|
|
261
|
-
│ ├── tasks.md.j2 # Task summary + detailed sections
|
|
304
|
+
│ ├── tasks.md.j2 # Task summary + status + detailed sections
|
|
262
305
|
│ ├── acceptance.yaml.j2 # Executable acceptance checks
|
|
263
306
|
│ ├── context.md.j2 # Project context for agents
|
|
264
307
|
│ └── sources.md.j2 # Source traceability mapping
|
|
265
|
-
└── utils/ # Shared utilities
|
|
308
|
+
└── utils/ # Shared utilities
|
|
266
309
|
├── file_detect.py # Extension-based format detection
|
|
267
310
|
├── project_detect.py # Auto-detect tech stack from project files
|
|
311
|
+
├── source_uri.py # URI parsing (jira://, github://, http://, files, text)
|
|
312
|
+
├── task_state.py # Task status tracking in tasks.md
|
|
268
313
|
├── cost.py # Cost accumulation with per-phase breakdown
|
|
269
314
|
└── logging.py # structlog configuration
|
|
270
315
|
```
|
|
@@ -272,9 +317,11 @@ src/intake/
|
|
|
272
317
|
**Key design principles:**
|
|
273
318
|
|
|
274
319
|
- **Protocol over ABC** — All extension points use `typing.Protocol`
|
|
320
|
+
- **Plugin-first architecture** — Parsers and exporters discovered via entry points, manual fallback
|
|
275
321
|
- **Dataclasses for pipeline data, Pydantic for config** — Never mixed
|
|
276
322
|
- **Async only in analyze/** — Everything else is synchronous
|
|
277
323
|
- **Offline mode** — Parsing, verification, export, diff, doctor all work without LLM
|
|
324
|
+
- **Adaptive generation** — Complexity auto-detection selects quick/standard/enterprise mode
|
|
278
325
|
- **No magic strings** — All constants defined explicitly
|
|
279
326
|
- **Budget enforcement** — LLM cost tracked per call with configurable limits
|
|
280
327
|
|
|
@@ -320,24 +367,29 @@ python -m pytest tests/ --cov=intake --cov-report=term-missing
|
|
|
320
367
|
# Lint
|
|
321
368
|
ruff check src/ tests/
|
|
322
369
|
|
|
370
|
+
# Format
|
|
371
|
+
ruff format src/ tests/
|
|
372
|
+
|
|
323
373
|
# Type check (strict)
|
|
324
374
|
mypy src/ --strict
|
|
325
375
|
```
|
|
326
376
|
|
|
327
|
-
Current test suite: **
|
|
377
|
+
Current test suite: **492 tests**, **86% coverage**, **0 mypy --strict errors**, **0 ruff warnings**.
|
|
328
378
|
|
|
329
379
|
### Implementation Status
|
|
330
380
|
|
|
331
381
|
| Phase | Module | Status |
|
|
332
382
|
|-------|--------|--------|
|
|
333
|
-
| Phase 1 — Ingest | `ingest/` (
|
|
334
|
-
| Phase 2 — Analyze | `analyze/` (orchestrator + 7 sub-modules) | Implemented |
|
|
335
|
-
| Phase 3 — Generate | `generate/` (spec builder + 6 templates + lock) | Implemented |
|
|
383
|
+
| Phase 1 — Ingest | `ingest/` (11 parsers + plugin-based registry) | Implemented |
|
|
384
|
+
| Phase 2 — Analyze | `analyze/` (orchestrator + 7 sub-modules + complexity) | Implemented |
|
|
385
|
+
| Phase 3 — Generate | `generate/` (spec builder + adaptive builder + 6 templates + lock) | Implemented |
|
|
336
386
|
| Phase 4 — Verify | `verify/` (engine + 3 reporters) | Implemented |
|
|
337
|
-
| Phase 5 — Export | `export/` (architect + generic) | Implemented |
|
|
387
|
+
| Phase 5 — Export | `export/` (architect + generic + plugin registry) | Implemented |
|
|
388
|
+
| Plugins | `plugins/` (protocols + discovery + hooks) | Implemented |
|
|
389
|
+
| Connectors | `connectors/` (registry infrastructure, no concrete connectors) | Implemented |
|
|
338
390
|
| Standalone | `doctor/`, `config/`, `llm/`, `utils/` | Implemented |
|
|
339
391
|
| Standalone | `diff/` (spec differ) | Implemented |
|
|
340
|
-
| CLI |
|
|
392
|
+
| CLI | 13 commands/subcommands wired end-to-end | Implemented |
|
|
341
393
|
|
|
342
394
|
---
|
|
343
395
|
|
|
@@ -77,13 +77,26 @@ intake init "API gateway" -s reqs.yaml --preset enterprise
|
|
|
77
77
|
|
|
78
78
|
# Export for a specific agent
|
|
79
79
|
intake init "User endpoint" -s reqs.pdf --format architect
|
|
80
|
+
|
|
81
|
+
# Quick mode for simple tasks (only context.md + tasks.md)
|
|
82
|
+
intake init "Fix login bug" -s notes.txt --mode quick
|
|
83
|
+
|
|
84
|
+
# Fetch requirements from a URL
|
|
85
|
+
intake init "API review" -s https://wiki.company.com/rfc/auth
|
|
86
|
+
|
|
87
|
+
# List discovered plugins
|
|
88
|
+
intake plugins list
|
|
89
|
+
|
|
90
|
+
# Track task progress
|
|
91
|
+
intake task list ./specs/auth-oauth2
|
|
92
|
+
intake task update ./specs/auth-oauth2 1 done --note "Implemented and tested"
|
|
80
93
|
```
|
|
81
94
|
|
|
82
95
|
---
|
|
83
96
|
|
|
84
97
|
## Supported Input Formats
|
|
85
98
|
|
|
86
|
-
| Format | Extensions | Parser |
|
|
99
|
+
| Format | Extensions / Source | Parser |
|
|
87
100
|
|--------|-----------|--------|
|
|
88
101
|
| Markdown | `.md` | Front matter, heading-based sections |
|
|
89
102
|
| Plain text | `.txt`, stdin (`-`) | Paragraph sections, Slack dumps |
|
|
@@ -93,8 +106,11 @@ intake init "User endpoint" -s reqs.pdf --format architect
|
|
|
93
106
|
| Jira export | `.json` (auto-detected) | Issues, comments, links, priorities |
|
|
94
107
|
| Confluence export | `.html` (auto-detected) | Clean Markdown via BS4 + markdownify |
|
|
95
108
|
| Images | `.png`, `.jpg`, `.webp`, `.gif` | LLM vision analysis |
|
|
109
|
+
| URLs | `http://`, `https://` | Fetches page, converts HTML → Markdown |
|
|
110
|
+
| Slack export | `.json` (auto-detected) | Messages, threads, decisions, action items |
|
|
111
|
+
| GitHub Issues | `.json` (auto-detected) | Issues, labels, comments, cross-references |
|
|
96
112
|
|
|
97
|
-
Format is auto-detected by file extension and content inspection. Jira
|
|
113
|
+
Format is auto-detected by file extension and content inspection. Jira, Slack, and GitHub Issues JSON exports are distinguished automatically from generic JSON files. Confluence HTML is distinguished from generic HTML.
|
|
98
114
|
|
|
99
115
|
---
|
|
100
116
|
|
|
@@ -111,6 +127,10 @@ Format is auto-detected by file extension and content inspection. Jira JSON expo
|
|
|
111
127
|
| `intake diff` | Compare two spec versions | **Available** |
|
|
112
128
|
| `intake doctor` | Check environment and configuration health | **Available** |
|
|
113
129
|
| `intake doctor --fix` | Auto-fix environment issues (install deps, create config) | **Available** |
|
|
130
|
+
| `intake plugins list` | List all discovered plugins (parsers, exporters) | **Available** |
|
|
131
|
+
| `intake plugins check` | Validate plugin compatibility | **Available** |
|
|
132
|
+
| `intake task list` | List tasks from a spec with current status | **Available** |
|
|
133
|
+
| `intake task update` | Update a task's status (pending/in_progress/done/blocked) | **Available** |
|
|
114
134
|
|
|
115
135
|
---
|
|
116
136
|
|
|
@@ -134,6 +154,7 @@ spec:
|
|
|
134
154
|
design_depth: moderate # minimal | moderate | detailed
|
|
135
155
|
task_granularity: medium # coarse | medium | fine
|
|
136
156
|
risk_assessment: true
|
|
157
|
+
auto_mode: true # auto-detect quick/standard/enterprise
|
|
137
158
|
|
|
138
159
|
export:
|
|
139
160
|
default_format: generic # architect | claude-code | cursor | kiro | generic
|
|
@@ -176,13 +197,19 @@ See the [`examples/`](examples/) directory for ready-to-run scenarios:
|
|
|
176
197
|
src/intake/
|
|
177
198
|
├── cli.py # Click CLI — thin adapter, no logic
|
|
178
199
|
├── config/ # Pydantic v2 models, presets, layered loader
|
|
179
|
-
│ ├── schema.py #
|
|
200
|
+
│ ├── schema.py # 7 config models (LLM, Project, Spec, Verification, Export, Security, Connectors)
|
|
180
201
|
│ ├── presets.py # minimal / standard / enterprise presets
|
|
181
202
|
│ ├── loader.py # Layered merge: defaults → preset → YAML → CLI
|
|
182
203
|
│ └── defaults.py # Centralized constants
|
|
183
|
-
├──
|
|
204
|
+
├── plugins/ # Plugin system (v0.2.0)
|
|
205
|
+
│ ├── protocols.py # V2 protocols: ParserPlugin, ExporterPlugin, ConnectorPlugin
|
|
206
|
+
│ ├── discovery.py # Entry point scanning via importlib.metadata
|
|
207
|
+
│ └── hooks.py # Pipeline hook system (HookManager)
|
|
208
|
+
├── connectors/ # Connector infrastructure (Phase 2 prep)
|
|
209
|
+
│ └── base.py # ConnectorRegistry, ConnectorError
|
|
210
|
+
├── ingest/ # Phase 1 — 11 parsers, registry, auto-detection
|
|
184
211
|
│ ├── base.py # ParsedContent dataclass + Parser Protocol
|
|
185
|
-
│ ├── registry.py # Auto-detection + parser dispatch
|
|
212
|
+
│ ├── registry.py # Auto-detection + plugin discovery + parser dispatch
|
|
186
213
|
│ ├── markdown.py # .md with YAML front matter
|
|
187
214
|
│ ├── plaintext.py # .txt, stdin, Slack dumps
|
|
188
215
|
│ ├── yaml_input.py # .yaml/.yml/.json structured input
|
|
@@ -190,11 +217,15 @@ src/intake/
|
|
|
190
217
|
│ ├── docx.py # .docx via python-docx
|
|
191
218
|
│ ├── jira.py # Jira JSON exports (API + list format)
|
|
192
219
|
│ ├── confluence.py # Confluence HTML via BS4 + markdownify
|
|
193
|
-
│
|
|
220
|
+
│ ├── image.py # Image analysis via LLM vision
|
|
221
|
+
│ ├── url.py # HTTP/HTTPS URLs via httpx + markdownify
|
|
222
|
+
│ ├── slack.py # Slack workspace export JSON
|
|
223
|
+
│ └── github_issues.py # GitHub Issues JSON
|
|
194
224
|
├── analyze/ # Phase 2 — LLM orchestration (async)
|
|
195
225
|
│ ├── analyzer.py # Orchestrator: extraction → dedup → risk → design
|
|
196
226
|
│ ├── prompts.py # 3 system prompts (extraction, risk, design)
|
|
197
227
|
│ ├── models.py # 10 dataclasses for analysis pipeline
|
|
228
|
+
│ ├── complexity.py # Heuristic complexity classification (quick/standard/enterprise)
|
|
198
229
|
│ ├── extraction.py # LLM JSON → typed AnalysisResult
|
|
199
230
|
│ ├── dedup.py # Jaccard word similarity deduplication
|
|
200
231
|
│ ├── conflicts.py # Conflict validation
|
|
@@ -203,13 +234,14 @@ src/intake/
|
|
|
203
234
|
│ └── design.py # Design output parsing (tasks, checks)
|
|
204
235
|
├── generate/ # Phase 3 — Jinja2 template rendering
|
|
205
236
|
│ ├── spec_builder.py # Orchestrates 6 spec files + lock
|
|
237
|
+
│ ├── adaptive.py # AdaptiveSpecBuilder — mode-aware file selection
|
|
206
238
|
│ └── lock.py # spec.lock.yaml for reproducibility
|
|
207
239
|
├── verify/ # Phase 4 — Acceptance check engine
|
|
208
240
|
│ ├── engine.py # 4 check types: command, files_exist, pattern_*
|
|
209
241
|
│ └── reporter.py # Terminal (Rich), JSON, JUnit XML reporters
|
|
210
242
|
├── export/ # Phase 5 — Agent-ready output
|
|
211
243
|
│ ├── base.py # Exporter Protocol
|
|
212
|
-
│ ├── registry.py #
|
|
244
|
+
│ ├── registry.py # Plugin discovery + format-based dispatch
|
|
213
245
|
│ ├── architect.py # pipeline.yaml generation
|
|
214
246
|
│ └── generic.py # SPEC.md + verify.sh generation
|
|
215
247
|
├── diff/ # Spec comparison
|
|
@@ -221,13 +253,15 @@ src/intake/
|
|
|
221
253
|
├── templates/ # Jinja2 templates for spec generation
|
|
222
254
|
│ ├── requirements.md.j2 # FR, NFR, conflicts, open questions
|
|
223
255
|
│ ├── design.md.j2 # Components, files, tech decisions
|
|
224
|
-
│ ├── tasks.md.j2 # Task summary + detailed sections
|
|
256
|
+
│ ├── tasks.md.j2 # Task summary + status + detailed sections
|
|
225
257
|
│ ├── acceptance.yaml.j2 # Executable acceptance checks
|
|
226
258
|
│ ├── context.md.j2 # Project context for agents
|
|
227
259
|
│ └── sources.md.j2 # Source traceability mapping
|
|
228
|
-
└── utils/ # Shared utilities
|
|
260
|
+
└── utils/ # Shared utilities
|
|
229
261
|
├── file_detect.py # Extension-based format detection
|
|
230
262
|
├── project_detect.py # Auto-detect tech stack from project files
|
|
263
|
+
├── source_uri.py # URI parsing (jira://, github://, http://, files, text)
|
|
264
|
+
├── task_state.py # Task status tracking in tasks.md
|
|
231
265
|
├── cost.py # Cost accumulation with per-phase breakdown
|
|
232
266
|
└── logging.py # structlog configuration
|
|
233
267
|
```
|
|
@@ -235,9 +269,11 @@ src/intake/
|
|
|
235
269
|
**Key design principles:**
|
|
236
270
|
|
|
237
271
|
- **Protocol over ABC** — All extension points use `typing.Protocol`
|
|
272
|
+
- **Plugin-first architecture** — Parsers and exporters discovered via entry points, manual fallback
|
|
238
273
|
- **Dataclasses for pipeline data, Pydantic for config** — Never mixed
|
|
239
274
|
- **Async only in analyze/** — Everything else is synchronous
|
|
240
275
|
- **Offline mode** — Parsing, verification, export, diff, doctor all work without LLM
|
|
276
|
+
- **Adaptive generation** — Complexity auto-detection selects quick/standard/enterprise mode
|
|
241
277
|
- **No magic strings** — All constants defined explicitly
|
|
242
278
|
- **Budget enforcement** — LLM cost tracked per call with configurable limits
|
|
243
279
|
|
|
@@ -283,24 +319,29 @@ python -m pytest tests/ --cov=intake --cov-report=term-missing
|
|
|
283
319
|
# Lint
|
|
284
320
|
ruff check src/ tests/
|
|
285
321
|
|
|
322
|
+
# Format
|
|
323
|
+
ruff format src/ tests/
|
|
324
|
+
|
|
286
325
|
# Type check (strict)
|
|
287
326
|
mypy src/ --strict
|
|
288
327
|
```
|
|
289
328
|
|
|
290
|
-
Current test suite: **
|
|
329
|
+
Current test suite: **492 tests**, **86% coverage**, **0 mypy --strict errors**, **0 ruff warnings**.
|
|
291
330
|
|
|
292
331
|
### Implementation Status
|
|
293
332
|
|
|
294
333
|
| Phase | Module | Status |
|
|
295
334
|
|-------|--------|--------|
|
|
296
|
-
| Phase 1 — Ingest | `ingest/` (
|
|
297
|
-
| Phase 2 — Analyze | `analyze/` (orchestrator + 7 sub-modules) | Implemented |
|
|
298
|
-
| Phase 3 — Generate | `generate/` (spec builder + 6 templates + lock) | Implemented |
|
|
335
|
+
| Phase 1 — Ingest | `ingest/` (11 parsers + plugin-based registry) | Implemented |
|
|
336
|
+
| Phase 2 — Analyze | `analyze/` (orchestrator + 7 sub-modules + complexity) | Implemented |
|
|
337
|
+
| Phase 3 — Generate | `generate/` (spec builder + adaptive builder + 6 templates + lock) | Implemented |
|
|
299
338
|
| Phase 4 — Verify | `verify/` (engine + 3 reporters) | Implemented |
|
|
300
|
-
| Phase 5 — Export | `export/` (architect + generic) | Implemented |
|
|
339
|
+
| Phase 5 — Export | `export/` (architect + generic + plugin registry) | Implemented |
|
|
340
|
+
| Plugins | `plugins/` (protocols + discovery + hooks) | Implemented |
|
|
341
|
+
| Connectors | `connectors/` (registry infrastructure, no concrete connectors) | Implemented |
|
|
301
342
|
| Standalone | `doctor/`, `config/`, `llm/`, `utils/` | Implemented |
|
|
302
343
|
| Standalone | `diff/` (spec differ) | Implemented |
|
|
303
|
-
| CLI |
|
|
344
|
+
| CLI | 13 commands/subcommands wired end-to-end | Implemented |
|
|
304
345
|
|
|
305
346
|
---
|
|
306
347
|
|