ralphx 0.2.2__tar.gz → 0.3.4__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.4}/PKG-INFO +2 -1
- {ralphx-0.2.2 → ralphx-0.3.4}/README.md +1 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/pyproject.toml +17 -3
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/__init__.py +1 -1
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/api/main.py +9 -1
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/api/routes/auth.py +56 -0
- ralphx-0.3.4/ralphx/api/routes/export_import.py +798 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/api/routes/projects.py +84 -2
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/api/routes/templates.py +113 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/api/routes/workflows.py +21 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/cli.py +17 -5
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/database.py +27 -3
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/loop_templates.py +66 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/project_db.py +51 -3
- ralphx-0.3.4/ralphx/core/project_export.py +473 -0
- ralphx-0.3.4/ralphx/core/project_import.py +685 -0
- ralphx-0.3.4/ralphx/core/sample_project.py +434 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/templates.py +37 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/workflow_executor.py +35 -5
- ralphx-0.3.4/ralphx/core/workflow_export.py +609 -0
- ralphx-0.3.4/ralphx/core/workflow_import.py +1173 -0
- ralphx-0.3.4/ralphx/examples/sample_project/DESIGN.md +345 -0
- ralphx-0.3.4/ralphx/examples/sample_project/README.md +37 -0
- ralphx-0.3.4/ralphx/examples/sample_project/guardrails.md +57 -0
- ralphx-0.3.4/ralphx/examples/sample_project/stories.jsonl +10 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/mcp/server.py +99 -29
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/mcp/tools/__init__.py +4 -0
- ralphx-0.3.4/ralphx/mcp/tools/help.py +204 -0
- ralphx-0.3.4/ralphx/static/assets/index-CcRDyY3b.css +1 -0
- ralphx-0.3.4/ralphx/static/assets/index-CcxfTosc.js +251 -0
- ralphx-0.3.4/ralphx/static/assets/index-CcxfTosc.js.map +1 -0
- ralphx-0.3.4/ralphx/static/index.html +14 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/.gitignore +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/adapters/__init__.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/adapters/base.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/adapters/claude_cli.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/api/__init__.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/api/routes/__init__.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/api/routes/config.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/api/routes/files.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/api/routes/filesystem.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/api/routes/imports.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/api/routes/items.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/api/routes/logs.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/api/routes/loops.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/api/routes/planning.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/api/routes/resources.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/api/routes/runs.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/api/routes/stream.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/__init__.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/auth.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/checkpoint.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/dependencies.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/display.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/doctor.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/executor.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/global_db.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/guardrails.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/import_manager.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/input_templates.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/logger.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/loop.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/oauth.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/permission_templates.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/permissions.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/planning_service.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/preview.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/project.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/resources.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/schemas.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/session.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/core/workspace.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/mcp/__init__.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/mcp/base.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/mcp/registry.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/mcp/tools/diagnostics.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/mcp/tools/guardrails.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/mcp/tools/imports.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/mcp/tools/items.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/mcp/tools/loops.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/mcp/tools/monitoring.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/mcp/tools/permissions.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/mcp/tools/projects.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/mcp/tools/resources.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/mcp/tools/workflows.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/mcp_server.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/models/__init__.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/models/guardrail.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/models/loop.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/models/project.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/models/run.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/models/session.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/models/work_item.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/stores/__init__.py +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/templates/guardrails/default.md +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/templates/loop_templates/consumer.md +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/ralphx/templates/loop_templates/generator.md +0 -0
- {ralphx-0.2.2 → ralphx-0.3.4}/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.4
|
|
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
|
|
@@ -296,6 +296,7 @@ Claude gets full access to RalphX:
|
|
|
296
296
|
- [SDLC Workflows](design/SDLC_WORKFLOWS.md) - All workflow templates explained
|
|
297
297
|
- [Design Overview](design/DESIGN.md) - Architecture deep dive
|
|
298
298
|
- [Loop Schema](design/LOOP_SCHEMA.md) - Configuration reference
|
|
299
|
+
- [Backup & Import Guide](docs/BACKUP_AND_IMPORT.md) - Export workflows, import items
|
|
299
300
|
|
|
300
301
|
---
|
|
301
302
|
|
|
@@ -256,6 +256,7 @@ Claude gets full access to RalphX:
|
|
|
256
256
|
- [SDLC Workflows](design/SDLC_WORKFLOWS.md) - All workflow templates explained
|
|
257
257
|
- [Design Overview](design/DESIGN.md) - Architecture deep dive
|
|
258
258
|
- [Loop Schema](design/LOOP_SCHEMA.md) - Configuration reference
|
|
259
|
+
- [Backup & Import Guide](docs/BACKUP_AND_IMPORT.md) - Export workflows, import items
|
|
259
260
|
|
|
260
261
|
---
|
|
261
262
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ralphx"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.4"
|
|
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"
|
|
@@ -67,8 +67,18 @@ Documentation = "https://github.com/jackneil/ralphx#readme"
|
|
|
67
67
|
|
|
68
68
|
[tool.hatch.build.targets.wheel]
|
|
69
69
|
packages = ["ralphx"]
|
|
70
|
-
#
|
|
71
|
-
|
|
70
|
+
# Exclude static and examples - they're added explicitly via force-include
|
|
71
|
+
# to avoid duplicate entries when these dirs exist during CI build
|
|
72
|
+
exclude = [
|
|
73
|
+
"ralphx/static",
|
|
74
|
+
"ralphx/static/**",
|
|
75
|
+
"ralphx/examples",
|
|
76
|
+
"ralphx/examples/**",
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
[tool.hatch.build.targets.wheel.force-include]
|
|
80
|
+
"ralphx/static" = "ralphx/static"
|
|
81
|
+
"ralphx/examples" = "ralphx/examples"
|
|
72
82
|
|
|
73
83
|
[tool.hatch.build.targets.sdist]
|
|
74
84
|
include = [
|
|
@@ -77,6 +87,10 @@ include = [
|
|
|
77
87
|
"/LICENSE",
|
|
78
88
|
]
|
|
79
89
|
|
|
90
|
+
[tool.hatch.build.targets.sdist.force-include]
|
|
91
|
+
"ralphx/static" = "ralphx/static"
|
|
92
|
+
"ralphx/examples" = "ralphx/examples"
|
|
93
|
+
|
|
80
94
|
[tool.ruff]
|
|
81
95
|
line-length = 100
|
|
82
96
|
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
|
|
@@ -181,6 +181,62 @@ async def validate_credentials(
|
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
|
|
184
|
+
@router.get("/usage")
|
|
185
|
+
async def get_usage(
|
|
186
|
+
project_path: Optional[str] = Query(
|
|
187
|
+
None, description="Project path for scoped credentials"
|
|
188
|
+
),
|
|
189
|
+
):
|
|
190
|
+
"""Get Claude API usage statistics.
|
|
191
|
+
|
|
192
|
+
Returns 5-hour and 7-day utilization percentages.
|
|
193
|
+
"""
|
|
194
|
+
import httpx
|
|
195
|
+
|
|
196
|
+
project_id = _get_project_id(project_path)
|
|
197
|
+
db = Database()
|
|
198
|
+
creds = db.get_credentials(project_id)
|
|
199
|
+
|
|
200
|
+
if not creds or not creds.get("access_token"):
|
|
201
|
+
return {
|
|
202
|
+
"success": False,
|
|
203
|
+
"error": "No credentials found",
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
try:
|
|
207
|
+
async with httpx.AsyncClient() as client:
|
|
208
|
+
response = await client.get(
|
|
209
|
+
"https://api.anthropic.com/api/oauth/usage",
|
|
210
|
+
headers={
|
|
211
|
+
"Authorization": f"Bearer {creds['access_token']}",
|
|
212
|
+
"anthropic-beta": "oauth-2025-04-20",
|
|
213
|
+
},
|
|
214
|
+
timeout=10.0,
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
if response.status_code != 200:
|
|
218
|
+
return {
|
|
219
|
+
"success": False,
|
|
220
|
+
"error": f"API error: {response.status_code}",
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
data = response.json()
|
|
224
|
+
five_hour = data.get("five_hour", {})
|
|
225
|
+
seven_day = data.get("seven_day", {})
|
|
226
|
+
return {
|
|
227
|
+
"success": True,
|
|
228
|
+
"five_hour_utilization": five_hour.get("utilization"),
|
|
229
|
+
"five_hour_resets_at": five_hour.get("resets_at"),
|
|
230
|
+
"seven_day_utilization": seven_day.get("utilization"),
|
|
231
|
+
"seven_day_resets_at": seven_day.get("resets_at"),
|
|
232
|
+
}
|
|
233
|
+
except Exception as e:
|
|
234
|
+
return {
|
|
235
|
+
"success": False,
|
|
236
|
+
"error": str(e),
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
|
|
184
240
|
@router.get("/credentials/export")
|
|
185
241
|
async def export_credentials(
|
|
186
242
|
scope: Literal["project", "global"] = Query("global"),
|