ralphx 0.2.2__tar.gz → 0.3.5__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.
- {ralphx-0.2.2 → ralphx-0.3.5}/PKG-INFO +34 -12
- {ralphx-0.2.2 → ralphx-0.3.5}/README.md +33 -9
- {ralphx-0.2.2 → ralphx-0.3.5}/pyproject.toml +17 -6
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/__init__.py +1 -1
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/api/main.py +9 -1
- ralphx-0.3.5/ralphx/api/routes/auth.py +891 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/api/routes/config.py +3 -56
- ralphx-0.3.5/ralphx/api/routes/export_import.py +795 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/api/routes/loops.py +4 -4
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/api/routes/planning.py +19 -5
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/api/routes/projects.py +84 -2
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/api/routes/templates.py +115 -2
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/api/routes/workflows.py +22 -22
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/cli.py +21 -6
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/auth.py +346 -171
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/database.py +615 -167
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/executor.py +0 -3
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/loop.py +15 -2
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/loop_templates.py +69 -3
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/planning_service.py +109 -21
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/preview.py +9 -25
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/project_db.py +175 -75
- ralphx-0.3.5/ralphx/core/project_export.py +469 -0
- ralphx-0.3.5/ralphx/core/project_import.py +670 -0
- ralphx-0.3.5/ralphx/core/sample_project.py +430 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/templates.py +46 -9
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/workflow_executor.py +35 -5
- ralphx-0.3.5/ralphx/core/workflow_export.py +606 -0
- ralphx-0.3.5/ralphx/core/workflow_import.py +1149 -0
- ralphx-0.3.5/ralphx/examples/sample_project/DESIGN.md +345 -0
- ralphx-0.3.5/ralphx/examples/sample_project/README.md +37 -0
- ralphx-0.3.5/ralphx/examples/sample_project/guardrails.md +57 -0
- ralphx-0.3.5/ralphx/examples/sample_project/stories.jsonl +10 -0
- ralphx-0.3.5/ralphx/mcp/__init__.py +16 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/mcp/registry.py +3 -3
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/mcp/server.py +99 -29
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/mcp/tools/__init__.py +4 -0
- ralphx-0.3.5/ralphx/mcp/tools/help.py +204 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/mcp/tools/workflows.py +114 -32
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/mcp_server.py +6 -2
- ralphx-0.3.5/ralphx/static/assets/index-0ovNnfOq.css +1 -0
- ralphx-0.3.5/ralphx/static/assets/index-CY9s08ZB.js +251 -0
- ralphx-0.3.5/ralphx/static/assets/index-CY9s08ZB.js.map +1 -0
- ralphx-0.3.5/ralphx/static/index.html +14 -0
- ralphx-0.2.2/ralphx/api/routes/auth.py +0 -226
- ralphx-0.2.2/ralphx/mcp/__init__.py +0 -12
- {ralphx-0.2.2 → ralphx-0.3.5}/.gitignore +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/adapters/__init__.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/adapters/base.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/adapters/claude_cli.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/api/__init__.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/api/routes/__init__.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/api/routes/files.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/api/routes/filesystem.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/api/routes/imports.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/api/routes/items.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/api/routes/logs.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/api/routes/resources.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/api/routes/runs.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/api/routes/stream.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/__init__.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/checkpoint.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/dependencies.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/display.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/doctor.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/global_db.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/guardrails.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/import_manager.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/input_templates.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/logger.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/oauth.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/permission_templates.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/permissions.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/project.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/resources.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/schemas.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/session.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/core/workspace.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/mcp/base.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/mcp/tools/diagnostics.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/mcp/tools/guardrails.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/mcp/tools/imports.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/mcp/tools/items.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/mcp/tools/loops.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/mcp/tools/monitoring.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/mcp/tools/permissions.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/mcp/tools/projects.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/mcp/tools/resources.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/models/__init__.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/models/guardrail.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/models/loop.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/models/project.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/models/run.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/models/session.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/models/work_item.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/stores/__init__.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/templates/guardrails/default.md +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/templates/loop_templates/consumer.md +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/templates/loop_templates/generator.md +0 -0
- {ralphx-0.2.2 → ralphx-0.3.5}/ralphx/templates/loop_templates/hybrid.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ralphx
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.5
|
|
4
4
|
Summary: Autonomous AI loop orchestration for Claude Code - define workflows in YAML, run autonomously, monitor in real-time
|
|
5
5
|
Project-URL: Homepage, https://github.com/jackneil/ralphx
|
|
6
6
|
Project-URL: Repository, https://github.com/jackneil/ralphx
|
|
@@ -34,8 +34,6 @@ Requires-Dist: httpx>=0.24; extra == 'dev'
|
|
|
34
34
|
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
|
|
35
35
|
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
36
36
|
Requires-Dist: ruff>=0.1; extra == 'dev'
|
|
37
|
-
Provides-Extra: mcp
|
|
38
|
-
Requires-Dist: mcp>=0.1; extra == 'mcp'
|
|
39
37
|
Description-Content-Type: text/markdown
|
|
40
38
|
|
|
41
39
|
# RalphX
|
|
@@ -106,7 +104,7 @@ for product development. I'm not technical so please handle everything:
|
|
|
106
104
|
1. Check if I have conda/miniconda installed. If not, install miniconda for my OS.
|
|
107
105
|
2. Create a Python 3.11 environment called "ralphx" and activate it
|
|
108
106
|
3. Install RalphX from PyPI: pip install ralphx
|
|
109
|
-
4. Add RalphX as an MCP server
|
|
107
|
+
4. Add RalphX as an MCP server using the full path to the ralphx binary in the conda env (use the right command for my OS to find it)
|
|
110
108
|
5. Start the RalphX dashboard: ralphx serve
|
|
111
109
|
6. Ask me if I want a desktop shortcut to launch the dashboard. If yes, create
|
|
112
110
|
a shortcut for my OS that uses the full path to the Python executable in the
|
|
@@ -130,10 +128,26 @@ Open `http://localhost:16768` to monitor progress.
|
|
|
130
128
|
|
|
131
129
|
---
|
|
132
130
|
|
|
133
|
-
**Already technical?** Here's the
|
|
131
|
+
**Already technical?** Here's the quick setup:
|
|
134
132
|
|
|
135
133
|
```bash
|
|
136
|
-
|
|
134
|
+
# Create and activate a Python 3.11+ environment:
|
|
135
|
+
conda create -n ralphx python=3.11 -y && conda activate ralphx
|
|
136
|
+
|
|
137
|
+
# Install RalphX:
|
|
138
|
+
pip install ralphx
|
|
139
|
+
|
|
140
|
+
# Add MCP server with full path to ralphx binary:
|
|
141
|
+
|
|
142
|
+
# Linux/Mac:
|
|
143
|
+
claude mcp add ralphx -e PYTHONDONTWRITEBYTECODE=1 -- "$(which ralphx)" mcp
|
|
144
|
+
|
|
145
|
+
# Mac (zsh) - if "which ralphx" fails, first run: conda init zsh && source ~/.zshrc
|
|
146
|
+
|
|
147
|
+
# Windows - first find your path, then use it:
|
|
148
|
+
# CMD: where.exe ralphx
|
|
149
|
+
# PowerShell: (Get-Command ralphx).Source
|
|
150
|
+
claude mcp add ralphx -e PYTHONDONTWRITEBYTECODE=1 -- C:\Users\YOU\miniconda3\envs\ralphx\Scripts\ralphx.exe mcp
|
|
137
151
|
```
|
|
138
152
|
|
|
139
153
|
---
|
|
@@ -226,16 +240,23 @@ Ask Claude: *"Set up a new-product workflow starting from my idea for a task man
|
|
|
226
240
|
For those who prefer to do it themselves:
|
|
227
241
|
|
|
228
242
|
```bash
|
|
229
|
-
#
|
|
230
|
-
#
|
|
231
|
-
|
|
232
|
-
# Create environment and install
|
|
243
|
+
# Create a virtual environment (use conda, venv, or your preferred tool)
|
|
244
|
+
# Example with conda:
|
|
233
245
|
conda create -n ralphx python=3.11 -y
|
|
234
246
|
conda activate ralphx
|
|
247
|
+
|
|
248
|
+
# Or with venv:
|
|
249
|
+
# python3 -m venv ~/.venvs/ralphx && source ~/.venvs/ralphx/bin/activate
|
|
250
|
+
|
|
251
|
+
# Install RalphX
|
|
235
252
|
pip install ralphx
|
|
236
253
|
|
|
237
|
-
# Set up MCP so Claude can control RalphX
|
|
238
|
-
|
|
254
|
+
# Set up MCP so Claude can control RalphX (uses full path so it works outside the env)
|
|
255
|
+
# Linux/Mac:
|
|
256
|
+
claude mcp add ralphx -e PYTHONDONTWRITEBYTECODE=1 -- "$(which ralphx)" mcp
|
|
257
|
+
# Mac (zsh): if "which" fails, run: conda init zsh && source ~/.zshrc
|
|
258
|
+
# Windows: find path with "where.exe ralphx" (CMD) or "(Get-Command ralphx).Source" (PowerShell)
|
|
259
|
+
# then: claude mcp add ralphx -e PYTHONDONTWRITEBYTECODE=1 -- C:\Users\YOU\...\ralphx.exe mcp
|
|
239
260
|
|
|
240
261
|
# Start the dashboard
|
|
241
262
|
ralphx serve
|
|
@@ -296,6 +317,7 @@ Claude gets full access to RalphX:
|
|
|
296
317
|
- [SDLC Workflows](design/SDLC_WORKFLOWS.md) - All workflow templates explained
|
|
297
318
|
- [Design Overview](design/DESIGN.md) - Architecture deep dive
|
|
298
319
|
- [Loop Schema](design/LOOP_SCHEMA.md) - Configuration reference
|
|
320
|
+
- [Backup & Import Guide](docs/BACKUP_AND_IMPORT.md) - Export workflows, import items
|
|
299
321
|
|
|
300
322
|
---
|
|
301
323
|
|
|
@@ -66,7 +66,7 @@ for product development. I'm not technical so please handle everything:
|
|
|
66
66
|
1. Check if I have conda/miniconda installed. If not, install miniconda for my OS.
|
|
67
67
|
2. Create a Python 3.11 environment called "ralphx" and activate it
|
|
68
68
|
3. Install RalphX from PyPI: pip install ralphx
|
|
69
|
-
4. Add RalphX as an MCP server
|
|
69
|
+
4. Add RalphX as an MCP server using the full path to the ralphx binary in the conda env (use the right command for my OS to find it)
|
|
70
70
|
5. Start the RalphX dashboard: ralphx serve
|
|
71
71
|
6. Ask me if I want a desktop shortcut to launch the dashboard. If yes, create
|
|
72
72
|
a shortcut for my OS that uses the full path to the Python executable in the
|
|
@@ -90,10 +90,26 @@ Open `http://localhost:16768` to monitor progress.
|
|
|
90
90
|
|
|
91
91
|
---
|
|
92
92
|
|
|
93
|
-
**Already technical?** Here's the
|
|
93
|
+
**Already technical?** Here's the quick setup:
|
|
94
94
|
|
|
95
95
|
```bash
|
|
96
|
-
|
|
96
|
+
# Create and activate a Python 3.11+ environment:
|
|
97
|
+
conda create -n ralphx python=3.11 -y && conda activate ralphx
|
|
98
|
+
|
|
99
|
+
# Install RalphX:
|
|
100
|
+
pip install ralphx
|
|
101
|
+
|
|
102
|
+
# Add MCP server with full path to ralphx binary:
|
|
103
|
+
|
|
104
|
+
# Linux/Mac:
|
|
105
|
+
claude mcp add ralphx -e PYTHONDONTWRITEBYTECODE=1 -- "$(which ralphx)" mcp
|
|
106
|
+
|
|
107
|
+
# Mac (zsh) - if "which ralphx" fails, first run: conda init zsh && source ~/.zshrc
|
|
108
|
+
|
|
109
|
+
# Windows - first find your path, then use it:
|
|
110
|
+
# CMD: where.exe ralphx
|
|
111
|
+
# PowerShell: (Get-Command ralphx).Source
|
|
112
|
+
claude mcp add ralphx -e PYTHONDONTWRITEBYTECODE=1 -- C:\Users\YOU\miniconda3\envs\ralphx\Scripts\ralphx.exe mcp
|
|
97
113
|
```
|
|
98
114
|
|
|
99
115
|
---
|
|
@@ -186,16 +202,23 @@ Ask Claude: *"Set up a new-product workflow starting from my idea for a task man
|
|
|
186
202
|
For those who prefer to do it themselves:
|
|
187
203
|
|
|
188
204
|
```bash
|
|
189
|
-
#
|
|
190
|
-
#
|
|
191
|
-
|
|
192
|
-
# Create environment and install
|
|
205
|
+
# Create a virtual environment (use conda, venv, or your preferred tool)
|
|
206
|
+
# Example with conda:
|
|
193
207
|
conda create -n ralphx python=3.11 -y
|
|
194
208
|
conda activate ralphx
|
|
209
|
+
|
|
210
|
+
# Or with venv:
|
|
211
|
+
# python3 -m venv ~/.venvs/ralphx && source ~/.venvs/ralphx/bin/activate
|
|
212
|
+
|
|
213
|
+
# Install RalphX
|
|
195
214
|
pip install ralphx
|
|
196
215
|
|
|
197
|
-
# Set up MCP so Claude can control RalphX
|
|
198
|
-
|
|
216
|
+
# Set up MCP so Claude can control RalphX (uses full path so it works outside the env)
|
|
217
|
+
# Linux/Mac:
|
|
218
|
+
claude mcp add ralphx -e PYTHONDONTWRITEBYTECODE=1 -- "$(which ralphx)" mcp
|
|
219
|
+
# Mac (zsh): if "which" fails, run: conda init zsh && source ~/.zshrc
|
|
220
|
+
# Windows: find path with "where.exe ralphx" (CMD) or "(Get-Command ralphx).Source" (PowerShell)
|
|
221
|
+
# then: claude mcp add ralphx -e PYTHONDONTWRITEBYTECODE=1 -- C:\Users\YOU\...\ralphx.exe mcp
|
|
199
222
|
|
|
200
223
|
# Start the dashboard
|
|
201
224
|
ralphx serve
|
|
@@ -256,6 +279,7 @@ Claude gets full access to RalphX:
|
|
|
256
279
|
- [SDLC Workflows](design/SDLC_WORKFLOWS.md) - All workflow templates explained
|
|
257
280
|
- [Design Overview](design/DESIGN.md) - Architecture deep dive
|
|
258
281
|
- [Loop Schema](design/LOOP_SCHEMA.md) - Configuration reference
|
|
282
|
+
- [Backup & Import Guide](docs/BACKUP_AND_IMPORT.md) - Export workflows, import items
|
|
259
283
|
|
|
260
284
|
---
|
|
261
285
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ralphx"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.5"
|
|
8
8
|
description = "Autonomous AI loop orchestration for Claude Code - define workflows in YAML, run autonomously, monitor in real-time"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -53,9 +53,6 @@ dev = [
|
|
|
53
53
|
"httpx>=0.24",
|
|
54
54
|
"ruff>=0.1",
|
|
55
55
|
]
|
|
56
|
-
mcp = [
|
|
57
|
-
"mcp>=0.1",
|
|
58
|
-
]
|
|
59
56
|
|
|
60
57
|
[project.scripts]
|
|
61
58
|
ralphx = "ralphx.cli:main"
|
|
@@ -67,8 +64,18 @@ Documentation = "https://github.com/jackneil/ralphx#readme"
|
|
|
67
64
|
|
|
68
65
|
[tool.hatch.build.targets.wheel]
|
|
69
66
|
packages = ["ralphx"]
|
|
70
|
-
#
|
|
71
|
-
|
|
67
|
+
# Exclude static and examples - they're added explicitly via force-include
|
|
68
|
+
# to avoid duplicate entries when these dirs exist during CI build
|
|
69
|
+
exclude = [
|
|
70
|
+
"ralphx/static",
|
|
71
|
+
"ralphx/static/**",
|
|
72
|
+
"ralphx/examples",
|
|
73
|
+
"ralphx/examples/**",
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
[tool.hatch.build.targets.wheel.force-include]
|
|
77
|
+
"ralphx/static" = "ralphx/static"
|
|
78
|
+
"ralphx/examples" = "ralphx/examples"
|
|
72
79
|
|
|
73
80
|
[tool.hatch.build.targets.sdist]
|
|
74
81
|
include = [
|
|
@@ -77,6 +84,10 @@ include = [
|
|
|
77
84
|
"/LICENSE",
|
|
78
85
|
]
|
|
79
86
|
|
|
87
|
+
[tool.hatch.build.targets.sdist.force-include]
|
|
88
|
+
"ralphx/static" = "ralphx/static"
|
|
89
|
+
"ralphx/examples" = "ralphx/examples"
|
|
90
|
+
|
|
80
91
|
[tool.ruff]
|
|
81
92
|
line-length = 100
|
|
82
93
|
target-version = "py310"
|
|
@@ -27,7 +27,7 @@ from fastapi.responses import FileResponse, JSONResponse
|
|
|
27
27
|
from fastapi.staticfiles import StaticFiles
|
|
28
28
|
|
|
29
29
|
from ralphx import __version__
|
|
30
|
-
from ralphx.api.routes import auth, config, files, filesystem, imports, items, logs, loops, planning, projects, resources, runs, stream, templates, workflows
|
|
30
|
+
from ralphx.api.routes import auth, config, export_import, files, filesystem, imports, items, logs, loops, planning, projects, resources, runs, stream, templates, workflows
|
|
31
31
|
from ralphx.core.auth import restore_orphaned_backup
|
|
32
32
|
from ralphx.core.workspace import ensure_workspace
|
|
33
33
|
|
|
@@ -123,10 +123,17 @@ async def _stale_run_cleanup_loop():
|
|
|
123
123
|
async def lifespan(app: FastAPI):
|
|
124
124
|
"""Application lifespan events."""
|
|
125
125
|
from ralphx.core.logger import system_log
|
|
126
|
+
from ralphx.core.sample_project import ensure_sample_project_created
|
|
126
127
|
|
|
127
128
|
# Startup
|
|
128
129
|
ensure_workspace()
|
|
129
130
|
|
|
131
|
+
# Create sample project on first run
|
|
132
|
+
try:
|
|
133
|
+
ensure_sample_project_created()
|
|
134
|
+
except Exception as e:
|
|
135
|
+
logger.warning(f"Sample project creation failed: {e}")
|
|
136
|
+
|
|
130
137
|
# Restore any orphaned credential backups from previous crashes
|
|
131
138
|
# This ensures user's main credentials are ALWAYS restored
|
|
132
139
|
restore_orphaned_backup()
|
|
@@ -278,6 +285,7 @@ app.include_router(logs.router, prefix="/api", tags=["logs"])
|
|
|
278
285
|
app.include_router(config.router, prefix="/api/projects", tags=["config"])
|
|
279
286
|
app.include_router(workflows.router, prefix="/api/projects/{slug}", tags=["workflows"])
|
|
280
287
|
app.include_router(planning.router, prefix="/api/projects/{slug}", tags=["planning"])
|
|
288
|
+
app.include_router(export_import.router, prefix="/api/projects/{slug}", tags=["export-import"])
|
|
281
289
|
|
|
282
290
|
|
|
283
291
|
# Root endpoint
|