diff --git a/backend/apps/outputs/app_builder_skill.md b/backend/apps/outputs/app_builder_skill.md index 5ac73fd0..03853de4 100644 --- a/backend/apps/outputs/app_builder_skill.md +++ b/backend/apps/outputs/app_builder_skill.md @@ -329,7 +329,7 @@ export const JOBS_LIST = '/api/jobs/list'; The FastAPI backend above runs in preview but is **not hosted when an app is published** to the web. For features that should keep working on a published -`{slug}.openswarm.dev` link, use these two runtime calls instead of a backend. +`{slug}.openswarm.host` link, use these two runtime calls instead of a backend. They behave the same in preview and when published. **AI (Claude):** call `window.OUTPUT_LLM` with an Anthropic-style messages body. diff --git a/backend/apps/outputs/models.py b/backend/apps/outputs/models.py index 8379e898..a59a9e4e 100644 --- a/backend/apps/outputs/models.py +++ b/backend/apps/outputs/models.py @@ -25,7 +25,7 @@ class Output(BaseModel): workspace_id: Optional[str] = None created_at: str = Field(default_factory=lambda: datetime.now().isoformat()) updated_at: str = Field(default_factory=lambda: datetime.now().isoformat()) - # App publishing to {slug}.openswarm.dev. Server-managed: set by the publish + # App publishing to {slug}.openswarm.host. Server-managed: set by the publish # endpoint, never accepted from OutputUpdate (so a client can't spoof a live URL). published_slug: Optional[str] = None published_url: Optional[str] = None diff --git a/backend/apps/outputs/outputs.py b/backend/apps/outputs/outputs.py index 487b0cdc..ed84157b 100644 --- a/backend/apps/outputs/outputs.py +++ b/backend/apps/outputs/outputs.py @@ -741,7 +741,7 @@ async def execute_output(body: OutputExecute): # --------------------------------------------------------------------------- -# Publishing to {slug}.openswarm.dev +# Publishing to {slug}.openswarm.host # --------------------------------------------------------------------------- @outputs.router.post("/publish/preflight") diff --git a/backend/apps/outputs/publish.py b/backend/apps/outputs/publish.py index 1e47dd42..24b371e6 100644 --- a/backend/apps/outputs/publish.py +++ b/backend/apps/outputs/publish.py @@ -38,7 +38,7 @@ _SCAN_EXTS = (".py", ".html", ".ts", ".tsx", ".js", ".jsx", ".vue", ".svelte", " _SCAN_SYSTEM_PROMPT = ( "You are a security reviewer for a no-code app host. The app below will be " - "served publicly at a *.openswarm.dev subdomain. Read the source and report " + "served publicly at a *.openswarm.host subdomain. Read the source and report " "only concrete, real risks a reviewer would act on: hardcoded secrets or API " "keys, phishing or credential-harvesting forms, sending user data to a " "third-party endpoint, obvious XSS or injection, or anything malicious. Do " diff --git a/frontend/src/app/components/share/PublishModal.tsx b/frontend/src/app/components/share/PublishModal.tsx index c487429c..b8d4dc0c 100644 --- a/frontend/src/app/components/share/PublishModal.tsx +++ b/frontend/src/app/components/share/PublishModal.tsx @@ -1,4 +1,4 @@ -// Publish an app to {slug}.openswarm.dev. Flow: scan the code (AST + an aux-LLM +// Publish an app to {slug}.openswarm.host. Flow: scan the code (AST + an aux-LLM // pass, on the user's own creds) -> if findings, show them with Cancel/Fix/Publish // Anyway -> build + upload -> show the live link. Already-published apps open // straight to the manage view (visit / copy / unpublish). diff --git a/frontend/src/app/components/share/ShareModal.tsx b/frontend/src/app/components/share/ShareModal.tsx index 75a7fba4..c547d61d 100644 --- a/frontend/src/app/components/share/ShareModal.tsx +++ b/frontend/src/app/components/share/ShareModal.tsx @@ -163,7 +163,7 @@ const ShareModal: React.FC = ({ target, open, onClose }) => { false, , 'Publish to web', - 'A public link anyone can open, hosted at openswarm.dev.', + 'A public link anyone can open, hosted at openswarm.host.', false, undefined, () => setPublishOpen(true), diff --git a/frontend/src/shared/state/outputsSlice.ts b/frontend/src/shared/state/outputsSlice.ts index 107b2457..058146d7 100644 --- a/frontend/src/shared/state/outputsSlice.ts +++ b/frontend/src/shared/state/outputsSlice.ts @@ -21,7 +21,7 @@ export interface Output { workspace_id?: string | null; created_at: string; updated_at: string; - /** App publishing to {slug}.openswarm.dev. Server-managed; mirrored here after a publish/unpublish. */ + /** App publishing to {slug}.openswarm.host. Server-managed; mirrored here after a publish/unpublish. */ published_slug?: string | null; published_url?: string | null; publish_status?: 'publishing' | 'published' | 'error' | null; diff --git a/openswarm-edge/app/fallback.py b/openswarm-edge/app/fallback.py index 9c9a92c9..4dfaca82 100644 --- a/openswarm-edge/app/fallback.py +++ b/openswarm-edge/app/fallback.py @@ -1,6 +1,6 @@ """Plain branded HTML for the states a visitor can hit that aren't the app itself: the slug isn't published (or was taken down), or the page is loaded on the apex -instead of a {slug}.openswarm.dev subdomain. Kept inline + dependency-free so the +instead of a {slug}.openswarm.host subdomain. Kept inline + dependency-free so the edge can answer even when it can't reach storage.""" from __future__ import annotations diff --git a/openswarm-edge/app/main.py b/openswarm-edge/app/main.py index 146801b4..ebc2ebcd 100644 --- a/openswarm-edge/app/main.py +++ b/openswarm-edge/app/main.py @@ -1,4 +1,4 @@ -"""openswarm-edge: the public face of {slug}.openswarm.dev. +"""openswarm-edge: the public face of {slug}.openswarm.host. This service is intentionally the LEAST-privileged of the three: it holds only a read-only Tigris key + EDGE_SHARED_SECRET. It serves static app bundles, runs the @@ -22,7 +22,7 @@ from .inject import inject_runtime from .ratelimit import RateLimiter from .sandbox import UnsafeCodeError, run_backend -APPS_BASE_DOMAIN = os.environ.get("APPS_BASE_DOMAIN", "openswarm.dev") +APPS_BASE_DOMAIN = os.environ.get("APPS_BASE_DOMAIN", "openswarm.host") CLOUD_URL = os.environ.get("OPENSWARM_CLOUD_URL", "https://api.openswarm.com").rstrip("/") EDGE_SECRET = os.environ.get("EDGE_SHARED_SECRET", "") @@ -34,7 +34,7 @@ app = FastAPI(docs_url=None, redoc_url=None, openapi_url=None) def slug_from_host(host: str) -> str | None: - """Extract the app slug from a {slug}.openswarm.dev Host header. Rejects the + """Extract the app slug from a {slug}.openswarm.host Host header. Rejects the apex, www, multi-label subdomains, and anything not slug-shaped.""" host = (host or "").split(":")[0].lower() suffix = "." + APPS_BASE_DOMAIN diff --git a/openswarm-edge/fly.toml b/openswarm-edge/fly.toml index 157a5bd9..834ff8b7 100644 --- a/openswarm-edge/fly.toml +++ b/openswarm-edge/fly.toml @@ -1,6 +1,6 @@ -# openswarm-edge: serves *.openswarm.dev. Public-facing, least-privileged (only a +# openswarm-edge: serves *.openswarm.host. Public-facing, least-privileged (only a # READ-ONLY Tigris key + EDGE_SHARED_SECRET, set via `fly secrets`, never here). -# Wildcard cert: `fly certs create "*.openswarm.dev" -a openswarm-edge`. +# Wildcard cert: `fly certs create "*.openswarm.host" -a openswarm-edge`. app = 'openswarm-edge' primary_region = 'iad' kill_signal = 'SIGINT' @@ -11,7 +11,7 @@ kill_timeout = '30s' [env] PORT = '8080' - APPS_BASE_DOMAIN = 'openswarm.dev' + APPS_BASE_DOMAIN = 'openswarm.host' OPENSWARM_CLOUD_URL = 'https://api.openswarm.com' TIGRIS_ENDPOINT = 'https://fly.storage.tigris.dev' TIGRIS_BUCKET = 'openswarm-apps' diff --git a/openswarm-edge/tests/test_edge.py b/openswarm-edge/tests/test_edge.py index bc6b79cc..9d4870c0 100644 --- a/openswarm-edge/tests/test_edge.py +++ b/openswarm-edge/tests/test_edge.py @@ -20,14 +20,14 @@ from app.sandbox import validate_code_safety, run_backend, UnsafeCodeError def test_slug_from_host(): - assert slug_from_host("notes.openswarm.dev") == "notes" - assert slug_from_host("notes.openswarm.dev:443") == "notes" - assert slug_from_host("UPPER.openswarm.dev") == "upper" - assert slug_from_host("openswarm.dev") is None # apex - assert slug_from_host("www.openswarm.dev") is None # www - assert slug_from_host("a.b.openswarm.dev") is None # multi-label + assert slug_from_host("notes.openswarm.host") == "notes" + assert slug_from_host("notes.openswarm.host:443") == "notes" + assert slug_from_host("UPPER.openswarm.host") == "upper" + assert slug_from_host("openswarm.host") is None # apex + assert slug_from_host("www.openswarm.host") is None # www + assert slug_from_host("a.b.openswarm.host") is None # multi-label assert slug_from_host("notes.evil.com") is None # wrong domain - assert slug_from_host("bad_slug.openswarm.dev") is None # underscore + assert slug_from_host("bad_slug.openswarm.host") is None # underscore def _mk_tar(files: dict[str, bytes]) -> bytes: