From 4b81f25ec0b657460b5702bf9babd0397e945345 Mon Sep 17 00:00:00 2001
From: nbkdoesntknowcoding
Date: Thu, 9 Jul 2026 21:53:41 +0530
Subject: [PATCH 1/2] =?UTF-8?q?fix(web):=20restore=20Settings=20=E2=86=92?=
=?UTF-8?q?=20Community=20tab=20(self-host)=20+=20add=20get-key=20email=20?=
=?UTF-8?q?form?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reverts the tab removal (#85) for the PUBLIC/self-host build: on self-host the
operator IS the user, and this tab is their only in-app path to enable
publishing. Restores the nav entry, the page, and the CommunitySettings
component, and adds a 'Get a free community key' email form — it posts to the
hosted licensing service (PUBLIC_COMMUNITY_LICENSE_URL) which signs + emails a
free community key the operator then sets as COMMUNITY_HUB_KEY.
Browse/import needs no key and already works out of the box; this is only the
publish-setup path. Cloud (private repo) intentionally does NOT carry this tab.
Co-Authored-By: Claude Opus 4.8
Signed-off-by: nbkdoesntknowcoding
---
apps/web/src/components/flows/FlowHeader.tsx | 2 +-
.../components/settings/CommunitySettings.tsx | 137 ++++++++++++++++++
apps/web/src/layouts/SettingsLayout.astro | 1 +
.../src/pages/app/settings/community.astro | 17 +++
4 files changed, 156 insertions(+), 1 deletion(-)
create mode 100644 apps/web/src/components/settings/CommunitySettings.tsx
create mode 100644 apps/web/src/pages/app/settings/community.astro
diff --git a/apps/web/src/components/flows/FlowHeader.tsx b/apps/web/src/components/flows/FlowHeader.tsx
index f7e510fcd..750b35671 100644
--- a/apps/web/src/components/flows/FlowHeader.tsx
+++ b/apps/web/src/components/flows/FlowHeader.tsx
@@ -259,7 +259,7 @@ function PublishToCommunityModal({ flow, onClose }: { flow: Flow; onClose: () =>
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ tags }),
});
- if (res.status === 400) { setErr('Publishing to the community hub is not configured on this instance.'); return; }
+ if (res.status === 400) { setErr('No community key configured. Get one in Settings → Community, then set COMMUNITY_HUB_KEY.'); return; }
if (res.status === 409) { setErr('Publish a version of this flow first, then publish it to the community.'); return; }
if (res.status === 403) { setErr('Only workspace owners, admins, and editors can publish.'); return; }
if (!res.ok) { setErr('Publish failed. Try again.'); return; }
diff --git a/apps/web/src/components/settings/CommunitySettings.tsx b/apps/web/src/components/settings/CommunitySettings.tsx
new file mode 100644
index 000000000..962b04eae
--- /dev/null
+++ b/apps/web/src/components/settings/CommunitySettings.tsx
@@ -0,0 +1,137 @@
+/**
+ * Community settings (Community Flows — Phase 3, P3-6). Self-host surface.
+ *
+ * Shows this instance's community-hub status. The publish credential
+ * (COMMUNITY_HUB_KEY) is an instance env var, so setting it stays out-of-band
+ * (env + restart) — there is no browser-writable secret here by design. But we
+ * DO surface a "get a free key" action: it emails a signed community-license key
+ * (via our hosted licensing service) that the operator then sets as
+ * COMMUNITY_HUB_KEY. This is the self-hoster's setup path for publishing.
+ */
+import { type JSX, useEffect, useState } from 'react';
+
+const ink = 'var(--ink, #e7e7e9)';
+const soft = 'var(--ink-soft, #a1a1aa)';
+const muted = 'var(--ink-muted, #71717a)';
+const line = 'var(--line, rgba(255,255,255,0.1))';
+const surface = 'var(--surface, rgba(255,255,255,0.02))';
+const mono = { fontFamily: 'var(--mono, monospace)', fontSize: 12 } as const;
+
+// OUR hosted licensing service — the only outbound call, by explicit user action.
+const LICENSE_SERVICE_URL =
+ (import.meta.env.PUBLIC_COMMUNITY_LICENSE_URL as string | undefined) ?? 'https://mnema.app/community-license';
+
+interface Config {
+ enabled: boolean;
+ hub_url: string;
+ can_publish: boolean;
+}
+
+function Row({ label, children }: { label: string; children: React.ReactNode }): JSX.Element {
+ return (
+
+ Browsing and importing community flows works out of the box. To publish your own flows,
+ this instance needs a community-license key set as the COMMUNITY_HUB_KEY environment
+ variable. To point at a different hub or disable the feature entirely, set{' '}
+ COMMUNITY_HUB_URL / COMMUNITY_HUB_ENABLED.
+
+
+ {!cfg.can_publish && (
+
+
Get a free community key
+ {keyState === 'sent' ? (
+
+ Check your inbox for the signed key, then set it as COMMUNITY_HUB_KEY in this
+ instance's environment and restart the API. Publishing turns on once it's set.
+
+ ) : (
+ <>
+
+ We'll email you a free signed community-license key. Set it as COMMUNITY_HUB_KEY to
+ enable publishing from this instance.
+
Browse and import community flows, and publish your own for others to use.
+
+
+
From 9007c8b781760318b9ee3e813f47c2d91ee80793 Mon Sep 17 00:00:00 2001
From: nbkdoesntknowcoding
Date: Thu, 9 Jul 2026 21:59:35 +0530
Subject: [PATCH 2/2] fix(web): clearer redeem placeholder + point Community
tab at Billing for license redemption
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- RedeemLicense: the placeholder implied only the MNEMA-XXXX admin-code format,
but community-license keys are long signed strings (the route accepts both).
Neutral placeholder + copy that names both.
- CommunitySettings: add a pointer clarifying that unlocking history/export is a
separate per-workspace step done under Settings → Billing (vs the instance
publish key here).
Co-Authored-By: Claude Opus 4.8
Signed-off-by: nbkdoesntknowcoding
---
apps/web/src/components/settings/CommunitySettings.tsx | 6 ++++++
apps/web/src/components/settings/RedeemLicense.tsx | 4 ++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/apps/web/src/components/settings/CommunitySettings.tsx b/apps/web/src/components/settings/CommunitySettings.tsx
index 962b04eae..5af6fac7f 100644
--- a/apps/web/src/components/settings/CommunitySettings.tsx
+++ b/apps/web/src/components/settings/CommunitySettings.tsx
@@ -100,6 +100,12 @@ export function CommunitySettings(): JSX.Element {
COMMUNITY_HUB_URL / COMMUNITY_HUB_ENABLED.
+
+ Looking to unlock version history and document export? That's a separate,
+ per-workspace step — redeem a community-license key under{' '}
+ Settings → Billing.
+