Skip to content

Commit 48dc703

Browse files
committed
Merge release-1.11.0 into main
2 parents bfc8224 + 562e5f2 commit 48dc703

2,798 files changed

Lines changed: 268202 additions & 194677 deletions

File tree

Some content is hidden

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

.agents/skills/e2e-testing/SKILL.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,17 +167,19 @@ withEventDeliveryModes(
167167

168168
## Tags System
169169

170-
Every test MUST have at least one tag. Tags enable filtering and CI pipeline configuration.
170+
Every test MUST be tagged with `@release` — the release run greps for it, so an
171+
untagged or wrongly-tagged spec silently drops out of release coverage. Add the
172+
domain tag(s) below on top of `@release` (a test can have more than one). These
173+
six are the only allowed tags; do not invent new ones.
171174

172175
| Tag | Purpose | When to Use |
173176
|-----|---------|-------------|
174-
| `@release` | Tests that must pass before release | Critical user flows |
177+
| `@release` | Part of the release run (required on every spec) | All tests |
175178
| `@workspace` | Workspace/flow management | Creating, editing, deleting flows |
176179
| `@api` | API-dependent features | Tests that call backend endpoints |
177180
| `@database` | Database operations | Tests involving persistence |
178181
| `@components` | Component-level tests | Individual component behavior |
179182
| `@starter-projects` | Template/starter project tests | Pre-built flow templates |
180-
| `@regression` | Bug regression tests | Tests for specific fixed bugs |
181183

182184
```typescript
183185
// Right: tag your test
@@ -322,7 +324,7 @@ test.skip(true, "Feature not yet implemented with new designs");
322324
## Writing Good E2E Tests
323325

324326
### Do:
325-
- **Tag every test** with at least one tag
327+
- **Tag every test** with `@release` (plus any domain tags that apply)
326328
- **Import from `../../fixtures`**, not `@playwright/test`
327329
- **Start with `awaitBootstrapTest(page)`** — always
328330
- **Use `getByTestId`** for stable selectors

.agents/skills/frontend-a11y-check/SKILL.md

Lines changed: 239 additions & 0 deletions
Large diffs are not rendered by default.

.agents/skills/frontend-code-review/SKILL.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Notes when using this skill:
3737
- **Code quality**: For any reviewed file, follow [references/code-quality.md](references/code-quality.md) to check styling conventions, TypeScript usage, Biome compliance, and component patterns.
3838
- **Performance**: If the review scope involves React components, hooks, Zustand stores, React Query usage, or @xyflow/react node rendering, follow [references/performance.md](references/performance.md) to check for re-render issues, memoization, and data flow patterns.
3939
- **Business logic**: If the review scope involves custom nodes (GenericNode), flow state, API calls, the component system, global variables, or the inspection panel, follow [references/business-logic.md](references/business-logic.md) to check for Langflow-specific correctness.
40+
- **i18n**: If the diff adds or changes user-facing text (labels, buttons, tooltips, modals, toasts, errors, placeholders, aria-labels), follow the [frontend-i18n skill](../frontend-i18n/SKILL.md): no hardcoded UI strings — everything through `t(...)` — and every new key present in **all** locale files (`src/frontend/src/locales/*.json`).
4041

4142
## General Review Rules
4243

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
name: frontend-i18n
3+
description: Add, change, or review user-facing text in the Langflow frontend using the i18n system (i18next / react-i18next). Use whenever a change adds or edits UI strings — labels, buttons, tooltips, modals, toasts, error messages, empty states — or when reviewing a diff that contains user-facing text. Every user-facing string must go through the translation system and every new key must exist in ALL locale files. Do NOT use for backend strings, log messages, or code identifiers.
4+
---
5+
6+
# Frontend i18n
7+
8+
The Langflow frontend is internationalized with **i18next + react-i18next**. Locales live in `src/frontend/src/locales/` — currently `en`, `de`, `es`, `fr`, `ja`, `pt`, `zh-Hans`. A hardcoded user-facing string, or a key missing from one locale, ships broken UI for part of the user base.
9+
10+
## The two rules
11+
12+
1. **Every user-facing string goes through `t(...)`** — never hardcoded JSX text for labels, buttons, tooltips, modals, toasts, errors, placeholders, `aria-label`s, or empty states.
13+
2. **Every new key is added to ALL locale files in the same PR** (`en.json`, `de.json`, `es.json`, `fr.json`, `ja.json`, `pt.json`, `zh-Hans.json`). `fallbackLng: "en"` means a missing key silently shows English — it won't crash, which is exactly why reviews must catch it.
14+
15+
## How it works here
16+
17+
- Config: `src/frontend/src/i18n.ts` — a custom i18next instance. `en` is bundled statically; other languages are **lazy-loaded** by `loadLanguage()` via dynamic import. Language preference comes from `localStorage.getItem("languagePreference")`, normalized (e.g. `zh-CN``zh-Hans`, unknown → `en`).
18+
- Keys are **flat, dot-namespaced by feature**: `deleteModal.title`, `errors.fileTooLarge`, `crash.restartButton`. Follow the existing namespace of the area you're touching; create a new prefix only for a genuinely new surface.
19+
- Interpolation uses `{{variable}}` in the string and an options object in the call.
20+
21+
## Adding a string (the pattern)
22+
23+
```tsx
24+
import { useTranslation } from "react-i18next";
25+
26+
const { t } = useTranslation();
27+
28+
<span>{t("deleteModal.title")}</span>
29+
<p>{t("errors.fileTooLarge", { maxSizeMB: "10MB" })}</p>
30+
```
31+
32+
In `locales/en.json` (and **every** other locale file):
33+
34+
```json
35+
"errors.fileTooLarge": "The file size is too large. Please select a file smaller than {{maxSizeMB}}."
36+
```
37+
38+
For the non-English locales, write a real translation when confident; if not, add the key with the English value and flag it in the PR — a present-but-untranslated key is visible and searchable, a missing key is invisible.
39+
40+
## Rules that prevent real bugs
41+
42+
- **Don't concatenate translated fragments** (`t("a") + name + t("b")`) — word order differs across languages. Use one key with interpolation: `t("greeting", { name })`.
43+
- **Don't put JSX/HTML inside translation strings**; compose in JSX around `t()` calls (see how `crash.descriptionBefore` / `crash.githubIssues` / `crash.descriptionAfter` split around a link).
44+
- **Plurals**: use i18next plural forms (`_one` / `_other` suffixes), not `count === 1 ? ... : ...`.
45+
- **Keys are code**: renaming or deleting a key means updating **all seven** locale files — an orphan key in one file is dead weight; a rename missed in one file is a regression.
46+
- Dates/numbers/currency: format with `Intl.*` using the active locale, never hardcoded formats.
47+
48+
## Review checklist (apply to any diff with UI text)
49+
50+
- [ ] No hardcoded user-facing string in JSX (including `placeholder`, `title`, `aria-label`, toast/error text).
51+
- [ ] Every new key exists in **all** locale files (grep the key across `src/frontend/src/locales/*.json`).
52+
- [ ] No concatenation of translated fragments; interpolation used instead.
53+
- [ ] Removed/renamed keys cleaned up in all locales (no orphans).
54+
- [ ] Key follows the existing dot-namespace of the feature area.
55+
56+
Quick check for a key across locales:
57+
58+
```bash
59+
for f in src/frontend/src/locales/*.json; do grep -L '"my.new.key"' "$f"; done
60+
```
61+
62+
(prints the locale files where the key is **missing** — should print nothing)

.agents/skills/frontend-testing/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Activate this skill when:
3333
- **Path alias**: `@/` maps to `<rootDir>/src/`
3434
- **Test match patterns**: `src/**/__tests__/**/*.{test,spec}.{ts,tsx}` and `src/**/*.{test,spec}.{ts,tsx}`
3535
- **Transform**: Custom `transform-import-meta.js` handles `import.meta` for Jest compatibility
36-
- **Global mocks** (in `jest.setup.js`): `@radix-ui/react-form`, `react-markdown`, `lucide-react/dynamicIconImports`, `@/components/common/genericIconComponent`, `@/icons/BotMessageSquare`, `@/stores/darkStore`, `localStorage`, `sessionStorage`, `crypto`
36+
- **Global mocks** (in `jest.setup.js`): `@radix-ui/react-form`, `react-markdown`, `remark-gfm`, `remark-math`, `rehype-mathjax/browser`, `lucide-react/dynamicIconImports`, `@/components/common/genericIconComponent`, `@/icons/BotMessageSquare`, `@/stores/darkStore`, `localStorage`, `sessionStorage`, `crypto`
3737

3838
## Key Commands
3939

.agents/skills/frontend-testing/references/mocking.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ These modules are already mocked in `jest.setup.js`. Do NOT re-mock them unless
2121

2222
- `@radix-ui/react-form` (all exports render children)
2323
- `react-markdown` (renders null)
24+
- `remark-gfm`, `remark-math`, `rehype-mathjax/browser` (no-op plugins; pure ESM that fails to parse under jest)
2425
- `lucide-react/dynamicIconImports` (empty object)
2526
- `@/components/common/genericIconComponent` (renders null)
2627
- `@/icons/BotMessageSquare` (renders null)
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
---
2+
name: ibm-a11y-automation
3+
description: Run Langflow's local accessibility scanner script against frontend routes from src/frontend/src/routes.tsx and summarize the JSON report.
4+
---
5+
6+
# Langflow Accessibility Scanner
7+
8+
Use this skill when asked to scan Langflow frontend pages for accessibility issues.
9+
10+
## Scanner
11+
12+
Use the Python script:
13+
14+
```bash
15+
uv run python scripts/a11y/a11y_scan.py \
16+
--url http://localhost:3000 \
17+
--routes-file scripts/a11y/a11y_routes.json \
18+
--route-group static \
19+
--out /tmp/langflow-a11y-report.json \
20+
--markdown /tmp/langflow-a11y-report.md \
21+
--html /tmp/langflow-a11y-report.html \
22+
--timeout-ms 45000
23+
```
24+
25+
Script options:
26+
27+
- `--url`: base app URL, usually `http://localhost:3000`.
28+
- `--routes-file`: route manifest JSON file. Prefer `scripts/a11y/a11y_routes.json`.
29+
- `--route-group`: manifest group to scan. Default: `static`.
30+
- `--routes`: comma-separated route paths to scan.
31+
- `--route`: one route path; can be repeated instead of `--routes`.
32+
- `--levels`: comma-separated issue levels. Default: `violation`.
33+
- `--out`: JSON report path.
34+
- `--markdown`: optional Markdown report path.
35+
- `--html`: optional self-contained HTML report path.
36+
- `--timeout-ms`: per-route timeout.
37+
- `--quiet-ms`: network quiet window before scanning. Default: `1000`.
38+
- `--states-file`: JSON file with explicit modal/state actions.
39+
- `--headed`: show browser while scanning.
40+
41+
## Route Selection
42+
43+
Use `scripts/a11y/a11y_routes.json` as the source of truth for route selection.
44+
45+
The normal CI/local batch is the manifest `static` group. Prefer that unless the user asks for custom, dynamic, or gated routes.
46+
47+
Common manifest-backed command:
48+
49+
```bash
50+
uv run python scripts/a11y/a11y_scan.py \
51+
--url http://localhost:3000 \
52+
--routes-file scripts/a11y/a11y_routes.json \
53+
--route-group static \
54+
--out /tmp/langflow-a11y-static.json \
55+
--markdown /tmp/langflow-a11y-static.md \
56+
--html /tmp/langflow-a11y-static.html
57+
```
58+
59+
Dynamic routes need real IDs before scanning:
60+
61+
- `/flow/:id/`
62+
- `/flow/:id/view`
63+
- `/playground/:id/`
64+
- `/assets/knowledge-bases/:sourceId/chunks`
65+
66+
For dynamic routes, get IDs from the loaded app, API responses, or existing test data before replacing placeholders.
67+
68+
## Examples
69+
70+
Scan one route:
71+
72+
```bash
73+
uv run python scripts/a11y/a11y_scan.py \
74+
--url http://localhost:3000 \
75+
--route /flows \
76+
--out /tmp/langflow-a11y-flows.json
77+
```
78+
79+
Scan multiple routes:
80+
81+
```bash
82+
uv run python scripts/a11y/a11y_scan.py \
83+
--url http://localhost:3000 \
84+
--routes-file scripts/a11y/a11y_routes.json \
85+
--route-group static \
86+
--out /tmp/langflow-a11y-report.json \
87+
--markdown /tmp/langflow-a11y-report.md \
88+
--html /tmp/langflow-a11y-report.html
89+
```
90+
91+
Scan more than violations:
92+
93+
```bash
94+
uv run python scripts/a11y/a11y_scan.py \
95+
--url http://localhost:3000 \
96+
--routes-file scripts/a11y/a11y_routes.json \
97+
--route-group static \
98+
--levels violation,potentialviolation,recommendation \
99+
--out /tmp/langflow-a11y-expanded.json
100+
```
101+
102+
Scan route plus modal states:
103+
104+
```bash
105+
uv run python scripts/a11y/a11y_scan.py \
106+
--url http://localhost:3000 \
107+
--states-file /tmp/langflow-a11y-states.json \
108+
--out /tmp/langflow-a11y-modal-report.json \
109+
--markdown /tmp/langflow-a11y-modal-report.md \
110+
--html /tmp/langflow-a11y-modal-report.html \
111+
--timeout-ms 45000
112+
```
113+
114+
State file shape:
115+
116+
```json
117+
[
118+
{
119+
"route": "/settings/global-variables",
120+
"states": [
121+
{
122+
"name": "new-global-variable-modal",
123+
"open": [
124+
{ "click": "[data-testid='api-key-button-store']" },
125+
{ "waitFor": "[role='dialog']" }
126+
],
127+
"close": [
128+
{ "press": "Escape" },
129+
{ "waitForHidden": "[role='dialog']" }
130+
]
131+
}
132+
]
133+
}
134+
]
135+
```
136+
137+
Supported state actions:
138+
139+
- `{ "click": "<css selector>" }`
140+
- `{ "clickText": "<visible text>" }`
141+
- `{ "clickRole": { "role": "button", "name": "Create" } }`
142+
- `{ "fill": { "selector": "<css selector>", "value": "text" } }`
143+
- `{ "press": "Escape" }`
144+
- `{ "press": { "selector": "<css selector>", "key": "Enter" } }`
145+
- `{ "waitFor": "<css selector>" }`
146+
- `{ "waitForHidden": "<css selector>" }`
147+
- `{ "waitForText": "<visible text>" }`
148+
- `{ "wait": 500 }`
149+
150+
## Report
151+
152+
The scanner always writes JSON. It can also write Markdown and HTML for presentation.
153+
154+
Use JSON for exact data. Use Markdown for PR comments or issues. Use HTML when the user wants a browsable report.
155+
156+
Summarize:
157+
158+
- report path
159+
- Markdown/HTML report paths, when generated
160+
- total issue count
161+
- per-route issue count
162+
- per-route API request count
163+
- per-route request failure count
164+
- top rule IDs
165+
166+
Use report fields directly:
167+
168+
- `totalIssues`
169+
- `results[].route`
170+
- `results[].state`
171+
- `results[].phase`
172+
- `results[].apiRequests`
173+
- `results[].requestFailures`
174+
- `results[].diagnostics`
175+
- `results[].issues[].ruleId`
176+
177+
## Rules
178+
179+
- Use only scanner output for findings.
180+
- Do not invent route names. Read `routes.tsx`.
181+
- Do not auto-click arbitrary buttons to find modals. Use explicit state actions.
182+
- Avoid destructive modal actions unless the user explicitly asks and data is safe.
183+
- If a route has zero API requests, mention that scan quality may be limited.
184+
- Ask before fixing files unless the user explicitly asks for fixes.

0 commit comments

Comments
 (0)