Agentic BI. Analytics at the speed of code ⚡️
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
feat(admin-mcp): overview stats panel on the MCP activity page (#25293) Part of the MCP observability stack (overview UI). Adds an overview panel to the MCP activity settings page so admins can read the health of MCP usage at a glance without scanning the table: - Stat tiles: total calls, success rate, error count - Top tools with proportional usage bars - Active agents with per-agent call counts (including calls made without an agent) - Recent errors — clicking one opens the same tool call drawer as a table row States are covered end to end: loading skeletons, a filtered/global empty state, a positive "no errors" state, and a failure state (stat tiles fall back to em dashes and a quiet card offers Retry, which refetches in place). When a filter change fails mid-flight, previously loaded stats stay on screen instead of flashing to the error state. The panel shares the page's project/agent filters, so the stats always describe exactly what the table is scoped to. The status filter deliberately doesn't affect it, so the success/error split stays meaningful while the table is filtered to errors. Layout is container-query based (it reacts to actual content width, so it also handles the settings sidebar collapsing): at wide widths the panel is a 300px rail to the right of the table; below ~1040px the tiles become a strip above the table and the cards re-flow into a grid above it (Top tools and Active agents side by side with equal heights, Recent errors full width); below ~640px everything is single column. Relates: PROD-6844 🤖 Generated with [Claude Code](https://claude.com/claude-code) | 1 天前 | |
fix: wire missing org-management and dashboard-export scopes into role tiers and add org-parity + vocabulary-coverage tests (#22802) | 2 个月前 | |
docs: update CASL audit rule to reference createAuditedAbility (#22668) Point contributors to BaseService.createAuditedAbility and the audit-logging.md doc instead of the lower-level caslAuditWrapper.ts implementation. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> | 2 个月前 | |
ci: pin npm to 11.x in the release job, unbreaking Build & Release (#25314) npm 12.0.0 bumped its engines requirement to Node >=22.22.2 (or >=24.15.0 / >=26.0.0), so "sfw npm install -g npm@latest" in the release job now fails with EBADENGINE on our current Node 20 (.nvmrc), taking down the release/publish step on every push to main since npm 12.0.0 shipped. npm 11.x still supports Node ^20.17.0 and the OIDC/trusted-publishing flow this step exists for, so pin to the latest 11.x release. Temporary: the scheduled Node 24 cutover (PROD-8557, due 2026-07-29) will let this step track npm@latest again. | 19 小时前 | |
chore: revert chore: rename pre-commit hook to pre-push (#16826) Reverts lightdash/lightdash#16825 | 9 个月前 | |
chore: add Lightdash dbt 2.0 schema validation for model files (#21943) <!-- Thanks so much for your PR, your contribution is appreciated! ❤️ -->Description: Added JSON schema validation for Lightdash dbt 2.0 configuration files in VS Code. This enables IntelliSense, validation, and auto-completion for YAML files in the `models` directory by associating them with the Lightdash dbt 2.0 JSON schema. <!-- Even better add a screenshot / gif / loom --> | 2 个月前 | |
chore: exclude generated files from Zed file scanning (#21350) ### Description: Added file scan exclusions to Zed editor settings to ignore all files and directories under `**/generated/**` paths. This prevents the editor from scanning generated code files, improving performance and reducing noise in search results. | 3 个月前 | |
chore: remove PostHog from codebase (#22972) | 1 个月前 | |
feat: add organization brand profile fetching (#25208) * Add Brandfetch organization brand profile with hidden prototype page Backend: - New organization_brands table (one brand profile per organization) - BRANDFETCH_API_KEY env config (lightdashConfig.brandfetch); brand fetching is only available when the key is configured - GET /api/v1/org/brand returns the stored brand profile (null if none) - POST /api/v1/org/brand fetches the brand for a domain from the Brandfetch Brand API and upserts it on the organization Frontend: - Hidden prototype page at /brand-prototype (direct link only, no nav entry) that fetches a brand by company domain and renders the detected logo, theme colors and example charts themed to the brand Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SzA5JvZBM5BGig15Zpw7Q5 * Address review: store brand on organizations, preview env var, design polish - Replace the 1:1 organization_brands table with a nullable brand JSONB column on organizations (rewrote the unmerged migration in place; preview DBs are ephemeral so no upgrade path is needed) - Add BRANDFETCH_API_KEY passthrough to docker-compose.preview.yml so preview envs pick up the value set in the Okteto panel - Restyle the brand prototype page to match the app design system: theme tokens (ldGray/foreground, radius/shadow vars), Paper cards, native dark Button variant, heading weight 600, Badge/input theme defaults instead of hardcoded hex values and overrides Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SzA5JvZBM5BGig15Zpw7Q5 * Redesign brand prototype: app preview with brand header + derived palettes Replace the onboarding-style mock with a theme derivation playground: - New brandPrototypeTheme.ts ports the OKLCH brand->theme derivation: neutral/primary ramps, 8-series categorical palette (brand hues as anchors, greedy max-gap hue fill, 3:1 contrast enforcement, CVD collision gating), 9-step sequential and diverging palettes, and contrast-solved surface/header/button tokens. Brand hues seed the palettes but raw brand hexes are not reused as data colors. - Page now shows an app preview (header in the primary brand color with the fetched logo, KPI cards, bar/line/heatmap charts using the derived palettes) alongside categorical/sequential/diverging palette sections, with a swatch picker to choose which brand color seeds the theme. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SzA5JvZBM5BGig15Zpw7Q5 * Fix oxfmt formatting on brand prototype files Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SzA5JvZBM5BGig15Zpw7Q5 * Restrict brand fetching to org admins and gate the prototype page - POST /org/brand already required 'update Organization' (the same permission as managing color palettes); add an explicit 'view Organization' check to GET /org/brand - Gate /brand-prototype behind the same ability check on the frontend: users without 'update Organization' see the forbidden panel Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SzA5JvZBM5BGig15Zpw7Q5 * Increase out-of-the-box vibrancy of derived palettes Raise the OKLCH chroma ceilings slightly: categorical 0.14 -> 0.17, sequential ramp max 0.16 -> 0.20, diverging endpoints 0.15 -> 0.18. Hues that can't reach the ceiling in sRGB are still gamut-mapped down per colour, so nothing clips. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SzA5JvZBM5BGig15Zpw7Q5 * Fix unused-exports check: make theme helpers module-private Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SzA5JvZBM5BGig15Zpw7Q5 --------- Co-authored-by: Claude <noreply@anthropic.com> | 2 天前 | |
feat: surface app dependency changes; instance toggle for custom deps [GLITCH-603] (#25179) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 6 小时前 | |
feat: support filter autocomplete values and labels and disable warehouse fetch (#24851) * Add dbt filter autocomplete labels * chore: update PR title validation | 10 天前 | |
feat(mcp): server-side session segmentation for activity grouping (#25335) ## Summary Moves session grouping into SQL so it's exact (stacked on #25334). The activity query now orders calls by *session segments*: each call belongs to a block (its session id, or a shared no-session block), blocks split into segments on 1-hour inactivity gaps, and each segment anchors at its latest call. This fixes the two limitations of client-side grouping: - **Interleaved sessions no longer fragment** — a segment's calls are contiguous in the stream even when other activity overlaps them in time. - **A session resumed days later renders as two separately placed segments** sharing the same session id, instead of hoisting old calls out of their chronological neighborhood. Sessionless calls keep their exact chronological position. ## Implementation - `McpToolCallModel.buildSessionGroupedQuery`: CTE chain (block key → gap detection via `lag` → running-sum segment numbering → per-segment anchor/counts via window functions), with the final CTE aliased back to the tool-call table name so existing joins, selects, and `KnexPaginate` work unchanged - Each row carries `sessionGroup: { key, callCount, errorCount }` — server-computed totals for the whole segment, so headers show true counts even when a segment spans page boundaries - Grouping is opt-in per query: the activity endpoint enables it (time sort only); stats `recentErrors` keeps flat chronological order - Frontend groups by the server key instead of run-contiguity, and a lone sessionless call renders as a plain row instead of a one-call group ## Testing Validated the SQL directly and end-to-end in the dev app with a seeded session spanning two sittings 3 days apart: the return sitting renders at the top (2 calls · 1 error), the first sitting renders at its 3-days-ago position (3 calls), both labeled with the same session id. Typecheck, lint, and backend tests pass. Relates: ZAP-602 🤖 Generated with [Claude Code](https://claude.com/claude-code) | 1 小时前 | |
feat: surface app dependency changes; instance toggle for custom deps [GLITCH-603] (#25179) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 6 小时前 | |
chore: improve k8s down script (#25267) | 1 天前 | |
feat(ai-writeback): add dbt/SQL best-practice skill for the writeback agent (PROD-8719) (#25248) The dbt-writeback sandbox agent had no curated guidance on how to write good dbt SQL, so on repos whose existing models use non-idiomatic patterns it would imitate them — e.g. adding a metric via a correlated subquery instead of reusing existing fields or joining an aggregated CTE. Add a baked Claude Code skill, `skills/effective-dbt-sql/`, installed into the sandbox via the existing `lightdash install-skills` step. It is deliberately semantics-only (reuse over re-derivation, CTEs/joins over correlated subqueries, explicit joins and columns) and defers naming/formatting to the target repo, so it never fights a repo's existing conventions. Auto-discovery surfaces a skill's frontmatter but does not load its body, so `buildSystemPrompt` now names the skill (mirroring the existing warehouse-skill nudge) to trigger the load. Scoped to the dbt-writeback agent only; the general editRepo prompt is unchanged. Adds a repo-root skill-package validation test (also guards the existing developing-in-lightdash package). Claude-Session: https://claude.ai/code/session_01CgtQMJ5u1o8j4FUKhg3f7g Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> | 2 天前 | |
docs: Update README.md with new features and updated resources (#7654) * Delete static/screenshots/lightdash_preview_chart_animation.gif * docs: update README gif * Delete static/screenshots/lightdash_preview_chart_animation.gif * docs: update README gif * Update README.md | 2 年前 | |
docs: add st-lab7 as a contributor for code (#24412) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] --------- Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> | 22 天前 | |
chore: deploy previews with okteto (#14925) --------- Co-authored-by: Javier Rengel Jiménez <rephus@gmail.com> Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com> | 1 年前 | |
feat: add SCHEDULER_INCLUDE_TASKS and SCHEDULER_EXCLUDE_TASKS environment variables (#15729) | 11 个月前 | |
chore: document S3_PUBLIC_ENDPOINT better (#21880) | 2 个月前 | |
chore: add max payload env var to docker compose (#3689) | 3 年前 | |
feat(avatars): gradient ids, deterministic picker and avatar payload types (#25053) ## Summary First slice of user avatars: gradient identity + payload plumbing (no UI yet). - `USER_AVATAR_GRADIENT_IDS` + deterministic `getUserAvatarGradient(userUuid, override)` in `@lightdash/common` — every user maps to a stable brand gradient; an explicit override wins. - `user_avatars` table (uuid PK/FK, processed image bytea, sha256 `content_hash`) + nullable `users.avatar_gradient` (additive migration). - `UserAvatarModel` — deliberately exposes no list-shaped query that selects the blob; list joins only ever read `content_hash`. - `LightdashUser` and `OrganizationMemberProfile` gain `avatarUrl: string | null` + `avatarGradient` (session-user query joins a derived table projecting only the hash, so the bytea never enters `select *`). ## Regression analysis Payload fields are additive `| null` — no existing consumer changes behavior. No visual change ships in this PR (rendering lands upstack). Applies to all auth paths (session, PAT, service accounts) identically since it rides `mapDbUserDetailsToLightdashUser`. Stack: 1/4 (foundations) → #25054 (API) → #25055 (rendering) → #25056 (settings UI) 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_012qtyCMqL6tkoDoZ46bn4Q2 | 7 天前 | |
chore: migrate Prettier to Oxfmt (#20557) * chore: migrate prettier to oxfmt * chore: format with oxfmt * chore: ignore gitblame on bulk formatting with oxfmt | 4 个月前 | |
chore: gitignore docs/superpowers and untrack existing files (#25171) Superpowers plans and specs are local working artifacts. Stop tracking them in git and ignore the directory to avoid future accidental commits. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> | 3 天前 | |
chore: remove lightdash yaml completely (#10796) | 1 年前 | |
chore: from yarn to pnpm (#13258) | 1 年前 | |
chore: use --isolated flag for Chrome DevTools MCP to prevent profile lock conflicts (#21419) The previous approach used `isolatedContext` on individual tool calls, which only creates isolated browser contexts within a single Chrome instance. It doesn't prevent the "browser is already running" error when another process holds the profile directory lock. The `--isolated` server flag creates a temporary user-data-dir per MCP server instance, which is the correct fix. Reverts the isolatedContext additions from #21416. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> | 3 个月前 | |
chore: upgrade pnpm to v10.33 and add 3-day minimum release age (#21701) * chore: upgrade pnpm to v10.33 and add 2-day minimum release age Upgrades pnpm from 9.15.5 to 10.33.0 across the monorepo (package.json, Dockerfiles, cloud-init). Adds `minimumReleaseAge: 2880` (2 days) to pnpm-workspace.yaml as supply chain protection — pnpm will refuse to install any package version published less than 2 days ago. Also adds `pnpm.onlyBuiltDependencies` allowlist for the 16 packages that require postinstall lifecycle scripts, since pnpm 10 disables them by default. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ci: trigger full test suite * chore: fix .npmrc cooldown to use npm 11.10+ syntax The existing .npmrc value `minimum-release-age=3d` (added in #21785) is a no-op on every installer: - npm CLI 11.10+ accepts `min-release-age` (kebab, no leading "minimum"), not `minimum-release-age`. Value must be an integer number of days, not a duration string like "3d". - pnpm does not read .npmrc for this setting at all — it requires `minimumReleaseAge` (in minutes) in pnpm-workspace.yaml, which this PR adds at the workspace level. Together with this PR's pnpm-workspace.yaml change, both install paths are now actually protected: - pnpm install (this monorepo) → 2880 minutes (2 days) via pnpm-workspace.yaml - npm install -g @lightdash/cli (CLI users on npm 11.10+) → 3 days via .npmrc Older npm versions silently ignore the setting — graceful fallback. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: bump pnpm minimumReleaseAge from 2 to 3 days Aligns with .npmrc `min-release-age=3` so both pnpm and npm install paths apply the same 3-day cooldown window. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: pin e2b sandbox to pnpm@10.33.0 Aligns with the other Dockerfiles (dockerfile, dockerfile-prs, agent-harness/cloud/cloud-init.yml) which all pin to 10.33.0 via corepack. Without the patch suffix, the sandbox could drift to a newer pnpm 10.x at build time and behave differently from the rest of the Lightdash environment. Spotted by Graphite AI review. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> | 2 个月前 | |
chore: update nvmrc to 20.19 (#17502) <!-- Thanks so much for your PR, your contribution is appreciated! ❤️ --> Relates to: https://app.graphite.dev/github/pr/lightdash/lightdash/17495/chore-update-Vite-to-v7-and-related-dependencies ### Description: Updates Node.js version from 20.8.0 to 20.19 in `.nvmrc` file. https://vite.dev/blog/announcing-vite7 required by vite 7 | 8 个月前 | |
chore: deploy previews with okteto (#14925) --------- Co-authored-by: Javier Rengel Jiménez <rephus@gmail.com> Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com> | 1 年前 | |
chore: add CLAUDE.md to formatting ignore patterns (#21134) | 3 个月前 | |
feat: upgrade echarts to v6 (#17896) <!-- Thanks so much for your PR, your contribution is appreciated! ❤️ --> Related: #8811 ### Description: Upgraded echarts from v5.x to v6.0.0 across all packages. Fixed legend positioning in charts to maintain consistent behavior after the upgrade, as echarts v6 changed the default legend position to bottom. The changes include: - Updated echarts dependency to ^6.0.0 in backend, common, and frontend packages - Added explicit legend orientation and positioning in useEchartsCartesianConfig.ts to maintain backward compatibility with previous chart layouts This upgrade includes fix for issue https://github.com/apache/echarts/issues/9265 that should avoid chart labels overlapping axis [WIP] | 7 个月前 | |
chore: deploy previews with okteto (#14925) --------- Co-authored-by: Javier Rengel Jiménez <rephus@gmail.com> Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com> | 1 年前 | |
chore(release): 0.3351.0 # [0.3351.0](https://github.com/lightdash/lightdash/compare/0.3350.0...0.3351.0) (2026-07-09) ### Bug Fixes * **scheduler:** enforce AI agent space access on AI-augmented deliveries ([#25357](https://github.com/lightdash/lightdash/issues/25357)) ([5d64b50](https://github.com/lightdash/lightdash/commit/5d64b502551ad1ab0334c37951e779814a985491)) ### Features * **tables:** use 3-dot icon for column header context menus ([#25354](https://github.com/lightdash/lightdash/issues/25354)) ([8765ca9](https://github.com/lightdash/lightdash/commit/8765ca948d686cbe77a2436aa6e09afb8a874daa)) * **totals:** gate totals on query success and show loading skeletons ([#25353](https://github.com/lightdash/lightdash/issues/25353)) ([17ce73d](https://github.com/lightdash/lightdash/commit/17ce73d2c36ad1559ec15c055d5d0aae2834c351)) | 1 小时前 | |
chore(ci): block unreviewed dependency install scripts via strictDepBuilds (#24762) Enable pnpm strictDepBuilds so `pnpm install` fails when a dependency has a preinstall/install/postinstall script that isn't reviewed in onlyBuiltDependencies or ignoredBuiltDependencies. Move the build-script config to pnpm-workspace.yaml so each ignored package documents why its script is safe to skip. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> | 14 天前 | |
feat: ee features (#13402) * feat: EE features * docs: license * docs: license * docs: license * docs: license * chore: amend api examples * docs: license * fix: migration rollback * fix: split EE migrations * fix: update commercial catalog model override | 1 年前 | |
docs: add st-lab7 as a contributor for code (#24412) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] --------- Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> | 22 天前 | |
docs: fix typo(#15451) | 1 年前 | |
feat(coding-agent): general-purpose editRepo agent (#24542) * feat(coding-agent): general-purpose editRepo agent (squashed stack) Squash of the full coding-agent stack (former slices 1–14, PRs #24502–24508) into a single commit. Generalises the dbt-writeback engine into a general-purpose coding agent that edits a customer's own repositories and opens PRs, with verification delegated to the PR's own CI. Engine & tool: - Extract runCodingAgent core from AiWritebackService; lean E2B image (git + Claude CLI, no dbt/compile) published per release by CI. - editRepo tool wired end-to-end (common schema + ToolName, backend tool, frontend chat card), gated by the ai-coding-agent feature flag. Authorization & security: - resolveWritableRepoTarget authz chokepoint; non-writable repos badged in the @-mention picker. - Host-enforced denied-path commit gate (.github/workflows, secrets) with a .git scrub; scoped clone token, pre-clone size guard, audit logging. Multi-PR workstreams: - Re-key ai_writeback_thread by (thread, repo); a thread holds multiple workstreams (one sandbox + one PR each), even several per repo. - listWorkstreams tool routes a follow-up to the right PR; per-workstream concurrency lock + per-thread sandbox cap (3) serialize concurrent turns. - First-class "Pull requests in this conversation" panel. - closePullRequest tool to close a thread's PR. Parity & fixes: - GitLab parity for editRepo. - Keep agent prompt files off sticky /tmp so a resumed sandbox can overwrite them (E2B envd quirk) — fixes every follow-up turn on a resumed sandbox. - Address Graphite AI review comments (error hierarchy, JSDoc, build retry, stale config comment). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WnFUP914iUf5s15GRHtJsL * fix(coding-agent): harden writeback authz, secret reads, error mapping, PR close Address four review findings in the general coding-agent writeback path: - Fail closed when a linked user's GitHub repo listing fails: previously a transient API/rate-limit error degraded write authz to the full installation repo set, bypassing the user∩installation intersection. Now denies the target. - Deny Grep (not just Read) on .git/.env/keys/credentials so the agent can't grep secret lines out and write them into an allowed file. - Classify WritebackGitNotConnectedError before the generic ForbiddenError it extends, so a missing GitHub/GitLab app maps to *_not_installed (install CTA) instead of repo_write_forbidden, in both the catch block and the classifier. - Close PRs through the workstream's own provider: resolve the URL back to the recorded pull_requests row scoped to the current thread, re-check manage:SourceCode, and close via that provider. CiService only closes PRs in the project's dbt repo, so general-agent PRs in other repos were unclosable. Adds GitProvider.closePullRequest (+ Github/Gitlab impls), a gitlab closeMergeRequest client, and PullRequestsModel.findByAiThreadUuidAndUrl. Adds regression tests for each finding. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(coding-agent): close denylist bypasses, case-sensitivity, blank tool label Address review findings on the editRepo coding agent: - M1/R3: CI-path denylist now matches both `.yml` and `.yaml` for every single-file CI config (.gitlab-ci, azure-pipelines, bitbucket-pipelines) — a workflow under the alternate extension was an RCE-in-customer-CI bypass. - M2/R6: secret-path denylist now catches `<name>.env` files (prod.env, app.env.local), plus `.keystore`/`.jks`, not just dotfile `.env*`. - L1: writable-repo membership is now case-insensitive at the authz chokepoint and in the user-intersection, so a repo whose slug differs only in case between the installation and user listings is no longer falsely denied. - M5: add `listWorkstreams` to both tool display-message maps (was in the enum but rendered a blank activity row). - H1: correct the misleading concurrency comment — the partial unique is pull_request_uuid-keyed and does NOT prevent a cross-pod double-open; the in-process guard is single-instance best-effort. Adds regression tests: denylist `.yaml`/`<name>.env` coverage with near-miss allows, case-insensitive intersection, and a zero-`Bash(` assertion on GENERAL_ALLOWED_TOOLS (the headline no-shell invariant). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(coding-agent): cross-pod workstream lock, GitLab size guard, stale-PR recovery Address the higher-priority concurrency/GitLab/multi-turn review findings: - H1: add a cross-pod workstream guard. The in-memory Set only serialized turns on one instance (the partial unique is PR-keyed and can't stop a cross-pod double-open). AiWritebackThreadModel.acquireWorkstreamLock now takes a session-level pg_try_advisory_lock keyed on the workstream, held across the turn and released in the run's finally; a racing turn on any instance is rejected. Non-transaction-scoped to avoid an idle-in-transaction abort over the multi-minute run; pins one pooled connection per in-flight turn (flag-gated, low concurrency). - H2/R9: add a GitLab pre-clone repo-size guard (getRepositorySizeMb via project statistics), mirroring the GitHub path, so a giant GitLab repo fails closed with an actionable error instead of an opaque clone timeout. (Note: keeping the ai-coding-agent flag off for GitLab orgs until Slice 6 remains a rollout policy, not enforced in code.) - M4: a resumed workstream whose PR was deleted (null pr_url via FK ON DELETE SET NULL) is now treated as a fresh turn (new PR off the default branch) instead of throwing and discarding the agent's work. - M3: remove the dead setPullRequest plumbing (zero callers) and tighten create()'s pullRequestUuid/targetRepo to non-null; document R11 as fresh-PR-on-retry (no "PR pending" placeholder state exists). Adds tests: advisory-lock acquire/contend/release/error-cleanup, GitLab size-in-MB parsing + null fallback, and stale-PR recovery in prepareTurn. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(coding-agent): general-agent security invariants + review cleanups (H3, L2-L8) Close the remaining review findings: - H3/M6: cover the general-agent (mode:'general') security invariants that previously rode only on constants + comments — generalCodingAgentConfig tests (no-Bash allowlist + secret/CI denylist passed to the CLI, no compile hooks, scoped contents:read clone token minted + revoked after clone, non-GitHub falls back to scrub-only), the manage:SourceCode write-audit line (allowed + denied), the R9 size-guard fail-closed, and a stronger R13 netlock invariant (deny-all + specific-hosts, not a literal allowlist). - L2: verified via Claude Code docs that `//path` is the ABSOLUTE-path syntax (`/path` is project-root-relative) — dropping the slash would break the deny rules. Kept the `//`, hardened the comment, and added guard tests that lock the absolute-path prefix on the allow + deny lists. - L3/vector-b: redactTokens() scrubs token-shaped substrings (GitHub/GitLab tokens, URL credentials) from the PR title/body/summary and the user reply. - L4/L5/L6: reconcile docstrings with as-built — runEditRepo/editRepo gate target any writable repo via the chokepoint (not just the dbt repo); the picker's writable flag is display-only (resolver is authoritative + fails closed); migration note on null-target_repo legacy rows + absent provider column. - L7: ThreadWorkstreamsPanel uses ldGray + CSS-module classes (no inline styles); merge/close now invalidate the workstreams query so the panel badge updates. - L8: drop redundant `?? null` in editRepo success metadata (already T | null). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(coding-agent): deterministic findByAiThreadUuid; document single-repo writeback coupling findByAiThreadUuid ordered the multi-PR thread query by created_at desc before LIMIT 1, so getThreadPullRequest no longer returns an arbitrary PR for a multi-PR thread. Also document that the remediation writeback path's "latest wins" [0] selection is only correct because the thread is forced to editDbtProject (single dbt repo) — a future switch to the general editRepo tool would silently drop all-but-newest PRs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(coding-agent): cover denied-path commit gate wiring (secret/CI, no PR) The denied-path chokepoint is the single host-enforced backstop for a no-Bash agent that commits via the GitHub/GitLab API. Until now only the pure findDeniedCommitPaths helper was tested; the glue that actually enforces it (git -z output -> parseGitNameStatus -> findDeniedCommitPaths -> throw DeniedPathError, and no PR opened) was untested, so a wiring regression could leak a secret or CI file into a customer PR with every test still green. - sandboxGit.test.ts: drive real parseGitNameStatus + findDeniedCommitPaths through collectFileChanges (GitHub) and assertStagedPathsAllowed (GitLab), stubbing only sandbox.commands.run. Covers secret-always-denied, CI-only-for-general-agent (denyCiPaths), denied deletions, and the allowed-changeset pass-through. - GitlabProvider.test.ts: assert a CI-touching commit rejects with DeniedPathError and opens no MR / performs no push. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(coding-agent): finish vitest migration of writeback tests after rebase main migrated the backend test suite from jest to vitest; our new/auto-merged writeback test files still used the jest.* mock API. Convert the remaining jest.fn/spyOn/clearAllMocks/Mock usages to their vi.* equivalents so they run under the vitest project. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TzfMeGvUzKNECxFyNXf5Mi * chore(coding-agent): oxfmt AiWritebackService types + tests Fixes the backend format check (oxfmt --check) that failed CI: import ordering in types.ts and a multi-line signature reflow. Formatting only, no behaviour change. * chore(coding-agent): regenerate OpenAPI spec after rebase on main Rebased onto origin/main (+23 commits); regenerated routes.ts + swagger.json so the spec reflects both main's new endpoints and the coding-agent (editRepo/listWorkstreams/closePullRequest) routes. Generated artifact only. * chore(coding-agent): reconcile with #24967 dbt-source targeting after rebase Rebased onto origin/main (+#24967, which added per-turn dbt-source selection to the same prepareTurn/writeback-thread surface). Merged both: prepareTurn resolves the git target per mode (general → resolveWritableRepoTarget; dbt → resolveDbtTarget source selection) and keys the workstream row on the resolved repo; ai_writeback_thread carries both project_dbt_source_uuid and target_repo. Regenerated OpenAPI + MCP snapshots; adapted workstream tests to the PreparedTurn return shape + the dbt path's findByAiThreadUuid source-binding lookup. * chore(coding-agent): regenerate OpenAPI route assets after rebase on main Rebased onto origin/main (+60 commits); regenerated routes.ts + swagger.json so the spec reflects main's new endpoints and the coding-agent (editRepo/listWorkstreams/closePullRequest) routes. Generated artifact only. * chore(coding-agent): regenerate OpenAPI assets after rebase on main Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TzfMeGvUzKNECxFyNXf5Mi --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> | 3 天前 | |
chore: remove exposed port from headless browser service (#24912) Closes: https://linear.app/lightdash/issue/SPK-532/veria-40-unauthenticated-headless-browser-exposure-enabling-server ### Description: Removes the exposed port mapping (`3001:3000`) from the headless browser service in `docker-compose.yml`. This prevents the headless browser service from being directly accessible on the host machine, keeping it as an internal service only. | 9 天前 | |
fix(docker): pin dbt 1.12 pre-releases, unbreaking image builds (#25327) * fix(docker): pin dbt 1.12 pre-releases, unbreaking image builds dbt-core 1.12 has no stable PyPI release (latest is 1.12.0rc1), so pip cannot satisfy dbt-core~=1.12.0 and every image build fails, including all preview environment deploys. Pin the latest available pre-releases explicitly and drop dbt-databricks from the 1.12 venv: no dbt-databricks release is compatible with dbt-core 1.12 (1.12.1 caps dbt-core<1.11.12). Resolution of the full pin set verified with pip install --dry-run on Python 3.11. * ci: trigger preview deploy | 7 小时前 | |
fix(docker): pin dbt 1.12 pre-releases, unbreaking image builds (#25327) * fix(docker): pin dbt 1.12 pre-releases, unbreaking image builds dbt-core 1.12 has no stable PyPI release (latest is 1.12.0rc1), so pip cannot satisfy dbt-core~=1.12.0 and every image build fails, including all preview environment deploys. Pin the latest available pre-releases explicitly and drop dbt-databricks from the 1.12 venv: no dbt-databricks release is compatible with dbt-core 1.12 (1.12.1 caps dbt-core<1.11.12). Resolution of the full pin set verified with pip install --dry-run on Python 3.11. * ci: trigger preview deploy | 7 小时前 | |
feat: add formula function suggestions to formula editor (#21867) <!-- Thanks so much for your PR, your contribution is appreciated! ❤️ --> Closes: <!-- reference the related issue e.g. #150 --> ### Description: <!-- Add a description of the changes proposed in the pull request. --> <!-- Even better add a screenshot / gif / loom --> | 2 个月前 | |
chore(nix): add sfw devtool to flake.nix (#23059) | 1 个月前 | |
feat: snowflake project creation SSO (#15126) * feat: snowflake project creation SSO * Add Snowflake SSO button with stubs for hooks * Update packages/frontend/src/components/ProjectConnection/WarehouseForms/SnowflakeForm.tsx Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com> * Setup proper default. Replace string labels with types and constants * Include isSsoEnabled when checking isLoadingAuth for input description * Fix build errors * Fix missed type error in cli * Use isTouched instead of isDirty --------- Co-authored-by: Steve Gardner <stevegardner@Mac.lan> Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com> Co-authored-by: Steve Gardner <gardnersj@gmail.com> | 1 年前 | |
refactor: improve CSV download tests by removing retries and fixing selectors (#15293) * fix: improve CSV download test reliability in Cypress * chore: dont use minio in preview envs | 1 年前 | |
chore(release): 0.3351.0 # [0.3351.0](https://github.com/lightdash/lightdash/compare/0.3350.0...0.3351.0) (2026-07-09) ### Bug Fixes * **scheduler:** enforce AI agent space access on AI-augmented deliveries ([#25357](https://github.com/lightdash/lightdash/issues/25357)) ([5d64b50](https://github.com/lightdash/lightdash/commit/5d64b502551ad1ab0334c37951e779814a985491)) ### Features * **tables:** use 3-dot icon for column header context menus ([#25354](https://github.com/lightdash/lightdash/issues/25354)) ([8765ca9](https://github.com/lightdash/lightdash/commit/8765ca948d686cbe77a2436aa6e09afb8a874daa)) * **totals:** gate totals on query success and show loading skeletons ([#25353](https://github.com/lightdash/lightdash/issues/25353)) ([17ce73d](https://github.com/lightdash/lightdash/commit/17ce73d2c36ad1559ec15c055d5d0aae2834c351)) | 1 小时前 | |
feat(coding-agent): general-purpose editRepo agent (#24542) * feat(coding-agent): general-purpose editRepo agent (squashed stack) Squash of the full coding-agent stack (former slices 1–14, PRs #24502–24508) into a single commit. Generalises the dbt-writeback engine into a general-purpose coding agent that edits a customer's own repositories and opens PRs, with verification delegated to the PR's own CI. Engine & tool: - Extract runCodingAgent core from AiWritebackService; lean E2B image (git + Claude CLI, no dbt/compile) published per release by CI. - editRepo tool wired end-to-end (common schema + ToolName, backend tool, frontend chat card), gated by the ai-coding-agent feature flag. Authorization & security: - resolveWritableRepoTarget authz chokepoint; non-writable repos badged in the @-mention picker. - Host-enforced denied-path commit gate (.github/workflows, secrets) with a .git scrub; scoped clone token, pre-clone size guard, audit logging. Multi-PR workstreams: - Re-key ai_writeback_thread by (thread, repo); a thread holds multiple workstreams (one sandbox + one PR each), even several per repo. - listWorkstreams tool routes a follow-up to the right PR; per-workstream concurrency lock + per-thread sandbox cap (3) serialize concurrent turns. - First-class "Pull requests in this conversation" panel. - closePullRequest tool to close a thread's PR. Parity & fixes: - GitLab parity for editRepo. - Keep agent prompt files off sticky /tmp so a resumed sandbox can overwrite them (E2B envd quirk) — fixes every follow-up turn on a resumed sandbox. - Address Graphite AI review comments (error hierarchy, JSDoc, build retry, stale config comment). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WnFUP914iUf5s15GRHtJsL * fix(coding-agent): harden writeback authz, secret reads, error mapping, PR close Address four review findings in the general coding-agent writeback path: - Fail closed when a linked user's GitHub repo listing fails: previously a transient API/rate-limit error degraded write authz to the full installation repo set, bypassing the user∩installation intersection. Now denies the target. - Deny Grep (not just Read) on .git/.env/keys/credentials so the agent can't grep secret lines out and write them into an allowed file. - Classify WritebackGitNotConnectedError before the generic ForbiddenError it extends, so a missing GitHub/GitLab app maps to *_not_installed (install CTA) instead of repo_write_forbidden, in both the catch block and the classifier. - Close PRs through the workstream's own provider: resolve the URL back to the recorded pull_requests row scoped to the current thread, re-check manage:SourceCode, and close via that provider. CiService only closes PRs in the project's dbt repo, so general-agent PRs in other repos were unclosable. Adds GitProvider.closePullRequest (+ Github/Gitlab impls), a gitlab closeMergeRequest client, and PullRequestsModel.findByAiThreadUuidAndUrl. Adds regression tests for each finding. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(coding-agent): close denylist bypasses, case-sensitivity, blank tool label Address review findings on the editRepo coding agent: - M1/R3: CI-path denylist now matches both `.yml` and `.yaml` for every single-file CI config (.gitlab-ci, azure-pipelines, bitbucket-pipelines) — a workflow under the alternate extension was an RCE-in-customer-CI bypass. - M2/R6: secret-path denylist now catches `<name>.env` files (prod.env, app.env.local), plus `.keystore`/`.jks`, not just dotfile `.env*`. - L1: writable-repo membership is now case-insensitive at the authz chokepoint and in the user-intersection, so a repo whose slug differs only in case between the installation and user listings is no longer falsely denied. - M5: add `listWorkstreams` to both tool display-message maps (was in the enum but rendered a blank activity row). - H1: correct the misleading concurrency comment — the partial unique is pull_request_uuid-keyed and does NOT prevent a cross-pod double-open; the in-process guard is single-instance best-effort. Adds regression tests: denylist `.yaml`/`<name>.env` coverage with near-miss allows, case-insensitive intersection, and a zero-`Bash(` assertion on GENERAL_ALLOWED_TOOLS (the headline no-shell invariant). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(coding-agent): cross-pod workstream lock, GitLab size guard, stale-PR recovery Address the higher-priority concurrency/GitLab/multi-turn review findings: - H1: add a cross-pod workstream guard. The in-memory Set only serialized turns on one instance (the partial unique is PR-keyed and can't stop a cross-pod double-open). AiWritebackThreadModel.acquireWorkstreamLock now takes a session-level pg_try_advisory_lock keyed on the workstream, held across the turn and released in the run's finally; a racing turn on any instance is rejected. Non-transaction-scoped to avoid an idle-in-transaction abort over the multi-minute run; pins one pooled connection per in-flight turn (flag-gated, low concurrency). - H2/R9: add a GitLab pre-clone repo-size guard (getRepositorySizeMb via project statistics), mirroring the GitHub path, so a giant GitLab repo fails closed with an actionable error instead of an opaque clone timeout. (Note: keeping the ai-coding-agent flag off for GitLab orgs until Slice 6 remains a rollout policy, not enforced in code.) - M4: a resumed workstream whose PR was deleted (null pr_url via FK ON DELETE SET NULL) is now treated as a fresh turn (new PR off the default branch) instead of throwing and discarding the agent's work. - M3: remove the dead setPullRequest plumbing (zero callers) and tighten create()'s pullRequestUuid/targetRepo to non-null; document R11 as fresh-PR-on-retry (no "PR pending" placeholder state exists). Adds tests: advisory-lock acquire/contend/release/error-cleanup, GitLab size-in-MB parsing + null fallback, and stale-PR recovery in prepareTurn. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(coding-agent): general-agent security invariants + review cleanups (H3, L2-L8) Close the remaining review findings: - H3/M6: cover the general-agent (mode:'general') security invariants that previously rode only on constants + comments — generalCodingAgentConfig tests (no-Bash allowlist + secret/CI denylist passed to the CLI, no compile hooks, scoped contents:read clone token minted + revoked after clone, non-GitHub falls back to scrub-only), the manage:SourceCode write-audit line (allowed + denied), the R9 size-guard fail-closed, and a stronger R13 netlock invariant (deny-all + specific-hosts, not a literal allowlist). - L2: verified via Claude Code docs that `//path` is the ABSOLUTE-path syntax (`/path` is project-root-relative) — dropping the slash would break the deny rules. Kept the `//`, hardened the comment, and added guard tests that lock the absolute-path prefix on the allow + deny lists. - L3/vector-b: redactTokens() scrubs token-shaped substrings (GitHub/GitLab tokens, URL credentials) from the PR title/body/summary and the user reply. - L4/L5/L6: reconcile docstrings with as-built — runEditRepo/editRepo gate target any writable repo via the chokepoint (not just the dbt repo); the picker's writable flag is display-only (resolver is authoritative + fails closed); migration note on null-target_repo legacy rows + absent provider column. - L7: ThreadWorkstreamsPanel uses ldGray + CSS-module classes (no inline styles); merge/close now invalidate the workstreams query so the panel badge updates. - L8: drop redundant `?? null` in editRepo success metadata (already T | null). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(coding-agent): deterministic findByAiThreadUuid; document single-repo writeback coupling findByAiThreadUuid ordered the multi-PR thread query by created_at desc before LIMIT 1, so getThreadPullRequest no longer returns an arbitrary PR for a multi-PR thread. Also document that the remediation writeback path's "latest wins" [0] selection is only correct because the thread is forced to editDbtProject (single dbt repo) — a future switch to the general editRepo tool would silently drop all-but-newest PRs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(coding-agent): cover denied-path commit gate wiring (secret/CI, no PR) The denied-path chokepoint is the single host-enforced backstop for a no-Bash agent that commits via the GitHub/GitLab API. Until now only the pure findDeniedCommitPaths helper was tested; the glue that actually enforces it (git -z output -> parseGitNameStatus -> findDeniedCommitPaths -> throw DeniedPathError, and no PR opened) was untested, so a wiring regression could leak a secret or CI file into a customer PR with every test still green. - sandboxGit.test.ts: drive real parseGitNameStatus + findDeniedCommitPaths through collectFileChanges (GitHub) and assertStagedPathsAllowed (GitLab), stubbing only sandbox.commands.run. Covers secret-always-denied, CI-only-for-general-agent (denyCiPaths), denied deletions, and the allowed-changeset pass-through. - GitlabProvider.test.ts: assert a CI-touching commit rejects with DeniedPathError and opens no MR / performs no push. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(coding-agent): finish vitest migration of writeback tests after rebase main migrated the backend test suite from jest to vitest; our new/auto-merged writeback test files still used the jest.* mock API. Convert the remaining jest.fn/spyOn/clearAllMocks/Mock usages to their vi.* equivalents so they run under the vitest project. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TzfMeGvUzKNECxFyNXf5Mi * chore(coding-agent): oxfmt AiWritebackService types + tests Fixes the backend format check (oxfmt --check) that failed CI: import ordering in types.ts and a multi-line signature reflow. Formatting only, no behaviour change. * chore(coding-agent): regenerate OpenAPI spec after rebase on main Rebased onto origin/main (+23 commits); regenerated routes.ts + swagger.json so the spec reflects both main's new endpoints and the coding-agent (editRepo/listWorkstreams/closePullRequest) routes. Generated artifact only. * chore(coding-agent): reconcile with #24967 dbt-source targeting after rebase Rebased onto origin/main (+#24967, which added per-turn dbt-source selection to the same prepareTurn/writeback-thread surface). Merged both: prepareTurn resolves the git target per mode (general → resolveWritableRepoTarget; dbt → resolveDbtTarget source selection) and keys the workstream row on the resolved repo; ai_writeback_thread carries both project_dbt_source_uuid and target_repo. Regenerated OpenAPI + MCP snapshots; adapted workstream tests to the PreparedTurn return shape + the dbt path's findByAiThreadUuid source-binding lookup. * chore(coding-agent): regenerate OpenAPI route assets after rebase on main Rebased onto origin/main (+60 commits); regenerated routes.ts + swagger.json so the spec reflects main's new endpoints and the coding-agent (editRepo/listWorkstreams/closePullRequest) routes. Generated artifact only. * chore(coding-agent): regenerate OpenAPI assets after rebase on main Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TzfMeGvUzKNECxFyNXf5Mi --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> | 3 天前 | |
fix: upgrade js-yaml 4.2.0→4.3.0 (security) (#25320)  ### Snyk has created this PR to fix 1 vulnerabilities in the pnpm dependencies of this project. #### Snyk changed the following file(s): - `packages/cli/package.json` <details> <summary>⚠️ <b>Warning</b></summary> ``` Failed to update the pnpm-lock.yaml, please update manually before merging. ``` </details> #### Vulnerabilities that will be fixed with an upgrade: | | Issue | :-------------------------:|:-------------------------  | Inefficient Algorithmic Complexity <br/>[SNYK-JS-JSYAML-17900054](https://snyk.io/vuln/SNYK-JS-JSYAML-17900054) #### Breaking Change Risk  > **Notice:** This assessment is enhanced by AI. --- > [!IMPORTANT] > > - Check the changes in this PR to ensure they won't cause issues with your project. > - Max score is 1000. Note that the real score may have changed since the PR was raised. > - This PR was automatically created by Snyk using the credentials of a real user. --- **Note:** _You are seeing this because you or someone else with access to this repository has authorized Snyk to open fix PRs._ For more information: <img src="https://api.segment.io/v1/pixel/track?data=eyJ3cml0ZUtleSI6InJyWmxZcEdHY2RyTHZsb0lYd0dUcVg4WkFRTnNCOUEwIiwiYW5vbnltb3VzSWQiOiIxZDYxMzBlMi0wMDgwLTQxMjctOTBkOS02MWNiNWU2ZmYzNDAiLCJldmVudCI6IlBSIHZpZXdlZCIsInByb3BlcnRpZXMiOnsicHJJZCI6IjFkNjEzMGUyLTAwODAtNDEyNy05MGQ5LTYxY2I1ZTZmZjM0MCJ9fQ==" width="0" height="0"/> 🧐 [View latest project report](https://app.snyk.io/org/oliver-Y822YbHSk6q5P9ZaauR79z/project/85e38e90-321e-4aa0-9179-2a7fc5a6f9b6?utm_source=github&utm_medium=referral&page=fix-pr) 📜 [Customise PR templates](https://docs.snyk.io/scan-using-snyk/pull-requests/snyk-fix-pull-or-merge-requests/customize-pr-templates?utm_source=github&utm_content=fix-pr-template) 🛠 [Adjust project settings](https://app.snyk.io/org/oliver-Y822YbHSk6q5P9ZaauR79z/project/85e38e90-321e-4aa0-9179-2a7fc5a6f9b6?utm_source=github&utm_medium=referral&page=fix-pr/settings) 📚 [Read about Snyk's upgrade logic](https://docs.snyk.io/scan-with-snyk/snyk-open-source/manage-vulnerabilities/upgrade-package-versions-to-fix-vulnerabilities?utm_source=github&utm_content=fix-pr-template) --- **Learn how to fix vulnerabilities with free interactive lessons:** 🦉 [Learn about vulnerability in an interactive lesson of Snyk Learn.](https://learn.snyk.io/?loc=fix-pr) [//]: # 'snyk:metadata:{"breakingChangeRiskLevel":"low","FF_showPullRequestBreakingChanges":true,"FF_showPullRequestBreakingChangesWebSearch":false,"customTemplate":{"variablesUsed":[],"fieldsUsed":[]},"dependencies":[{"name":"js-yaml","from":"4.2.0","to":"4.3.0"}],"env":"prod","issuesToFix":["SNYK-JS-JSYAML-17900054"],"prId":"1d6130e2-0080-4127-90d9-61cb5e6ff340","prPublicId":"1d6130e2-0080-4127-90d9-61cb5e6ff340","packageManager":"pnpm","priorityScoreList":[null],"projectPublicId":"85e38e90-321e-4aa0-9179-2a7fc5a6f9b6","projectUrl":"https://app.snyk.io/org/oliver-Y822YbHSk6q5P9ZaauR79z/project/85e38e90-321e-4aa0-9179-2a7fc5a6f9b6?utm_source=github&utm_medium=referral&page=fix-pr","prType":"fix","templateFieldSources":{"branchName":"default","commitMessage":"default","description":"default","title":"default"},"templateVariants":["updated-fix-title","pr-warning-shown"],"type":"auto","upgrade":["SNYK-JS-JSYAML-17900054"],"vulns":["SNYK-JS-JSYAML-17900054"],"patch":[],"isBreakingChange":false,"remediationStrategy":"vuln"}' test-frontend test-backend test-cli | 5 小时前 | |
chore(deps): update dependency hono (patch) [security] (#24371) Co-authored-by: lightdash-renovate-bot[bot] <285140159+lightdash-renovate-bot[bot]@users.noreply.github.com> | 2 天前 | |
feat(coding-agent): general-purpose editRepo agent (#24542) * feat(coding-agent): general-purpose editRepo agent (squashed stack) Squash of the full coding-agent stack (former slices 1–14, PRs #24502–24508) into a single commit. Generalises the dbt-writeback engine into a general-purpose coding agent that edits a customer's own repositories and opens PRs, with verification delegated to the PR's own CI. Engine & tool: - Extract runCodingAgent core from AiWritebackService; lean E2B image (git + Claude CLI, no dbt/compile) published per release by CI. - editRepo tool wired end-to-end (common schema + ToolName, backend tool, frontend chat card), gated by the ai-coding-agent feature flag. Authorization & security: - resolveWritableRepoTarget authz chokepoint; non-writable repos badged in the @-mention picker. - Host-enforced denied-path commit gate (.github/workflows, secrets) with a .git scrub; scoped clone token, pre-clone size guard, audit logging. Multi-PR workstreams: - Re-key ai_writeback_thread by (thread, repo); a thread holds multiple workstreams (one sandbox + one PR each), even several per repo. - listWorkstreams tool routes a follow-up to the right PR; per-workstream concurrency lock + per-thread sandbox cap (3) serialize concurrent turns. - First-class "Pull requests in this conversation" panel. - closePullRequest tool to close a thread's PR. Parity & fixes: - GitLab parity for editRepo. - Keep agent prompt files off sticky /tmp so a resumed sandbox can overwrite them (E2B envd quirk) — fixes every follow-up turn on a resumed sandbox. - Address Graphite AI review comments (error hierarchy, JSDoc, build retry, stale config comment). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WnFUP914iUf5s15GRHtJsL * fix(coding-agent): harden writeback authz, secret reads, error mapping, PR close Address four review findings in the general coding-agent writeback path: - Fail closed when a linked user's GitHub repo listing fails: previously a transient API/rate-limit error degraded write authz to the full installation repo set, bypassing the user∩installation intersection. Now denies the target. - Deny Grep (not just Read) on .git/.env/keys/credentials so the agent can't grep secret lines out and write them into an allowed file. - Classify WritebackGitNotConnectedError before the generic ForbiddenError it extends, so a missing GitHub/GitLab app maps to *_not_installed (install CTA) instead of repo_write_forbidden, in both the catch block and the classifier. - Close PRs through the workstream's own provider: resolve the URL back to the recorded pull_requests row scoped to the current thread, re-check manage:SourceCode, and close via that provider. CiService only closes PRs in the project's dbt repo, so general-agent PRs in other repos were unclosable. Adds GitProvider.closePullRequest (+ Github/Gitlab impls), a gitlab closeMergeRequest client, and PullRequestsModel.findByAiThreadUuidAndUrl. Adds regression tests for each finding. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(coding-agent): close denylist bypasses, case-sensitivity, blank tool label Address review findings on the editRepo coding agent: - M1/R3: CI-path denylist now matches both `.yml` and `.yaml` for every single-file CI config (.gitlab-ci, azure-pipelines, bitbucket-pipelines) — a workflow under the alternate extension was an RCE-in-customer-CI bypass. - M2/R6: secret-path denylist now catches `<name>.env` files (prod.env, app.env.local), plus `.keystore`/`.jks`, not just dotfile `.env*`. - L1: writable-repo membership is now case-insensitive at the authz chokepoint and in the user-intersection, so a repo whose slug differs only in case between the installation and user listings is no longer falsely denied. - M5: add `listWorkstreams` to both tool display-message maps (was in the enum but rendered a blank activity row). - H1: correct the misleading concurrency comment — the partial unique is pull_request_uuid-keyed and does NOT prevent a cross-pod double-open; the in-process guard is single-instance best-effort. Adds regression tests: denylist `.yaml`/`<name>.env` coverage with near-miss allows, case-insensitive intersection, and a zero-`Bash(` assertion on GENERAL_ALLOWED_TOOLS (the headline no-shell invariant). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(coding-agent): cross-pod workstream lock, GitLab size guard, stale-PR recovery Address the higher-priority concurrency/GitLab/multi-turn review findings: - H1: add a cross-pod workstream guard. The in-memory Set only serialized turns on one instance (the partial unique is PR-keyed and can't stop a cross-pod double-open). AiWritebackThreadModel.acquireWorkstreamLock now takes a session-level pg_try_advisory_lock keyed on the workstream, held across the turn and released in the run's finally; a racing turn on any instance is rejected. Non-transaction-scoped to avoid an idle-in-transaction abort over the multi-minute run; pins one pooled connection per in-flight turn (flag-gated, low concurrency). - H2/R9: add a GitLab pre-clone repo-size guard (getRepositorySizeMb via project statistics), mirroring the GitHub path, so a giant GitLab repo fails closed with an actionable error instead of an opaque clone timeout. (Note: keeping the ai-coding-agent flag off for GitLab orgs until Slice 6 remains a rollout policy, not enforced in code.) - M4: a resumed workstream whose PR was deleted (null pr_url via FK ON DELETE SET NULL) is now treated as a fresh turn (new PR off the default branch) instead of throwing and discarding the agent's work. - M3: remove the dead setPullRequest plumbing (zero callers) and tighten create()'s pullRequestUuid/targetRepo to non-null; document R11 as fresh-PR-on-retry (no "PR pending" placeholder state exists). Adds tests: advisory-lock acquire/contend/release/error-cleanup, GitLab size-in-MB parsing + null fallback, and stale-PR recovery in prepareTurn. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(coding-agent): general-agent security invariants + review cleanups (H3, L2-L8) Close the remaining review findings: - H3/M6: cover the general-agent (mode:'general') security invariants that previously rode only on constants + comments — generalCodingAgentConfig tests (no-Bash allowlist + secret/CI denylist passed to the CLI, no compile hooks, scoped contents:read clone token minted + revoked after clone, non-GitHub falls back to scrub-only), the manage:SourceCode write-audit line (allowed + denied), the R9 size-guard fail-closed, and a stronger R13 netlock invariant (deny-all + specific-hosts, not a literal allowlist). - L2: verified via Claude Code docs that `//path` is the ABSOLUTE-path syntax (`/path` is project-root-relative) — dropping the slash would break the deny rules. Kept the `//`, hardened the comment, and added guard tests that lock the absolute-path prefix on the allow + deny lists. - L3/vector-b: redactTokens() scrubs token-shaped substrings (GitHub/GitLab tokens, URL credentials) from the PR title/body/summary and the user reply. - L4/L5/L6: reconcile docstrings with as-built — runEditRepo/editRepo gate target any writable repo via the chokepoint (not just the dbt repo); the picker's writable flag is display-only (resolver is authoritative + fails closed); migration note on null-target_repo legacy rows + absent provider column. - L7: ThreadWorkstreamsPanel uses ldGray + CSS-module classes (no inline styles); merge/close now invalidate the workstreams query so the panel badge updates. - L8: drop redundant `?? null` in editRepo success metadata (already T | null). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(coding-agent): deterministic findByAiThreadUuid; document single-repo writeback coupling findByAiThreadUuid ordered the multi-PR thread query by created_at desc before LIMIT 1, so getThreadPullRequest no longer returns an arbitrary PR for a multi-PR thread. Also document that the remediation writeback path's "latest wins" [0] selection is only correct because the thread is forced to editDbtProject (single dbt repo) — a future switch to the general editRepo tool would silently drop all-but-newest PRs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(coding-agent): cover denied-path commit gate wiring (secret/CI, no PR) The denied-path chokepoint is the single host-enforced backstop for a no-Bash agent that commits via the GitHub/GitLab API. Until now only the pure findDeniedCommitPaths helper was tested; the glue that actually enforces it (git -z output -> parseGitNameStatus -> findDeniedCommitPaths -> throw DeniedPathError, and no PR opened) was untested, so a wiring regression could leak a secret or CI file into a customer PR with every test still green. - sandboxGit.test.ts: drive real parseGitNameStatus + findDeniedCommitPaths through collectFileChanges (GitHub) and assertStagedPathsAllowed (GitLab), stubbing only sandbox.commands.run. Covers secret-always-denied, CI-only-for-general-agent (denyCiPaths), denied deletions, and the allowed-changeset pass-through. - GitlabProvider.test.ts: assert a CI-touching commit rejects with DeniedPathError and opens no MR / performs no push. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(coding-agent): finish vitest migration of writeback tests after rebase main migrated the backend test suite from jest to vitest; our new/auto-merged writeback test files still used the jest.* mock API. Convert the remaining jest.fn/spyOn/clearAllMocks/Mock usages to their vi.* equivalents so they run under the vitest project. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TzfMeGvUzKNECxFyNXf5Mi * chore(coding-agent): oxfmt AiWritebackService types + tests Fixes the backend format check (oxfmt --check) that failed CI: import ordering in types.ts and a multi-line signature reflow. Formatting only, no behaviour change. * chore(coding-agent): regenerate OpenAPI spec after rebase on main Rebased onto origin/main (+23 commits); regenerated routes.ts + swagger.json so the spec reflects both main's new endpoints and the coding-agent (editRepo/listWorkstreams/closePullRequest) routes. Generated artifact only. * chore(coding-agent): reconcile with #24967 dbt-source targeting after rebase Rebased onto origin/main (+#24967, which added per-turn dbt-source selection to the same prepareTurn/writeback-thread surface). Merged both: prepareTurn resolves the git target per mode (general → resolveWritableRepoTarget; dbt → resolveDbtTarget source selection) and keys the workstream row on the resolved repo; ai_writeback_thread carries both project_dbt_source_uuid and target_repo. Regenerated OpenAPI + MCP snapshots; adapted workstream tests to the PreparedTurn return shape + the dbt path's findByAiThreadUuid source-binding lookup. * chore(coding-agent): regenerate OpenAPI route assets after rebase on main Rebased onto origin/main (+60 commits); regenerated routes.ts + swagger.json so the spec reflects main's new endpoints and the coding-agent (editRepo/listWorkstreams/closePullRequest) routes. Generated artifact only. * chore(coding-agent): regenerate OpenAPI assets after rebase on main Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TzfMeGvUzKNECxFyNXf5Mi --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> | 3 天前 | |
ci: release-safety marker for self-hosted upgrades (PROD-8359) (#24879) * ci: add release-safety marker generator (PROD-8359) Generate a machine-readable release-safety.json marker at release time so self-hosted operators' CI/CD can decide whether a release is risky to roll out. During a Helm upgrade the migration Job applies schema changes before the app rolls out, then a default RollingUpdate leaves the previous release's pods serving traffic against the already-migrated schema until the rollout completes. A non-backward-compatible migration can crash those old pods. Operators have had no machine-readable signal to gate on. P1 (this commit): - scripts/gen-release-safety.ts: pure core (detectMigrations, buildMarker) plus a thin IO shell. Detects DB migrations added since the previous tag, emits a flat, jq-gateable marker. Honest by design: rollingUpdateSafe is tri-state and never silently true/false for a migration-bearing release; capabilities[] declares what was checked; fails loud (non-zero exit, atomic write) rather than emitting a falsely-safe file. - scripts/release-safety.schema.json: versioned draft-07 contract for consumers. - scripts/gen-release-safety.test.ts: unit tests for the pure core. - release.config.js: generate the marker before @semantic-release/github and attach it as a release asset (asset-only, not committed). - docs/superpowers/specs: design doc covering the phased plan and blind spots. REST/MCP breaking-change detection and required-stop prerequisites are stubbed honestly (checked:false) for later phases. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: add release-safety backtest script (PROD-8359) Replays the migration detector across the last N release tags to measure the distribution of clear-to-roll vs migration-bearing releases — the empirical ship-gate for the marker. Over the last 300 releases (~26 days), ~10% carry migrations and ~90% are clear-to-roll, confirming the signal partitions releases meaningfully rather than reporting "unknown" on every one. Run: npx tsx scripts/release-safety-backtest.ts [count] Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: add agentic AI migration-safety review (PROD-8359, P6) Resolves the release-safety marker's rollingUpdateSafe "unknown" verdict into a real true/false when a release contains migrations. The migration detector is a cheap presence check; this is the gated second stage that decides whether the new migrations are backward-compatible with the PREVIOUS release's code during a rolling deployment — the thing that actually determines whether old pods crash. scripts/ai-migration-review.ts is an agentic reviewer (raw Messages API via fetch, no SDK). Claude gets two read-only tools scoped to the previous release's source — grep_old_code (git grep -E <lastTag>) and read_old_file (git show <lastTag>:<path>) — so it can verify whether the old code reads or writes the columns/tables/constraints a migration changes. A single structured call could only classify migration shape and returned "unknown" on anything app-dependent; with code access the agent cleared a 4-migration foreign-key batch to safe/high by confirming the old insert paths only ever write valid references. Fail-safe by construction: the verdict moves "unknown" -> true only on a high-confidence "safe"; "breaking" -> false; any API error, refusal, truncation, unparseable output, or tool-budget exhaustion degrades to "unknown" (Recreate) and exits 0. It never emits a falsely-safe verdict and never fails the release. Runs only on the ~10% of releases that carry migrations, so cost is bounded. Reads ANTHROPIC_API_KEY. Model: claude-opus-4-8, adaptive thinking, effort high. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: fold AI migration review into the marker generator + cache the loop (PROD-8359, P6) Wire the agentic migration reviewer into gen-release-safety.ts so the marker self-resolves. With --ai-review (and ANTHROPIC_API_KEY) the generator runs the review only when migrations.present is true, and folds the verdict into compatibility.rollingUpdateSafe / recommendedStrategy, appends the AI summary to notes, and adds "ai-review" to capabilities. buildMarker stays pure — it takes the verdict as an optional input and applies it only for migration-bearing releases, so the AI can never invent a verdict for a no-migration or first release. A degraded/null review leaves the honest "unknown" default; the review never fails the release. Also make the agentic loop cache-efficient: cache_control on the system prompt and the migration-files turn, plus a single rolling breakpoint that moves onto the last block each turn so the growing tool transcript is cached. Measured on the 4-migration batch, full-price input dropped from ~403k tokens to ~18 (rest served from cache), about 10x cheaper per review. ai-migration-review.ts is refactored to export aiMigrationReview() returning a structured result (or null on any fail-safe degrade); the CLI is a thin wrapper guarded so importing it doesn't run the CLI. Adds 3 unit tests for the verdict override (flip to true, breaking to false, ignored on no-migration releases); 15 tests pass. Note: the agentic verdict is non-deterministic (same migrations gave safe/high once and unknown/medium on repeat runs) — acceptable only because the gating lets variance cost an unnecessary Recreate but never silently clear a breaking change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: add status/resume section to release-safety design (PROD-8359) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: add REST API breaking-change detection to the release-safety marker (PROD-8359, P2) Populate the marker's api.rest block by diffing the generated OpenAPI spec (packages/backend/src/generated/swagger.json) between the previous tag and HEAD with `oasdiff breaking`. A non-empty breaking list means a REST consumer may break across the upgrade. - scripts/rest-api-diff.ts: pure summarizeBreaking() + IO diffRestApi(). Both spec sides are read from git (git show <ref>:<path>), never the working tree, matching the P1 migration detector — a mid-release spec regen can't perturb it. oasdiff compares a semantic model, so no key-normalization is needed. - Deterministic, so no opt-in flag: the generator auto-runs the diff when oasdiff is on PATH (OASDIFF_BIN or `which`) and a previous tag exists. Folds into api.rest and adds "rest" to capabilities; orthogonal to the migration signal. - Soft fail-safe: oasdiff missing / spec absent at a ref / oasdiff error / unparseable output -> checked:false (honest "not checked"), never asserts an unproven "no break", never fails the release. - buildMarker stays pure (takes the result as data), mirroring the P6 aiReview. - release.yml: pinned + sha256-verified oasdiff install step (audited harden-runner egress; plain curl, no Socket Firewall wrapper). - Fix a latent P6 schema bug: the capabilities enum was missing "ai-review". - Tests: scripts/rest-api-diff.test.ts + buildMarker restApi cases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci: add MCP tool-surface + upgrade-overrides signals to the release-safety marker (PROD-8359, P3 + P4) Two more independently-shippable marker phases; schemaVersion stays "1". P3 — api.mcp breaking-change detection: - packages/common/src/schemas/generateMcpToolsSnapshot.ts serializes the declared MCP tool surface (mcpToolDefinitions, each tool's for('mcp') view, input/output Zod -> zodToJsonSchema jsonSchema7 — same settings as the runtime contract snapshot test) to a byte-stable committed mcp-tools-1.0.json (27 tools). Wired into postgenerate-api with a --check freshness guard, mirroring the chart-as-code generator. - scripts/mcp-tools-diff.ts diffs the snapshot between the previous tag and HEAD (git show, never the working tree) with a conservative 4-rule classifier: tool removed, input field became required, input field removed, input field type changed. Additive / output-schema / description changes are NOT breaking. Folds into api.mcp + adds "mcp" to capabilities. Soft fail-safe: snapshot absent at a ref -> checked:false, never fails the release. - Resolved the declared-vs-runtime question: snapshot the DECLARED superset, not the flag-gated runtime subset — flag-gating is an operator's per-request choice, not a release change, and the declared set is the complete contract surface. P4 — upgrade-path overrides: - A committed, maintainer-authored release-safety.overrides.json (+ JSON schema) populates upgrade.minPreviousVersion/requiredStop/note. Version-keyed, most- specific entry wins; inert for every release except the one it names. - scripts/upgrade-overrides.ts: pure resolver + strict validator + loader. Folds into the upgrade block + adds "upgrade" to capabilities when consulted. - Fail-safe ASYMMETRY (deliberate): an absent file is inert, but a present-but- malformed file FAILS LOUD (non-zero exit) — silently dropping a maintainer's required-stop is the falsely-safe direction. Committed an inert default so the mechanism is live. buildMarker stays pure (both results passed as data). Tests: scripts/mcp-tools-diff.test.ts, scripts/upgrade-overrides.test.ts, plus buildMarker mcpApi/upgrade cases. All 53 release-safety tests pass; common typecheck clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci: add deterministic SQL-shape migration linter + activate AI review (PROD-8359) The non-LLM floor under the AI migration review, and the flip that turns the AI review on in the release pipeline. schemaVersion stays "1". SQL-shape linter (scripts/sql-migration-lint.ts): - Pure lintSource statically scans the up() body of each added Knex migration for destructive shapes that break the previous version's running code during a rolling update: drop/rename column or table, NOT NULL without a default (context-aware — createTable is safe, alterTable is a candidate, .defaultTo clears it), and raw-SQL equivalents. IO lintMigrations reuses addedMigrationPaths. - Precedence: a "breaking" finding is AUTHORITATIVE — it sets rollingUpdateSafe false and the generator SHORT-CIRCUITS the paid, non-deterministic AI review (no point paying a tool-loop to confirm what a regex proved). The AI remains the only path to a "true" verdict. Adds "sql-lint" to capabilities. - Bias is toward over-flagging: a false "breaking" only costs an unnecessary Recreate — the cautious direction the whole marker leans. It is a FLOOR, not a complete check; subtle data-backfill and code-only breaks stay the AI's and the blind-spot note's job. - Validated on a real historical migration: flagged the up() dropTableIfExists and the .notNullable().alter() that drops a default, but NOT the sibling .notNullable().defaultTo(...), and ignored the down() rollback. Activate the AI review: - --ai-review added to the release.config.js prepareCmd. - ANTHROPIC_API_KEY exported into the Semantic Release step (egress to api.anthropic.com over the harden-runner audited policy). - Still fully gated: migrations-present only, only when the SQL linter did not already prove a break, key-present only; any degrade leaves "unknown" and never fails the release. buildMarker stays pure (the lint summary is passed as data). Tests: scripts/sql-migration-lint.test.ts + buildMarker precedence cases (linter wins over AI; capability ordering migrations, sql-lint, ai-review, rest, mcp, upgrade). 73 release-safety tests pass; all scripts typecheck clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci: dark-launch the release-safety marker behind a kill-switch + add a PR preview comment (PROD-8359) Make the marker safe to merge without going live, and surface it on PRs so the author sees the determination before merge. Kill-switch (dark launch): - RELEASE_SAFETY_MARKER_ENABLED env, default false. While off, gen-release-safety computes + logs the marker but writes no file AND skips the paid AI review — a dark release publishes nothing and spends nothing. release.config.js ALSO gates the GitHub asset listing on the same env, so a missing file can never fail a release (bulletproof, not relying on plugin skip behaviour). Set to 'false' in the release.yml Semantic Release step; flipping to 'true' writes the file, attaches the asset, and enables the AI review in one switch. PR preview comment (shift-left): - .github/workflows/release-safety-pr.yml runs on PRs touching the schema/API/MCP surface (path-filtered). Lightweight: tsx + a pinned, sha256-verified oasdiff, no pnpm install (the generator imports only Node built-ins + git). Computes the marker against the merge-base with the target branch (enabled=true to a throwaway temp file, no --ai-review → zero API spend). - scripts/release-safety-pr-comment.ts renders a sticky comment (find-or-update via actions/github-script — the same pinned action the repo already uses for the test- selection comment) with: the determination, the matrix of which checks ran + what each found, and the customer-deploy consequence (old pods could CrashLoopBackOff -> Recreate; required stop; REST/MCP consumer breaks). Fork PRs are skipped (read-only token). The published asset stays dark — the comment is informational. Tests: scripts/release-safety-pr-comment.test.ts (9). 82 release-safety tests pass; all scripts typecheck clean; both workflows valid YAML. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci: run the AI migration review on ready PRs, not drafts (PROD-8359) The release-safety PR preview now runs the AI migration review on ready PRs — a real "about to merge" signal worth the spend — but skips it on drafts, which are still churning. release-safety-pr.yml passes --ai-review + ANTHROPIC_API_KEY only when pull_request.draft is false, and adds ready_for_review to the trigger types so flipping a draft to ready re-runs the preview with the AI. Still gated downstream: migration-bearing PRs only, only when the deterministic SQL linter didn't already decide, and degrades to "unknown" without a key (fork PRs, which don't comment anyway). The comment is draft-aware: on a draft it shows the AI row as skipped and invites the author to mark the PR ready to get the AI-refined verdict; once it has run, that nudge disappears and the verdict is folded into the determination. Tests updated for the draft/ready branches (11 renderer tests). 84 release-safety tests pass; renderer typechecks clean; workflow valid YAML. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> | 10 天前 | |
ci: carry the release-safety upgrade floor forward across releases (PROD-8359) (#24948) The marker's upgrade.minPreviousVersion was only ever set on the single release that declared it (a human override, or an expand/contract drop the AI cleared). A self-hosted operator skipping from an old version straight to a much later one read only the target marker, saw no floor, and could roll a destructive in-between migration under RollingUpdate — crashing the old pods mid-rollout. Make a single marker self-sufficient for version-skips: - carriedUpgradeFloor() computes a forward-carried high-water mark from the committed overrides: the most restrictive floor any release <= the target imposes (declared minPreviousVersion floors + required stops). buildMarker folds it in, only ever RAISING the floor (never lowering — the safe direction), so it can over-constrain but never falsely free a skip. - recordDerivedFloor() persists this release's own AI-cleared expand/contract floor back into release-safety.overrides.json (write-if-absent, atomic, re-validated), and release.config.js commits the file. Future releases then carry it forward automatically — they cannot re-derive it without re-running the AI. Gated by the same RELEASE_SAFETY_MARKER_ENABLED kill-switch. - ownExpandContractFloor() is the single source of truth for the derived floor, shared by the marker and the persistence write, with a drift-guard test asserting the two can never disagree. Tests: +14 across the two suites (version-skip carry, required-stop-as-floor, raise-not-lower, write-if-absent IO, drift guard). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> | 9 天前 | |
chore: drop shared jest deps now that all packages use vitest (#24888) <!-- Thanks so much for your PR, your contribution is appreciated! ❤️ --> Closes: <!-- reference the related issue e.g. #150 --> ### Description: <!-- Add a description of the changes proposed in the pull request. --> <!-- Even better add a screenshot / gif / loom --> ## Drop shared Jest deps (cleanup) Final step of the Jest → Vitest migration. With backend (merged to main), **common**, **cli**, and **warehouses** all on Vitest — and frontend already was — nothing in the repo uses Jest anymore. Removes from root `devDependencies`: `jest`, `ts-jest`, `@types/jest`, `jest-watch-typeahead`, `eslint-plugin-jest`; and the corresponding `renovate.json` groupings. Kept `eslint-plugin-jest-dom` (frontend uses `@testing-library/jest-dom` matchers, which work under Vitest). Lockfile: **−312 / +148**. Verified: no `jest.config`, no `jest` test script, no `jest` tsconfig types, and eslint config still resolves without `eslint-plugin-jest`. | 9 天前 | |
fix: keep pivot reference lines on matching series (#24326) ### Description - Keep pivoted reference lines attached to their matching pivot series instead of redistributing by base field only. - Preserve pivot field references when editing existing reference lines. - Add regression coverage for pivoted average reference lines. ### Testing - `pnpm exec oxlint -c .oxlintrc.json --ignore-path ./../../.gitignore src/components/common/ReferenceLine.tsx src/components/VisualizationConfigs/ChartConfigPanel/Legend/ReferenceLines.tsx src/hooks/cartesianChartConfig/useCartesianChartConfig.ts src/hooks/cartesianChartConfig/useCartesianChartConfig.test.ts` - Content-as-code verification in local app: - average reference-line chart renders two separate labels/lines - fixed-value reference-line chart renders two separate labels/lines Closes: https://github.com/lightdash/lightdash/issues/24391 | 21 天前 | |
ci: add socket.yml to scope Socket GitHub App on this monorepo (#22096) Without an explicit triggerPaths block, the Socket GitHub App's PR alerts default to scanning every change. With a pnpm monorepo of this size that means PR comments fire on irrelevant edits and (more importantly) the App's documented examples only cover npm/yarn lockfile paths — pnpm-lock.yaml is not in the default trigger set, so transitive dependency changes go unscanned. Scopes Socket scanning to: - Root and per-package package.json - pnpm-lock.yaml (transitive changes) - .npmrc and pnpm-workspace.yaml (registry / workspace config) Excludes examples/, node_modules, cypress fixtures, and formula tests from project-level reports. Suppresses PR comments authored by dependabot[bot] and renovate[bot] so bot bumps don't double-comment alongside Socket's own dependency-overview comment. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> | 2 个月前 | |
feat: add formula test harness (#21792) * feat: add formula test harness * fix: pin formula package dependencies to exact versions Replace range specifiers (^) with exact versions to comply with repo policy (.npmrc save-exact=true). Also bump typescript to 6.0.0-beta to match the rest of the monorepo and add ignoreDeprecations flag for node10 moduleResolution. - packages/formula: peggy, typescript, jest, ts-jest, @types/jest - packages/formula-tests: duckdb, pg, tsx, @types/pg, typescript Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Joao Viana <joao@lightdash.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> | 3 个月前 | |
feat(ci): use TS7 fast paths in PR checks (#24930) Use TypeScript 7 fast build and typecheck paths in PR checks. | 8 天前 |
开源 Looker 替代方案。
官网 • 观看演示 • 文档 • 加入 Slack 社区
功能特性:
- 🙏 熟悉的界面,方便用户使用预定义指标自助分析
- 👩💻 在 dbt 项目旁的 yaml 文件中声明维度和指标
- 🤖 从您的 dbt 模型自动创建维度
- 📖 为用户同步 dbt 描述和元数据
- 🔍 轻松访问图表的基础记录,并支持数据下钻
- 🧮 表格计算功能,便于实时深入分析数据
- 🕵️♀️ 血缘关系让您可以查看模型的上游和下游依赖
- 📊 全面且直观的指标数据可视化库
- 👷♂️ 保存图表并构建仪表板,与团队分享您的见解
- 💻 强大的开发者体验,包括预览 BI 环境和通过 CI/CD 进行自动化内容验证
- 🔄 查看所有图表的版本历史,并可随时回滚
- 🚀 通过 URL 轻松分享您的工作,或通过 Slack 或电子邮件安排交付
有什么功能缺失吗?查看我们的 开放问题,看看您需要的功能是否已经存在(如果存在,请给它点个👍)。如果没有,我们非常欢迎您提交新的需求 issue 😊
演示
体验我们的 演示应用!
快速开始
使用 Lightdash Cloud 开始
您可以通过 注册 Lightdash Cloud 免费试用版,避免自行托管和配置 Lightdash 的麻烦。更多定价详情 请见。
一键部署
在 Render 上一键免费部署 Lightdash。
本地运行
利用我们的安装脚本,轻松在本地运行 Lightdash。
git clone https://github.com/lightdash/lightdash
cd lightdash
./scripts/install.sh
部署到生产环境
请按照我们的Kubernetes指南,使用我们的社区Helm图表将Lightdash部署到生产环境。
快速开始
步骤1 - ⚡️ 自行托管Lightdash(可选)
步骤2 - 🔌 连接项目
步骤3 - 👩💻 创建您的第一个指标
社区支持
📣 如果您需要更多帮助,欢迎加入我们的Slack社区,您可以在那里直接与Lightdash团队的所有成员以及社区中其他优秀成员交流。我们很乐意讨论任何话题,从功能请求、实施细节、dbt的使用技巧,到表情包和SQL笑话!
您也可以通过以下渠道关注Lightdash的最新动态:
关于Lightdash
🗂 将所有业务逻辑集中管理。
我们允许您直接在dbt项目中定义指标和维度,将所有业务逻辑集中在一处,增加分析的上下文信息。
再也不用纠结四个不同的总收入数值中哪一个才是**正确**的(稍后您会感谢我们 😉)。
🤝 建立对数据的信任。
我们希望公司里的每个人都能放心使用数据。那么,为什么不**向他们展示**这种可靠性呢?
我们将您所需的数据质量上下文直接整合到BI工具中,让人们知道他们可以信任这些数据。
🧱 为用户提供有意义的构建块,助其自主解答数据问题。
使用Lightdash,SQL工作可以交给专家处理。我们为数据团队提供构建指标和维度所需的工具,供其他所有人使用。
这样,公司中的任何人都可以组合、细分和筛选这些指标与维度,自行解答他们的问题。
📖 开源至上,初心不改
Lightdash 由社区打造,为社区服务。
我们坚信,一款优秀的 BI 工具应当经济实惠、灵活配置且安全可靠——而开源模式让我们得以实现这三者的完美结合 🙂
🤑 经济实惠的数据分析
喜欢 Looker 的功能,却对其价格望而却步?
使用 Lightdash,您可以选择完全免费的自托管服务(全部开源!),如果您希望轻松搭建分析环境,我们也提供经济实惠的云服务方案。
文档
对某个功能有疑问?或者想找些资料阅读?欢迎访问我们的 Lightdash 文档,其中包含教程、参考文档、常见问题解答等丰富内容。
报告漏洞与功能建议
如发现漏洞或有功能建议,请创建 issue。
本地开发与贡献
我们欢迎各种形式的贡献,无论大小。请查看 贡献指南 了解如何开始。
有关在本地开发 Lightdash 的说明,请参见 开发环境设置。
贡献者 ✨
感谢以下杰出人士的贡献(表情符号说明):
本项目遵循 all-contributors 规范。 欢迎任何形式的贡献!