forgeo-cli 0.3.0__tar.gz → 0.4.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.
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/CHANGELOG.md +37 -1
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/PKG-INFO +20 -23
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/README.md +19 -22
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/docs/agent-contract.md +6 -6
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/docs/backlog.md +25 -3
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/docs/cli-reference.md +1 -1
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/docs/getting-started.md +5 -2
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/docs/index.md +13 -7
- forgeo_cli-0.4.0/docs/web-console-api.md +496 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/install.sh +1 -1
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/pyproject.toml +1 -1
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/__init__.py +1 -1
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/agent.py +1 -3
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/backlog.py +123 -33
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/central.py +435 -81
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/cli.py +62 -93
- forgeo_cli-0.4.0/src/forgeo/config.py +69 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/daemon.py +18 -15
- forgeo_cli-0.4.0/src/forgeo/daemon_control.py +132 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/forgeo.py +136 -77
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/instances.py +1 -1
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/models.py +19 -2
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/setup.py +31 -9
- forgeo_cli-0.4.0/src/forgeo/web/central/central.css +768 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/web/central/central.js +636 -45
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/web/central/instance.html +51 -3
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/tests/test_agent.py +78 -1
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/tests/test_backlog.py +148 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/tests/test_factory.py +120 -9
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/tests/test_git.py +20 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/tests/test_install.py +1 -1
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/tests/test_models.py +71 -1
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/tests/test_runs.py +24 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/tests/test_setup.py +38 -5
- forgeo_cli-0.4.0/tests/test_web.py +1662 -0
- forgeo_cli-0.4.0/tests/test_web_common.py +134 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/www/index.html +23 -23
- forgeo_cli-0.3.0/docs/web-console-api.md +0 -275
- forgeo_cli-0.3.0/src/forgeo/config.py +0 -36
- forgeo_cli-0.3.0/src/forgeo/web/central/central.css +0 -380
- forgeo_cli-0.3.0/tests/test_web.py +0 -781
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/.github/workflows/ci.yml +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/.gitignore +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/CONTRIBUTING.md +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/LICENSE +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/config/nginx-forgeo.conf +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/docs/configuration.md +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/docs/img/console.png +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/docs/img/logo.png +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/docs/img/title.svg +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/forgeo.spec +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/mkdocs.yml +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/__main__.py +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/git.py +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/io.py +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/notify.py +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/runs.py +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/web/central/index.html +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/web/style.css +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/src/forgeo/web_common.py +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/tests/conftest.py +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/tests/test_cli.py +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/tests/test_daemon.py +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/tests/test_instances.py +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/tests/test_io.py +0 -0
- {forgeo_cli-0.3.0 → forgeo_cli-0.4.0}/www/404.html +0 -0
|
@@ -7,6 +7,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.4.0] - 2026-08-10
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Delete OPEN tasks from the web console: a Delete button (with
|
|
15
|
+
confirmation) in the task detail modal, backed by `DELETE
|
|
16
|
+
/api/instances/<name>/tasks/<id>` and `JSONBacklog.delete_task`.
|
|
17
|
+
- Resolve BLOCKED tasks from the web console: the task modal shows the
|
|
18
|
+
blocker reason and can reopen the task (back to `OPEN`) via `POST
|
|
19
|
+
/api/instances/<name>/tasks/<id>/reopen`.
|
|
20
|
+
- The web console stays usable with many tasks: non-OPEN columns collapse
|
|
21
|
+
behind count badges with an expand toggle, so a long backlog no longer
|
|
22
|
+
renders every task as a tall card up front.
|
|
23
|
+
- The failure/block reason is shown prominently in the task detail modal.
|
|
24
|
+
- Config editing from the web console: `PUT /api/instances/<name>/config`
|
|
25
|
+
validates and persists `forgeo.yaml` changes, and a new Config tab in the
|
|
26
|
+
instance page edits the fields in a form (with a restart hint).
|
|
27
|
+
- Daemon control from the web console: start, stop, and restart an
|
|
28
|
+
instance's daemon from the top bar via `POST
|
|
29
|
+
/api/instances/<name>/{start,stop,restart}`.
|
|
30
|
+
- `forgeo init` now asks only for the bare agent command and appends the
|
|
31
|
+
task prompt automatically.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- Commit messages no longer carry the `forgeo: ` prefix.
|
|
36
|
+
- The instance is registered before the run lock is taken, so a `--name`
|
|
37
|
+
lookup never fails while starting.
|
|
38
|
+
- README revised for clarity and formatting.
|
|
39
|
+
|
|
40
|
+
## [0.3.0] - 2026-08-07
|
|
41
|
+
|
|
10
42
|
### Added
|
|
11
43
|
|
|
12
44
|
- `forgeo web [--host HOST] [--port PORT]` — a standalone central dashboard
|
|
@@ -22,6 +54,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
22
54
|
- Task editing in the web console: the task detail modal gained an **Edit**
|
|
23
55
|
mode (Save/Cancel), backed by a new `PATCH
|
|
24
56
|
/api/instances/<name>/tasks/<id>` endpoint and `JSONBacklog.update_task`.
|
|
57
|
+
- PyPI publishing: tagging a release now also publishes the `forgeo-cli`
|
|
58
|
+
wheel and sdist to PyPI via trusted publishing.
|
|
25
59
|
|
|
26
60
|
### Changed
|
|
27
61
|
|
|
@@ -108,7 +142,9 @@ Initial release of the scheduled, agent-driven software forgeo.
|
|
|
108
142
|
overlapping-run skipping.
|
|
109
143
|
- Dogfooding docs removed; local configs kept out of the repository.
|
|
110
144
|
|
|
111
|
-
[Unreleased]: https://github.com/lucaGazzola/forgeo/compare/v0.
|
|
145
|
+
[Unreleased]: https://github.com/lucaGazzola/forgeo/compare/v0.3.0...HEAD
|
|
146
|
+
[0.4.0]: https://github.com/lucaGazzola/forgeo/compare/v0.3.0...v0.4.0
|
|
147
|
+
[0.3.0]: https://github.com/lucaGazzola/forgeo/compare/v0.2.0...v0.3.0
|
|
112
148
|
[0.2.1]: https://github.com/lucaGazzola/forgeo/compare/v0.2.0...v0.2.1
|
|
113
149
|
[0.2.0]: https://github.com/lucaGazzola/forgeo/compare/v0.1.0...v0.2.0
|
|
114
150
|
[0.1.0]: https://github.com/lucaGazzola/forgeo/releases/tag/v0.1.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: forgeo-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: A scheduled software forgeo: executes backlog tasks on main, refactors when idle, and writes BLOCKER.md when it needs human input.
|
|
5
5
|
Project-URL: Homepage, https://forgeo.org
|
|
6
6
|
Project-URL: Documentation, https://forgeo.org
|
|
@@ -64,32 +64,30 @@ Description-Content-Type: text/markdown
|
|
|
64
64
|
[](https://github.com/lucaGazzola/forgeo/actions/workflows/ci.yml)
|
|
65
65
|
[](https://opensource.org/licenses/MIT)
|
|
66
66
|
|
|
67
|
-
**Forgeo is
|
|
68
|
-
You
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
**Forgeo is a software factory for your coding-agent.**
|
|
68
|
+
You're already working with an AI coding agent, prompting it task by task
|
|
69
|
+
or giving it a goal. Forgeo organizes your work in a structured way with
|
|
70
|
+
a backlog, and it decides what to work on next, runs your
|
|
71
|
+
agent on it, and commits the result. Progress, pending decisions, and history
|
|
72
|
+
are tracked in plain files you can inspect at any time, plus a web dashboard.
|
|
73
|
+
Forgeo only interrupts you when a decision is genuinely yours to
|
|
74
|
+
make, everything else happens autonomously.
|
|
73
75
|
|
|
74
76
|
All you need is basic comfort with a terminal, a git repository, and any coding
|
|
75
|
-
agent CLI
|
|
76
|
-
all of them.
|
|
77
|
-
|
|
78
|
-
Forgeo decides what to do next on its own: while tasks are left it implements
|
|
79
|
-
the oldest one and commits the result, and when the backlog is empty it reviews
|
|
80
|
-
the codebase and cleans it up. It only interrupts you when a decision is
|
|
81
|
-
genuinely yours to make — everything else happens autonomously.
|
|
77
|
+
agent CLI.
|
|
82
78
|
|
|
83
79
|
## Quickstart
|
|
84
80
|
|
|
85
|
-
|
|
86
|
-
prebuilt binary for your OS, or `pipx install forgeo-cli` works too). The full
|
|
87
|
-
walkthrough is in [Getting started](docs/getting-started.md).
|
|
81
|
+
The full walkthrough is in [Getting started](docs/getting-started.md).
|
|
88
82
|
|
|
89
83
|
```bash
|
|
90
84
|
# 1. Install
|
|
91
85
|
curl -fsSL https://forgeo.org/install.sh | bash
|
|
92
86
|
|
|
87
|
+
or
|
|
88
|
+
|
|
89
|
+
pipx install forgeo-cli
|
|
90
|
+
|
|
93
91
|
# 2. Create your Forgeo (guided wizard, run from your project root)
|
|
94
92
|
forgeo init
|
|
95
93
|
|
|
@@ -98,18 +96,17 @@ forgeo start # run forever: every interval_minutes, implement the oldest OPEN
|
|
|
98
96
|
```
|
|
99
97
|
|
|
100
98
|
`forgeo init` writes `forgeo.yaml` and a `.forgeo/` folder for the backlog
|
|
101
|
-
and logs
|
|
102
|
-
[Backlog format](docs/backlog.md))
|
|
103
|
-
it runs
|
|
104
|
-
dashboard with `forgeo web` (default <http://0.0.0.0:8790>):
|
|
99
|
+
and logs. Fill the backlog with plain JSON tasks (see
|
|
100
|
+
[Backlog format](docs/backlog.md)) or add them from the web console while
|
|
101
|
+
it runs, Forgeo does the rest. Open the dashboard with `forgeo web` (default <http://0.0.0.0:8790>):
|
|
105
102
|
|
|
106
103
|

|
|
107
104
|
|
|
108
105
|
One-off commands: `forgeo once` (single cycle), `forgeo status` (summary),
|
|
109
|
-
`forgeo stop`, `forgeo restart
|
|
106
|
+
`forgeo stop`, `forgeo restart`, every command is in the
|
|
110
107
|
[CLI reference](docs/cli-reference.md).
|
|
111
108
|
|
|
112
|
-
You can run several factories at once, one per repository
|
|
109
|
+
You can run several factories at once, one per repository, each config is
|
|
113
110
|
fully independent (own backlog, logs, locks). Register each `forgeo.yaml`
|
|
114
111
|
in the instance registry with `forgeo instance add NAME --config PATH`,
|
|
115
112
|
manage any of them by name with `forgeo start/status/stop --name NAME`,
|
|
@@ -10,32 +10,30 @@
|
|
|
10
10
|
[](https://github.com/lucaGazzola/forgeo/actions/workflows/ci.yml)
|
|
11
11
|
[](https://opensource.org/licenses/MIT)
|
|
12
12
|
|
|
13
|
-
**Forgeo is
|
|
14
|
-
You
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
**Forgeo is a software factory for your coding-agent.**
|
|
14
|
+
You're already working with an AI coding agent, prompting it task by task
|
|
15
|
+
or giving it a goal. Forgeo organizes your work in a structured way with
|
|
16
|
+
a backlog, and it decides what to work on next, runs your
|
|
17
|
+
agent on it, and commits the result. Progress, pending decisions, and history
|
|
18
|
+
are tracked in plain files you can inspect at any time, plus a web dashboard.
|
|
19
|
+
Forgeo only interrupts you when a decision is genuinely yours to
|
|
20
|
+
make, everything else happens autonomously.
|
|
19
21
|
|
|
20
22
|
All you need is basic comfort with a terminal, a git repository, and any coding
|
|
21
|
-
agent CLI
|
|
22
|
-
all of them.
|
|
23
|
-
|
|
24
|
-
Forgeo decides what to do next on its own: while tasks are left it implements
|
|
25
|
-
the oldest one and commits the result, and when the backlog is empty it reviews
|
|
26
|
-
the codebase and cleans it up. It only interrupts you when a decision is
|
|
27
|
-
genuinely yours to make — everything else happens autonomously.
|
|
23
|
+
agent CLI.
|
|
28
24
|
|
|
29
25
|
## Quickstart
|
|
30
26
|
|
|
31
|
-
|
|
32
|
-
prebuilt binary for your OS, or `pipx install forgeo-cli` works too). The full
|
|
33
|
-
walkthrough is in [Getting started](docs/getting-started.md).
|
|
27
|
+
The full walkthrough is in [Getting started](docs/getting-started.md).
|
|
34
28
|
|
|
35
29
|
```bash
|
|
36
30
|
# 1. Install
|
|
37
31
|
curl -fsSL https://forgeo.org/install.sh | bash
|
|
38
32
|
|
|
33
|
+
or
|
|
34
|
+
|
|
35
|
+
pipx install forgeo-cli
|
|
36
|
+
|
|
39
37
|
# 2. Create your Forgeo (guided wizard, run from your project root)
|
|
40
38
|
forgeo init
|
|
41
39
|
|
|
@@ -44,18 +42,17 @@ forgeo start # run forever: every interval_minutes, implement the oldest OPEN
|
|
|
44
42
|
```
|
|
45
43
|
|
|
46
44
|
`forgeo init` writes `forgeo.yaml` and a `.forgeo/` folder for the backlog
|
|
47
|
-
and logs
|
|
48
|
-
[Backlog format](docs/backlog.md))
|
|
49
|
-
it runs
|
|
50
|
-
dashboard with `forgeo web` (default <http://0.0.0.0:8790>):
|
|
45
|
+
and logs. Fill the backlog with plain JSON tasks (see
|
|
46
|
+
[Backlog format](docs/backlog.md)) or add them from the web console while
|
|
47
|
+
it runs, Forgeo does the rest. Open the dashboard with `forgeo web` (default <http://0.0.0.0:8790>):
|
|
51
48
|
|
|
52
49
|

|
|
53
50
|
|
|
54
51
|
One-off commands: `forgeo once` (single cycle), `forgeo status` (summary),
|
|
55
|
-
`forgeo stop`, `forgeo restart
|
|
52
|
+
`forgeo stop`, `forgeo restart`, every command is in the
|
|
56
53
|
[CLI reference](docs/cli-reference.md).
|
|
57
54
|
|
|
58
|
-
You can run several factories at once, one per repository
|
|
55
|
+
You can run several factories at once, one per repository, each config is
|
|
59
56
|
fully independent (own backlog, logs, locks). Register each `forgeo.yaml`
|
|
60
57
|
in the instance registry with `forgeo instance add NAME --config PATH`,
|
|
61
58
|
manage any of them by name with `forgeo start/status/stop --name NAME`,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# Agent contract
|
|
2
2
|
|
|
3
|
-
The coding agent is **any shell command
|
|
4
|
-
Code, a custom script) or a plain command. It must be able to:
|
|
3
|
+
The coding agent is **any shell command**: a CLI coding tool or a plain command. It must be able to:
|
|
5
4
|
|
|
6
5
|
1. read the task from the `FORGEO_TASK` environment variable,
|
|
7
6
|
2. work on the repository from the current working directory,
|
|
@@ -39,8 +38,8 @@ The exit code decides the outcome of the run:
|
|
|
39
38
|
|
|
40
39
|
| Exit code | Outcome | What happens |
|
|
41
40
|
| --- | --- | --- |
|
|
42
|
-
| `0` | **SUCCESS** | Everything is committed (`git add -A && git commit`) with the message
|
|
43
|
-
| `blocked_exit_code` (default `2`) | **BLOCKED** | The agent needs a human decision. Partial work is committed as
|
|
41
|
+
| `0` | **SUCCESS** | Everything is committed (`git add -A && git commit`) with the message `<title> (#<id>)`, pushed when a remote is set, and the task is marked `COMPLETED`. |
|
|
42
|
+
| `blocked_exit_code` (default `2`) | **BLOCKED** | The agent needs a human decision. Partial work is committed as `<title> (#<id>) [partial]`, the agent's reason is persisted on the task (`blocker_reason`), an optional Telegram notification is sent, and the task is marked `BLOCKED`. `BLOCKER.md` is rendered from the backlog's `BLOCKED` tasks on the next cycle — real per-task reasons, never generic text — and disappears once the last one is resolved (reopen it from the web console). |
|
|
44
43
|
| anything else | **ERROR** | Changes are discarded (`git reset --hard` + `git clean -fd`), the failure is logged, and the task is marked `FAILED`. |
|
|
45
44
|
|
|
46
45
|
The blocked exit code is configurable via `blocked_exit_code` in
|
|
@@ -73,8 +72,9 @@ interrupted.
|
|
|
73
72
|
The agent's stdout and stderr are captured live, prefixed with `[stdout]` /
|
|
74
73
|
`[stderr]`, and retained in the run result. To keep memory bounded, only the
|
|
75
74
|
**last 1000 lines** are kept for a chatty agent. On a BLOCKED result, the
|
|
76
|
-
|
|
77
|
-
`
|
|
75
|
+
agent's questions (falling back to the captured output lines) are stored on
|
|
76
|
+
the task as `blocker_reason` and become the "what the agent needs" section of
|
|
77
|
+
`BLOCKER.md` (up to the last 10 lines), rendered on the next cycle.
|
|
78
78
|
|
|
79
79
|
## Git contract
|
|
80
80
|
|
|
@@ -37,6 +37,9 @@ Each entry in `tasks` is a task object:
|
|
|
37
37
|
| `files_to_modify` | list[string] | `[]` | Informational; hints for the agent. |
|
|
38
38
|
| `agent_command` | string / list[string] | — | Override the configured `agent_command` for this task (e.g. route it to a different model). Validated like the global key; falls back to the config default when omitted. |
|
|
39
39
|
| `agent_timeout_seconds` | number | — | Override the configured `agent_timeout_seconds` for this task (must be positive). Falls back to the config default when omitted. |
|
|
40
|
+
| `blocker_reason` | list[string] | `[]` | Engine-managed: the agent's explanation (its questions, falling back to captured output) when the task becomes `BLOCKED`. Cleared on reopen; not editable via `PATCH`. |
|
|
41
|
+
| `blocked_count` | integer | `0` | Engine-managed: how many times the task has transitioned into `BLOCKED`. Kept as history when the task is reopened, so you can see a task that keeps blocking needs splitting or rewriting rather than a blind retry. Not editable via `PATCH`. |
|
|
42
|
+
| `failure_reason` | list[string] | `[]` | Engine-managed: the agent's error when the task becomes `FAILED` (e.g. a timeout message or a non-zero exit code). Shown in the web console's task modal so you can see why a task failed without opening the logs. Cleared when the task leaves the `FAILED` state; not editable via `PATCH`. |
|
|
40
43
|
|
|
41
44
|
Only `id`, `title`, `description`, and `status` (optionally) are required;
|
|
42
45
|
every other field is optional.
|
|
@@ -74,14 +77,33 @@ cheap/fast model and hard ones to a frontier model:
|
|
|
74
77
|
| `OPEN` | To be picked by Forgeo. |
|
|
75
78
|
| `BLOCKED` | Waiting on a human decision; Forgeo pauses while any task is blocked. |
|
|
76
79
|
| `COMPLETED` | The agent finished and the work was committed (and pushed). |
|
|
77
|
-
| `FAILED` | The agent errored; changes were discarded
|
|
80
|
+
| `FAILED` | The agent errored; changes were discarded and the reason is recorded in `failure_reason`. |
|
|
78
81
|
|
|
79
82
|
You add, remove, or reopen tasks by editing the file directly — or use the
|
|
80
83
|
[web console](web-console-api.md): the **new-task form** (`POST
|
|
81
84
|
/api/instances/<name>/tasks`) assigns the next free `WEB-###` id for you, and
|
|
82
85
|
the task detail modal's **Edit** button updates an existing task's fields
|
|
83
|
-
(`PATCH /api/instances/<name>/tasks/<id>`)
|
|
84
|
-
|
|
86
|
+
(`PATCH /api/instances/<name>/tasks/<id>`), while its **Delete** button
|
|
87
|
+
removes an `OPEN` or `BLOCKED` task (`DELETE /api/instances/<name>/tasks/<id>`).
|
|
88
|
+
|
|
89
|
+
### Resolving a blocked task
|
|
90
|
+
|
|
91
|
+
When the agent signals BLOCKED, Forgeo commits its partial work as a
|
|
92
|
+
`[partial]` commit on `main` and marks the task `BLOCKED`, recording the
|
|
93
|
+
agent's reason in `blocker_reason`. `BLOCKER.md` is a *derived view* of the
|
|
94
|
+
backlog's `BLOCKED` tasks — it is re-rendered every cycle with the real
|
|
95
|
+
per-task reasons and disappears automatically once the last `BLOCKED` task is
|
|
96
|
+
resolved.
|
|
97
|
+
|
|
98
|
+
To retry a `BLOCKED` task, **reopen** it: in the web console, open the task
|
|
99
|
+
card and press **Reopen** (edit the task first if you want to correct
|
|
100
|
+
something — editing is optional). Reopen is also available as `POST
|
|
101
|
+
/api/instances/<name>/tasks/<id>/reopen`; either way the status goes back to
|
|
102
|
+
`OPEN`, `blocker_reason` is cleared, and `blocked_count` is kept. Forgeo
|
|
103
|
+
picks the task up on the next scheduled run, building on the preserved
|
|
104
|
+
partial work. Reopening by hand is the same as setting the status back to
|
|
105
|
+
`OPEN` in this file — but that does *not* clear `blocker_reason`, so prefer
|
|
106
|
+
the web console's Reopen when the task was blocked by the agent.
|
|
85
107
|
|
|
86
108
|
## Oldest-first ordering
|
|
87
109
|
|
|
@@ -74,7 +74,7 @@ Outcomes a cycle can produce:
|
|
|
74
74
|
| --- | --- |
|
|
75
75
|
| `task` | A task ran and finished. |
|
|
76
76
|
| `refactor` | A refactoring pass ran (backlog was empty). |
|
|
77
|
-
| `blocked` | A `BLOCKED` task exists; `BLOCKER.md`
|
|
77
|
+
| `blocked` | A `BLOCKED` task exists; `BLOCKER.md` re-rendered from the backlog; paused. |
|
|
78
78
|
| `paused` | A blocker file exists; nothing ran. |
|
|
79
79
|
| `dirty` | The working tree was dirty; the task was not started. |
|
|
80
80
|
| `skipped` | A previous run was still in progress (daemon only). |
|
|
@@ -43,8 +43,11 @@ The wizard asks for three things:
|
|
|
43
43
|
|
|
44
44
|
1. **Forgeo folder** — where the backlog, `BLOCKER.md` and the log live
|
|
45
45
|
(default `.forgeo`). It is gitignored by default.
|
|
46
|
-
2. **Coding agent command** —
|
|
47
|
-
|
|
46
|
+
2. **Coding agent command** — the bare command that launches your coding
|
|
47
|
+
agent (default `opencode run --auto`). Forgeo appends the standard task
|
|
48
|
+
prompt (which ends in `$FORGEO_TASK`) automatically, so you never type
|
|
49
|
+
it. Enter a command that already references `$FORGEO_TASK` and it is
|
|
50
|
+
kept verbatim.
|
|
48
51
|
3. **Refactor prompt** — the instruction used when the backlog is empty; the
|
|
49
52
|
default is offered, or you can paste a custom one.
|
|
50
53
|
|
|
@@ -8,8 +8,10 @@ A **scheduled, agent-driven software forgeo** for one repository. Every
|
|
|
8
8
|
directly on the single configured branch — no branches, no PRs;
|
|
9
9
|
2. if the backlog is empty, runs the agent in **refactoring mode** and commits
|
|
10
10
|
whatever it improves;
|
|
11
|
-
3. if the agent signals it needs a human decision,
|
|
12
|
-
|
|
11
|
+
3. if the agent signals it needs a human decision, the task is marked
|
|
12
|
+
`BLOCKED` with the agent's reason preserved, `BLOCKER.md` is rendered from
|
|
13
|
+
the backlog's blocked tasks, and Forgeo pauses until you resolve it (reopen
|
|
14
|
+
it from the web console).
|
|
13
15
|
|
|
14
16
|
## What Forgeo is
|
|
15
17
|
|
|
@@ -37,7 +39,7 @@ forgeo.yaml ──► forgeo start (daemon)
|
|
|
37
39
|
▼
|
|
38
40
|
Forgeo.run_cycle()
|
|
39
41
|
│
|
|
40
|
-
├── BLOCKED task exists ──►
|
|
42
|
+
├── BLOCKED task exists ──► render BLOCKER.md from backlog, pause
|
|
41
43
|
│
|
|
42
44
|
├── oldest OPEN task ──► run agent ──► commit & push ──► COMPLETED
|
|
43
45
|
│
|
|
@@ -45,7 +47,8 @@ forgeo.yaml ──► forgeo start (daemon)
|
|
|
45
47
|
│
|
|
46
48
|
exit 0 │ exit blocked_exit_code
|
|
47
49
|
commit & push ──────── ShellAgent ──────┴─────► partial work committed,
|
|
48
|
-
task COMPLETED (FORGEO_TASK env)
|
|
50
|
+
task COMPLETED (FORGEO_TASK env) reason persisted on task,
|
|
51
|
+
BLOCKER.md rendered next cycle
|
|
49
52
|
task BLOCKED
|
|
50
53
|
```
|
|
51
54
|
|
|
@@ -55,6 +58,7 @@ forgeo.yaml ──► forgeo start (daemon)
|
|
|
55
58
|
| --- | --- | --- |
|
|
56
59
|
| `forgeo.cli` | `src/forgeo/cli.py` | `init`, `start`, `once`, `status`, `stop`, `restart` commands. |
|
|
57
60
|
| `forgeo.daemon` | `src/forgeo/daemon.py` | The scheduled worker: wakes every `interval_minutes`, holds the run locks, records `last_outcome`. |
|
|
61
|
+
| `forgeo.daemon_control` | `src/forgeo/daemon_control.py` | Daemon lifecycle shared by the CLI and web console: SIGTERM + wait, detached start/restart. |
|
|
58
62
|
| `forgeo.forgeo` | `src/forgeo/forgeo.py` | One cycle of work: task run, refactor pass, blocker handling, git side effects. |
|
|
59
63
|
| `forgeo.backlog` | `src/forgeo/backlog.py` | JSON backlog read/write; picks the oldest `OPEN` task. |
|
|
60
64
|
| `forgeo.agent` | `src/forgeo/agent.py` | `ShellAgent`: runs your command, maps exit codes to outcomes, delivers `FORGEO_TASK`. |
|
|
@@ -71,9 +75,11 @@ forgeo.yaml ──► forgeo start (daemon)
|
|
|
71
75
|
`once` is refused while it is held.
|
|
72
76
|
2. `Forgeo.run_cycle()` ensures the configured branch exists and is checked
|
|
73
77
|
out.
|
|
74
|
-
3. If any task is `BLOCKED`, Forgeo
|
|
75
|
-
(
|
|
76
|
-
the block.
|
|
78
|
+
3. If any task is `BLOCKED`, Forgeo re-renders `BLOCKER.md` from the backlog
|
|
79
|
+
(real per-task reasons, never generic text) and pauses (`blocked` outcome)
|
|
80
|
+
— it will not start new work until the block is resolved. Once the last
|
|
81
|
+
`BLOCKED` task is reopened, the file disappears automatically on the next
|
|
82
|
+
cycle.
|
|
77
83
|
4. Otherwise it takes the oldest `OPEN` task. If the working tree is dirty the
|
|
78
84
|
cycle aborts (`dirty`) rather than running over manual changes.
|
|
79
85
|
5. The agent runs with the repository as its working directory and the task in
|