Initial import: open-design source for helix-mind.ai distribution
Some checks failed
ci / Validate workspace (push) Successful in 12m32s
landing-page-ci / Validate landing page (push) Successful in 9m41s
landing-page-deploy / Deploy landing page (push) Failing after 5m23s
github-metrics / Generate repository metrics SVG (push) Failing after 2m6s
refresh-contributors-wall / Refresh contributors wall cache bust (push) Failing after 12s

This repository contains the open-design daemon CLI source code, built
and packaged at https://helix-mind.ai/cli/open-design/latest.tgz for use
by the HelixMind /design slash command.

Licenses: Apache-2.0 (root) + MIT (skills/*)
This commit is contained in:
marco
2026-05-06 20:50:24 +02:00
commit 5dd70b5016
1336 changed files with 287186 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
'use client';
import dynamic from 'next/dynamic';
// The product is a fully client-driven SPA — every component reads
// localStorage, window.location, etc. — so we opt out of static-time
// rendering for the entire tree. This keeps `next build --output export`
// from trying to evaluate browser-only code while still emitting a real
// shell HTML the daemon can serve as the SPA fallback.
const App = dynamic(() => import('../../src/App').then((m) => m.App), {
ssr: false,
loading: () => <div className="od-loading-shell">Loading Open Design</div>,
});
export function ClientApp() {
return <App />;
}

View File

@@ -0,0 +1,19 @@
import { ClientApp } from './client-app';
// The whole product is a client-driven SPA: project IDs and file paths are
// unbounded user input, so we route every URL through this single optional
// catch-all and let the existing client router (src/router.ts, which reads
// window.location at runtime) decide what to render.
//
// For `output: 'export'` we return a single empty `slug` so Next.js emits
// one shell HTML at out/index.html; the daemon's SPA fallback (see
// apps/daemon/src/server.ts) serves it for any unknown non-API path so deep links
// still hydrate to the right view. In dev we leave `dynamicParams` at its
// default (true) so `next dev` happily renders /projects/<id> directly.
export function generateStaticParams() {
return [{ slug: [] as string[] }];
}
export default function Page() {
return <ClientApp />;
}

44
apps/web/app/layout.tsx Normal file
View File

@@ -0,0 +1,44 @@
import type { Metadata, Viewport } from 'next';
import type { ReactNode } from 'react';
import { I18nProvider } from '../src/i18n';
import '../src/index.css';
export const metadata: Metadata = {
title: 'Open Design',
icons: {
icon: '/app-icon.svg',
// Safari pinned-tab mask icon — Next.js's Metadata API doesn't have a
// dedicated `mask` field, so we surface it via the generic `other`
// bucket which renders as a raw <link rel="mask-icon" ...>.
other: [{ rel: 'mask-icon', url: '/app-icon.svg', color: '#363636' }],
},
};
export const viewport: Viewport = {
themeColor: '#F4EFE6',
};
/**
* Inline script that runs before React hydrates to apply the saved theme
* preference without a flash of unstyled content. It reads the same
* localStorage key used by `state/config.ts` and sets `data-theme` on
* `<html>` immediately — before any CSS or React paint.
* Keep the accent variable mix ratios in sync with `accentVars()` in
* `src/state/appearance.ts`; this script cannot import application modules.
*/
const themeInitScript = `(function(){try{var c=JSON.parse(localStorage.getItem('open-design:config')||'{}');var t=c.theme;if(t==='light'||t==='dark')document.documentElement.setAttribute('data-theme',t);var a=typeof c.accentColor==='string'&&/^#[0-9a-fA-F]{6}$/.test(c.accentColor.trim())?c.accentColor.trim().toLowerCase():'';if(a){var s=document.documentElement.style;s.setProperty('--accent',a);s.setProperty('--accent-strong','color-mix(in srgb, '+a+' 86%, var(--text-strong))');s.setProperty('--accent-soft','color-mix(in srgb, '+a+' 22%, var(--bg-panel))');s.setProperty('--accent-tint','color-mix(in srgb, '+a+' 12%, var(--bg-panel))');s.setProperty('--accent-hover','color-mix(in srgb, '+a+' 90%, var(--text-strong))');}}catch(e){}})();`;
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang='en' suppressHydrationWarning>
{/* eslint-disable-next-line @next/next/no-sync-scripts */}
<head>
{/* biome-ignore lint/security/noDangerouslySetInnerHtml: intentional theme-init inline script to prevent FOUC */}
<script dangerouslySetInnerHTML={{ __html: themeInitScript }} />
</head>
<body suppressHydrationWarning>
<I18nProvider>{children}</I18nProvider>
</body>
</html>
);
}