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.
Files changed (169) hide show
  1. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/.gitignore +1 -0
  2. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/CHANGELOG.md +94 -0
  3. intake_ai_cli-0.2.0/LICENSE +21 -0
  4. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/PKG-INFO +68 -16
  5. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/README.md +56 -15
  6. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/SEGUIMIENTO-V0.md +305 -9
  7. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/README.md +18 -4
  8. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/arquitectura.md +97 -20
  9. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/buenas-practicas.md +82 -3
  10. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/configuracion.md +39 -0
  11. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/exportacion.md +14 -2
  12. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/formatos-entrada.md +148 -9
  13. intake_ai_cli-0.2.0/docs/github-notes/v0.2.0.md +317 -0
  14. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/guia-cli.md +162 -7
  15. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/pipeline.md +72 -23
  16. intake_ai_cli-0.2.0/docs/plugins.md +297 -0
  17. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/solucion-problemas.md +109 -0
  18. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/pyproject.toml +35 -1
  19. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/__init__.py +1 -1
  20. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/analyzer.py +1 -4
  21. intake_ai_cli-0.2.0/src/intake/analyze/complexity.py +165 -0
  22. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/dedup.py +2 -6
  23. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/extraction.py +1 -3
  24. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/models.py +1 -0
  25. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/cli.py +449 -65
  26. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/config/loader.py +1 -3
  27. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/config/presets.py +1 -3
  28. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/config/schema.py +34 -6
  29. intake_ai_cli-0.2.0/src/intake/connectors/__init__.py +11 -0
  30. intake_ai_cli-0.2.0/src/intake/connectors/base.py +129 -0
  31. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/diff/differ.py +56 -48
  32. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/doctor/checks.py +17 -13
  33. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/export/__init__.py +5 -0
  34. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/export/architect.py +13 -8
  35. intake_ai_cli-0.2.0/src/intake/export/registry.py +140 -0
  36. intake_ai_cli-0.2.0/src/intake/generate/adaptive.py +206 -0
  37. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/generate/spec_builder.py +1 -3
  38. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/__init__.py +4 -0
  39. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/base.py +1 -4
  40. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/confluence.py +8 -8
  41. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/docx.py +15 -11
  42. intake_ai_cli-0.2.0/src/intake/ingest/github_issues.py +319 -0
  43. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/image.py +1 -3
  44. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/jira.py +22 -19
  45. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/markdown.py +8 -5
  46. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/pdf.py +7 -5
  47. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/plaintext.py +6 -4
  48. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/registry.py +117 -12
  49. intake_ai_cli-0.2.0/src/intake/ingest/slack.py +258 -0
  50. intake_ai_cli-0.2.0/src/intake/ingest/url.py +233 -0
  51. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/ingest/yaml_input.py +7 -7
  52. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/llm/adapter.py +3 -9
  53. intake_ai_cli-0.2.0/src/intake/plugins/__init__.py +32 -0
  54. intake_ai_cli-0.2.0/src/intake/plugins/discovery.py +304 -0
  55. intake_ai_cli-0.2.0/src/intake/plugins/hooks.py +87 -0
  56. intake_ai_cli-0.2.0/src/intake/plugins/protocols.py +256 -0
  57. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/templates/tasks.md.j2 +4 -3
  58. intake_ai_cli-0.2.0/src/intake/utils/source_uri.py +162 -0
  59. intake_ai_cli-0.2.0/src/intake/utils/task_state.py +333 -0
  60. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/verify/engine.py +2 -3
  61. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/verify/reporter.py +7 -3
  62. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/conftest.py +18 -0
  63. intake_ai_cli-0.2.0/tests/fixtures/github_issues.json +82 -0
  64. intake_ai_cli-0.2.0/tests/fixtures/sample_webpage.html +62 -0
  65. intake_ai_cli-0.2.0/tests/fixtures/slack_export.json +65 -0
  66. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_analyze/test_analyzer.py +1 -2
  67. intake_ai_cli-0.2.0/tests/test_analyze/test_complexity.py +169 -0
  68. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_analyze/test_extraction.py +1 -2
  69. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_analyze/test_llm_adapter.py +2 -1
  70. intake_ai_cli-0.2.0/tests/test_cli.py +482 -0
  71. intake_ai_cli-0.2.0/tests/test_connectors/test_base.py +139 -0
  72. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_diff/test_differ.py +26 -15
  73. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_doctor/test_checks.py +3 -2
  74. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_export/test_architect.py +23 -25
  75. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_export/test_generic.py +22 -20
  76. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_export/test_registry.py +20 -0
  77. intake_ai_cli-0.2.0/tests/test_generate/test_adaptive.py +369 -0
  78. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_generate/test_lock.py +2 -6
  79. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_ingest/test_confluence.py +2 -6
  80. intake_ai_cli-0.2.0/tests/test_ingest/test_github_issues.py +135 -0
  81. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_ingest/test_hardening.py +13 -7
  82. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_ingest/test_image.py +1 -3
  83. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_ingest/test_jira.py +9 -27
  84. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_ingest/test_markdown.py +1 -3
  85. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_ingest/test_plaintext.py +3 -6
  86. intake_ai_cli-0.2.0/tests/test_ingest/test_registry.py +222 -0
  87. intake_ai_cli-0.2.0/tests/test_ingest/test_slack.py +96 -0
  88. intake_ai_cli-0.2.0/tests/test_ingest/test_url.py +145 -0
  89. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_ingest/test_yaml_input.py +4 -12
  90. intake_ai_cli-0.2.0/tests/test_plugins/test_discovery.py +118 -0
  91. intake_ai_cli-0.2.0/tests/test_plugins/test_hooks.py +68 -0
  92. intake_ai_cli-0.2.0/tests/test_plugins/test_protocols.py +183 -0
  93. intake_ai_cli-0.2.0/tests/test_utils/__init__.py +0 -0
  94. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_utils/test_file_detect.py +16 -2
  95. intake_ai_cli-0.2.0/tests/test_utils/test_source_uri.py +109 -0
  96. intake_ai_cli-0.2.0/tests/test_utils/test_task_state.py +247 -0
  97. intake_ai_cli-0.2.0/tests/test_verify/__init__.py +0 -0
  98. intake_ai_cli-0.1.0/src/intake/export/registry.py +0 -70
  99. intake_ai_cli-0.1.0/tests/test_cli.py +0 -256
  100. intake_ai_cli-0.1.0/tests/test_ingest/test_registry.py +0 -107
  101. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/.intake.yaml.example +0 -0
  102. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/github-notes/v0.1.0.md +0 -0
  103. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/docs/verificacion.md +0 -0
  104. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/from-jira/README.md +0 -0
  105. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/from-jira/jira-export.json +0 -0
  106. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/from-markdown/README.md +0 -0
  107. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/from-markdown/requirements.md +0 -0
  108. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/from-scratch/README.md +0 -0
  109. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/from-scratch/idea.txt +0 -0
  110. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/multi-source/README.md +0 -0
  111. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/multi-source/api-decisions.json +0 -0
  112. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/multi-source/notes.txt +0 -0
  113. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/examples/multi-source/user-stories.md +0 -0
  114. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/__main__.py +0 -0
  115. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/__init__.py +0 -0
  116. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/conflicts.py +0 -0
  117. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/design.py +0 -0
  118. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/prompts.py +0 -0
  119. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/questions.py +0 -0
  120. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/analyze/risks.py +0 -0
  121. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/config/__init__.py +0 -0
  122. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/config/defaults.py +0 -0
  123. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/diff/__init__.py +0 -0
  124. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/doctor/__init__.py +0 -0
  125. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/export/base.py +0 -0
  126. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/export/generic.py +0 -0
  127. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/generate/__init__.py +0 -0
  128. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/generate/lock.py +0 -0
  129. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/llm/__init__.py +0 -0
  130. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/templates/acceptance.yaml.j2 +0 -0
  131. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/templates/context.md.j2 +0 -0
  132. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/templates/design.md.j2 +0 -0
  133. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/templates/requirements.md.j2 +0 -0
  134. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/templates/sources.md.j2 +0 -0
  135. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/utils/__init__.py +0 -0
  136. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/utils/cost.py +0 -0
  137. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/utils/file_detect.py +0 -0
  138. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/utils/logging.py +0 -0
  139. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/utils/project_detect.py +0 -0
  140. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/src/intake/verify/__init__.py +0 -0
  141. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/__init__.py +0 -0
  142. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/fixtures/confluence_page.html +0 -0
  143. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/fixtures/jira_export.json +0 -0
  144. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/fixtures/jira_export_multi.json +0 -0
  145. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/fixtures/simple_spec.md +0 -0
  146. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/fixtures/slack_thread.txt +0 -0
  147. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/fixtures/structured_reqs.yaml +0 -0
  148. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/fixtures/wireframe.png +0 -0
  149. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_analyze/__init__.py +0 -0
  150. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_analyze/test_conflicts.py +0 -0
  151. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_analyze/test_dedup.py +0 -0
  152. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_analyze/test_design.py +0 -0
  153. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_analyze/test_risks.py +0 -0
  154. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_config/__init__.py +0 -0
  155. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_config/test_loader.py +0 -0
  156. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_config/test_presets.py +0 -0
  157. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_config/test_schema.py +0 -0
  158. {intake_ai_cli-0.1.0/tests/test_diff → intake_ai_cli-0.2.0/tests/test_connectors}/__init__.py +0 -0
  159. {intake_ai_cli-0.1.0/tests/test_doctor → intake_ai_cli-0.2.0/tests/test_diff}/__init__.py +0 -0
  160. {intake_ai_cli-0.1.0/tests/test_export → intake_ai_cli-0.2.0/tests/test_doctor}/__init__.py +0 -0
  161. {intake_ai_cli-0.1.0/tests/test_generate → intake_ai_cli-0.2.0/tests/test_export}/__init__.py +0 -0
  162. {intake_ai_cli-0.1.0/tests/test_ingest → intake_ai_cli-0.2.0/tests/test_generate}/__init__.py +0 -0
  163. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_generate/test_spec_builder.py +0 -0
  164. {intake_ai_cli-0.1.0/tests/test_utils → intake_ai_cli-0.2.0/tests/test_ingest}/__init__.py +0 -0
  165. {intake_ai_cli-0.1.0/tests/test_verify → intake_ai_cli-0.2.0/tests/test_plugins}/__init__.py +0 -0
  166. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_utils/test_cost.py +0 -0
  167. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_utils/test_project_detect.py +0 -0
  168. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_verify/test_engine.py +0 -0
  169. {intake_ai_cli-0.1.0 → intake_ai_cli-0.2.0}/tests/test_verify/test_reporter.py +0 -0
@@ -92,5 +92,6 @@ logs/
92
92
  tmp/
93
93
  CLAUDE.md
94
94
  .coverage
95
+ .claude/
95
96
 
96
97
  __pycache__/
@@ -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.1.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 JSON exports and Confluence HTML exports are distinguished automatically from generic JSON/HTML files.
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 # 6 config models (LLM, Project, Spec, Verification, Export, Security)
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
- ├── ingest/ # Phase 1 — 8 parsers, registry, auto-detection
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
- └── image.py # Image analysis via LLM vision
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 # Format-based exporter dispatch
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 (logging, cost, detection)
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: **313 tests**, **83% coverage**.
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/` (8 parsers + registry) | Implemented |
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 | All 8 commands wired end-to-end | Implemented |
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 JSON exports and Confluence HTML exports are distinguished automatically from generic JSON/HTML files.
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 # 6 config models (LLM, Project, Spec, Verification, Export, Security)
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
- ├── ingest/ # Phase 1 — 8 parsers, registry, auto-detection
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
- └── image.py # Image analysis via LLM vision
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 # Format-based exporter dispatch
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 (logging, cost, detection)
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: **313 tests**, **83% coverage**.
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/` (8 parsers + registry) | Implemented |
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 | All 8 commands wired end-to-end | Implemented |
344
+ | CLI | 13 commands/subcommands wired end-to-end | Implemented |
304
345
 
305
346
  ---
306
347