Import AITURK IDE 1.0.0-beta.1 from Hermes 63279301; preserve MIT license

This commit is contained in:
yilsem committed 2026-09-05 13:26:46 +03:00
commit 03634b1ca3
11340 files changed
+3442369

No files matched your search

@@ -0,0 +1,13 @@
import { cn } from '../lib/utils'
const assetPath = (path: string) => `${import.meta.env.BASE_URL}${path.replace(/^\/+/, '')}`
// Brand badge: nous-girl mark on a white tile, identical in light/dark.
// Ported from apps/desktop's BrandMark; asset lives in this app's public/.
export function BrandMark({ className, ...props }: React.ComponentProps<'span'>) {
return (
<span className={cn('inline-flex size-14 shrink-0 items-center justify-center bg-white', className)} {...props}>
<img alt="" className="size-full object-contain" src={assetPath('nous-girl.jpg')} />
</span>
)
}
@@ -0,0 +1,81 @@
import { cva, type VariantProps } from 'class-variance-authority'
import { Slot } from 'radix-ui'
import * as React from 'react'
import { cn } from '../lib/utils'
/*
* Button — copied verbatim from apps/desktop/src/components/ui/button.tsx.
*
* We import the desktop's local shadcn-style Button rather than
* @nous-research/ui's <Button>, because the DS Button uses bg-midground /
* text-background-base utilities that resolve to the DS's hardcoded
* gold/brown brand defaults (#ffac02 / #170d02) unless overridden in
* runtime. The desktop never sets those vars; it routes through its
* own --dt-* token chain via shadcn classes like bg-primary. We do
* the same so visuals match exactly.
*/
const buttonVariants = cva(
"inline-flex shrink-0 cursor-pointer items-center justify-center gap-1.5 rounded-[2.5px] text-xs leading-4 font-medium whitespace-nowrap shadow-none transition-all duration-100 outline-none focus-visible:border-ring focus-visible:ring-[0.1875rem] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-default disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
destructive:
'bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40',
outline:
'bg-transparent text-(--ui-text-primary) shadow-[inset_0_0_0_1px_color-mix(in_srgb,var(--ui-stroke-secondary)_50%,transparent)] hover:bg-(--chrome-action-hover) hover:text-(--ui-text-primary)',
secondary:
'bg-(--ui-bg-quaternary) text-(--ui-text-primary) hover:bg-(--chrome-action-hover) hover:text-(--ui-text-primary)',
ghost: 'text-(--ui-text-secondary) hover:bg-(--chrome-action-hover) hover:text-(--ui-text-primary)',
link: 'text-primary underline-offset-4 decoration-current/20 hover:underline',
text: 'text-muted-foreground underline-offset-4 hover:text-foreground hover:underline',
textStrong: 'font-semibold text-muted-foreground underline underline-offset-4 hover:text-foreground'
},
size: {
default: 'px-3 py-1.5 has-[>svg]:px-2.5',
xs: "gap-1 px-2 py-0.5 text-[0.6875rem] leading-4 has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
sm: 'px-2.5 py-1 has-[>svg]:px-2',
lg: 'px-5 py-2 text-sm leading-5 has-[>svg]:px-4',
inline: 'h-auto gap-1 p-0 has-[>svg]:px-0',
icon: 'size-9 rounded-[4px]',
'icon-xs': "size-6 rounded-[4px] [&_svg:not([class*='size-'])]:size-3",
'icon-sm': 'size-8 rounded-[4px]',
'icon-lg': 'size-10 rounded-[4px]'
}
},
defaultVariants: {
variant: 'default',
size: 'default'
}
}
)
interface ButtonProps
extends React.ComponentProps<'button'>,
VariantProps<typeof buttonVariants> {
asChild?: boolean
}
export function Button({
className,
variant = 'default',
size = 'default',
asChild = false,
...props
}: ButtonProps) {
const Comp = asChild ? Slot.Root : 'button'
return (
<Comp
className={cn(buttonVariants({ variant, size }), className)}
data-size={size}
data-slot="button"
data-variant={variant}
{...props}
/>
)
}
export { buttonVariants }
@@ -0,0 +1,36 @@
import { Loader2 } from 'lucide-react'
import { cn } from '../lib/utils'
/*
* HackeryButton — the onboarding "Begin" CTA, ported standalone.
*
* Bracketed [ LABEL ], mono/uppercase, primary accent on a --stroke-nous hairline.
* Lifted from apps/desktop's desktop-onboarding-overlay.tsx (sans the exit-scramble
* choreography, which is overlay-specific). Self-contained: cn + lucide only.
*/
export function HackeryButton({
className,
label,
loading,
...props
}: Omit<React.ComponentProps<'button'>, 'children'> & { label: React.ReactNode; loading?: boolean }) {
return (
<button
{...props}
className={cn(
'group inline-flex cursor-pointer items-center gap-2 rounded-md border border-(--stroke-nous) px-6 py-2.5',
'font-mono text-xs font-semibold uppercase text-primary',
'transition-all duration-150 hover:border-primary/60 hover:bg-primary/[0.06]',
'disabled:pointer-events-none disabled:opacity-50',
className
)}
type="button"
>
<span className="text-primary/40 transition-colors group-hover:text-primary">[</span>
{loading ? <Loader2 className="size-3 animate-spin" /> : null}
<span className="-mr-[0.25em] pl-[0.25em] tracking-[0.25em]">{label}</span>
<span className="text-primary/40 transition-colors group-hover:text-primary">]</span>
</button>
)
}
@@ -0,0 +1,136 @@
import { type ComponentProps, useEffect, useRef } from 'react'
import { cn } from '../lib/utils'
/*
* Loader — the desktop's "Fourier Flow" curve, ported standalone.
*
* The shim can't import apps/desktop's 559-line multi-curve <Loader> (cross-app
* coupling + bundle bloat that defeats the point of a lightweight installer), so
* this is just the one curve the installer uses. Math + tuning lifted verbatim
* from apps/desktop/src/components/ui/loader.tsx ('fourier-flow'); rotation is
* dropped because that curve never rotates. Keep the constants in sync if the
* desktop's curve is retuned.
*/
const TWO_PI = Math.PI * 2
const CURVE = {
durationMs: 2200,
particleCount: 92,
pulseDurationMs: 2000,
strokeWidth: 4.2,
trailSpan: 0.31,
point(progress: number, detailScale: number) {
const t = progress * TWO_PI
const mix = 1 + detailScale * 0.16
const x = 17 * Math.cos(t) + 7.5 * Math.cos(3 * t + 0.6 * mix) + 3.2 * Math.sin(5 * t - 0.4)
const y = 15 * Math.sin(t) + 8.2 * Math.sin(2 * t + 0.25) - 4.2 * Math.cos(4 * t - 0.5 * mix)
return { x: 50 + x, y: 50 + y }
}
}
const norm = (progress: number) => ((progress % 1) + 1) % 1
function detailScaleFor(time: number, phaseOffset: number) {
const p = ((time + phaseOffset * CURVE.pulseDurationMs) % CURVE.pulseDurationMs) / CURVE.pulseDurationMs
return 0.52 + ((Math.sin(p * TWO_PI + 0.55) + 1) / 2) * 0.48
}
function buildPath(detailScale: number, steps: number) {
return Array.from({ length: steps + 1 }, (_, i) => {
const { x, y } = CURVE.point(i / steps, detailScale)
return `${i === 0 ? 'M' : 'L'} ${x.toFixed(2)} ${y.toFixed(2)}`
}).join(' ')
}
function particleFor(index: number, progress: number, detailScale: number, strokeScale: number) {
const tail = index / (CURVE.particleCount - 1)
const { x, y } = CURVE.point(norm(progress - tail * CURVE.trailSpan), detailScale)
const fade = (1 - tail) ** 0.56
return { x, y, opacity: 0.04 + fade * 0.96, radius: (0.9 + fade * 2.7) * strokeScale }
}
interface LoaderProps extends Omit<ComponentProps<'div'>, 'children'> {
label?: string
pathSteps?: number
strokeScale?: number
}
export function Loader({
className,
label = 'Loading',
pathSteps = 240,
role = 'status',
strokeScale = 1,
...props
}: LoaderProps) {
const particleRefs = useRef<Array<SVGCircleElement | null>>([])
const pathRef = useRef<SVGPathElement | null>(null)
useEffect(() => {
let frame = 0
const startedAt = performance.now()
const phaseOffset = Math.random()
particleRefs.current.length = CURVE.particleCount
const render = (now: number) => {
const time = now - startedAt
const progress = ((time + phaseOffset * CURVE.durationMs) % CURVE.durationMs) / CURVE.durationMs
const detailScale = detailScaleFor(time, phaseOffset)
pathRef.current?.setAttribute('d', buildPath(detailScale, pathSteps))
particleRefs.current.forEach((node, index) => {
if (!node) {
return
}
const p = particleFor(index, progress, detailScale, strokeScale)
node.setAttribute('cx', p.x.toFixed(2))
node.setAttribute('cy', p.y.toFixed(2))
node.setAttribute('r', p.radius.toFixed(2))
node.setAttribute('opacity', p.opacity.toFixed(3))
})
frame = window.requestAnimationFrame(render)
}
render(performance.now())
return () => window.cancelAnimationFrame(frame)
}, [pathSteps, strokeScale])
return (
<div
{...props}
aria-label={props['aria-label'] ?? label}
className={cn('inline-grid size-10 place-items-center text-primary', className)}
role={role}
>
<svg aria-hidden="true" className="size-full overflow-visible" fill="none" viewBox="0 0 100 100">
<path
opacity="0.1"
ref={pathRef}
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={CURVE.strokeWidth * strokeScale}
/>
{Array.from({ length: CURVE.particleCount }, (_, index) => (
<circle
fill="currentColor"
key={index}
ref={node => {
particleRefs.current[index] = node
}}
/>
))}
</svg>
</div>
)
}