plantod 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. plantod-0.1.0/LICENSE +21 -0
  2. plantod-0.1.0/PKG-INFO +188 -0
  3. plantod-0.1.0/README.md +153 -0
  4. plantod-0.1.0/pyproject.toml +51 -0
  5. plantod-0.1.0/setup.cfg +4 -0
  6. plantod-0.1.0/src/plantod/__init__.py +6 -0
  7. plantod-0.1.0/src/plantod/adapters/__init__.py +6 -0
  8. plantod-0.1.0/src/plantod/adapters/base.py +59 -0
  9. plantod-0.1.0/src/plantod/adapters/cliagent.py +210 -0
  10. plantod-0.1.0/src/plantod/adapters/mock.py +64 -0
  11. plantod-0.1.0/src/plantod/adapters/registry.py +20 -0
  12. plantod-0.1.0/src/plantod/artifacts.py +81 -0
  13. plantod-0.1.0/src/plantod/cli.py +241 -0
  14. plantod-0.1.0/src/plantod/config.py +111 -0
  15. plantod-0.1.0/src/plantod/executor.py +94 -0
  16. plantod-0.1.0/src/plantod/gitutil.py +71 -0
  17. plantod-0.1.0/src/plantod/interactive.py +80 -0
  18. plantod-0.1.0/src/plantod/locking.py +50 -0
  19. plantod-0.1.0/src/plantod/orchestrator.py +138 -0
  20. plantod-0.1.0/src/plantod/parsing.py +37 -0
  21. plantod-0.1.0/src/plantod/planner.py +88 -0
  22. plantod-0.1.0/src/plantod/repo.py +94 -0
  23. plantod-0.1.0/src/plantod/retry.py +32 -0
  24. plantod-0.1.0/src/plantod/reviewer.py +69 -0
  25. plantod-0.1.0/src/plantod/schemas.py +215 -0
  26. plantod-0.1.0/src/plantod/scope.py +62 -0
  27. plantod-0.1.0/src/plantod/state.py +169 -0
  28. plantod-0.1.0/src/plantod/testrunner.py +38 -0
  29. plantod-0.1.0/src/plantod/ui.py +54 -0
  30. plantod-0.1.0/src/plantod.egg-info/PKG-INFO +188 -0
  31. plantod-0.1.0/src/plantod.egg-info/SOURCES.txt +41 -0
  32. plantod-0.1.0/src/plantod.egg-info/dependency_links.txt +1 -0
  33. plantod-0.1.0/src/plantod.egg-info/entry_points.txt +2 -0
  34. plantod-0.1.0/src/plantod.egg-info/requires.txt +9 -0
  35. plantod-0.1.0/src/plantod.egg-info/top_level.txt +1 -0
  36. plantod-0.1.0/tests/test_artifacts.py +31 -0
  37. plantod-0.1.0/tests/test_cliagent.py +40 -0
  38. plantod-0.1.0/tests/test_config.py +54 -0
  39. plantod-0.1.0/tests/test_escalation.py +41 -0
  40. plantod-0.1.0/tests/test_hardening.py +61 -0
  41. plantod-0.1.0/tests/test_orchestrator_mock.py +51 -0
  42. plantod-0.1.0/tests/test_scope.py +42 -0
  43. plantod-0.1.0/tests/test_state_machine.py +41 -0
plantod-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PLANTOD
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.
plantod-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,188 @@
1
+ Metadata-Version: 2.4
2
+ Name: plantod
3
+ Version: 0.1.0
4
+ Summary: Planning-first, repo-aware AI coding orchestrator CLI
5
+ Author-email: PLANTOD <admin@beinsoft.co.id>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/wandi1209/plantod
8
+ Project-URL: Repository, https://github.com/wandi1209/plantod
9
+ Project-URL: Issues, https://github.com/wandi1209/plantod/issues
10
+ Keywords: ai,cli,coding,orchestrator,planning,agent,llm
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development
21
+ Classifier: Topic :: Software Development :: Code Generators
22
+ Classifier: Topic :: Utilities
23
+ Requires-Python: >=3.11
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: typer>=0.12
27
+ Requires-Dist: rich>=13.7
28
+ Requires-Dist: pydantic>=2.6
29
+ Requires-Dist: pyyaml>=6.0
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest>=8.0; extra == "dev"
32
+ Requires-Dist: build>=1.2; extra == "dev"
33
+ Requires-Dist: twine>=5.0; extra == "dev"
34
+ Dynamic: license-file
35
+
36
+ # PLANTOD
37
+
38
+ **Plan, Task, Orchestrate, Deliver** — a planning-first, repo-aware AI coding orchestrator CLI.
39
+
40
+ PLANTOD turns a natural-language request ("add login feature") into a structured
41
+ workflow: **plan → tasks → scoped execution → test → handoff → escalation → final review**.
42
+ A strong model plans and reviews; a fast model executes small, scoped tasks. All
43
+ decisions and outputs are written to `.plantod/` in the repo so the work is auditable.
44
+
45
+ ## Install
46
+
47
+ ```bash
48
+ python -m venv .venv && source .venv/bin/activate
49
+ pip install -e ".[dev]"
50
+ ```
51
+
52
+ ## Providers
53
+
54
+ PLANTOD drives **agentic coding CLIs** as its backends — one per role. Install the
55
+ CLI(s) for the providers you pick; each handles its own auth/model config.
56
+
57
+ | Provider | Binary | Invocation |
58
+ |----------|--------|-----------|
59
+ | `claude-code` | `claude` | `claude -p "<prompt>"` |
60
+ | `codex` | `codex` | `codex exec "<prompt>"` |
61
+ | `opencode` | `opencode` | `opencode run "<prompt>"` |
62
+
63
+ ### `plantod login`
64
+
65
+ Set the provider + model for each role (planner / executor / reviewer):
66
+
67
+ ```bash
68
+ plantod login # interactive wizard (all roles)
69
+ plantod login --role executor --provider codex --model o4 # non-interactive, one role
70
+ plantod login --role planner --provider claude-code # model optional -> provider default
71
+ plantod login ... --project # save to THIS repo instead of global
72
+ ```
73
+
74
+ Config precedence (low → high): **defaults < global (`~/.config/plantod/config.yaml`) < project (`.plantod/config.yaml`)**.
75
+ `login` writes the global scope by default so settings carry across repos (NFR-02);
76
+ `--project` overrides for one repo. `plantod init` inherits the global defaults.
77
+
78
+ ## Prerequisites
79
+
80
+ - Install the CLI for each provider you configure (see table above); each tool
81
+ manages its own authentication.
82
+ - `.env` in the repo root is auto-loaded into the environment (see `.env.example`)
83
+ for any provider that reads env vars.
84
+ - A **git repo** is required for the scope guard — run `plantod init` inside one.
85
+
86
+ ## Usage
87
+
88
+ ```bash
89
+ plantod login # pick provider + model per role (see Providers)
90
+ plantod init # detect repo, scaffold .plantod/ (inherits global)
91
+ plantod plan "add login feature" # plan + break into tasks + run the default flow
92
+ plantod plan "..." --yes --review # approve gated tasks, run final review
93
+ plantod tasks # list tasks + status
94
+ plantod next # next runnable task
95
+ plantod run T001 # run a single task
96
+ plantod review R001 # final review for a requirement
97
+ plantod status # board summary
98
+ plantod resume # where the last session left off
99
+ plantod # interactive chat-like session
100
+ ```
101
+
102
+ ## Why planning-first saves tokens (cost model)
103
+
104
+ PLANTOD's economics come from **routing**: a strong, expensive model only *plans*
105
+ and *reviews* (low token volume, high-value reasoning), while a cheap, fast model
106
+ does the *bulk editing* (high token volume, low-level work). Most tokens in a coding
107
+ task are spent reading context and writing edits — so you want those on the cheap model.
108
+
109
+ **Illustrative example** — one feature = 1 plan + 4 tasks + 1 review. Token splits
110
+ below are *assumptions to show the shape of the saving*, not measurements:
111
+
112
+ | Stage | Tokens | All-in-one (strong model) | PLANTOD (routed) |
113
+ |-------|-------:|--------------------------:|-----------------:|
114
+ | Plan + review | ~30K | strong | strong |
115
+ | Task execution (×4) | ~200K | strong | **cheap executor** |
116
+ | **Total billed as** | ~230K | 230K × strong-rate | 30K × strong-rate + 200K × cheap-rate |
117
+
118
+ If the executor model is ~15× cheaper per token than the planner (a typical
119
+ fast-model vs frontier-model gap), the routed run costs roughly:
120
+
121
+ ```
122
+ strong_share = 30K
123
+ cheap_share = 200K / 15 ≈ 13.3K strong-equivalent tokens
124
+ routed_total ≈ 43.3K vs 230K → ~5× cheaper for this mix
125
+ ```
126
+
127
+ The exact multiple depends on your models and the plan/execution token ratio —
128
+ plug in current per-token prices for your planner and executor to get real numbers.
129
+
130
+ > **Honest caveat:** these figures are an illustrative model, not a benchmark.
131
+ > PLANTOD does not yet meter real token usage — **cost tracking is on the v2
132
+ > roadmap** (PRD §27). The structural saving (route bulk edits to a cheap model,
133
+ > keep reasoning on a strong one) holds regardless; the exact ratio is yours to measure.
134
+
135
+ Beyond cost, the planning-first flow also reduces *wasted* tokens: scoped tasks and
136
+ the scope guard stop the executor from sprawling across the repo and re-generating
137
+ work, which is where "just let the big model code" runs burn tokens on churn.
138
+
139
+ ## How it works
140
+
141
+ - **Adapters** (`plantod/adapters/`) make backends swappable: `claude`, `opencode`, `mock`.
142
+ - **State machine** (`plantod/schemas.py`) enforces legal task transitions
143
+ (`pending → ready → in_progress → testing → done → reviewed`, plus `blocked → needs_planner_review`).
144
+ - **Approval gate** (`plantod/orchestrator.py`) auto-runs only low-risk, small-scope,
145
+ testable tasks; everything else asks for approval.
146
+ - **Artifacts** (`.plantod/`): `requirements/ plans/ tasks/ handoffs/ reviews/ logs/`,
147
+ markdown + YAML frontmatter; `board.json` / `session.json` for state.
148
+
149
+ ## Configuration (`.plantod/config.yaml`)
150
+
151
+ | Key | Default | Meaning |
152
+ |-----|---------|---------|
153
+ | `planner` / `executor` / `reviewer` | `{provider, model}` per role | backend for each role — set via `plantod login` |
154
+ | default providers | claude-code / opencode / claude-code | planner / executor / reviewer |
155
+ | `auto_run_small_tasks` | true | auto-run low-risk tasks |
156
+ | `require_approval_for_architecture` | true | gate high-risk changes |
157
+ | `test_before_done` | true | run tests before marking done |
158
+ | `enforce_scope` | true | revert executor edits outside `files_allowed` |
159
+ | `apply_requires_approval` | false | confirm the in-scope diff before keeping it |
160
+ | `exec_timeout_s` / `test_timeout_s` | 900 / 600 | subprocess timeouts |
161
+ | `max_retries` | 3 | retry transient backend failures / cap replans |
162
+ | `auto_replan_on_escalation` | true | planner advises + retries an escalated task |
163
+
164
+ ## Production notes
165
+
166
+ - **Scope guard** — after each executor run, any file changed outside the task's
167
+ `files_allowed` (or matching `files_forbidden`) is reverted via git and the task
168
+ is escalated. This is enforced, not just prompted.
169
+ - **State safety** — `board.json` / `session.json` and all artifacts are written
170
+ atomically (temp file + rename). A per-project advisory lock (`.plantod/.lock`)
171
+ stops concurrent runs from corrupting state.
172
+ - **Escalation loop** — a blocked task goes `needs_planner_review`; the planner
173
+ produces guidance and the task retries with narrower scope, capped by `max_retries`.
174
+ - **Resilience** — backend calls retry with exponential backoff; subprocesses have
175
+ timeouts; malformed model JSON is parsed defensively.
176
+ - Requires a **git repo** for the scope guard; run `plantod init` inside one.
177
+
178
+ ## Development
179
+
180
+ ```bash
181
+ pytest # state machine, artifacts, config, full mock-adapter flow
182
+ ```
183
+
184
+ Layout: `src/` package layout, entry point `plantod.cli:app`.
185
+
186
+ ## License
187
+
188
+ MIT
@@ -0,0 +1,153 @@
1
+ # PLANTOD
2
+
3
+ **Plan, Task, Orchestrate, Deliver** — a planning-first, repo-aware AI coding orchestrator CLI.
4
+
5
+ PLANTOD turns a natural-language request ("add login feature") into a structured
6
+ workflow: **plan → tasks → scoped execution → test → handoff → escalation → final review**.
7
+ A strong model plans and reviews; a fast model executes small, scoped tasks. All
8
+ decisions and outputs are written to `.plantod/` in the repo so the work is auditable.
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ python -m venv .venv && source .venv/bin/activate
14
+ pip install -e ".[dev]"
15
+ ```
16
+
17
+ ## Providers
18
+
19
+ PLANTOD drives **agentic coding CLIs** as its backends — one per role. Install the
20
+ CLI(s) for the providers you pick; each handles its own auth/model config.
21
+
22
+ | Provider | Binary | Invocation |
23
+ |----------|--------|-----------|
24
+ | `claude-code` | `claude` | `claude -p "<prompt>"` |
25
+ | `codex` | `codex` | `codex exec "<prompt>"` |
26
+ | `opencode` | `opencode` | `opencode run "<prompt>"` |
27
+
28
+ ### `plantod login`
29
+
30
+ Set the provider + model for each role (planner / executor / reviewer):
31
+
32
+ ```bash
33
+ plantod login # interactive wizard (all roles)
34
+ plantod login --role executor --provider codex --model o4 # non-interactive, one role
35
+ plantod login --role planner --provider claude-code # model optional -> provider default
36
+ plantod login ... --project # save to THIS repo instead of global
37
+ ```
38
+
39
+ Config precedence (low → high): **defaults < global (`~/.config/plantod/config.yaml`) < project (`.plantod/config.yaml`)**.
40
+ `login` writes the global scope by default so settings carry across repos (NFR-02);
41
+ `--project` overrides for one repo. `plantod init` inherits the global defaults.
42
+
43
+ ## Prerequisites
44
+
45
+ - Install the CLI for each provider you configure (see table above); each tool
46
+ manages its own authentication.
47
+ - `.env` in the repo root is auto-loaded into the environment (see `.env.example`)
48
+ for any provider that reads env vars.
49
+ - A **git repo** is required for the scope guard — run `plantod init` inside one.
50
+
51
+ ## Usage
52
+
53
+ ```bash
54
+ plantod login # pick provider + model per role (see Providers)
55
+ plantod init # detect repo, scaffold .plantod/ (inherits global)
56
+ plantod plan "add login feature" # plan + break into tasks + run the default flow
57
+ plantod plan "..." --yes --review # approve gated tasks, run final review
58
+ plantod tasks # list tasks + status
59
+ plantod next # next runnable task
60
+ plantod run T001 # run a single task
61
+ plantod review R001 # final review for a requirement
62
+ plantod status # board summary
63
+ plantod resume # where the last session left off
64
+ plantod # interactive chat-like session
65
+ ```
66
+
67
+ ## Why planning-first saves tokens (cost model)
68
+
69
+ PLANTOD's economics come from **routing**: a strong, expensive model only *plans*
70
+ and *reviews* (low token volume, high-value reasoning), while a cheap, fast model
71
+ does the *bulk editing* (high token volume, low-level work). Most tokens in a coding
72
+ task are spent reading context and writing edits — so you want those on the cheap model.
73
+
74
+ **Illustrative example** — one feature = 1 plan + 4 tasks + 1 review. Token splits
75
+ below are *assumptions to show the shape of the saving*, not measurements:
76
+
77
+ | Stage | Tokens | All-in-one (strong model) | PLANTOD (routed) |
78
+ |-------|-------:|--------------------------:|-----------------:|
79
+ | Plan + review | ~30K | strong | strong |
80
+ | Task execution (×4) | ~200K | strong | **cheap executor** |
81
+ | **Total billed as** | ~230K | 230K × strong-rate | 30K × strong-rate + 200K × cheap-rate |
82
+
83
+ If the executor model is ~15× cheaper per token than the planner (a typical
84
+ fast-model vs frontier-model gap), the routed run costs roughly:
85
+
86
+ ```
87
+ strong_share = 30K
88
+ cheap_share = 200K / 15 ≈ 13.3K strong-equivalent tokens
89
+ routed_total ≈ 43.3K vs 230K → ~5× cheaper for this mix
90
+ ```
91
+
92
+ The exact multiple depends on your models and the plan/execution token ratio —
93
+ plug in current per-token prices for your planner and executor to get real numbers.
94
+
95
+ > **Honest caveat:** these figures are an illustrative model, not a benchmark.
96
+ > PLANTOD does not yet meter real token usage — **cost tracking is on the v2
97
+ > roadmap** (PRD §27). The structural saving (route bulk edits to a cheap model,
98
+ > keep reasoning on a strong one) holds regardless; the exact ratio is yours to measure.
99
+
100
+ Beyond cost, the planning-first flow also reduces *wasted* tokens: scoped tasks and
101
+ the scope guard stop the executor from sprawling across the repo and re-generating
102
+ work, which is where "just let the big model code" runs burn tokens on churn.
103
+
104
+ ## How it works
105
+
106
+ - **Adapters** (`plantod/adapters/`) make backends swappable: `claude`, `opencode`, `mock`.
107
+ - **State machine** (`plantod/schemas.py`) enforces legal task transitions
108
+ (`pending → ready → in_progress → testing → done → reviewed`, plus `blocked → needs_planner_review`).
109
+ - **Approval gate** (`plantod/orchestrator.py`) auto-runs only low-risk, small-scope,
110
+ testable tasks; everything else asks for approval.
111
+ - **Artifacts** (`.plantod/`): `requirements/ plans/ tasks/ handoffs/ reviews/ logs/`,
112
+ markdown + YAML frontmatter; `board.json` / `session.json` for state.
113
+
114
+ ## Configuration (`.plantod/config.yaml`)
115
+
116
+ | Key | Default | Meaning |
117
+ |-----|---------|---------|
118
+ | `planner` / `executor` / `reviewer` | `{provider, model}` per role | backend for each role — set via `plantod login` |
119
+ | default providers | claude-code / opencode / claude-code | planner / executor / reviewer |
120
+ | `auto_run_small_tasks` | true | auto-run low-risk tasks |
121
+ | `require_approval_for_architecture` | true | gate high-risk changes |
122
+ | `test_before_done` | true | run tests before marking done |
123
+ | `enforce_scope` | true | revert executor edits outside `files_allowed` |
124
+ | `apply_requires_approval` | false | confirm the in-scope diff before keeping it |
125
+ | `exec_timeout_s` / `test_timeout_s` | 900 / 600 | subprocess timeouts |
126
+ | `max_retries` | 3 | retry transient backend failures / cap replans |
127
+ | `auto_replan_on_escalation` | true | planner advises + retries an escalated task |
128
+
129
+ ## Production notes
130
+
131
+ - **Scope guard** — after each executor run, any file changed outside the task's
132
+ `files_allowed` (or matching `files_forbidden`) is reverted via git and the task
133
+ is escalated. This is enforced, not just prompted.
134
+ - **State safety** — `board.json` / `session.json` and all artifacts are written
135
+ atomically (temp file + rename). A per-project advisory lock (`.plantod/.lock`)
136
+ stops concurrent runs from corrupting state.
137
+ - **Escalation loop** — a blocked task goes `needs_planner_review`; the planner
138
+ produces guidance and the task retries with narrower scope, capped by `max_retries`.
139
+ - **Resilience** — backend calls retry with exponential backoff; subprocesses have
140
+ timeouts; malformed model JSON is parsed defensively.
141
+ - Requires a **git repo** for the scope guard; run `plantod init` inside one.
142
+
143
+ ## Development
144
+
145
+ ```bash
146
+ pytest # state machine, artifacts, config, full mock-adapter flow
147
+ ```
148
+
149
+ Layout: `src/` package layout, entry point `plantod.cli:app`.
150
+
151
+ ## License
152
+
153
+ MIT
@@ -0,0 +1,51 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "plantod"
7
+ version = "0.1.0"
8
+ description = "Planning-first, repo-aware AI coding orchestrator CLI"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "PLANTOD", email = "admin@beinsoft.co.id" }]
13
+ keywords = ["ai", "cli", "coding", "orchestrator", "planning", "agent", "llm"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Environment :: Console",
17
+ "Intended Audience :: Developers",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Operating System :: OS Independent",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Topic :: Software Development",
25
+ "Topic :: Software Development :: Code Generators",
26
+ "Topic :: Utilities",
27
+ ]
28
+ dependencies = [
29
+ "typer>=0.12",
30
+ "rich>=13.7",
31
+ "pydantic>=2.6",
32
+ "pyyaml>=6.0",
33
+ ]
34
+
35
+ [project.optional-dependencies]
36
+ dev = ["pytest>=8.0", "build>=1.2", "twine>=5.0"]
37
+
38
+ [project.urls]
39
+ Homepage = "https://github.com/wandi1209/plantod"
40
+ Repository = "https://github.com/wandi1209/plantod"
41
+ Issues = "https://github.com/wandi1209/plantod/issues"
42
+
43
+ [project.scripts]
44
+ plantod = "plantod.cli:app"
45
+
46
+ [tool.setuptools.packages.find]
47
+ where = ["src"]
48
+ include = ["plantod*"]
49
+
50
+ [tool.pytest.ini_options]
51
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,6 @@
1
+ """PLANTOD — Plan, Task, Orchestrate, Deliver.
2
+
3
+ Planning-first, repo-aware AI coding orchestrator CLI.
4
+ """
5
+
6
+ __version__ = "0.1.0"
@@ -0,0 +1,6 @@
1
+ """Model backend adapters (planner / executor / reviewer)."""
2
+
3
+ from .base import ExecResult, ModelAdapter, PlanResult, ReviewResult
4
+ from .registry import resolve
5
+
6
+ __all__ = ["ModelAdapter", "PlanResult", "ExecResult", "ReviewResult", "resolve"]
@@ -0,0 +1,59 @@
1
+ """ModelAdapter interface + result types (PRD 14.1, NFR-03)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from abc import ABC, abstractmethod
6
+ from dataclasses import dataclass, field
7
+
8
+ from ..repo import RepoContext
9
+ from ..schemas import Handoff, Task
10
+
11
+
12
+ @dataclass
13
+ class PlanResult:
14
+ title: str
15
+ summary: str
16
+ risk_level: str
17
+ # each task dict is validated into a Task by the planner layer
18
+ tasks: list[dict] = field(default_factory=list)
19
+ raw: str = ""
20
+
21
+
22
+ @dataclass
23
+ class ExecResult:
24
+ files_changed: list[str] = field(default_factory=list)
25
+ summary: str = ""
26
+ diff: str = ""
27
+ escalate: bool = False
28
+ escalate_reason: str = ""
29
+ raw: str = ""
30
+
31
+
32
+ @dataclass
33
+ class ReviewResult:
34
+ verdict: str = "approve" # approve | revise
35
+ summary: str = ""
36
+ findings: list[str] = field(default_factory=list)
37
+ raw: str = ""
38
+
39
+
40
+ class ModelAdapter(ABC):
41
+ """Backend-agnostic model interface. Concrete adapters wrap a provider."""
42
+
43
+ name: str = "adapter"
44
+
45
+ @abstractmethod
46
+ def plan(self, request: str, repo: RepoContext) -> PlanResult: ...
47
+
48
+ @abstractmethod
49
+ def execute(self, task: Task, repo: RepoContext) -> ExecResult: ...
50
+
51
+ @abstractmethod
52
+ def review(self, request: str, handoffs: list[Handoff], repo: RepoContext) -> ReviewResult: ...
53
+
54
+ def advise(self, task: Task, reason: str, repo: RepoContext) -> str:
55
+ """Planner guidance for a blocked/escalated task. Override in planner adapters."""
56
+ return (
57
+ f"Reduce scope and retry {task.id}. Split any architecture decision into a "
58
+ f"separate task. Blocking reason: {reason}"
59
+ )