diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..fcb5694 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,32 @@ +name: ci + +on: + push: + branches: [main] + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + with: + version: 9 + + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: pnpm + + # frozen-lockfile so CI fails if pnpm-lock.yaml is stale + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Typecheck + run: pnpm exec tsc --noEmit + + # next build also runs eslint internally + - name: Build + run: pnpm build diff --git a/README.md b/README.md index 5cdb5f3..d2c947f 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,22 @@ -# Argus +

+ argus +

-A local web app that orchestrates Claude Code agents from a real UI. +

argus

-Workspaces, persistent agent personas, pinned skills, live output streams — all wrapping the `claude` CLI you already have. Uses your existing Max plan, no Anthropic API key required. +

+ A local web app that orchestrates Claude Code agents from a real UI. +

+ +

+ + MIT License + +

+ +--- + +Workspaces, persistent agent personas, pinned skills, live output streams, all wrapping the `claude` CLI you already have. Uses your existing Max plan, no Anthropic API key required. Named after Argus Panoptes, the many-eyed giant who watched everything. diff --git a/package.json b/package.json index 14bff7f..c45578f 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "db:studio": "drizzle-kit studio" }, "pnpm": { - "onlyBuiltDependencies": ["better-sqlite3", "esbuild"] + "onlyBuiltDependencies": ["better-sqlite3", "esbuild"], + "ignoredBuiltDependencies": ["sharp", "unrs-resolver"] }, "dependencies": { "better-sqlite3": "^12.10.0", diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml deleted file mode 100644 index 581a9d5..0000000 --- a/pnpm-workspace.yaml +++ /dev/null @@ -1,3 +0,0 @@ -ignoredBuiltDependencies: - - sharp - - unrs-resolver diff --git a/public/argus-mark.svg b/public/argus-mark.svg new file mode 100644 index 0000000..8100db6 --- /dev/null +++ b/public/argus-mark.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/app/fonts/StackSansNotch-VariableFont_wght.ttf b/src/app/fonts/StackSansNotch-VariableFont_wght.ttf new file mode 100755 index 0000000..f514ec2 Binary files /dev/null and b/src/app/fonts/StackSansNotch-VariableFont_wght.ttf differ diff --git a/src/app/globals.css b/src/app/globals.css index a2dc41e..7a73e48 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,26 +1,19 @@ @import "tailwindcss"; :root { - --background: #ffffff; - --foreground: #171717; + --background: #0a0a0a; + --foreground: #ededed; } @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); - --font-sans: var(--font-geist-sans); - --font-mono: var(--font-geist-mono); -} - -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } + --font-sans: var(--font-stack-sans), ui-sans-serif, system-ui, sans-serif; + --font-mono: var(--font-geist-mono), ui-monospace, SFMono-Regular, monospace; } body { background: var(--background); color: var(--foreground); - font-family: Arial, Helvetica, sans-serif; + font-family: var(--font-stack-sans), ui-sans-serif, system-ui, sans-serif; } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 0689c45..e98efb7 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,11 +1,19 @@ import type { Metadata } from 'next' -import { Geist, Geist_Mono } from 'next/font/google' +import { Geist_Mono } from 'next/font/google' +import localFont from 'next/font/local' import Link from 'next/link' +import { ArgusMark } from '@/components/ArgusMark' import './globals.css' -const geistSans = Geist({ - variable: '--font-geist-sans', - subsets: ['latin'], + +// Stack Sans Notch is the brand display + UI typeface. Variable font +// covers the full 200..700 weight range from one file, so we register +// it once and let Tailwind / CSS pick the weight per element. +const stackSans = localFont({ + src: './fonts/StackSansNotch-VariableFont_wght.ttf', + variable: '--font-stack-sans', + display: 'swap', + weight: '200 700', }) const geistMono = Geist_Mono({ @@ -14,7 +22,7 @@ const geistMono = Geist_Mono({ }) export const metadata: Metadata = { - title: 'Argus · Claude Code workspace', + title: 'argus · claude code workspace', description: 'Local desktop-class workspace for orchestrating Claude Code agents, pinning skills, and watching what they do.', } @@ -27,31 +35,18 @@ export default function RootLayout({ return (
- - Argus - - claude code workspace - + + argus -
diff --git a/src/components/ArgusMark.tsx b/src/components/ArgusMark.tsx new file mode 100644 index 0000000..3e4847c --- /dev/null +++ b/src/components/ArgusMark.tsx @@ -0,0 +1,29 @@ +/** + * Inline SVG of the Argus mark. + * + * Inlined (not loaded as a static asset) so it inherits text color via + * `currentColor` and the parent element can size it via `width` / + * `height` className utilities. Use it anywhere a logo glyph is needed. + */ +export function ArgusMark({ + className = 'h-5 w-5', +}: { + className?: string +}) { + return ( + + + + + + + + + ) +}