Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions a2ui-composer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# Dependencies
node_modules
.pnp
.pnp.js
.pnpm-store
.corepack

.wireit

# Local env files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# Testing
coverage

# Turbo
.turbo

# Vercel
.vercel

# Build Outputs
.next/
next-env.d.ts
out/
build
dist


# Debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Misc
.DS_Store
*.pem

.venv
.venv_test
.env
__pycache__

.playwright-mcp
16 changes: 16 additions & 0 deletions a2ui-composer/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Repository Guidelines

## Build, Test, and Development Commands
Run `pnpm install` once, then `pnpm dev` for the web server (Next.js watches on port 3000). Build artifacts with `pnpm build`;

## Coding Style & Naming Conventions
TypeScript and modern React are mandatory; prefer function components and colocate UI logic in `app/components`. Follow Prettier's defaults (two-space indentation, single quotes) by running `pnpm format` before commits. Component files use PascalCase (e.g., `AgentPanel.tsx`); hooks and utilities use camelCase in `*.ts`. The shared ESLint preset (`packages/eslint-config`) enforces `turbo/no-undeclared-env-vars`, so surface new env variables via typed helpers.

## Testing Guidelines
There is no bundled unit-test runner yet, so treat linting and type-checking as minimum CI gates. Keep test fixtures (JSON, mock responses) alongside the code they exercise to match existing samples.

## Commit & Pull Request Guidelines
Existing history uses short imperative subjects ("Add themed a2ui surface"); continue that pattern and reference issues in the footer as needed. Each PR should state scope, testing evidence, and any UI screenshots or terminal output that prove the agent path. Link design docs and flag follow-ups; ensure CI (`pnpm build`) is green before requesting review.

## Security & Configuration
Never commit `.env` files or API keys; use `.env.local` for web and `.env` inside sample agents. Document any new secrets in `README.md`
19 changes: 19 additions & 0 deletions a2ui-composer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# A2UI Composer
A tool for building A2UI widgets, powered by copilot kit. Run it yourself, or just go to https://a2ui-editor.ag-ui.com

![A2UI Composer](images/composer.png)

## Using the composer
Just ask the composer to build you a widget, have it make any changes you want, copy the json, and paste it into your components that you give to your a2ui enabled agent!

<video src="images/demo.mp4" controls width="100%"></video>


## Running the composer
You need a `GEMINI_API_KEY` or `OPENAI_API_KEY` in `apps/widget-builder/.env.local`.

Then, just install, build, and run!
```
pnpm i && pnpm build
pnpm dev
```
22 changes: 22 additions & 0 deletions a2ui-composer/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/app/globals.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {}
}
72 changes: 72 additions & 0 deletions a2ui-composer/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import js from "@eslint/js";
import eslintConfigPrettier from "eslint-config-prettier";
import turboPlugin from "eslint-plugin-turbo";
import tseslint from "typescript-eslint";
import onlyWarn from "eslint-plugin-only-warn";
import pluginReactHooks from "eslint-plugin-react-hooks";
import pluginReact from "eslint-plugin-react";
import globals from "globals";
import pluginNext from "@next/eslint-plugin-next";

/**
* ESLint configuration for widget-builder (Next.js app)
* @type {import("eslint").Linter.Config[]}
*/
export default [
// Base config
js.configs.recommended,
eslintConfigPrettier,
...tseslint.configs.recommended,
{
plugins: {
turbo: turboPlugin,
},
rules: {
"turbo/no-undeclared-env-vars": "warn",
},
},
{
plugins: {
onlyWarn,
},
},
// Next.js specific config
{
...pluginReact.configs.flat.recommended,
languageOptions: {
...pluginReact.configs.flat.recommended.languageOptions,
globals: {
...globals.serviceworker,
},
},
},
{
plugins: {
"@next/next": pluginNext,
},
rules: {
...pluginNext.configs.recommended.rules,
...pluginNext.configs["core-web-vitals"].rules,
},
},
{
plugins: {
"react-hooks": pluginReactHooks,
},
settings: { react: { version: "detect" } },
rules: {
...pluginReactHooks.configs.recommended.rules,
// React scope no longer necessary with new JSX transform.
"react/react-in-jsx-scope": "off",
},
},
{
ignores: [
"dist/**",
".next/**",
"out/**",
"build/**",
"next-env.d.ts",
],
},
];
Binary file added a2ui-composer/images/composer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added a2ui-composer/images/demo.mp4
Binary file not shown.
7 changes: 7 additions & 0 deletions a2ui-composer/next.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
/* config options here */
};

export default nextConfig;
57 changes: 57 additions & 0 deletions a2ui-composer/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"name": "widget-builder",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev --turbopack --port 3001",
"build": "next build",
"start": "next start",
"lint": "eslint",
"format": "prettier --write \"**/*.{ts,tsx,md}\""
},
"dependencies": {
"@copilotkit/a2ui-renderer": "1.50.1",
"@copilotkit/react-core": "^1.50.1",
"@copilotkit/react-ui": "^1.50.1",
"@copilotkit/runtime": "^1.50.1",
"@monaco-editor/react": "^4.7.0",
"@radix-ui/react-alert-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-separator": "^1.1.8",
"@radix-ui/react-slot": "^1.2.4",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"hono": "^4.6.18",
"localforage": "^1.10.0",
"lucide-react": "^0.556.0",
"next": "16.0.10",
"react": "19.2.1",
"react-dom": "19.2.1",
"react-resizable-panels": "^3.0.6",
"shiki": "^3.20.0",
"tailwind-merge": "^3.4.0",
"uuid": "^13.0.0",
"zod": "^3.25.75"
},
"devDependencies": {
"@eslint/js": "^9.34.0",
"@next/eslint-plugin-next": "^15.5.0",
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "19.2.3",
"@types/react-dom": "19.2.3",
"@types/uuid": "^11.0.0",
"eslint": "^9.34.0",
"eslint-config-prettier": "^10.1.1",
"eslint-plugin-only-warn": "^1.1.0",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-turbo": "^2.5.0",
"globals": "^16.3.0",
"prettier": "^3.7.4",
"tailwindcss": "^4",
"tw-animate-css": "^1.4.0",
"typescript": "^5.9.2",
"typescript-eslint": "^8.40.0"
}
}
Loading
Loading