diff --git a/app/routers/recipes.py b/app/routers/recipes.py
index f27fdb9..84eb714 100644
--- a/app/routers/recipes.py
+++ b/app/routers/recipes.py
@@ -396,3 +396,40 @@ async def ui_discard_recipe(
'
Recipe deleted
'
''
)
+
+
+@router.post("/{recipe_id}/publish")
+async def publish_recipe(
+ recipe_id: str,
+ request: Request,
+ ctx: UserContext = Depends(require_auth),
+ recipe_service: RecipeService = Depends(get_recipe_service),
+):
+ """Publish recipe to L2 and IPFS."""
+ from ..services.cache_service import CacheService
+ from ..dependencies import get_cache_manager
+ import database
+
+ # Verify recipe exists
+ recipe = await recipe_service.get_recipe(recipe_id)
+ if not recipe:
+ raise HTTPException(404, "Recipe not found")
+
+ # Use cache service to publish (recipes are stored in cache)
+ cache_service = CacheService(database, get_cache_manager())
+ ipfs_cid, error = await cache_service.publish_to_l2(
+ content_hash=recipe_id,
+ actor_id=ctx.actor_id,
+ l2_server=ctx.l2_server,
+ auth_token=request.cookies.get("auth_token"),
+ )
+
+ if error:
+ if wants_html(request):
+ return HTMLResponse(f'{error}')
+ raise HTTPException(400, error)
+
+ if wants_html(request):
+ return HTMLResponse(f'Shared: {ipfs_cid[:16]}...')
+
+ return {"ipfs_cid": ipfs_cid, "published": True}
diff --git a/app/routers/runs.py b/app/routers/runs.py
index 9a828df..f7c84e7 100644
--- a/app/routers/runs.py
+++ b/app/routers/runs.py
@@ -440,3 +440,47 @@ async def ui_discard_run(
'Run discarded
'
''
)
+
+
+@router.post("/{run_id}/publish")
+async def publish_run(
+ run_id: str,
+ request: Request,
+ ctx: UserContext = Depends(require_auth),
+ run_service: RunService = Depends(get_run_service),
+):
+ """Publish run output to L2 and IPFS."""
+ from ..services.cache_service import CacheService
+ from ..dependencies import get_cache_manager
+ import database
+
+ run = await run_service.get_run(run_id)
+ if not run:
+ raise HTTPException(404, "Run not found")
+
+ # Check if run has output
+ output_hash = run.get("output_hash")
+ if not output_hash:
+ error = "Run has no output to publish"
+ if wants_html(request):
+ return HTMLResponse(f'{error}')
+ raise HTTPException(400, error)
+
+ # Use cache service to publish the output
+ cache_service = CacheService(database, get_cache_manager())
+ ipfs_cid, error = await cache_service.publish_to_l2(
+ content_hash=output_hash,
+ actor_id=ctx.actor_id,
+ l2_server=ctx.l2_server,
+ auth_token=request.cookies.get("auth_token"),
+ )
+
+ if error:
+ if wants_html(request):
+ return HTMLResponse(f'{error}')
+ raise HTTPException(400, error)
+
+ if wants_html(request):
+ return HTMLResponse(f'Shared: {ipfs_cid[:16]}...')
+
+ return {"ipfs_cid": ipfs_cid, "output_hash": output_hash, "published": True}
diff --git a/app/templates/cache/detail.html b/app/templates/cache/detail.html
index 1eff930..ea2be15 100644
--- a/app/templates/cache/detail.html
+++ b/app/templates/cache/detail.html
@@ -97,14 +97,12 @@
class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded font-medium">
Download
- {% if not cache.ipfs_cid %}
-
- {% endif %}
+
{% endblock %}
diff --git a/app/templates/recipes/detail.html b/app/templates/recipes/detail.html
index 839781a..23255c8 100644
--- a/app/templates/recipes/detail.html
+++ b/app/templates/recipes/detail.html
@@ -77,6 +77,16 @@
+
+
+
+
+
+