diff --git a/Makefile b/Makefile
index d26df428e8..45f0963199 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,6 @@
# Directories
BACKEND_DIR := apps/backend
WEB_DIR := apps/web
-LANDING_DIR := apps/landing
APPS_DIR := apps
# Tools
@@ -46,20 +45,18 @@ help:
@echo " dev Run backend + web via CLI (auto ports)"
@echo " dev-backend Run backend in development mode (port 8080)"
@echo " dev-web Run web app in development mode (port 3000)"
- @echo " dev-landing Run landing page in development mode (port 3001)"
@echo " dev Note: Uses apps/cli launcher (auto ports)"
@echo ""
@echo "Production Commands:"
@echo " start Install deps, build, and start backend + web in production mode"
@echo ""
@echo "Build Commands:"
- @echo " build Build backend, web app, and landing page"
+ @echo " build Build backend and web app"
@echo " build-backend Build backend binary"
@echo " build-web Build web app for production"
- @echo " build-landing Build landing page for production"
@echo ""
@echo "Installation:"
- @echo " install Install all dependencies (backend + web + landing)"
+ @echo " install Install all dependencies (backend + web)"
@echo " install-backend Install backend dependencies"
@echo " install-web Install web dependencies (uses pnpm workspace)"
@echo ""
@@ -103,17 +100,12 @@ dev-web:
@echo "Starting web app on http://localhost:3000"
@cd $(APPS_DIR) && $(PNPM) --filter @kandev/web dev
-.PHONY: dev-landing
-dev-landing:
- @echo "Starting landing page on http://localhost:3001"
- @cd $(APPS_DIR) && $(PNPM) --filter @kandev/landing dev
-
#
# Build
#
.PHONY: build
-build: build-backend build-web build-landing
+build: build-backend build-web
@printf "\n$(GREEN)$(BOLD)✓ Build complete!$(RESET)\n"
#
@@ -153,16 +145,6 @@ build-web-quiet:
@printf " $(DIM)Web app$(RESET)\n"
@cd $(APPS_DIR) && $(PNPM) --filter @kandev/web build 2>&1 | grep -v "Warning:" | grep -v "parseLineType" | grep -v "^$$" || true
-.PHONY: build-landing
-build-landing:
- @printf "$(CYAN)Building landing page...$(RESET)\n"
- @cd $(APPS_DIR) && $(PNPM) --filter @kandev/landing build
-
-.PHONY: build-landing-quiet
-build-landing-quiet:
- @printf " $(DIM)Landing page$(RESET)\n"
- @cd $(APPS_DIR) && $(PNPM) --filter @kandev/landing build 2>&1 | grep -v "Warning:" | grep -v "parseLineType" | grep -v "^$$" || true
-
#
# Installation
#
@@ -178,7 +160,7 @@ install-backend:
.PHONY: install-web
install-web:
- @printf "$(CYAN)Installing web and landing dependencies...$(RESET)\n"
+ @printf "$(CYAN)Installing web dependencies...$(RESET)\n"
@cd $(APPS_DIR) && $(PNPM) install --silent 2>/dev/null || cd $(APPS_DIR) && $(PNPM) install
#
@@ -256,8 +238,8 @@ clean-backend:
.PHONY: clean-web
clean-web:
- @printf "$(CYAN)Cleaning web and landing artifacts...$(RESET)\n"
- @rm -rf $(WEB_DIR)/.next $(LANDING_DIR)/.next $(APPS_DIR)/node_modules
+ @printf "$(CYAN)Cleaning web artifacts...$(RESET)\n"
+ @rm -rf $(WEB_DIR)/.next $(APPS_DIR)/node_modules
@rm -rf $(APPS_DIR)/packages/*/node_modules
.PHONY: clean-db
diff --git a/apps/landing/app/about/page.tsx b/apps/landing/app/about/page.tsx
deleted file mode 100644
index b436f2329d..0000000000
--- a/apps/landing/app/about/page.tsx
+++ /dev/null
@@ -1,105 +0,0 @@
-import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@kandev/ui/card';
-import { IconTarget, IconRocket, IconHeartHandshake } from '@tabler/icons-react';
-
-const values = [
- {
- icon: IconTarget,
- title: 'Developer First',
- description: 'Built by developers, for developers. We understand your workflow because we live it every day.',
- },
- {
- icon: IconRocket,
- title: 'Ship Fast, Ship Safe',
- description: 'Speed without sacrificing security. AI-powered automation with human oversight and approval.',
- },
- {
- icon: IconHeartHandshake,
- title: 'Open & Transparent',
- description: 'Open source at heart. We believe in building in public and learning from the community.',
- },
-];
-
-const timeline = [
- {
- year: '2026',
- title: 'The Beginning',
- description: 'kandev.ai is born from the need to combine visual task management with AI-assisted development.',
- },
-];
-
-export default function AboutPage() {
- return (
-
-
-
About kandev.ai
-
- We're building the future of development workflows.
-
-
-
-
-
Our Mission
-
- kandev.ai exists to make software development more visual, more collaborative, and more efficient.
- We believe that combining Kanban methodology with AI-assisted coding creates a workflow that's
- greater than the sum of its parts.
-
-
- Traditional development tools force you to context switch between project management, coding,
- and deployment. We're building a unified experience where your Kanban board is the control center
- for AI agents working in isolated, secure environments.
-
-
-
-
-
Our Values
-
- {values.map((value) => {
- const Icon = value.icon;
- return (
-
-
-
- {value.title}
-
-
- {value.description}
-
-
- );
- })}
-
-
-
-
-
Our Journey
-
- {timeline.map((item) => (
-
-
- {item.year}
- {item.title}
-
-
- {item.description}
-
-
- ))}
-
-
-
-
-
Why Kanban + Development + AI?
-
- Kanban boards provide visual clarity. Development tools provide execution. AI provides automation.
- Together, they create a workflow where you can see all your work, execute it in parallel, and
- automate the routine parts while maintaining full control.
-
-
- We're just getting started. As we grow, we'll continue to focus on making development more
- intuitive, more powerful, and more enjoyable.
-
-
-
- );
-}
diff --git a/apps/landing/app/blog/page.tsx b/apps/landing/app/blog/page.tsx
deleted file mode 100644
index ef9aecc3fd..0000000000
--- a/apps/landing/app/blog/page.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import { redirect } from 'next/navigation';
-
-export default function BlogPage() {
- redirect('/changelog');
-}
diff --git a/apps/landing/app/changelog/[slug]/page.tsx b/apps/landing/app/changelog/[slug]/page.tsx
deleted file mode 100644
index 057c8ce834..0000000000
--- a/apps/landing/app/changelog/[slug]/page.tsx
+++ /dev/null
@@ -1,61 +0,0 @@
-import { notFound } from 'next/navigation';
-import { MDXRemote } from 'next-mdx-remote/rsc';
-import { getChangelogEntry, getChangelogSlugs } from '@/lib/changelog';
-import { mdxComponents } from '@/components/mdx-components';
-
-function formatDate(date: string) {
- if (!date) return '';
- return new Intl.DateTimeFormat('en-US', {
- month: 'long',
- day: 'numeric',
- year: 'numeric',
- }).format(new Date(date));
-}
-
-export async function generateStaticParams() {
- const slugs = await getChangelogSlugs();
- return slugs.map((slug) => ({ slug }));
-}
-
-export default async function ChangelogEntryPage({
- params,
-}: {
- params: { slug?: string } | Promise<{ slug?: string }>;
-}) {
- const resolvedParams = await Promise.resolve(params);
- const slug = resolvedParams.slug;
-
- if (!slug) {
- notFound();
- }
- const entry = await getChangelogEntry(slug);
-
- if (!entry) {
- notFound();
- }
-
- return (
-
-
-
-
-
{entry.surface}
-
{entry.title}
-
{formatDate(entry.date)}
-
-
-
- {entry.summary.map((line) => (
-
- {line}
-
- ))}
-
-
-
-
-
-
-
- );
-}
diff --git a/apps/landing/app/changelog/page.tsx b/apps/landing/app/changelog/page.tsx
deleted file mode 100644
index b41513c643..0000000000
--- a/apps/landing/app/changelog/page.tsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import Link from 'next/link';
-import { getChangelogEntries } from '@/lib/changelog';
-
-function formatDate(date: string) {
- if (!date) return '';
- return new Intl.DateTimeFormat('en-US', {
- month: 'long',
- day: 'numeric',
- year: 'numeric',
- }).format(new Date(date));
-}
-
-export default async function ChangelogPage() {
- const entries = await getChangelogEntries();
-
- return (
-
-
-
-
-
Changelog
-
Product updates
-
- A running log of kandev.ai releases, shipped features, and operational improvements.
-
-
-
-
- {entries.map((entry, index) => (
-
-
-
{entry.surface}
-
{formatDate(entry.date)}
- {index === 0 ? (
-
- Latest
-
- ) : null}
-
-
-
-
-
- {entry.title}
-
-
-
- {entry.summary.map((line) => (
-
{line}
- ))}
-
-
-
- Read full update →
-
-
-
-
- ))}
-
-
-
- );
-}
diff --git a/apps/landing/app/docs/agents/page.tsx b/apps/landing/app/docs/agents/page.tsx
deleted file mode 100644
index 8d02066c1f..0000000000
--- a/apps/landing/app/docs/agents/page.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import { DocsShell } from '@/components/docs-shell';
-import { DocsCard } from '@/components/docs-card';
-import { DocsCode } from '@/components/docs-code';
-
-export default function AgentsDocsPage() {
- return (
-
-
-
-
- Container starts with agentctl on port 9999.
- Backend calls initialize and session/new.
- Tasks are sent via session/prompt.
- Agent streams session/update notifications.
-
-
-
-
- Read and edit files inside the worktree
- Run shell commands with approval gates
- Stream progress updates to the UI
-
-
-
-
-
- {`{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"1.0"}}`}
-
-
- );
-}
diff --git a/apps/landing/app/docs/boards/page.tsx b/apps/landing/app/docs/boards/page.tsx
deleted file mode 100644
index 7e531db73a..0000000000
--- a/apps/landing/app/docs/boards/page.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-import { DocsShell } from '@/components/docs-shell';
-import { DocsCard } from '@/components/docs-card';
-import { DocsCode } from '@/components/docs-code';
-
-const stages = [
- { title: 'Backlog', desc: 'Collect ideas and future work.' },
- { title: 'In Progress', desc: 'Active tasks owned by agents.' },
- { title: 'Review', desc: 'Approvals and QA before merge.' },
- { title: 'Done', desc: 'Completed and shipped items.' },
-];
-
-export default function BoardsDocsPage() {
- return (
-
-
- {stages.map((stage) => (
-
- {stage.desc}
-
- ))}
-
-
-
- Keep columns minimal and apply WIP limits where review capacity is tight.
- {`board:
- name: "Product Roadmap"
- columns:
- - name: "Backlog"
- wipLimit: null
- - name: "In Progress"
- wipLimit: 4
- - name: "Review"
- wipLimit: 2
- - name: "Done"
- wipLimit: null`}
-
-
-
-
- Use a single “Review” column so approvals are centralized.
- Keep WIP limits low to prevent agent overload.
- Archive finished tasks weekly to keep focus on active work.
-
-
-
- );
-}
diff --git a/apps/landing/app/docs/docker/page.tsx b/apps/landing/app/docs/docker/page.tsx
deleted file mode 100644
index b719665017..0000000000
--- a/apps/landing/app/docs/docker/page.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import { DocsShell } from '@/components/docs-shell';
-import { DocsCard } from '@/components/docs-card';
-import { DocsCode } from '@/components/docs-code';
-
-export default function DockerDocsPage() {
- return (
-
-
-
-
- /workspace — your repository worktree
- /root/.augment/sessions — agent session storage (when enabled)
-
-
-
-
- Consistent, reproducible environments
- Security boundaries for file and network access
- Easy cleanup after task completion
-
-
-
-
-
- {`docker run -it --rm \
- -v /path/to/repo:/workspace \
- -e TASK_DESCRIPTION="Fix the login bug" \
- kandev/augment-agent:latest`}
-
-
- );
-}
diff --git a/apps/landing/app/docs/installation/page.tsx b/apps/landing/app/docs/installation/page.tsx
deleted file mode 100644
index 868bc61c5c..0000000000
--- a/apps/landing/app/docs/installation/page.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import { DocsShell } from '@/components/docs-shell';
-import { DocsCard } from '@/components/docs-card';
-import { DocsCode } from '@/components/docs-code';
-
-export default function InstallationDocsPage() {
- return (
-
-
-
-
- Docker Desktop (or Docker Engine)
- Git 2.30+
- Node.js 20+
-
-
-
- {`git clone https://github.com/kdlbs/kandev.git
-cd kandev
-pnpm install`}
-
-
-
-
- Start the backend, app, and landing site in separate terminals.
- {`pnpm --filter @kandev/backend dev
-pnpm --filter @kandev/web dev
-pnpm --filter @kandev/landing dev`}
-
-
-
-
- Open the UI and create a test workspace. The system should start an agent container on demand and stream
- progress back over WebSocket.
-
-
-
- );
-}
diff --git a/apps/landing/app/docs/layout.tsx b/apps/landing/app/docs/layout.tsx
deleted file mode 100644
index c4a742812c..0000000000
--- a/apps/landing/app/docs/layout.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import { DocsSidebar } from '@/components/docs-sidebar';
-
-export default function DocsLayout({ children }: { children: React.ReactNode }) {
- return (
-
- );
-}
diff --git a/apps/landing/app/docs/page.tsx b/apps/landing/app/docs/page.tsx
deleted file mode 100644
index fdb06a91ed..0000000000
--- a/apps/landing/app/docs/page.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-import { DocsShell } from '@/components/docs-shell';
-import { DocsCard } from '@/components/docs-card';
-import { DocsCode } from '@/components/docs-code';
-
-export default function DocsPage() {
- return (
-
-
-
-
- kandev.ai is a WebSocket-first platform that pairs Kanban task management with AI-assisted execution.
- Every task runs inside a dedicated git worktree and a Docker container, with approvals for sensitive
- operations.
-
-
-
-
- Ship in parallel without branch conflicts.
- Keep execution auditable and reviewable.
- Stream progress updates in real time.
-
-
-
-
-
- From task creation to approval, kandev.ai follows a consistent loop.
- {`1. Create task on the board
-2. Start agent container via agentctl
-3. Initialize ACP session
-4. Stream progress over WebSocket
-5. Review and approve output`}
-
-
-
-
- Group repositories, boards, and team settings.
-
-
- Model your workflow with Kanban columns.
-
-
- Define the scope, constraints, and agent requirements.
-
-
-
- );
-}
diff --git a/apps/landing/app/docs/quick-start/page.tsx b/apps/landing/app/docs/quick-start/page.tsx
deleted file mode 100644
index bf570d91d4..0000000000
--- a/apps/landing/app/docs/quick-start/page.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import { DocsShell } from '@/components/docs-shell';
-import { DocsCard } from '@/components/docs-card';
-import { DocsCode } from '@/components/docs-code';
-
-const steps = [
- {
- step: '1. Create a workspace',
- body: 'Create a workspace for the repository you want to manage.',
- },
- {
- step: '2. Add a board and task',
- body: 'Add a board with columns, then create a task that describes the desired change.',
- },
- {
- step: '3. Run an agent',
- body: 'Start an agent from the task. The UI should stream progress updates as the agent works.',
- },
- {
- step: '4. Review and merge',
- body: 'Review the diff, approve any gated actions, and merge the worktree.',
- },
-];
-
-export default function QuickStartDocsPage() {
- return (
-
-
- {steps.map((item) => (
-
- {item.body}
-
- ))}
-
-
-
- {`Task: Update onboarding copy
-Constraints: Touch only apps/landing
-Acceptance: Copy updated and passes lint`}
-
-
- );
-}
diff --git a/apps/landing/app/docs/tasks/page.tsx b/apps/landing/app/docs/tasks/page.tsx
deleted file mode 100644
index 9e9874bdd5..0000000000
--- a/apps/landing/app/docs/tasks/page.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import { DocsShell } from '@/components/docs-shell';
-import { DocsCard } from '@/components/docs-card';
-import { DocsCode } from '@/components/docs-code';
-
-export default function TasksDocsPage() {
- return (
-
-
-
-
- Title and description
- Priority and due date
- Repository and base branch
- Agent type and environment
- Approval requirements
-
-
-
-
- State the outcome, not the steps.
- Call out sensitive files or commands.
- Include acceptance criteria.
-
-
-
-
-
- {`Title: Add changelog page
-Repo: github.com/kdlbs/kandev
-Branch: main
-Agent: augment-agent
-Goal: Replace blog with changelog
-Constraints: Keep existing navbar/footer
-Output: New route + MDX entries`}
-
-
- );
-}
diff --git a/apps/landing/app/docs/workspaces/page.tsx b/apps/landing/app/docs/workspaces/page.tsx
deleted file mode 100644
index 0090bea1d3..0000000000
--- a/apps/landing/app/docs/workspaces/page.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import { DocsShell } from '@/components/docs-shell';
-import { DocsCard } from '@/components/docs-card';
-import { DocsCode } from '@/components/docs-code';
-
-export default function WorkspacesDocsPage() {
- return (
-
-
-
-
- Boards that define workflow stages
- Repositories connected to those boards
- Default agent settings and approvals
- Member roles and permissions
-
-
-
-
- Use one workspace per product or client.
- Keep board naming consistent across teams.
- Set approvals at the workspace level.
-
-
-
-
-
- A workspace keeps everything organized in one place.
- {`Workspace: "Core Platform"
-Boards:
- - Product Roadmap
- - Incident Response
-Repositories:
- - github.com/kdlbs/kandev
- - github.com/kdlbs/kandev-docs`}
-
-
- );
-}
diff --git a/apps/landing/app/docs/worktrees/page.tsx b/apps/landing/app/docs/worktrees/page.tsx
deleted file mode 100644
index 4055eb9972..0000000000
--- a/apps/landing/app/docs/worktrees/page.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import { DocsShell } from '@/components/docs-shell';
-import { DocsCard } from '@/components/docs-card';
-import { DocsCode } from '@/components/docs-code';
-
-const benefits = [
- { title: 'Parallel tasks', desc: 'Multiple agents can work without branch collisions.' },
- { title: 'Clean diffs', desc: 'Each task produces an isolated patch.' },
- { title: 'Fast setup', desc: 'No extra clones required.' },
-];
-
-export default function WorktreesDocsPage() {
- return (
-
-
- {benefits.map((item) => (
-
- {item.desc}
-
- ))}
-
-
-
- {`/repos/kandev
- /main (primary checkout)
- /.worktrees/task-123
- /.worktrees/task-124`}
-
-
-
-
- When a task is completed and merged, the worktree can be safely removed without affecting the main checkout.
-
-
-
- );
-}
diff --git a/apps/landing/app/global-error.tsx b/apps/landing/app/global-error.tsx
deleted file mode 100644
index 6841c83961..0000000000
--- a/apps/landing/app/global-error.tsx
+++ /dev/null
@@ -1,62 +0,0 @@
-'use client';
-
-export default function GlobalError({
- error,
- reset,
-}: {
- error: Error & { digest?: string };
- reset: () => void;
-}) {
- return (
-
-
- Error - kandev.ai
-
-
-
-
- Something went wrong!
-
-
- We're sorry, but something unexpected happened.
-
-
reset()}
- style={{
- padding: '0.75rem 1.5rem',
- backgroundColor: '#6B46C1',
- color: '#ffffff',
- border: 'none',
- borderRadius: '0.5rem',
- fontSize: '1rem',
- fontWeight: '500',
- cursor: 'pointer'
- }}
- >
- Try again
-
-
-
-
- );
-}
diff --git a/apps/landing/app/globals.css b/apps/landing/app/globals.css
deleted file mode 100644
index 2591006301..0000000000
--- a/apps/landing/app/globals.css
+++ /dev/null
@@ -1,155 +0,0 @@
-@import "tailwindcss";
-@import "tw-animate-css";
-@import "shadcn/tailwind.css";
-@import "@kandev/theme/fonts.css";
-
-@source "../components/**/*.{js,ts,jsx,tsx}";
-@source "../../packages/ui/src/**/*.{js,ts,jsx,tsx}";
-
-@custom-variant dark (&:is(.dark *));
-
-@theme inline {
- --color-background: var(--background);
- --color-foreground: var(--foreground);
- --font-sans: var(--font-sans);
- --font-mono: var(--font-geist-mono);
- --color-sidebar-ring: var(--sidebar-ring);
- --color-sidebar-border: var(--sidebar-border);
- --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
- --color-sidebar-accent: var(--sidebar-accent);
- --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
- --color-sidebar-primary: var(--sidebar-primary);
- --color-sidebar-foreground: var(--sidebar-foreground);
- --color-sidebar: var(--sidebar);
- --color-chart-5: var(--chart-5);
- --color-chart-4: var(--chart-4);
- --color-chart-3: var(--chart-3);
- --color-chart-2: var(--chart-2);
- --color-chart-1: var(--chart-1);
- --color-ring: var(--ring);
- --color-input: var(--input);
- --color-border: var(--border);
- --color-destructive: var(--destructive);
- --color-accent-foreground: var(--accent-foreground);
- --color-accent: var(--accent);
- --color-muted-foreground: var(--muted-foreground);
- --color-muted: var(--muted);
- --color-secondary-foreground: var(--secondary-foreground);
- --color-secondary: var(--secondary);
- --color-primary-foreground: var(--primary-foreground);
- --color-primary: var(--primary);
- --color-popover-foreground: var(--popover-foreground);
- --color-popover: var(--popover);
- --color-card-foreground: var(--card-foreground);
- --color-card: var(--card);
- --radius-sm: var(--radius);
- --radius-md: var(--radius);
- --radius-lg: var(--radius);
- --radius-xl: var(--radius);
- --radius-2xl: var(--radius);
- --radius-3xl: var(--radius);
- --radius-4xl: var(--radius);
-}
-
-:root {
- --font-geist-sans: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
- --font-sans: "Figtree", "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI",
- sans-serif;
- --font-geist-mono: "Geist Mono", ui-monospace, "SFMono-Regular", Menlo, Monaco, Consolas,
- "Liberation Mono", "Courier New", monospace;
- --background: oklch(1 0 0);
- --foreground: oklch(0.145 0 0);
- --card: oklch(1 0 0);
- --card-foreground: oklch(0.145 0 0);
- --popover: oklch(1 0 0);
- --popover-foreground: oklch(0.145 0 0);
- --primary: oklch(0.51 0.23 277);
- --primary-foreground: oklch(0.96 0.02 272);
- --secondary: oklch(0.967 0.001 286.375);
- --secondary-foreground: oklch(0.21 0.006 285.885);
- --muted: oklch(0.97 0 0);
- --muted-foreground: oklch(0.556 0 0);
- --accent: oklch(0.68 0.18 276);
- --accent-foreground: oklch(0.98 0 0);
- --destructive: oklch(0.58 0.22 27);
- --border: oklch(0.922 0 0);
- --input: oklch(0.922 0 0);
- --ring: oklch(0.708 0 0);
- --chart-1: oklch(0.79 0.10 275);
- --chart-2: oklch(0.68 0.16 277);
- --chart-3: oklch(0.59 0.20 277);
- --chart-4: oklch(0.51 0.23 277);
- --chart-5: oklch(0.46 0.21 277);
- --radius: 0.375rem;
- --sidebar: oklch(0.985 0 0);
- --sidebar-foreground: oklch(0.145 0 0);
- --sidebar-primary: oklch(0.51 0.23 277);
- --sidebar-primary-foreground: oklch(0.96 0.02 272);
- --sidebar-accent: oklch(0.97 0 0);
- --sidebar-accent-foreground: oklch(0.205 0 0);
- --sidebar-border: oklch(0.922 0 0);
- --sidebar-ring: oklch(0.708 0 0);
-}
-
-.dark {
- --background: oklch(0.145 0 0);
- --foreground: oklch(0.985 0 0);
- --card: oklch(0.205 0 0);
- --card-foreground: oklch(0.985 0 0);
- --popover: oklch(0.205 0 0);
- --popover-foreground: oklch(0.985 0 0);
- --primary: oklch(0.59 0.20 277);
- --primary-foreground: oklch(0.96 0.02 272);
- --secondary: oklch(0.274 0.006 286.033);
- --secondary-foreground: oklch(0.985 0 0);
- --muted: oklch(0.269 0 0);
- --muted-foreground: oklch(0.708 0 0);
- --accent: oklch(0.62 0.18 276);
- --accent-foreground: oklch(0.98 0 0);
- --destructive: oklch(0.704 0.191 22.216);
- --border: oklch(1 0 0 / 10%);
- --input: oklch(1 0 0 / 15%);
- --ring: oklch(0.556 0 0);
- --chart-1: oklch(0.79 0.10 275);
- --chart-2: oklch(0.68 0.16 277);
- --chart-3: oklch(0.59 0.20 277);
- --chart-4: oklch(0.51 0.23 277);
- --chart-5: oklch(0.46 0.21 277);
- --sidebar: oklch(0.205 0 0);
- --sidebar-foreground: oklch(0.985 0 0);
- --sidebar-primary: oklch(0.68 0.16 277);
- --sidebar-primary-foreground: oklch(0.96 0.02 272);
- --sidebar-accent: oklch(0.269 0 0);
- --sidebar-accent-foreground: oklch(0.985 0 0);
- --sidebar-border: oklch(1 0 0 / 10%);
- --sidebar-ring: oklch(0.556 0 0);
-}
-
-@layer base {
- * {
- @apply border-border outline-ring/50;
- }
- html {
- scrollbar-gutter: stable;
- }
- body {
- @apply bg-background text-foreground;
- }
-}
-
-@layer utilities {
- .animate-pulse-slow {
- animation: pulse-slow 8s ease-in-out infinite;
- }
-}
-
-@keyframes pulse-slow {
- 0%, 100% {
- transform: scale(1);
- opacity: 0.6;
- }
- 50% {
- transform: scale(1.1);
- opacity: 0.8;
- }
-}
diff --git a/apps/landing/app/layout.tsx b/apps/landing/app/layout.tsx
deleted file mode 100644
index b2ac53504c..0000000000
--- a/apps/landing/app/layout.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import type { Metadata } from 'next';
-import './globals.css';
-import { ThemeProvider } from '@/components/theme-provider';
-import { Navbar } from '@/components/navbar';
-import { Footer } from '@/components/footer';
-
-export const dynamic = 'force-dynamic';
-
-export const metadata: Metadata = {
- title: 'kandev.ai - AI-powered Kanban for Developers',
- description: 'Kanban meets AI development. Manage tasks with isolated worktrees, Docker containers, and AI agents.',
-};
-
-export default function RootLayout({
- children,
-}: Readonly<{
- children: React.ReactNode;
-}>) {
- return (
-
-
-
-
-
- {children}
-
-
-
-
-
- );
-}
diff --git a/apps/landing/app/page.tsx b/apps/landing/app/page.tsx
deleted file mode 100644
index fed9194969..0000000000
--- a/apps/landing/app/page.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import { HeroSection } from '@/components/hero-section';
-import { FeaturesSection } from '@/components/features-section';
-import { AgentsSection } from '@/components/agents-section';
-import { FutureFeaturesSection } from '@/components/future-features-section';
-
-export default function HomePage() {
- return (
-
-
-
-
-
-
- );
-}
diff --git a/apps/landing/components/agents-section.tsx b/apps/landing/components/agents-section.tsx
deleted file mode 100644
index 958c3ec0bc..0000000000
--- a/apps/landing/components/agents-section.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@kandev/ui/card';
-
-const agents = [
- {
- name: 'Claude Code',
- description: "Anthropic's official CLI for Claude. Powerful agent with excellent reasoning and code generation.",
- icon: '🤖',
- },
- {
- name: 'OpenAI Codex',
- description: 'GPT-4 powered coding assistant with strong performance across multiple languages.',
- icon: '🔮',
- },
- {
- name: 'Augment',
- description: 'AI coding assistant focused on code completion and refactoring workflows.',
- icon: '⚡',
- },
- {
- name: 'Opencode',
- description: 'Open-source AI coding agent with customizable models and integrations.',
- icon: '🌐',
- },
-];
-
-export function AgentsSection() {
- return (
-
-
-
-
- Supported AI Agents
-
-
- Work with your favorite AI coding assistants. All agents run in isolated, secure environments.
-
-
-
- {agents.map((agent) => (
-
-
- {agent.icon}
- {agent.name}
-
-
- {agent.description}
-
-
- ))}
-
-
-
- );
-}
diff --git a/apps/landing/components/changelog-video.tsx b/apps/landing/components/changelog-video.tsx
deleted file mode 100644
index 76c3072b33..0000000000
--- a/apps/landing/components/changelog-video.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import type { HTMLAttributes } from 'react';
-
-type ChangelogVideoProps = {
- src: string;
- poster?: string;
- caption?: string;
-} & HTMLAttributes;
-
-export function ChangelogVideo({ src, poster, caption, className, ...props }: ChangelogVideoProps) {
- return (
-
-
- {caption ? (
- {caption}
- ) : null}
-
- );
-}
diff --git a/apps/landing/components/docs-card.tsx b/apps/landing/components/docs-card.tsx
deleted file mode 100644
index 6e79e5a0a2..0000000000
--- a/apps/landing/components/docs-card.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import type { ReactNode } from 'react';
-
-export function DocsCard({
- title,
- children,
- variant = 'default',
-}: {
- title: string;
- children: ReactNode;
- variant?: 'default' | 'accent' | 'muted';
-}) {
- const base =
- 'rounded-2xl border border-border/60 bg-card/50 p-6 shadow-[0_12px_40px_-28px_rgba(37,99,235,0.5)] backdrop-blur';
- const variants: Record = {
- default: 'bg-card/50',
- accent: 'border-primary/30 bg-primary/10',
- muted: 'bg-muted/30',
- };
-
- return (
-
- );
-}
diff --git a/apps/landing/components/docs-code.tsx b/apps/landing/components/docs-code.tsx
deleted file mode 100644
index cb7bf808cd..0000000000
--- a/apps/landing/components/docs-code.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import type { ReactNode } from 'react';
-
-export function DocsCode({ children }: { children: ReactNode }) {
- return (
-
- {children}
-
- );
-}
diff --git a/apps/landing/components/docs-shell.tsx b/apps/landing/components/docs-shell.tsx
deleted file mode 100644
index 4ffbff80f8..0000000000
--- a/apps/landing/components/docs-shell.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-export function DocsShell({
- eyebrow,
- title,
- description,
- children,
-}: {
- eyebrow: string;
- title: string;
- description: string;
- children: React.ReactNode;
-}) {
- return (
-
-
-
-
- {eyebrow}
- {title}
- {description}
-
- {children}
-
-
- );
-}
diff --git a/apps/landing/components/docs-sidebar.tsx b/apps/landing/components/docs-sidebar.tsx
deleted file mode 100644
index f75cee0901..0000000000
--- a/apps/landing/components/docs-sidebar.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-'use client';
-
-import Link from 'next/link';
-import { usePathname } from 'next/navigation';
-import { cn } from '@/lib/utils';
-
-const sections = [
- {
- title: 'Getting Started',
- items: [
- { title: 'Introduction', href: '/docs' },
- { title: 'Installation', href: '/docs/installation' },
- { title: 'Quick Start', href: '/docs/quick-start' },
- ],
- },
- {
- title: 'Core Concepts',
- items: [
- { title: 'Workspaces', href: '/docs/workspaces' },
- { title: 'Boards', href: '/docs/boards' },
- { title: 'Tasks', href: '/docs/tasks' },
- ],
- },
- {
- title: 'Features',
- items: [
- { title: 'Git Worktrees', href: '/docs/worktrees' },
- { title: 'AI Agents', href: '/docs/agents' },
- { title: 'Docker Execution', href: '/docs/docker' },
- ],
- },
-];
-
-export function DocsSidebar() {
- const pathname = usePathname();
-
- return (
-
-
- {sections.map((section) => (
-
-
{section.title}
-
- {section.items.map((item) => (
-
-
- {item.title}
-
-
- ))}
-
-
- ))}
-
-
- );
-}
diff --git a/apps/landing/components/features-section.tsx b/apps/landing/components/features-section.tsx
deleted file mode 100644
index 0c9eafc5d0..0000000000
--- a/apps/landing/components/features-section.tsx
+++ /dev/null
@@ -1,72 +0,0 @@
-import { IconGitBranch, IconCode, IconShieldCheck, IconPlugConnected, IconFolders, IconBrandDocker } from '@tabler/icons-react';
-import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@kandev/ui/card';
-
-const features = [
- {
- icon: IconCode,
- title: 'Parallel Agent Execution',
- description:
- 'Run multiple AI coding agents simultaneously on different tasks. Each agent works in isolated environments, accelerating development without conflicts.',
- },
- {
- icon: IconGitBranch,
- title: 'Isolated Worktrees',
- description:
- 'Each task gets its own git worktree. Work on multiple features, bugs, and experiments in parallel without branch switching or stashing.',
- },
- {
- icon: IconShieldCheck,
- title: 'Built-in Code Review',
- description:
- 'Automated code review and approval workflows. Review agent changes before merging, with full audit logs and rollback capabilities.',
- },
- {
- icon: IconPlugConnected,
- title: 'MCP Integration',
- description:
- 'Connect with Model Context Protocol servers. Extend agent capabilities with custom tools, APIs, and integrations.',
- },
- {
- icon: IconFolders,
- title: 'Multiple Workspaces',
- description:
- 'Organize projects by client, team, or product. Switch between workspaces seamlessly and keep your work isolated.',
- },
- {
- icon: IconBrandDocker,
- title: 'Local Docker',
- description:
- 'AI agents run in local Docker containers for complete isolation. Secure execution with approval workflows and audit logs for every operation.',
- },
-];
-
-export function FeaturesSection() {
- return (
-
-
-
- Build for development velocity
-
-
- Combine the visual clarity of Kanban boards with the power of AI-assisted development.
-
-
-
- {features.map((feature) => {
- const Icon = feature.icon;
- return (
-
-
-
- {feature.title}
-
-
- {feature.description}
-
-
- );
- })}
-
-
- );
-}
diff --git a/apps/landing/components/footer.tsx b/apps/landing/components/footer.tsx
deleted file mode 100644
index 1063cdcd21..0000000000
--- a/apps/landing/components/footer.tsx
+++ /dev/null
@@ -1,80 +0,0 @@
-import Link from 'next/link';
-import { IconBrandGithub, IconBrandTwitter, IconBrandDiscord } from '@tabler/icons-react';
-
-export function Footer() {
- return (
-
-
-
-
-
kandev.ai
-
- AI-powered Kanban for developers. Ship faster with isolated worktrees and secure Docker execution.
-
-
-
-
Product
-
-
-
- Features
-
-
-
-
- Documentation
-
-
-
-
-
-
Company
-
-
-
- About
-
-
-
-
- Changelog
-
-
-
-
-
-
-
- © 2026 kandev.ai. All rights reserved. Built with respect for your privacy and GDPR compliance.
-
-
-
-
-
- );
-}
diff --git a/apps/landing/components/future-features-section.tsx b/apps/landing/components/future-features-section.tsx
deleted file mode 100644
index ea1f431ac7..0000000000
--- a/apps/landing/components/future-features-section.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-import { IconCloud, IconDeviceMobile, IconUsers } from '@tabler/icons-react';
-import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@kandev/ui/card';
-import { Badge } from '@kandev/ui/badge';
-
-const futureFeatures = [
- {
- icon: IconCloud,
- title: 'Remote Executors',
- description: 'Run AI agents on cloud or remote machines. Scale your development with powerful remote compute.',
- status: 'Coming Soon',
- },
- {
- icon: IconDeviceMobile,
- title: 'Mobile App',
- description: 'Launch and monitor tasks from your mobile device. Stay connected to your development workflow.',
- status: 'In Development',
- },
- {
- icon: IconUsers,
- title: 'Team Collaboration',
- description: 'Share workspaces, assign tasks, and collaborate with your team in real-time.',
- status: 'Planned',
- },
-];
-
-export function FutureFeaturesSection() {
- return (
-
-
-
- Coming Soon
-
-
- We're constantly improving kandev.ai. Here's what's on our roadmap.
-
-
-
- {futureFeatures.map((feature) => {
- const Icon = feature.icon;
- return (
-
-
-
-
- {feature.title}
-
-
- {feature.status}
-
-
-
- {feature.description}
-
-
- );
- })}
-
-
- );
-}
diff --git a/apps/landing/components/hero-section.tsx b/apps/landing/components/hero-section.tsx
deleted file mode 100644
index 50082cd8b9..0000000000
--- a/apps/landing/components/hero-section.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-'use client';
-
-import { useState } from 'react';
-import { Button } from '@kandev/ui/button';
-import { Badge } from '@kandev/ui/badge';
-import { IconCheck, IconCopy } from '@tabler/icons-react';
-
-export function HeroSection() {
- const [copied, setCopied] = useState(false);
-
- const copyCommand = () => {
- navigator.clipboard.writeText('npx kandev');
- setCopied(true);
- setTimeout(() => setCopied(false), 2000);
- };
-
- return (
-
-
-
-
- kandev.ai – AI-powered Kanban for developers
-
-
- Kanban meets AI development
-
-
- Manage development tasks with isolated git worktrees, secure Docker execution, and AI agents.
- Ship faster without breaking your workflow.
-
-
-
-
- npx kandev
-
- {copied ? (
-
- ) : (
-
- )}
-
-
-
-
-
-
- );
-}
diff --git a/apps/landing/components/mdx-components.tsx b/apps/landing/components/mdx-components.tsx
deleted file mode 100644
index 2c09e0f14b..0000000000
--- a/apps/landing/components/mdx-components.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import type { ComponentProps, ReactElement } from 'react';
-import { ChangelogVideo } from '@/components/changelog-video';
-
-function MdxHeading({ className, ...props }: ComponentProps<'h2'>) {
- return ;
-}
-
-function MdxSubheading({ className, ...props }: ComponentProps<'h3'>) {
- return ;
-}
-
-function MdxParagraph({ className, ...props }: ComponentProps<'p'>) {
- return
;
-}
-
-function MdxList({ className, ...props }: ComponentProps<'ul'>) {
- return ;
-}
-
-function MdxListItem({ className, ...props }: ComponentProps<'li'>) {
- return ;
-}
-
-function MdxImage({ className, alt, ...props }: ComponentProps<'img'>): ReactElement {
- return (
-
- );
-}
-
-export const mdxComponents = {
- h2: MdxHeading,
- h3: MdxSubheading,
- p: MdxParagraph,
- ul: MdxList,
- li: MdxListItem,
- img: MdxImage,
- ChangelogVideo,
-};
diff --git a/apps/landing/components/navbar.tsx b/apps/landing/components/navbar.tsx
deleted file mode 100644
index 121f2c7a41..0000000000
--- a/apps/landing/components/navbar.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-'use client';
-
-import Link from 'next/link';
-import { usePathname } from 'next/navigation';
-import { IconBrandGithub } from '@tabler/icons-react';
-import { Button } from '@kandev/ui/button';
-import { cn } from '@/lib/utils';
-
-export function Navbar() {
- const pathname = usePathname();
- const stars = '2k'; // Dummy star count display
-
- return (
-
-
-
-
kandev.ai
-
-
-
-
- Product
-
-
- Documentation
-
-
- Changelog
-
-
-
-
-
-
- );
-}
diff --git a/apps/landing/components/theme-provider.tsx b/apps/landing/components/theme-provider.tsx
deleted file mode 100644
index be89f8dde0..0000000000
--- a/apps/landing/components/theme-provider.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-'use client';
-
-import { ThemeProvider as NextThemesProvider } from 'next-themes';
-import type { ReactNode } from 'react';
-
-export function ThemeProvider({ children }: { children: ReactNode }) {
- return (
-
- {children}
-
- );
-}
diff --git a/apps/landing/content/changelog/2026-01-17-launch/index.mdx b/apps/landing/content/changelog/2026-01-17-launch/index.mdx
deleted file mode 100644
index f1619cbee2..0000000000
--- a/apps/landing/content/changelog/2026-01-17-launch/index.mdx
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "kandev.ai Launch"
-date: "2026-01-17"
-surface: "Platform"
-summary:
- - "kandev.ai ships a WebSocket-first Kanban + AI agent workflow for developer teams."
- - "Tasks run inside isolated git worktrees and Docker containers with approval gates."
----
-
-## What is kandev.ai?
-
-kandev.ai is a Kanban-native development platform that pairs task management with AI agents. Every task can be executed by an agent in a clean, isolated environment, while you keep control over approvals and merge decisions.
-
-
-
-## Initial launch features
-
-- **Kanban boards for engineering work** with task metadata, priorities, and agent selection.
-- **Isolated git worktrees** so parallel tasks never collide.
-- **Docker-based execution** for secure, repeatable runs.
-- **Agent control plane** via `agentctl` with start/stop/status and ACP relays.
-- **WebSocket-only client API** for real-time orchestration and updates.
-- **Approval gates** for sensitive paths and commands.
-
-## How it works (high level)
-
-1. The client opens a single WebSocket connection to the backend.
-2. The backend spins up an agent container with `agentctl` as a sidecar.
-3. The backend initializes ACP over stdin/stdout and creates a session.
-4. The task prompt is streamed to the agent and progress events flow back in real time.
-5. Results are reviewed, approved, and merged back into the main branch.
-
-
-
-### What’s next
-
-Expect expanded agent types, richer approvals, and deeper task analytics in upcoming releases.
diff --git a/apps/landing/lib/changelog.ts b/apps/landing/lib/changelog.ts
deleted file mode 100644
index 5375e1b650..0000000000
--- a/apps/landing/lib/changelog.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import fs from 'node:fs/promises';
-import path from 'node:path';
-import matter from 'gray-matter';
-
-export type ChangelogEntry = {
- slug: string;
- title: string;
- date: string;
- surface: string;
- summary: string[];
- content: string;
-};
-
-const changelogRoot = path.join(process.cwd(), 'content', 'changelog');
-
-function normalizeSummary(summary: unknown): string[] {
- if (Array.isArray(summary)) {
- return summary.filter((item): item is string => typeof item === 'string');
- }
- if (typeof summary === 'string') {
- return [summary];
- }
- return [];
-}
-
-function parseEntry(slug: string, fileContent: string): ChangelogEntry {
- const { data, content } = matter(fileContent);
-
- return {
- slug,
- title: String(data.title ?? slug),
- date: String(data.date ?? ''),
- surface: String(data.surface ?? 'Product'),
- summary: normalizeSummary(data.summary),
- content,
- };
-}
-
-export async function getChangelogEntries(): Promise {
- const entries = await fs.readdir(changelogRoot, { withFileTypes: true });
- const slugs = entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
-
- const items = await Promise.all(
- slugs.map(async (slug) => {
- const entryPath = path.join(changelogRoot, slug, 'index.mdx');
- const fileContent = await fs.readFile(entryPath, 'utf8');
- return parseEntry(slug, fileContent);
- })
- );
-
- return items.sort((a, b) => {
- const aTime = new Date(a.date).getTime();
- const bTime = new Date(b.date).getTime();
- return bTime - aTime;
- });
-}
-
-export async function getChangelogEntry(slug: string): Promise {
- const entryPath = path.join(changelogRoot, slug, 'index.mdx');
- try {
- const fileContent = await fs.readFile(entryPath, 'utf8');
- return parseEntry(slug, fileContent);
- } catch {
- return null;
- }
-}
-
-export async function getChangelogSlugs(): Promise {
- const entries = await fs.readdir(changelogRoot, { withFileTypes: true });
- return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
-}
diff --git a/apps/landing/lib/utils.ts b/apps/landing/lib/utils.ts
deleted file mode 100644
index 9ad0df4269..0000000000
--- a/apps/landing/lib/utils.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { type ClassValue, clsx } from 'clsx';
-import { twMerge } from 'tailwind-merge';
-
-export function cn(...inputs: ClassValue[]) {
- return twMerge(clsx(inputs));
-}
diff --git a/apps/landing/next.config.ts b/apps/landing/next.config.ts
deleted file mode 100644
index 36e0078346..0000000000
--- a/apps/landing/next.config.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import type { NextConfig } from "next";
-
-const nextConfig: NextConfig = {
- transpilePackages: ["@kandev/ui", "@kandev/theme", "@kandev/types"],
-};
-
-export default nextConfig;
diff --git a/apps/landing/package.json b/apps/landing/package.json
deleted file mode 100644
index b75ca6c291..0000000000
--- a/apps/landing/package.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "name": "@kandev/landing",
- "version": "0.1.0",
- "private": true,
- "scripts": {
- "dev": "next dev -p 3001",
- "build": "NODE_ENV=production next build",
- "start": "next start -p 3001",
- "lint": "next lint"
- },
- "dependencies": {
- "@kandev/theme": "workspace:*",
- "@kandev/ui": "workspace:*",
- "@tabler/icons-react": "^3.24.0",
- "clsx": "^2.1.1",
- "next": "16.1.1",
- "next-themes": "^0.4.6",
- "next-mdx-remote": "^5.0.0",
- "react": "19.2.3",
- "react-dom": "19.2.3",
- "gray-matter": "^4.0.3",
- "shadcn": "^3.6.3",
- "tailwind-merge": "^2.6.0",
- "tw-animate-css": "^1.4.0"
- },
- "devDependencies": {
- "@tailwindcss/postcss": "^4.0.0",
- "@types/node": "^20",
- "@types/react": "^19",
- "@types/react-dom": "^19",
- "eslint": "^9",
- "eslint-config-next": "16.1.1",
- "tailwindcss": "^4.0.0",
- "typescript": "^5"
- }
-}
diff --git a/apps/landing/postcss.config.mjs b/apps/landing/postcss.config.mjs
deleted file mode 100644
index 61e36849cf..0000000000
--- a/apps/landing/postcss.config.mjs
+++ /dev/null
@@ -1,7 +0,0 @@
-const config = {
- plugins: {
- "@tailwindcss/postcss": {},
- },
-};
-
-export default config;
diff --git a/apps/landing/public/changelog/2026-01-17-launch/high-level-flow.svg b/apps/landing/public/changelog/2026-01-17-launch/high-level-flow.svg
deleted file mode 100644
index 4d6cdd3403..0000000000
--- a/apps/landing/public/changelog/2026-01-17-launch/high-level-flow.svg
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
- Client WS
- Backend
- agentctl
- Agent
-
- orchestrator.start → /api/v1/start → ACP initialize/session/prompt → session/update
- Real-time progress streamed back over WebSocket
- High-level execution flow
-
diff --git a/apps/landing/public/changelog/2026-01-17-launch/launch-hero.svg b/apps/landing/public/changelog/2026-01-17-launch/launch-hero.svg
deleted file mode 100644
index 6b0c65f70a..0000000000
--- a/apps/landing/public/changelog/2026-01-17-launch/launch-hero.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- kandev.ai Launch
- Kanban + AI agents with secure execution
-
diff --git a/apps/landing/public/fonts/figtree/figtree-300-normal.woff2 b/apps/landing/public/fonts/figtree/figtree-300-normal.woff2
deleted file mode 100644
index a8a112383a..0000000000
Binary files a/apps/landing/public/fonts/figtree/figtree-300-normal.woff2 and /dev/null differ
diff --git a/apps/landing/public/fonts/geist-mono/geist-mono-100-normal.woff2 b/apps/landing/public/fonts/geist-mono/geist-mono-100-normal.woff2
deleted file mode 100644
index dbd79648d4..0000000000
Binary files a/apps/landing/public/fonts/geist-mono/geist-mono-100-normal.woff2 and /dev/null differ
diff --git a/apps/landing/public/fonts/geist/geist-100-normal.woff2 b/apps/landing/public/fonts/geist/geist-100-normal.woff2
deleted file mode 100644
index 2000e32fd2..0000000000
Binary files a/apps/landing/public/fonts/geist/geist-100-normal.woff2 and /dev/null differ
diff --git a/apps/landing/tsconfig.json b/apps/landing/tsconfig.json
deleted file mode 100644
index 0001da87e6..0000000000
--- a/apps/landing/tsconfig.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
- "extends": "../tsconfig.json",
- "compilerOptions": {
- "lib": [
- "dom",
- "dom.iterable",
- "esnext"
- ],
- "allowJs": true,
- "skipLibCheck": true,
- "strict": true,
- "noEmit": true,
- "esModuleInterop": true,
- "module": "esnext",
- "moduleResolution": "bundler",
- "resolveJsonModule": true,
- "isolatedModules": true,
- "jsx": "preserve",
- "incremental": true,
- "plugins": [
- {
- "name": "next"
- }
- ],
- "paths": {
- "@/*": ["./*"],
- "@kandev/ui": ["../packages/ui/src"],
- "@kandev/ui/*": ["../packages/ui/src/*"],
- "@kandev/theme": ["../packages/theme/src"],
- "@kandev/types": ["../packages/types/src"]
- }
- },
- "include": [
- "next-env.d.ts",
- "**/*.ts",
- "**/*.tsx",
- ".next/types/**/*.ts"
- ],
- "exclude": [
- "node_modules"
- ]
-}
diff --git a/apps/package.json b/apps/package.json
index 0b521b6bf7..365cb49eed 100644
--- a/apps/package.json
+++ b/apps/package.json
@@ -5,10 +5,8 @@
"scripts": {
"dev": "pnpm -r run dev",
"dev:web": "pnpm --filter @kandev/web dev",
- "dev:landing": "pnpm --filter @kandev/landing dev",
"build": "pnpm -r run build",
"build:web": "pnpm --filter @kandev/web build",
- "build:landing": "pnpm --filter @kandev/landing build",
"lint": "pnpm -r run lint",
"clean": "pnpm -r run clean && rm -rf node_modules"
},
diff --git a/apps/pnpm-workspace.yaml b/apps/pnpm-workspace.yaml
index 3a4a5217bd..4e9257f0cc 100644
--- a/apps/pnpm-workspace.yaml
+++ b/apps/pnpm-workspace.yaml
@@ -1,5 +1,4 @@
packages:
- 'cli'
- 'web'
- - 'landing'
- 'packages/*'