progi 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 (56) hide show
  1. progi-0.1.0/.env.example +15 -0
  2. progi-0.1.0/.github/workflows/ci.yml +26 -0
  3. progi-0.1.0/.github/workflows/publish.yml +47 -0
  4. progi-0.1.0/.gitignore +33 -0
  5. progi-0.1.0/AGENTS.md +173 -0
  6. progi-0.1.0/CHANGELOG.md +14 -0
  7. progi-0.1.0/CLAUDE.md +1 -0
  8. progi-0.1.0/CONTRIBUTING.md +19 -0
  9. progi-0.1.0/LICENSE +21 -0
  10. progi-0.1.0/PKG-INFO +123 -0
  11. progi-0.1.0/README.md +101 -0
  12. progi-0.1.0/alembic/env.py +58 -0
  13. progi-0.1.0/alembic/script.py.mako +24 -0
  14. progi-0.1.0/alembic.ini +40 -0
  15. progi-0.1.0/docs/FAQ.md +132 -0
  16. progi-0.1.0/docs/README.md +8 -0
  17. progi-0.1.0/docs/configuration.md +45 -0
  18. progi-0.1.0/docs/example-workflows.md +112 -0
  19. progi-0.1.0/docs/glossary.md +106 -0
  20. progi-0.1.0/docs/mcp.json.example +9 -0
  21. progi-0.1.0/docs/use-cases.md +14 -0
  22. progi-0.1.0/frontend/input.css +108 -0
  23. progi-0.1.0/justfile +137 -0
  24. progi-0.1.0/progi/__init__.py +3 -0
  25. progi-0.1.0/progi/cli.py +80 -0
  26. progi-0.1.0/progi/config.py +63 -0
  27. progi-0.1.0/progi/db.py +1058 -0
  28. progi-0.1.0/progi/logging_setup.py +28 -0
  29. progi-0.1.0/progi/mcp_server.py +200 -0
  30. progi-0.1.0/progi/models.py +124 -0
  31. progi-0.1.0/progi/prompts/playbook.md +40 -0
  32. progi-0.1.0/progi/prompts/workflow_skeleton.md +103 -0
  33. progi-0.1.0/progi/seed.py +397 -0
  34. progi-0.1.0/progi/web/__init__.py +1 -0
  35. progi-0.1.0/progi/web/app.py +42 -0
  36. progi-0.1.0/progi/web/routers/__init__.py +22 -0
  37. progi-0.1.0/progi/web/routers/board.py +56 -0
  38. progi-0.1.0/progi/web/routers/workflows.py +95 -0
  39. progi-0.1.0/progi/web/static/app.js +293 -0
  40. progi-0.1.0/progi/web/static/style.css +2 -0
  41. progi-0.1.0/progi/web/static/vendor/alpine-ajax.min.js +1 -0
  42. progi-0.1.0/progi/web/static/vendor/alpine.min.js +5 -0
  43. progi-0.1.0/progi/web/static/vendor/marked.min.js +79 -0
  44. progi-0.1.0/progi/web/static/vendor/mermaid.min.js +3405 -0
  45. progi-0.1.0/progi/web/templates/base.html +65 -0
  46. progi-0.1.0/progi/web/templates/base_partial.html +3 -0
  47. progi-0.1.0/progi/web/templates/pages/board.html +44 -0
  48. progi-0.1.0/progi/web/templates/pages/workflows.html +136 -0
  49. progi-0.1.0/progi/web/templates/partials/board.html +85 -0
  50. progi-0.1.0/progi/web/templates/partials/step_detail.html +196 -0
  51. progi-0.1.0/progi/web/templates/partials/task_detail.html +116 -0
  52. progi-0.1.0/pyproject.toml +50 -0
  53. progi-0.1.0/renovate.json +10 -0
  54. progi-0.1.0/tests/conftest.py +5 -0
  55. progi-0.1.0/tests/test_db.py +359 -0
  56. progi-0.1.0/uv.lock +1842 -0
@@ -0,0 +1,15 @@
1
+ # Copy this file to .env and adjust values for your local setup.
2
+ # All variables are optional — defaults are shown in comments.
3
+
4
+ # Path to the SQLite database file.
5
+ # Default: OS user data dir (e.g. ~/.local/share/progi/progi.db on Linux)
6
+ # PROGI_DB_PATH=/path/to/progi.db
7
+
8
+ # Web server host. Default: 127.0.0.1 (localhost only — do not expose on a network interface)
9
+ # PROGI_WEB_HOST=127.0.0.1
10
+
11
+ # Web server port. Default: 8000
12
+ # PROGI_WEB_PORT=8000
13
+
14
+ # Set to 1 to disable the web server entirely.
15
+ # PROGI_NO_WEB=0
@@ -0,0 +1,26 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: ["main"]
6
+ pull_request:
7
+ branches: ["main"]
8
+
9
+ jobs:
10
+ lint-and-test:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+
15
+ - uses: astral-sh/setup-uv@v5
16
+ with:
17
+ enable-caching: true
18
+
19
+ - name: Install dependencies
20
+ run: uv sync --extra dev
21
+
22
+ - name: Lint
23
+ run: uv run ruff check progi
24
+
25
+ - name: Test
26
+ run: uv run python -m pytest
@@ -0,0 +1,47 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ build:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - uses: astral-sh/setup-uv@v5
18
+ with:
19
+ enable-caching: true
20
+
21
+ - name: Build
22
+ run: uv build
23
+
24
+ - name: Check dist metadata
25
+ run: uvx twine check dist/*
26
+
27
+ - name: Upload dist artifacts
28
+ uses: actions/upload-artifact@v4
29
+ with:
30
+ name: dist
31
+ path: dist/
32
+
33
+ publish:
34
+ needs: build
35
+ runs-on: ubuntu-latest
36
+ environment: pypi
37
+ permissions:
38
+ id-token: write
39
+ steps:
40
+ - name: Download dist artifacts
41
+ uses: actions/download-artifact@v4
42
+ with:
43
+ name: dist
44
+ path: dist/
45
+
46
+ - name: Publish to PyPI
47
+ uses: pypa/gh-action-pypi-publish@release/v1
progi-0.1.0/.gitignore ADDED
@@ -0,0 +1,33 @@
1
+ # Python
2
+ __pycache__/
3
+ *.pyc
4
+ .venv/
5
+ *.egg-info/
6
+ dist/
7
+ build/
8
+
9
+ # Frontend build artifacts (downloaded/generated, not committed)
10
+ # style.css IS committed — it ships in the wheel so uvx installs work without a build step
11
+ frontend/tailwindcss
12
+ frontend/tailwindcss.exe
13
+
14
+ # Vendored JS IS committed (no CDN at runtime) — do not ignore vendor/
15
+
16
+ # Local databases
17
+ *.db
18
+ *.db-wal
19
+ *.db-shm
20
+
21
+ # Tooling
22
+ .pytest_cache/
23
+ .ruff_cache/
24
+
25
+
26
+ .env
27
+ .vscode/
28
+ .agents/
29
+ .claude/
30
+ .mcp.json
31
+
32
+ # Alembic generated migrations (local only)
33
+ alembic/versions/
progi-0.1.0/AGENTS.md ADDED
@@ -0,0 +1,173 @@
1
+ # AGENTS.md
2
+
3
+ ## What this is
4
+
5
+ Progi is an MCP-native workflow engine. Key terms:
6
+
7
+ - **workflow**: a reusable template of ordered **steps**; defines a repeatable, reused across many tasks
8
+ - **step**: one unit of work in a workflow; has a **playbook**, an input spec, and an output spec
9
+ - **playbook**: markdown attached to a step; the agent reads it via `start_or_continue_task` and follows it
10
+ - **task**: a single execution of a workflow; progresses through steps one at a time with lifecycle `todo` → `in_progress` → `done`
11
+
12
+ Two interfaces over one SQLite DB:
13
+
14
+ - **Progi MCP server** (FastMCP, stdio) — the work loop runs here, inside the user's harness.
15
+ - **Progi Monitoring** (FastAPI + Jinja + Alpine/AlpineAJAX) — a web app for tracking tasks and reviewing workflows.
16
+
17
+ ## The one rule
18
+
19
+ **All database access goes through `progi/db.py`.** MCP tools and web routes
20
+ are thin adapters that call named functions there — they never write SQL. This is
21
+ what keeps LLM-driven and human-driven edits behaviorally identical.
22
+
23
+ ## Layout
24
+
25
+ | File | Role |
26
+ |---|---|
27
+ | `progi/db.py` | Schema (SQLAlchemy Core) + **all** queries, mutations, and state-transition logic |
28
+ | `progi/mcp_server.py` | `@mcp.tool` wrappers (work loop + workflow authoring) |
29
+ | `progi/web/app.py` | FastAPI routes → Jinja partials |
30
+ | `progi/prompts/` | Pass 1 / Pass 2 authoring system prompts (served by tools) |
31
+ | `progi/seed.py` | "Blog Post" workflow + sample task (idempotent) |
32
+ | `tests/test_db.py` | DB roundtrip, full work loop, authoring |
33
+
34
+ ## Frontend / UI components
35
+
36
+ Templates live in `progi/web/templates/`. The UI stack is:
37
+
38
+ - **Tailwind CSS v4** (compiled by the standalone CLI via `just build`)
39
+ - **Alpine.js v3** + **Alpine AJAX** — vendored to `static/vendor/` by `just vendorize`
40
+ - **PenguinUI** — a copy-paste component library; no install needed
41
+
42
+ ### Using PenguinUI
43
+
44
+ Browse components at **https://www.penguinui.com/components**, pick what you need,
45
+ and paste the HTML directly into a template. There is nothing to download or import —
46
+ PenguinUI components are just Tailwind + Alpine markup.
47
+
48
+ Key conventions when adding components:
49
+ - Use `<article>` as the root for card-style components (PenguinUI's convention).
50
+ - Use the existing design tokens from `frontend/input.css` (`bg-surface-*`,
51
+ `text-primary`, `text-accent`, `border-subtle`, etc.) instead of raw colors.
52
+ - Interactive components that require Alpine plugins (Collapse, Focus, Mask) must
53
+ vendorize those scripts via `just vendorize` and load them **before** Alpine core
54
+ in `base.html` (plugins must register before Alpine initializes).
55
+ - Web routes return **HTML partials** for AJAX; the swapped element's `id` must
56
+ match the `x-target` attribute on the trigger element.
57
+
58
+ ### Adding a new top-level page
59
+
60
+ Pages live in `progi/web/templates/pages/`. Each page template extends a
61
+ variable base template so the same file works for both full page loads and
62
+ Alpine AJAX partial swaps — no separate `*_content.html` partial needed.
63
+
64
+ **1. Template** (`pages/mypage.html`):
65
+
66
+ ```html
67
+ {% extends base_template %}
68
+
69
+ {% block content %}
70
+ <!-- page content here -->
71
+ {% endblock %}
72
+ ```
73
+
74
+ If the page needs full-bleed layout (no max-width wrapper), also override
75
+ `outer_class` as an empty block (see `pages/workflows.html`).
76
+
77
+ **2. Router** (`routers/mypage.py`):
78
+
79
+ ```python
80
+ from . import base_template
81
+
82
+ @router.get("/mypage", response_class=HTMLResponse)
83
+ def mypage(request: Request):
84
+ ctx = {"base_template": base_template(request), ...}
85
+ return _templates(request).TemplateResponse(request, "pages/mypage.html", ctx)
86
+ ```
87
+
88
+ Always pass `"base_template": base_template(request)` in the context.
89
+ `base_template()` returns `"base_partial.html"` for Alpine AJAX requests and
90
+ `"base.html"` for direct browser navigation. `base_partial.html` wraps the
91
+ content in `<div id="page-content">` so Alpine AJAX can find its swap target.
92
+
93
+ **3. Nav link** (`base.html`):
94
+
95
+ ```html
96
+ <a href="/mypage"
97
+ x-target.push="page-content"
98
+ :class="{ 'text-primary': page === '/mypage', 'text-faint hover:text-muted': page !== '/mypage' }"
99
+ class="text-xs font-medium transition-colors duration-150"
100
+ x-cloak>
101
+ My Page
102
+ </a>
103
+ ```
104
+
105
+ **4. Register the router** (`web/app.py`):
106
+
107
+ ```python
108
+ from .routers import board, mypage, workflows
109
+ app.include_router(mypage.router)
110
+ ```
111
+
112
+ ## Conventions
113
+
114
+ - **No SQL outside `db.py`.** Add a named function; wrap writes in `with engine.begin()`.
115
+ - **Never `print()` / write to stdout** anywhere reachable from the MCP process — stdout is the MCP protocol channel. Log to stderr via `logging_setup`.
116
+ - **Web returns HTML partials** for AJAX (not JSON); the swapped element's `id` must match the trigger's `x-target`.
117
+ - `input_spec` / `output_spec` / `input_data` / `output` are `sa.JSON` columns — pass and receive plain dicts, no manual `json.dumps`.
118
+ - Keep the web UI localhost-only (unauthenticated DB viewer).
119
+
120
+ ### Choosing between fetch + JS state vs. Alpine AJAX partials
121
+
122
+ Use **plain `fetch` + Alpine reactive state** (in `app.js`) when:
123
+ - The backend returns no meaningful body (e.g. 204 on DELETE)
124
+ - The UI update is a local state mutation — remove an item, clear a field, reset a flag
125
+ - No new HTML needs to come from the server
126
+
127
+ Use **Alpine AJAX / HTML partials** when:
128
+ - The server is the source of truth for what to render (e.g. a detail panel, a refreshed list)
129
+ - The response *is* the UI update — swapping in rendered HTML is simpler than rebuilding it in JS
130
+
131
+ #### Alpine AJAX trigger pattern
132
+
133
+ Alpine AJAX intercepts clicks on `<a href>` elements and form submits — **not** bare button clicks. For any clickable element that should trigger an AJAX swap, wrap it in an `<a>` tag with `href` pointing to the endpoint and `x-target` naming the element ID to replace:
134
+
135
+ ```html
136
+ <a href="/board" x-target="board" class="...">
137
+ Refresh
138
+ </a>
139
+ ```
140
+
141
+ If you also need to send a payload to backend, use `<FORM>` instead of `<a>`.
142
+
143
+ Omit `.push` on `x-target` when you don't want the click to update the browser history (e.g. a refresh action vs. navigation).
144
+
145
+ Example of the fetch pattern (workflow delete in `app.js`):
146
+ ```js
147
+ const resp = await fetch(`/workflows/${id}`, { method: 'DELETE' });
148
+ if (resp.ok) {
149
+ this.workflows = this.workflows.filter(wf => wf.id !== id);
150
+ // clear canvas, reset active state, update URL as needed
151
+ }
152
+ ```
153
+
154
+ ## Dev commands
155
+
156
+ `just` ships in the dev group, so prefix recipes with `uv run` if you don't have a system `just`.
157
+
158
+ ```bash
159
+ uv sync --extra dev # deps + just
160
+ uv run just install # + vendored JS, Tailwind CLI
161
+ uv run just build # compile web/static/style.css
162
+ uv run just dev # web app with autoreload
163
+ uv run just mcp # MCP server only (stdio)
164
+ uv run just migrate "msg" && uv run just upgrade # Alembic migration
165
+ uv run just seed # load Blog Post workflow + sample task
166
+ uv run python -m pytest # tests (do NOT use `uv run pytest` — a system pytest may shadow it)
167
+ uv run ruff check progi # lint
168
+ ```
169
+
170
+ ## Run modes
171
+
172
+ `progi` (MCP + web), `progi --no-web` (MCP only), `progi-web` (web only).
173
+ Config via env: `PROGI_DB_PATH`, `PROGI_WEB_HOST`, `PROGI_WEB_PORT`, `PROGI_NO_WEB`.
@@ -0,0 +1,14 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2026-06-15
9
+
10
+ ### Added
11
+
12
+ - Initial release.
13
+
14
+ [0.1.0]: https://github.com/ateszika/progi/releases/tag/v0.1.0
progi-0.1.0/CLAUDE.md ADDED
@@ -0,0 +1 @@
1
+ AGENTS.md
@@ -0,0 +1,19 @@
1
+ # Contributing to Progi
2
+
3
+ ## Before submitting a PR
4
+ Run this:
5
+ ```bash
6
+ uv run ruff check src
7
+ uv run python -m pytest
8
+ ```
9
+
10
+ Both must pass.
11
+
12
+ Do not submit code that was not reviewed by you (the human). Make sure that you have a good understanding of the code changes you want to introduce.
13
+
14
+ If you are using agents to code, we have an `AGENTS.md` you should use.
15
+
16
+ Do not edit `CHANGELOG.md`. Changelog entries are added by maintainers.
17
+
18
+ ## Docs & content PRs
19
+ You can submit documentation fixes or even new guides/tutorials to share how you use Progi - use cases, workflow examples etc...
progi-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Progi contributors
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.
progi-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,123 @@
1
+ Metadata-Version: 2.4
2
+ Name: progi
3
+ Version: 0.1.0
4
+ Summary: An MCP-native workflow engine that teaches your agent how you like to get things done.
5
+ License: MIT
6
+ License-File: LICENSE
7
+ Requires-Python: >=3.11
8
+ Requires-Dist: alembic>=1.13
9
+ Requires-Dist: fastapi>=0.115
10
+ Requires-Dist: fastmcp>=2.0
11
+ Requires-Dist: jinja2>=3.1
12
+ Requires-Dist: platformdirs>=4.0
13
+ Requires-Dist: python-multipart>=0.0.9
14
+ Requires-Dist: sqlalchemy>=2.0
15
+ Requires-Dist: uvicorn>=0.30
16
+ Provides-Extra: dev
17
+ Requires-Dist: httpx>=0.27; extra == 'dev'
18
+ Requires-Dist: mcp[cli]>=1.27.2; extra == 'dev'
19
+ Requires-Dist: pytest>=8.0; extra == 'dev'
20
+ Requires-Dist: ruff>=0.6; extra == 'dev'
21
+ Description-Content-Type: text/markdown
22
+
23
+ # Progi - MCP-native Workflow Engine
24
+
25
+ Progi teaches your agent how **you** like to get things done. So you can do your best work without re-explaining your process or losing context between sessions.
26
+
27
+
28
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
29
+ [![Python](https://img.shields.io/pypi/pyversions/progi)](https://pypi.org/project/progi/)
30
+ [![PyPI](https://img.shields.io/pypi/v/progi)](https://pypi.org/project/progi/)
31
+ [![MCP](https://img.shields.io/badge/MCP-compatible-6366f1)](https://modelcontextprotocol.io)
32
+
33
+ ---
34
+
35
+ ## Get started
36
+
37
+ Add Progi to your MCP client config (VS Code / Cursor / Zed / Claude Code / etc):
38
+
39
+ ```json
40
+ {
41
+ "mcpServers": {
42
+ "progi": {
43
+ "command": "uvx",
44
+ "args": ["progi"]
45
+ }
46
+ }
47
+ }
48
+ ```
49
+
50
+ Or with the Claude Code CLI:
51
+
52
+ ```bash
53
+ claude mcp add progi -- uvx progi
54
+ ```
55
+
56
+ Requires [uv](https://docs.astral.sh/uv/). That's it — your AI now has tools to create workflows, follow playbooks step by step, and keep a kanban board current. The web UI (Progi Monitoring) starts automatically at `http://127.0.0.1:8000`.
57
+
58
+ ---
59
+
60
+ ## How it works
61
+
62
+ **1. Describe your workflow**
63
+
64
+ Describe your process in plain language. You can be detailed or just provide a rough idea. Progi stores it as a structured workflow with per-step playbooks.
65
+
66
+ **2. Run tasks, stay in the loop**
67
+
68
+ *"Hey Progi, continue working on xy task."* Your agent loads the workflow, works through each step using your playbooks, and loops you in at critical checkpoints to review output.
69
+
70
+ **3. Monitor progress**
71
+
72
+ Progi Monitoring gives you a live view of every running and completed task — status, progress, and the full output history across all your workflows.
73
+
74
+ **4. Optimize as you go**
75
+
76
+ Tweak playbooks between runs. Because workflows live in a database and survive context resets, every future task picks up your changes automatically — your process gets sharper with each iteration.
77
+
78
+ ---
79
+
80
+ ## MCP Tools
81
+
82
+ ### Work loop
83
+
84
+ | Tool | Description |
85
+ |---|---|
86
+ | `create_task` | Create a new task under a given workflow (status `todo`); returns a preview of its first step |
87
+ | `list_tasks` | List tasks, optionally filtered by status and/or workflow |
88
+ | `start_or_continue_task` | Main work-loop entry point — starts or resumes a task and returns the current step's playbook, input data, and output spec |
89
+ | `update_progress_notes` | Overwrite a task's progress notes (mid-step save point) |
90
+ | `submit_output` | Mark the current step complete, store its output, and advance to the next step (or mark done) |
91
+
92
+ ### Workflow authoring
93
+
94
+ | Tool | Description |
95
+ |---|---|
96
+ | `get_process_skeleton_prompt` | Return the Pass 1 system prompt for turning a plain-language description into a structured workflow skeleton |
97
+ | `get_playbook_authoring_prompt` | Return the Pass 2 system prompt for authoring a step's playbook (injects workflow context) |
98
+ | `save_workflow` | Persist a new workflow, its steps, and playbooks |
99
+ | `list_workflows` | Return all workflows with their ordered steps |
100
+ | `update_playbook` | Replace the playbook content for a step |
101
+
102
+ Authoring is two passes: Pass 1 turns a plain-language description into a structured skeleton; Pass 2 authors each step's playbook. `save_workflow` persists both.
103
+
104
+ ---
105
+
106
+ ## Configuration
107
+
108
+ | Variable | Default | Purpose |
109
+ |---|---|---|
110
+ | `PROGI_DB_PATH` | OS data dir (`platformdirs`) | SQLite file location |
111
+ | `PROGI_WEB_HOST` | `127.0.0.1` | Web UI bind host |
112
+ | `PROGI_WEB_PORT` | `8000` | Web UI port |
113
+ | `PROGI_NO_WEB` | `0` | Set to `1` to disable the web UI |
114
+
115
+ Run modes: `uvx progi` (MCP + web UI), `uvx progi --no-web` (MCP only), `uvx progi-web` (web UI only).
116
+
117
+ > Use an absolute path for `PROGI_DB_PATH`
118
+
119
+ ---
120
+
121
+ ## License
122
+
123
+ MIT
progi-0.1.0/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # Progi - MCP-native Workflow Engine
2
+
3
+ Progi teaches your agent how **you** like to get things done. So you can do your best work without re-explaining your process or losing context between sessions.
4
+
5
+
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
7
+ [![Python](https://img.shields.io/pypi/pyversions/progi)](https://pypi.org/project/progi/)
8
+ [![PyPI](https://img.shields.io/pypi/v/progi)](https://pypi.org/project/progi/)
9
+ [![MCP](https://img.shields.io/badge/MCP-compatible-6366f1)](https://modelcontextprotocol.io)
10
+
11
+ ---
12
+
13
+ ## Get started
14
+
15
+ Add Progi to your MCP client config (VS Code / Cursor / Zed / Claude Code / etc):
16
+
17
+ ```json
18
+ {
19
+ "mcpServers": {
20
+ "progi": {
21
+ "command": "uvx",
22
+ "args": ["progi"]
23
+ }
24
+ }
25
+ }
26
+ ```
27
+
28
+ Or with the Claude Code CLI:
29
+
30
+ ```bash
31
+ claude mcp add progi -- uvx progi
32
+ ```
33
+
34
+ Requires [uv](https://docs.astral.sh/uv/). That's it — your AI now has tools to create workflows, follow playbooks step by step, and keep a kanban board current. The web UI (Progi Monitoring) starts automatically at `http://127.0.0.1:8000`.
35
+
36
+ ---
37
+
38
+ ## How it works
39
+
40
+ **1. Describe your workflow**
41
+
42
+ Describe your process in plain language. You can be detailed or just provide a rough idea. Progi stores it as a structured workflow with per-step playbooks.
43
+
44
+ **2. Run tasks, stay in the loop**
45
+
46
+ *"Hey Progi, continue working on xy task."* Your agent loads the workflow, works through each step using your playbooks, and loops you in at critical checkpoints to review output.
47
+
48
+ **3. Monitor progress**
49
+
50
+ Progi Monitoring gives you a live view of every running and completed task — status, progress, and the full output history across all your workflows.
51
+
52
+ **4. Optimize as you go**
53
+
54
+ Tweak playbooks between runs. Because workflows live in a database and survive context resets, every future task picks up your changes automatically — your process gets sharper with each iteration.
55
+
56
+ ---
57
+
58
+ ## MCP Tools
59
+
60
+ ### Work loop
61
+
62
+ | Tool | Description |
63
+ |---|---|
64
+ | `create_task` | Create a new task under a given workflow (status `todo`); returns a preview of its first step |
65
+ | `list_tasks` | List tasks, optionally filtered by status and/or workflow |
66
+ | `start_or_continue_task` | Main work-loop entry point — starts or resumes a task and returns the current step's playbook, input data, and output spec |
67
+ | `update_progress_notes` | Overwrite a task's progress notes (mid-step save point) |
68
+ | `submit_output` | Mark the current step complete, store its output, and advance to the next step (or mark done) |
69
+
70
+ ### Workflow authoring
71
+
72
+ | Tool | Description |
73
+ |---|---|
74
+ | `get_process_skeleton_prompt` | Return the Pass 1 system prompt for turning a plain-language description into a structured workflow skeleton |
75
+ | `get_playbook_authoring_prompt` | Return the Pass 2 system prompt for authoring a step's playbook (injects workflow context) |
76
+ | `save_workflow` | Persist a new workflow, its steps, and playbooks |
77
+ | `list_workflows` | Return all workflows with their ordered steps |
78
+ | `update_playbook` | Replace the playbook content for a step |
79
+
80
+ Authoring is two passes: Pass 1 turns a plain-language description into a structured skeleton; Pass 2 authors each step's playbook. `save_workflow` persists both.
81
+
82
+ ---
83
+
84
+ ## Configuration
85
+
86
+ | Variable | Default | Purpose |
87
+ |---|---|---|
88
+ | `PROGI_DB_PATH` | OS data dir (`platformdirs`) | SQLite file location |
89
+ | `PROGI_WEB_HOST` | `127.0.0.1` | Web UI bind host |
90
+ | `PROGI_WEB_PORT` | `8000` | Web UI port |
91
+ | `PROGI_NO_WEB` | `0` | Set to `1` to disable the web UI |
92
+
93
+ Run modes: `uvx progi` (MCP + web UI), `uvx progi --no-web` (MCP only), `uvx progi-web` (web UI only).
94
+
95
+ > Use an absolute path for `PROGI_DB_PATH`
96
+
97
+ ---
98
+
99
+ ## License
100
+
101
+ MIT
@@ -0,0 +1,58 @@
1
+ """Alembic environment, wired to progi's config and Core metadata."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from logging.config import fileConfig
6
+
7
+ from alembic import context
8
+ from sqlalchemy import engine_from_config, pool
9
+
10
+ from progi.config import load_config
11
+ from progi.models import metadata
12
+
13
+ config = context.config
14
+
15
+ # Resolve the DB URL from progi's own config so migrations and the app always
16
+ # point at the same database.
17
+ _cfg = load_config()
18
+ _cfg.ensure_dirs()
19
+ config.set_main_option("sqlalchemy.url", _cfg.sqlalchemy_url)
20
+
21
+ if config.config_file_name is not None:
22
+ fileConfig(config.config_file_name)
23
+
24
+ target_metadata = metadata
25
+
26
+
27
+ def run_migrations_offline() -> None:
28
+ context.configure(
29
+ url=config.get_main_option("sqlalchemy.url"),
30
+ target_metadata=target_metadata,
31
+ literal_binds=True,
32
+ dialect_opts={"paramstyle": "named"},
33
+ render_as_batch=True, # required for SQLite ALTER support
34
+ )
35
+ with context.begin_transaction():
36
+ context.run_migrations()
37
+
38
+
39
+ def run_migrations_online() -> None:
40
+ connectable = engine_from_config(
41
+ config.get_section(config.config_ini_section, {}),
42
+ prefix="sqlalchemy.",
43
+ poolclass=pool.NullPool,
44
+ )
45
+ with connectable.connect() as connection:
46
+ context.configure(
47
+ connection=connection,
48
+ target_metadata=target_metadata,
49
+ render_as_batch=True, # SQLite-safe migrations
50
+ )
51
+ with context.begin_transaction():
52
+ context.run_migrations()
53
+
54
+
55
+ if context.is_offline_mode():
56
+ run_migrations_offline()
57
+ else:
58
+ run_migrations_online()
@@ -0,0 +1,24 @@
1
+ """${message}
2
+
3
+ Revision ID: ${up_revision}
4
+ Revises: ${down_revision | comma,n}
5
+ Create Date: ${create_date}
6
+ """
7
+ from typing import Sequence, Union
8
+
9
+ from alembic import op
10
+ import sqlalchemy as sa
11
+ ${imports if imports else ""}
12
+
13
+ revision: str = ${repr(up_revision)}
14
+ down_revision: Union[str, None] = ${repr(down_revision)}
15
+ branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
16
+ depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
17
+
18
+
19
+ def upgrade() -> None:
20
+ ${upgrades if upgrades else "pass"}
21
+
22
+
23
+ def downgrade() -> None:
24
+ ${downgrades if downgrades else "pass"}