Skip to content

Commit a968496

Browse files
teallarsonclaude
andcommitted
Add CI pipeline with linting, formatting, and template smoke tests
- ESLint v9 + Prettier for TypeScript/JS across src/ and templates/ - Ruff for Python linting/formatting in templates/langchain/ - GitHub Actions CI with 3 jobs: lint-and-build (Node 18/22), lint-python (Ruff), and smoke-test-templates (scaffold + build) - Generated TS projects now ship with Prettier config - Fix existing lint issues (unused imports, empty catch blocks) - Apply consistent formatting across all source files Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ea6c4f9 commit a968496

81 files changed

Lines changed: 2617 additions & 1226 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
lint-and-build:
11+
name: Lint, Format & Build (Node ${{ matrix.node-version }})
12+
runs-on: ubuntu-latest
13+
strategy:
14+
matrix:
15+
node-version: [18, 22]
16+
steps:
17+
- uses: actions/checkout@v4
18+
- uses: actions/setup-node@v4
19+
with:
20+
node-version: ${{ matrix.node-version }}
21+
cache: npm
22+
- run: npm ci
23+
- run: npm run lint
24+
- run: npm run format:check
25+
- run: npm run typecheck
26+
- run: npm run build
27+
28+
lint-python:
29+
name: Lint Python Templates
30+
runs-on: ubuntu-latest
31+
steps:
32+
- uses: actions/checkout@v4
33+
- uses: astral-sh/ruff-action@v3
34+
with:
35+
args: check templates/langchain/
36+
- uses: astral-sh/ruff-action@v3
37+
with:
38+
args: format --check templates/langchain/
39+
40+
smoke-test-templates:
41+
name: Smoke Test — ${{ matrix.template }}
42+
runs-on: ubuntu-latest
43+
needs: lint-and-build
44+
strategy:
45+
matrix:
46+
template: [ai-sdk, mastra, langchain]
47+
steps:
48+
- uses: actions/checkout@v4
49+
- uses: actions/setup-node@v4
50+
with:
51+
node-version: 22
52+
cache: npm
53+
- uses: actions/setup-python@v5
54+
if: matrix.template == 'langchain'
55+
with:
56+
python-version: "3.12"
57+
- run: npm ci
58+
- run: npm run build
59+
60+
- name: Scaffold template
61+
run: node dist/index.js ci-test-${{ matrix.template }} --template ${{ matrix.template }}
62+
63+
- name: Create .env from example
64+
working-directory: ci-test-${{ matrix.template }}
65+
run: cp .env.example .env
66+
67+
- name: Build (TypeScript templates)
68+
if: matrix.template != 'langchain'
69+
working-directory: ci-test-${{ matrix.template }}
70+
run: npm run build
71+
72+
- name: Lint (TypeScript templates)
73+
if: matrix.template != 'langchain'
74+
working-directory: ci-test-${{ matrix.template }}
75+
run: npm run lint
76+
77+
- name: Syntax check (Python template)
78+
if: matrix.template == 'langchain'
79+
working-directory: ci-test-${{ matrix.template }}
80+
run: |
81+
.venv/bin/python -m py_compile app/main.py
82+
.venv/bin/python -m py_compile app/config.py

.prettierignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
dist/
2+
node_modules/
3+
*.lock
4+
*.hbs
5+
templates/langchain/**/*.py

.prettierrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"semi": true,
3+
"singleQuote": false,
4+
"trailingComma": "es5",
5+
"printWidth": 100,
6+
"tabWidth": 2
7+
}

README.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ The generated agent is a daily planning and triage assistant that connects to Sl
1313

1414
## Templates
1515

16-
| Template | Flag value | Tech stack | UI |
17-
|---|---|---|---|
18-
| **AI SDK** | `ai-sdk` | Next.js 16 + Vercel AI SDK + `@ai-sdk/mcp` + Drizzle ORM + SQLite | React 19 + Tailwind CSS |
19-
| **Mastra** | `mastra` | Next.js 16 + Mastra + `@mastra/mcp` + Drizzle ORM + SQLite | React 19 + Tailwind CSS |
16+
| Template | Flag value | Tech stack | UI |
17+
| ------------- | ----------- | ----------------------------------------------------------------------- | ----------------------------- |
18+
| **AI SDK** | `ai-sdk` | Next.js 16 + Vercel AI SDK + `@ai-sdk/mcp` + Drizzle ORM + SQLite | React 19 + Tailwind CSS |
19+
| **Mastra** | `mastra` | Next.js 16 + Mastra + `@mastra/mcp` + Drizzle ORM + SQLite | React 19 + Tailwind CSS |
2020
| **LangChain** | `langchain` | FastAPI + LangGraph + `langchain-mcp-adapters` + SQLAlchemy + aiosqlite | Jinja2 templates + vanilla JS |
2121

2222
All three templates connect to Arcade's MCP Gateway for tool discovery and execution. The TypeScript templates (`ai-sdk` and `mastra`) share a common Next.js frontend. The Python template (`langchain`) uses server-rendered HTML with SSE streaming.
@@ -101,19 +101,19 @@ cp .env.example .env
101101

102102
### Required environment variables
103103

104-
| Variable | Description | Where to get it |
105-
|---|---|---|
106-
| `ARCADE_GATEWAY_URL` | Your Arcade MCP Gateway URL | [app.arcade.dev/mcp-gateways](https://app.arcade.dev/mcp-gateways) |
104+
| Variable | Description | Where to get it |
105+
| --------------------------------------- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
106+
| `ARCADE_GATEWAY_URL` | Your Arcade MCP Gateway URL | [app.arcade.dev/mcp-gateways](https://app.arcade.dev/mcp-gateways) |
107107
| `OPENAI_API_KEY` or `ANTHROPIC_API_KEY` | LLM provider API key (set at least one) | [platform.openai.com](https://platform.openai.com) or [console.anthropic.com](https://console.anthropic.com) |
108108

109109
### Optional environment variables
110110

111-
| Variable | Description |
112-
|---|---|
113-
| `ARCADE_CUSTOM_VERIFIER` | Set to `true` to enable per-user token binding (COAT protection) |
114-
| `ARCADE_API_KEY` | Required when custom verifier is enabled; get from [app.arcade.dev/settings](https://app.arcade.dev/settings) |
115-
| `DATABASE_URL` | SQLite file path (defaults to `local.db`) |
116-
| `PORT` | Server port (defaults to `8765` for langchain, `3000` for Next.js templates) |
111+
| Variable | Description |
112+
| ------------------------ | ------------------------------------------------------------------------------------------------------------- |
113+
| `ARCADE_CUSTOM_VERIFIER` | Set to `true` to enable per-user token binding (COAT protection) |
114+
| `ARCADE_API_KEY` | Required when custom verifier is enabled; get from [app.arcade.dev/settings](https://app.arcade.dev/settings) |
115+
| `DATABASE_URL` | SQLite file path (defaults to `local.db`) |
116+
| `PORT` | Server port (defaults to `8765` for langchain, `3000` for Next.js templates) |
117117

118118
### Arcade Gateway setup
119119

eslint.config.mjs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import js from "@eslint/js";
2+
import tseslint from "typescript-eslint";
3+
import eslintConfigPrettier from "eslint-config-prettier";
4+
5+
export default tseslint.config(
6+
{
7+
ignores: [
8+
"dist/**",
9+
"node_modules/**",
10+
"templates/langchain/**",
11+
"templates/_shared/nextjs-ui/**",
12+
],
13+
},
14+
15+
js.configs.recommended,
16+
...tseslint.configs.recommended,
17+
eslintConfigPrettier,
18+
19+
{
20+
files: ["src/**/*.ts"],
21+
languageOptions: {
22+
parserOptions: {
23+
projectService: true,
24+
tsconfigRootDir: import.meta.dirname,
25+
},
26+
},
27+
},
28+
29+
{
30+
files: ["templates/**/*.{ts,tsx,js,jsx,mjs}"],
31+
rules: {
32+
"@typescript-eslint/no-unused-vars": [
33+
"warn",
34+
{ argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
35+
],
36+
},
37+
},
38+
39+
{
40+
rules: {
41+
"no-console": "off",
42+
"@typescript-eslint/no-unused-vars": [
43+
"error",
44+
{ argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
45+
],
46+
},
47+
}
48+
);

0 commit comments

Comments
 (0)