awf 1.0.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 (74) hide show
  1. awf-1.0.0/LICENSE +21 -0
  2. awf-1.0.0/PKG-INFO +189 -0
  3. awf-1.0.0/README.md +159 -0
  4. awf-1.0.0/awf/__init__.py +3 -0
  5. awf-1.0.0/awf/__main__.py +6 -0
  6. awf-1.0.0/awf/_atomic.py +37 -0
  7. awf-1.0.0/awf/_env.py +90 -0
  8. awf-1.0.0/awf/_log.py +24 -0
  9. awf-1.0.0/awf/agent_stage.py +275 -0
  10. awf-1.0.0/awf/api/__init__.py +128 -0
  11. awf-1.0.0/awf/api/_background.py +158 -0
  12. awf-1.0.0/awf/api/_errors.py +10 -0
  13. awf-1.0.0/awf/api/_helpers.py +71 -0
  14. awf-1.0.0/awf/api/_results.py +286 -0
  15. awf-1.0.0/awf/api/_stack.py +130 -0
  16. awf-1.0.0/awf/api/_templates.py +110 -0
  17. awf-1.0.0/awf/api/context.py +420 -0
  18. awf-1.0.0/awf/api/dashboard.py +909 -0
  19. awf-1.0.0/awf/api/dashboard_server.py +76 -0
  20. awf-1.0.0/awf/api/dispatch.py +182 -0
  21. awf-1.0.0/awf/api/lifecycle.py +683 -0
  22. awf-1.0.0/awf/api/model_check.py +246 -0
  23. awf-1.0.0/awf/api/pipeline.py +764 -0
  24. awf-1.0.0/awf/api/planning.py +95 -0
  25. awf-1.0.0/awf/api/roles.py +448 -0
  26. awf-1.0.0/awf/api/setup.py +453 -0
  27. awf-1.0.0/awf/api/wait_event.py +186 -0
  28. awf-1.0.0/awf/cli.py +232 -0
  29. awf-1.0.0/awf/cmd_add_role.py +42 -0
  30. awf-1.0.0/awf/cmd_analyze_roles.py +82 -0
  31. awf-1.0.0/awf/cmd_approve.py +24 -0
  32. awf-1.0.0/awf/cmd_baseline.py +40 -0
  33. awf-1.0.0/awf/cmd_init.py +218 -0
  34. awf-1.0.0/awf/cmd_report.py +56 -0
  35. awf-1.0.0/awf/cmd_reset.py +78 -0
  36. awf-1.0.0/awf/cmd_rollback.py +51 -0
  37. awf-1.0.0/awf/cmd_start.py +70 -0
  38. awf-1.0.0/awf/cmd_status.py +71 -0
  39. awf-1.0.0/awf/commit_gate.py +272 -0
  40. awf-1.0.0/awf/config.py +36 -0
  41. awf-1.0.0/awf/git_utils.py +81 -0
  42. awf-1.0.0/awf/opencode_agents.py +159 -0
  43. awf-1.0.0/awf/orchestrator.py +189 -0
  44. awf-1.0.0/awf/paths.py +73 -0
  45. awf-1.0.0/awf/phase.py +170 -0
  46. awf-1.0.0/awf/pipeline.py +153 -0
  47. awf-1.0.0/awf/pipeline_engine.py +583 -0
  48. awf-1.0.0/awf/pipeline_state.py +135 -0
  49. awf-1.0.0/awf/plan_checkpoint.py +605 -0
  50. awf-1.0.0/awf/plan_progress.py +172 -0
  51. awf-1.0.0/awf/signal_watch.py +203 -0
  52. awf-1.0.0/awf/signals.py +152 -0
  53. awf-1.0.0/awf/supervisor.py +907 -0
  54. awf-1.0.0/awf/templates/dashboard.html.j2 +420 -0
  55. awf-1.0.0/awf/templates/roles/supervisor/_core.md +44 -0
  56. awf-1.0.0/awf/templates/roles/supervisor/phase-brief.md +61 -0
  57. awf-1.0.0/awf/templates/roles/supervisor/phase-form.md +29 -0
  58. awf-1.0.0/awf/templates/roles/supervisor/phase-goal.md +25 -0
  59. awf-1.0.0/awf/templates/roles/supervisor/phase-init.md +17 -0
  60. awf-1.0.0/awf/templates/roles/supervisor/phase-normalize.md +35 -0
  61. awf-1.0.0/awf/templates/roles/supervisor/phase-run.md +17 -0
  62. awf-1.0.0/awf/templates/roles/supervisor/phase-verify.md +28 -0
  63. awf-1.0.0/awf/templates/roles/supervisor.md +633 -0
  64. awf-1.0.0/awf/todos.py +161 -0
  65. awf-1.0.0/awf/transitions.py +54 -0
  66. awf-1.0.0/awf/verify.py +202 -0
  67. awf-1.0.0/awf/xdg.py +43 -0
  68. awf-1.0.0/awf.egg-info/PKG-INFO +189 -0
  69. awf-1.0.0/awf.egg-info/SOURCES.txt +72 -0
  70. awf-1.0.0/awf.egg-info/dependency_links.txt +1 -0
  71. awf-1.0.0/awf.egg-info/requires.txt +8 -0
  72. awf-1.0.0/awf.egg-info/top_level.txt +1 -0
  73. awf-1.0.0/pyproject.toml +76 -0
  74. awf-1.0.0/setup.cfg +4 -0
awf-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 EnerJize
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.
awf-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,189 @@
1
+ Metadata-Version: 2.4
2
+ Name: awf
3
+ Version: 1.0.0
4
+ Summary: Agentic Workflow Framework — declarative multi-agent pipeline orchestrator for opencode
5
+ Author: EnerJize
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/EnerJizeIT/agentic-workflow
8
+ Project-URL: Repository, https://github.com/EnerJizeIT/agentic-workflow
9
+ Project-URL: Issues, https://github.com/EnerJizeIT/agentic-workflow/issues
10
+ Keywords: opencode,mcp,ai-agent,pipeline,multi-agent,orchestrator,workflow
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: PyYAML>=6.0
23
+ Requires-Dist: jinja2>=3.1
24
+ Requires-Dist: markdown>=3.4
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest>=7.0; extra == "dev"
27
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
28
+ Requires-Dist: pytest-timeout>=2.0; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+ # Agentic Workflow (awf)
32
+
33
+ [![license: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
34
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
35
+ [![tests](https://github.com/EnerJizeIT/agentic-workflow/actions/workflows/test.yml/badge.svg)](https://github.com/EnerJizeIT/agentic-workflow/actions/workflows/test.yml)
36
+
37
+ > **Multi-agent pipeline orchestrator for opencode. Plan → build → verify → commit — through typed MCP tools, not bash.**
38
+
39
+ ## The problem it solves
40
+
41
+ AI coding agents are powerful but chaotic. They jump straight to code without planning, skip review, leave bugs. You watch helplessly as tokens burn.
42
+
43
+ **awf** adds structure: a supervisor agent plans the work, worker agents execute through a pipeline you design (any roles, any depth — from a single worker to a multi-stage chain), and you approve each result before it commits. All through natural language — *"start working on the backlog"*, *"verify and approve"*, *"reject — the DOMParser fix is missing"*.
44
+
45
+ You stay in control. The agent stays on rails.
46
+
47
+ ## Quick Start
48
+
49
+ ```bash
50
+ # 1. Install
51
+ pip install -e .
52
+ pip install -e ./agent_workflow_ui
53
+
54
+ # 2. Configure opencode — add to ~/.config/opencode/opencode.json:
55
+ # {
56
+ # "mcp": {
57
+ # "agent-workflow-ui": {
58
+ # "type": "local",
59
+ # "command": ["python3", "-m", "agent_workflow_ui"],
60
+ # "enabled": true
61
+ # }
62
+ # }
63
+ # }
64
+
65
+ # 3. Run — just talk to opencode:
66
+ # "Initialize awf in my project"
67
+ # "Develop the MVP based on the backlog"
68
+ ```
69
+
70
+ ## Requirements
71
+
72
+ | Component | Requirement |
73
+ |---|---|
74
+ | **Python** | 3.10+ |
75
+ | **opencode** | any recent version with MCP support |
76
+ | **OS** | Linux (tested), macOS (should work), Windows (untested) |
77
+ | **Models** | Model-agnostic. Tested with Qwen vLLM. Should work with Claude, GPT, or any opencode-supported provider. |
78
+ | **Git** | Required (commit gate, baselines, rollback) |
79
+
80
+ ## Features
81
+
82
+ - 🎯 **State-Machine Orchestration (SMO)** — awf guides the supervisor through phases: `init → goal → form → normalize → brief → run → verify → done`. Every tool returns a `next_action` hint — even weak models follow the full flow without getting lost.
83
+ - 🔧 **29 MCP tools** — typed pipeline control: init, dispatch, start, approve, reject, rollback, dashboard, model validation. No bash, no manual file editing.
84
+ - 📊 **Live Dashboard** — HTTP server with real-time polling. Chat-style agent handoffs, TODO content, TODO timeline, worker status, browser notifications. No page reloads.
85
+ - 🧱 **Custom pipelines** — any roles, any depth. 1 stage or 10. You choose in the setup form.
86
+ - ✅ **Approve / Reject** — symmetric verify tools. Approve commits and archives. Reject kills the pipeline and asks for fixes.
87
+ - 🔍 **Pre-dispatch check** — before launching a pipeline, awf greps your codebase for keywords from the TODO. Warning if the task might already be done.
88
+ - 🔄 **Crash recovery** — salvage path when workers don't signal, orphan TODO cleanup, state reconciliation on startup.
89
+ - 📋 **Increment planning** — decomposition variants (vertical, horizontal, risk-first) presented as an HTML form for user choice.
90
+
91
+ ## Usage
92
+
93
+ Talk in natural language — the supervisor agent calls the right tools:
94
+
95
+ | You say | What happens |
96
+ |---|---|
97
+ | *"Initialize awf in my project"* | Creates `.agentic/`, detects stack, asks for your goal |
98
+ | *"Develop the MVP"* | Opens setup form → configures pipeline → plans first TODO |
99
+ | *"Verify"* | Supervisor reads handoffs, checks git diff, approves or rejects |
100
+ | *"Reject — the cache is missing"* | Pipeline killed, new TODO dispatched with fix instructions |
101
+
102
+ See [USAGE.md](USAGE.md) for full scenarios and tool reference.
103
+
104
+ ### SMO Flow
105
+
106
+ ```mermaid
107
+ graph LR
108
+ init --> goal --> form --> normalize --> brief --> run --> verify --> done
109
+ ```
110
+
111
+ | Phase | You do | Supervisor does |
112
+ |---|---|---|
113
+ | init | — | Creates `.agentic/`, detects stack |
114
+ | goal | Answer "what do you want?" | Stores goal |
115
+ | form | Fill setup form in browser | Opens form, recommends roles |
116
+ | normalize | — | Analyzes role overlaps |
117
+ | brief | — | Studies project, dispatches TODO |
118
+ | run | Monitor dashboard | **IDLE** — waits for you |
119
+ | verify | Say *"verify"* | Reviews, approves/rejects |
120
+ | done | "continue" or "stop" | Waits for instruction |
121
+
122
+ ## Architecture
123
+
124
+ ```mermaid
125
+ graph TD
126
+ A[opencode supervisor LLM] -->|MCP stdio - 29 tools| B[agent-workflow-ui plugin]
127
+ B -->|Python import| C[awf orchestrator]
128
+ C -->|subprocess| D[opencode run - worker agents]
129
+ C -->|HTTP daemon| E[Dashboard - live /api/state]
130
+ ```
131
+
132
+ Two packages:
133
+ - **`awf`** — Python core. Pipeline engine, phase state machine, signals, commit gate, dashboard server.
134
+ - **`agent_workflow_ui`** — MCP plugin. Thin async wrappers + `next_action` guidance + HTML forms.
135
+
136
+ ## Comparison
137
+
138
+ | | awf | Aider | Claude Code | Devin |
139
+ |---|---|---|---|---|
140
+ | Planning before code | ✅ | ❌ | ⚠️ | ✅ |
141
+ | Human approve/reject | ✅ | ❌ | ❌ | ✅ |
142
+ | Custom pipelines | ✅ | ❌ | ❌ | ❌ |
143
+ | MCP-native | ✅ | ❌ | ❌ | ❌ |
144
+ | Self-hosted / free | ✅ | ✅ | ❌ | ❌ |
145
+ | Any LLM provider | ✅ | ✅ | ❌ | ❌ |
146
+
147
+ ## Dashboard
148
+
149
+ Live HTTP dashboard opens automatically when pipeline starts:
150
+
151
+ - **Two-panel layout** — pipeline sidebar (stages, progress, worker) + content tabs
152
+ - **💬 Agent Chat** — handoffs as conversation messages with chain visualization
153
+ - **📝 Задача** — full TODO content in rendered markdown
154
+ - **📊 События** — meaningful events, newest first
155
+ - **TODO timeline** — `[✅ TODO-0001] ─ [✅ TODO-0002] ─ [🔄 TODO-0003]`
156
+ - **Browser notification** when pipeline reaches verify
157
+
158
+ ## Real-world results
159
+
160
+ 6 sessions on jira-epic-presenter (Qwen vLLM):
161
+ - Full SMO flow end-to-end: init → goal → form → normalize → brief → run → verify
162
+ - 4 TODOs per session, 1× approve (no loops), zero polling
163
+ - Reject flow tested: supervisor found missing work, rejected, re-dispatched with fix
164
+ - Pre-dispatch check caught already-implemented tasks
165
+
166
+ ## Roadmap
167
+
168
+ - **SMO escape-hatch'и** — manual phase jumps, interruptions (from real session edge cases)
169
+ - **Coverage** — critical paths (verify, plan_checkpoint, context)
170
+ - **PyPI** — `pip install awf agent-workflow-ui` (no git clone needed)
171
+ - **Dashboard v3** — stage timing bars, session summary, sound notifications
172
+ - **Standalone mode** — awf without opencode (API-only)
173
+
174
+ Full backlog: [BACKLOG.md](BACKLOG.md)
175
+
176
+ ## Documentation
177
+
178
+ - [USAGE.md](USAGE.md) — usage scenarios and tool reference
179
+ - [Architecture](vision/architecture.md) — components, data flow, design decisions
180
+ - [Product Vision](vision/agent-ui-plugin.md) — competitive advantages
181
+ - [Supervisor Flow (SMO)](vision/supervisor-flow.md) — phase system, next_action pattern
182
+ - [CHANGELOG.md](CHANGELOG.md) — version history
183
+ - [CONTRIBUTING.md](CONTRIBUTING.md) — how to contribute
184
+ - [BACKLOG.md](BACKLOG.md) — open tasks
185
+ - [README.ru.md](README.ru.md) — Russian README
186
+
187
+ ## License
188
+
189
+ MIT — see [LICENSE](LICENSE).
awf-1.0.0/README.md ADDED
@@ -0,0 +1,159 @@
1
+ # Agentic Workflow (awf)
2
+
3
+ [![license: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
4
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
5
+ [![tests](https://github.com/EnerJizeIT/agentic-workflow/actions/workflows/test.yml/badge.svg)](https://github.com/EnerJizeIT/agentic-workflow/actions/workflows/test.yml)
6
+
7
+ > **Multi-agent pipeline orchestrator for opencode. Plan → build → verify → commit — through typed MCP tools, not bash.**
8
+
9
+ ## The problem it solves
10
+
11
+ AI coding agents are powerful but chaotic. They jump straight to code without planning, skip review, leave bugs. You watch helplessly as tokens burn.
12
+
13
+ **awf** adds structure: a supervisor agent plans the work, worker agents execute through a pipeline you design (any roles, any depth — from a single worker to a multi-stage chain), and you approve each result before it commits. All through natural language — *"start working on the backlog"*, *"verify and approve"*, *"reject — the DOMParser fix is missing"*.
14
+
15
+ You stay in control. The agent stays on rails.
16
+
17
+ ## Quick Start
18
+
19
+ ```bash
20
+ # 1. Install
21
+ pip install -e .
22
+ pip install -e ./agent_workflow_ui
23
+
24
+ # 2. Configure opencode — add to ~/.config/opencode/opencode.json:
25
+ # {
26
+ # "mcp": {
27
+ # "agent-workflow-ui": {
28
+ # "type": "local",
29
+ # "command": ["python3", "-m", "agent_workflow_ui"],
30
+ # "enabled": true
31
+ # }
32
+ # }
33
+ # }
34
+
35
+ # 3. Run — just talk to opencode:
36
+ # "Initialize awf in my project"
37
+ # "Develop the MVP based on the backlog"
38
+ ```
39
+
40
+ ## Requirements
41
+
42
+ | Component | Requirement |
43
+ |---|---|
44
+ | **Python** | 3.10+ |
45
+ | **opencode** | any recent version with MCP support |
46
+ | **OS** | Linux (tested), macOS (should work), Windows (untested) |
47
+ | **Models** | Model-agnostic. Tested with Qwen vLLM. Should work with Claude, GPT, or any opencode-supported provider. |
48
+ | **Git** | Required (commit gate, baselines, rollback) |
49
+
50
+ ## Features
51
+
52
+ - 🎯 **State-Machine Orchestration (SMO)** — awf guides the supervisor through phases: `init → goal → form → normalize → brief → run → verify → done`. Every tool returns a `next_action` hint — even weak models follow the full flow without getting lost.
53
+ - 🔧 **29 MCP tools** — typed pipeline control: init, dispatch, start, approve, reject, rollback, dashboard, model validation. No bash, no manual file editing.
54
+ - 📊 **Live Dashboard** — HTTP server with real-time polling. Chat-style agent handoffs, TODO content, TODO timeline, worker status, browser notifications. No page reloads.
55
+ - 🧱 **Custom pipelines** — any roles, any depth. 1 stage or 10. You choose in the setup form.
56
+ - ✅ **Approve / Reject** — symmetric verify tools. Approve commits and archives. Reject kills the pipeline and asks for fixes.
57
+ - 🔍 **Pre-dispatch check** — before launching a pipeline, awf greps your codebase for keywords from the TODO. Warning if the task might already be done.
58
+ - 🔄 **Crash recovery** — salvage path when workers don't signal, orphan TODO cleanup, state reconciliation on startup.
59
+ - 📋 **Increment planning** — decomposition variants (vertical, horizontal, risk-first) presented as an HTML form for user choice.
60
+
61
+ ## Usage
62
+
63
+ Talk in natural language — the supervisor agent calls the right tools:
64
+
65
+ | You say | What happens |
66
+ |---|---|
67
+ | *"Initialize awf in my project"* | Creates `.agentic/`, detects stack, asks for your goal |
68
+ | *"Develop the MVP"* | Opens setup form → configures pipeline → plans first TODO |
69
+ | *"Verify"* | Supervisor reads handoffs, checks git diff, approves or rejects |
70
+ | *"Reject — the cache is missing"* | Pipeline killed, new TODO dispatched with fix instructions |
71
+
72
+ See [USAGE.md](USAGE.md) for full scenarios and tool reference.
73
+
74
+ ### SMO Flow
75
+
76
+ ```mermaid
77
+ graph LR
78
+ init --> goal --> form --> normalize --> brief --> run --> verify --> done
79
+ ```
80
+
81
+ | Phase | You do | Supervisor does |
82
+ |---|---|---|
83
+ | init | — | Creates `.agentic/`, detects stack |
84
+ | goal | Answer "what do you want?" | Stores goal |
85
+ | form | Fill setup form in browser | Opens form, recommends roles |
86
+ | normalize | — | Analyzes role overlaps |
87
+ | brief | — | Studies project, dispatches TODO |
88
+ | run | Monitor dashboard | **IDLE** — waits for you |
89
+ | verify | Say *"verify"* | Reviews, approves/rejects |
90
+ | done | "continue" or "stop" | Waits for instruction |
91
+
92
+ ## Architecture
93
+
94
+ ```mermaid
95
+ graph TD
96
+ A[opencode supervisor LLM] -->|MCP stdio - 29 tools| B[agent-workflow-ui plugin]
97
+ B -->|Python import| C[awf orchestrator]
98
+ C -->|subprocess| D[opencode run - worker agents]
99
+ C -->|HTTP daemon| E[Dashboard - live /api/state]
100
+ ```
101
+
102
+ Two packages:
103
+ - **`awf`** — Python core. Pipeline engine, phase state machine, signals, commit gate, dashboard server.
104
+ - **`agent_workflow_ui`** — MCP plugin. Thin async wrappers + `next_action` guidance + HTML forms.
105
+
106
+ ## Comparison
107
+
108
+ | | awf | Aider | Claude Code | Devin |
109
+ |---|---|---|---|---|
110
+ | Planning before code | ✅ | ❌ | ⚠️ | ✅ |
111
+ | Human approve/reject | ✅ | ❌ | ❌ | ✅ |
112
+ | Custom pipelines | ✅ | ❌ | ❌ | ❌ |
113
+ | MCP-native | ✅ | ❌ | ❌ | ❌ |
114
+ | Self-hosted / free | ✅ | ✅ | ❌ | ❌ |
115
+ | Any LLM provider | ✅ | ✅ | ❌ | ❌ |
116
+
117
+ ## Dashboard
118
+
119
+ Live HTTP dashboard opens automatically when pipeline starts:
120
+
121
+ - **Two-panel layout** — pipeline sidebar (stages, progress, worker) + content tabs
122
+ - **💬 Agent Chat** — handoffs as conversation messages with chain visualization
123
+ - **📝 Задача** — full TODO content in rendered markdown
124
+ - **📊 События** — meaningful events, newest first
125
+ - **TODO timeline** — `[✅ TODO-0001] ─ [✅ TODO-0002] ─ [🔄 TODO-0003]`
126
+ - **Browser notification** when pipeline reaches verify
127
+
128
+ ## Real-world results
129
+
130
+ 6 sessions on jira-epic-presenter (Qwen vLLM):
131
+ - Full SMO flow end-to-end: init → goal → form → normalize → brief → run → verify
132
+ - 4 TODOs per session, 1× approve (no loops), zero polling
133
+ - Reject flow tested: supervisor found missing work, rejected, re-dispatched with fix
134
+ - Pre-dispatch check caught already-implemented tasks
135
+
136
+ ## Roadmap
137
+
138
+ - **SMO escape-hatch'и** — manual phase jumps, interruptions (from real session edge cases)
139
+ - **Coverage** — critical paths (verify, plan_checkpoint, context)
140
+ - **PyPI** — `pip install awf agent-workflow-ui` (no git clone needed)
141
+ - **Dashboard v3** — stage timing bars, session summary, sound notifications
142
+ - **Standalone mode** — awf without opencode (API-only)
143
+
144
+ Full backlog: [BACKLOG.md](BACKLOG.md)
145
+
146
+ ## Documentation
147
+
148
+ - [USAGE.md](USAGE.md) — usage scenarios and tool reference
149
+ - [Architecture](vision/architecture.md) — components, data flow, design decisions
150
+ - [Product Vision](vision/agent-ui-plugin.md) — competitive advantages
151
+ - [Supervisor Flow (SMO)](vision/supervisor-flow.md) — phase system, next_action pattern
152
+ - [CHANGELOG.md](CHANGELOG.md) — version history
153
+ - [CONTRIBUTING.md](CONTRIBUTING.md) — how to contribute
154
+ - [BACKLOG.md](BACKLOG.md) — open tasks
155
+ - [README.ru.md](README.ru.md) — Russian README
156
+
157
+ ## License
158
+
159
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,3 @@
1
+ """awf — Agentic Workflow Framework Python core."""
2
+
3
+ __version__ = "0.4.0"
@@ -0,0 +1,6 @@
1
+ """Entry point for ``python3 -m awf``."""
2
+ import sys
3
+
4
+ from .cli import main
5
+
6
+ sys.exit(main())
@@ -0,0 +1,37 @@
1
+ """Atomic file write helpers for awf-core.
2
+
3
+ Centralized so all modules use the same temp+rename pattern.
4
+ """
5
+ from __future__ import annotations
6
+
7
+ import os
8
+ import tempfile
9
+ from pathlib import Path
10
+
11
+
12
+ def atomic_write_text(path: Path, content: str, encoding: str = "utf-8") -> None:
13
+ """Write text file atomically via temp + rename.
14
+
15
+ Creates parent dir if missing. Uses tempfile in same dir to guarantee
16
+ same-filesystem rename (atomic on POSIX).
17
+
18
+ H5 fix: plan_progress.py was direct write_text — crash mid-write
19
+ corrupted plan.md (the only persistent progress artifact).
20
+ """
21
+ path.parent.mkdir(parents=True, exist_ok=True)
22
+ fd, tmp_path = tempfile.mkstemp(
23
+ prefix=f".{path.name}.",
24
+ suffix=".tmp",
25
+ dir=str(path.parent),
26
+ )
27
+ try:
28
+ with os.fdopen(fd, "w", encoding=encoding) as f:
29
+ f.write(content)
30
+ os.replace(tmp_path, path)
31
+ except Exception:
32
+ # Clean up temp file on failure
33
+ try:
34
+ os.unlink(tmp_path)
35
+ except OSError:
36
+ pass
37
+ raise
awf-1.0.0/awf/_env.py ADDED
@@ -0,0 +1,90 @@
1
+ """BD-22/25: subprocess environment setup for opencode run.
2
+
3
+ Centralized so signal_watch + supervisor + agent_stage can use it without
4
+ circular imports through orchestrator.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import json
9
+ import os
10
+ import sys
11
+
12
+
13
+ def _pdeathsig_preexec() -> None:
14
+ """DF6-8: Set PR_SET_PDEATHSIG so child dies when parent (orchestrator) dies.
15
+
16
+ Linux-only. On other platforms, no-op (best effort).
17
+ Prevents orphan worker subprocesses from continuing after orchestrator crash.
18
+ """
19
+ if sys.platform != "linux":
20
+ return
21
+ try:
22
+ import ctypes
23
+ import signal as _signal
24
+
25
+ libc = ctypes.CDLL("libc.so.6", use_errno=True)
26
+ PR_SET_PDEATHSIG = 1
27
+ libc.prctl(PR_SET_PDEATHSIG, _signal.SIGTERM)
28
+ except Exception:
29
+ pass # best effort — don't crash if libc/prctl unavailable
30
+
31
+
32
+ def awf_subprocess_env() -> dict[str, str]:
33
+ """BD-22/KAUD-5: env for opencode subprocess spawned by awf.
34
+
35
+ Sets ``OPENCODE_CONFIG_CONTENT`` to override permission rules so
36
+ the subprocess can run ``edit``/``bash``/``write`` without prompting.
37
+
38
+ KAUD-5: MERGES with user's existing opencode.json instead of replacing.
39
+ Reads user's config, adds our permission overrides on top, preserves
40
+ user's other settings (theme, providers, agents, etc.).
41
+
42
+ BD-25: strip ``OPENCODE_SERVER_*`` env vars so the subprocess does NOT
43
+ attach to a running ``opencode serve`` instance.
44
+ """
45
+ env = os.environ.copy()
46
+
47
+ # KAUD-5: Start from user's existing config, then merge our overrides
48
+ user_config: dict = {}
49
+ try:
50
+ from .xdg import opencode_config_file
51
+ config_path = opencode_config_file()
52
+ if config_path.is_file():
53
+ user_config = json.loads(config_path.read_text(encoding="utf-8"))
54
+ if not isinstance(user_config, dict):
55
+ user_config = {}
56
+ except (OSError, json.JSONDecodeError):
57
+ pass # If user config is unreadable, start from empty
58
+
59
+ # Merge: user config + our permission overrides (ours take priority)
60
+ merged = user_config.copy()
61
+ merged_permissions = merged.get("permission", {})
62
+ if not isinstance(merged_permissions, dict):
63
+ merged_permissions = {}
64
+ merged_permissions.update({
65
+ "edit": "allow",
66
+ "bash": "allow",
67
+ "write": "allow",
68
+ "webfetch": "allow",
69
+ })
70
+ merged["permission"] = merged_permissions
71
+
72
+ # P1 security: only serialize permission overrides to env — never API keys,
73
+ # providers, or other sensitive fields from opencode.json. Workers only
74
+ # need the permission overrides; everything else is loaded by opencode
75
+ # itself from the real config file.
76
+ config_json = json.dumps({"permission": merged_permissions})
77
+ env["OPENCODE_CONFIG_CONTENT"] = config_json
78
+
79
+ # BD-25: strip server env vars
80
+ strip_keys = (
81
+ "OPENCODE_SERVER",
82
+ "OPENCODE_SERVER_URL",
83
+ "OPENCODE_SERVER_TOKEN",
84
+ "OPENCODE_HOST",
85
+ "OPENCODE_HOST_TOKEN",
86
+ )
87
+ for key in list(env.keys()):
88
+ if key in strip_keys:
89
+ env.pop(key, None)
90
+ return env
awf-1.0.0/awf/_log.py ADDED
@@ -0,0 +1,24 @@
1
+ """Lightweight file-based logger for awf.
2
+
3
+ Centralized so any module can log without circular imports.
4
+ """
5
+ from __future__ import annotations
6
+
7
+ import datetime as _dt
8
+ from pathlib import Path
9
+
10
+
11
+ def log(logs_dir: Path, message: str) -> None:
12
+ """Append a timestamped message to ``logs_dir/orchestrator.log``."""
13
+ if not logs_dir.exists():
14
+ try:
15
+ logs_dir.mkdir(parents=True, exist_ok=True)
16
+ except OSError:
17
+ return
18
+ log_file = logs_dir / "orchestrator.log"
19
+ ts = _dt.datetime.now(_dt.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
20
+ try:
21
+ with open(log_file, "a", encoding="utf-8") as f:
22
+ f.write(f"[{ts}] {message}\n")
23
+ except OSError:
24
+ pass