Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
73f86c7
fix(webapp): stop saving global flags from unsetting the locked ones …
d-cs Aug 24, 2026
0205fed
refactor(run-engine): extract a WaitpointCoordinator seam around the …
d-cs Aug 24, 2026
d645752
fix(hosting): disable clickhouse system-log telemetry and apply profi…
nicktrn Aug 24, 2026
b55fba9
feat(run-store,run-engine): freeze the completed-waitpoints record an…
d-cs Aug 24, 2026
f98e303
feat(webapp): resolve which shard an environment mints run roots into…
d-cs Aug 24, 2026
cc69ff4
feat(run-engine): Redis waitpoint store coordinator, Lua protocol, an…
d-cs Aug 24, 2026
f866210
feat(cli): experimental --local-bundle deploy mode (#4331)
myftija Aug 25, 2026
2e87e93
ci: run codeql on all prs via advanced setup (#4767)
nicktrn Aug 25, 2026
11e1cd8
feat(webapp): isolate the runs list ClickHouse read pool (#4763)
ericallam Aug 25, 2026
036cf8d
chore(webapp): admin endpoint to backfill Vercel deployment external …
0ski Aug 25, 2026
45eaaa7
feat(run-store,testcontainers): execution-snapshot read comparator an…
d-cs Aug 25, 2026
1eda438
feat(webapp): put the admin dashboard behind an env var flag (#4774)
myftija Aug 25, 2026
47ff76d
feat(webapp,clickhouse): return an actionable error instead of a 500 …
ericallam Aug 25, 2026
ee29393
perf(webapp): cache deployment logs across navigations (#4775)
myftija Aug 25, 2026
97d70b8
feat(run-store): make the run-ops router correct at N shards (#4771)
d-cs Aug 25, 2026
6a6f0a4
feat(webapp): pause deployment log auto-scroll on scroll-up (#4776)
myftija Aug 25, 2026
ba57c1f
fix(webapp): disable browser autofill on environment variable inputs …
D-K-P Aug 25, 2026
00e3c15
feat(webapp): RUN_OPS_SHARDS config, topology and N-way store wiring …
d-cs Aug 26, 2026
38e78f8
feat(webapp): deployment lifecycle telemetry events (#4778)
myftija Aug 26, 2026
8da393b
feat(webapp): add org slug and project name to deployment telemetry e…
myftija Aug 26, 2026
1801b0e
feat(webapp,docker): run-ops boot interlocks and migrations at N data…
d-cs Aug 26, 2026
02e6157
feat(run-store): add an execution-snapshot store decorator behind an …
d-cs Aug 26, 2026
4c16387
fix(webapp): project integrations page — Staging gating, unreachable …
0ski Aug 26, 2026
920892b
feat(webapp,run-store): gen-2 shard arms in read-through and idempote…
d-cs Aug 26, 2026
c7f78e4
fix(sdk): reset skipToTurnComplete when a new chat turn starts (#4744)
wuweiweiwu Aug 26, 2026
b72c6c3
feat(sdk): allow a ttl on session-triggered runs
kathiekiwi Aug 27, 2026
432f17b
fix(webapp): expire dashboard agent turn runs that are never dequeued
kathiekiwi Aug 27, 2026
80b3fd3
test(webapp): assert the session ttl reaches the trigger options
kathiekiwi Aug 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/chat-session-run-ttl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@trigger.dev/core": patch
"@trigger.dev/sdk": patch
---

Chat server sessions can now set a `ttl` on the runs they trigger, so a run that is never picked up expires instead of waiting indefinitely.
5 changes: 5 additions & 0 deletions .changeset/fluffy-pans-argue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/sdk": patch
---

Fix chat transport discarding the next turn after stopping generation. `skipToTurnComplete` is now reset when a new message or action is sent, so a message sent after `stopGeneration` streams normally instead of leaving the chat stuck in a streaming state.
6 changes: 6 additions & 0 deletions .changeset/local-bundle-deploy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@trigger.dev/core": patch
"trigger.dev": patch
---

Add an experimental `--local-bundle` deploy flag that runs the install and bundling steps on your machine and uploads only the build output; the image is still built remotely. Useful when your project's install step needs tooling or credentials that only exist locally.
5 changes: 5 additions & 0 deletions .changeset/violet-buses-tease.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"trigger.dev": patch
---

Send the CLI version header on all API requests so deployments are attributable to a CLI version
40 changes: 40 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: CodeQL

on:
push:
branches: [main]
pull_request:

permissions: {}

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
analyze:
name: Analyze (${{ matrix.language }})
if: github.repository == 'triggerdotdev/trigger.dev'
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write # Upload SARIF to GitHub Security tab
strategy:
fail-fast: false
matrix:
language: [actions, javascript-typescript]
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false

- name: Initialize CodeQL
uses: github/codeql-action/init@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8
with:
languages: ${{ matrix.language }}

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8
with:
category: /language:${{ matrix.language }}
6 changes: 6 additions & 0 deletions .server-changes/admin-dashboard-enabled-flag.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
area: webapp
type: feature
---

Self-hosted instances can now disable the admin dashboard and user impersonation entirely. See the self-hosting docs for the new setting.
6 changes: 6 additions & 0 deletions .server-changes/deployment-logs-follow-scroll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
area: webapp
type: feature
---

Deployment logs no longer jump to the bottom while you are reading earlier output. Scroll up to pause auto-scroll, and scroll back down or use the new scroll-to-bottom button in the log header to resume following.
6 changes: 6 additions & 0 deletions .server-changes/env-var-inputs-autocomplete-off.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
area: webapp
type: improvement
---

Stop the browser offering to autofill or save environment variable values as saved credentials.
6 changes: 6 additions & 0 deletions .server-changes/runs-list-query-limit-error.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
area: webapp
type: improvement
---

When a runs list or runs.list API request spans too much data to complete, it now returns a clear, actionable error asking you to narrow the time range, instead of failing with a generic error.
6 changes: 6 additions & 0 deletions .server-changes/runs-list-read-isolation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
area: webapp
type: improvement
---

Improved the performance and reliability of the runs list and the runs.list API, especially for large projects and filtered views.
6 changes: 6 additions & 0 deletions .server-changes/vercel-staging-gating.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
area: webapp
type: fix
---

The Staging branch setting now shows an upgrade prompt on plans that don't include a Staging environment, instead of looking editable and then silently doing nothing when saved.
56 changes: 56 additions & 0 deletions apps/webapp/app/components/admin/flagChangeList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { derivedFlagsClearedWith } from "~/v3/featureFlags";

export type FlagChange =
| { key: string; type: "added"; newVal: string }
| { key: string; type: "removed"; oldVal: string }
| { key: string; type: "changed"; oldVal: string; newVal: string };

/**
* What a global flag save will do, for the confirm dialog.
*
* A graced primary that is unset also clears its stamps. Those keys are locked, so the caller
* filters them out of `initialValues` — the cascade therefore reads `storedValues`, which is the
* unfiltered set the loader returned. Reading `initialValues` finds nothing and understates the
* deletion, which is the defect this parameter exists to prevent.
*/
export function buildFlagChangeList(params: {
editableKeys: readonly string[];
lockedKeys: readonly string[];
initialValues: Record<string, unknown>;
storedValues: Record<string, unknown>;
newValues: Record<string, unknown>;
}): FlagChange[] {
const { editableKeys, initialValues, storedValues, newValues } = params;

return editableKeys.flatMap<FlagChange>((key) => {
const wasSet = key in initialValues;
const isSet = key in newValues;
const oldVal = initialValues[key];
const newVal = newValues[key];

if (!wasSet && !isSet) return [];
if (wasSet && isSet && stableValue(oldVal) === stableValue(newVal)) return [];

if (!wasSet && isSet) {
return [{ key, type: "added", newVal: String(newVal) }];
}

if (wasSet && !isSet) {
// Only an unset clears the stamps. A change re-stamps instead.
const cascaded = derivedFlagsClearedWith(key)
.filter((derived) => derived in storedValues)
.map<FlagChange>((derived) => ({
key: derived,
type: "removed",
oldVal: String(storedValues[derived]),
}));
return [{ key, type: "removed", oldVal: String(oldVal) }, ...cascaded];
}

return [{ key, type: "changed", oldVal: String(oldVal), newVal: String(newVal) }];
});
}

function stableValue(value: unknown): string {
return JSON.stringify(value ?? null);
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ type BuildSettingsFieldsProps = {
* the pin status is unknown — distinct from "not set". */
currentTriggerVersionFetchFailed?: boolean;
/** Hide the section-level master toggles for "Pull env vars" and "Discover new env vars". */
hideSectionToggles?: boolean;
showAtomicDeployments?: boolean;
layout?: "settings" | "card";
};
Expand All @@ -68,7 +67,6 @@ export function BuildSettingsFields({
onAutoPromoteChange,
currentTriggerVersion,
currentTriggerVersionFetchFailed,
hideSectionToggles,
showAtomicDeployments = true,
layout = "card",
}: BuildSettingsFieldsProps) {
Expand Down Expand Up @@ -222,7 +220,7 @@ export function BuildSettingsFields({
<div className="mb-2">
<div className="flex items-center justify-between">
<Label>Pull env vars before build</Label>
{!hideSectionToggles && availableEnvSlugs.length > 1 && (
{availableEnvSlugs.length > 1 && (
<Switch
variant="small"
checked={
Expand Down Expand Up @@ -292,7 +290,7 @@ export function BuildSettingsFields({
<div className="mb-2">
<div className="flex items-center justify-between">
<Label>Discover new env vars</Label>
{!hideSectionToggles && availableEnvSlugs.length > 1 && (
{availableEnvSlugs.length > 1 && (
<Switch
variant="small"
checked={
Expand Down
69 changes: 28 additions & 41 deletions apps/webapp/app/components/integrations/VercelOnboardingModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
ChevronDownIcon,
ChevronUpIcon,
} from "@heroicons/react/20/solid";
import { useFetcher, useNavigation, useSearchParams } from "@remix-run/react";
import { useFetcher, useSearchParams } from "@remix-run/react";
import { useTypedFetcher } from "remix-typedjson";
import { Dialog, DialogContent, DialogHeader } from "~/components/primitives/Dialog";
import { Button, LinkButton } from "~/components/primitives/Buttons";
Expand Down Expand Up @@ -34,13 +34,11 @@ import {
type EnvSlug,
ALL_ENV_SLUGS,
shouldSyncEnvVarForAnyEnvironment,
getAvailableEnvSlugs,
getAvailableEnvSlugsForBuildSettings,
} from "~/v3/vercel/vercelProjectIntegrationSchema";
import { type VercelCustomEnvironment } from "~/models/vercelIntegration.server";
import { type VercelOnboardingData } from "~/presenters/v3/VercelSettingsPresenter.server";
import {
vercelAppInstallPath,
v3ProjectSettingsIntegrationsPath,
githubAppInstallPath,
vercelResourcePath,
Expand Down Expand Up @@ -78,7 +76,6 @@ function formatVercelTargets(targets: string[]): string {

type OnboardingState =
| "idle"
| "installing"
| "loading-projects"
| "project-selection"
| "loading-env-mapping"
Expand All @@ -99,6 +96,7 @@ export function VercelOnboardingModal({
hasStagingEnvironment,
hasPreviewEnvironment,
hasOrgIntegration,
onboardingDataUnavailable = false,
nextUrl,
onDataReload,
vercelManageAccessUrl,
Expand All @@ -112,16 +110,15 @@ export function VercelOnboardingModal({
hasStagingEnvironment: boolean;
hasPreviewEnvironment: boolean;
hasOrgIntegration: boolean;
onboardingDataUnavailable?: boolean;
nextUrl?: string;
onDataReload?: (vercelStagingEnvironment?: string) => void;
vercelManageAccessUrl?: string;
}) {
const { capture, startSessionRecording } = usePostHogTracking();
const navigation = useNavigation();
const fetcher = useTypedFetcher<typeof loader>();
const envMappingFetcher = useFetcher();
const completeOnboardingFetcher = useFetcher();
const { Form: _CompleteOnboardingForm } = completeOnboardingFetcher;
const [searchParams] = useSearchParams();
const origin = searchParams.get("origin");
const fromMarketplaceContext = origin === "marketplace";
Expand All @@ -130,7 +127,6 @@ export function VercelOnboardingModal({
() => onboardingData?.availableProjects ?? [],
[onboardingData?.availableProjects]
);
const _hasProjectSelected = onboardingData?.hasProjectSelected ?? false;
const customEnvironments = useMemo(
() => onboardingData?.customEnvironments ?? [],
[onboardingData?.customEnvironments]
Expand Down Expand Up @@ -224,10 +220,6 @@ export function VercelOnboardingModal({
environmentId: string;
displayName: string;
} | null>(null);
const _availableEnvSlugsForOnboarding = getAvailableEnvSlugs(
hasStagingEnvironment,
hasPreviewEnvironment
);
const availableEnvSlugsForOnboardingBuildSettings = getAvailableEnvSlugsForBuildSettings(
hasStagingEnvironment,
hasPreviewEnvironment
Expand Down Expand Up @@ -375,7 +367,6 @@ export function VercelOnboardingModal({
}
break;

case "installing":
case "project-selection":
case "env-mapping":
case "env-var-sync":
Expand Down Expand Up @@ -459,8 +450,6 @@ export function VercelOnboardingModal({

const overlappingEnvVarsCount = enabledEnvVars.filter((v) => existingVars[v.key]).length;

const _isSubmitting = navigation.state === "submitting" || navigation.state === "loading";

const actionUrl = vercelResourcePath(organizationSlug, projectSlug, environmentSlug);

const handleToggleEnvVar = useCallback((key: string, enabled: boolean) => {
Expand Down Expand Up @@ -634,19 +623,6 @@ export function VercelOnboardingModal({
gitHubAppInstallations.length,
]);

const _handleFinishOnboarding = useCallback(
(e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const form = e.currentTarget;
const formData = new FormData(form);
completeOnboardingFetcher.submit(formData, {
method: "post",
action: actionUrl,
});
},
[completeOnboardingFetcher, actionUrl]
);

useEffect(() => {
if (
completeOnboardingFetcher.data &&
Expand Down Expand Up @@ -698,13 +674,6 @@ export function VercelOnboardingModal({
}
}, [state, onClose, trackOnboarding, isGitHubConnectedForOnboarding]);

useEffect(() => {
if (state === "installing") {
const installUrl = vercelAppInstallPath(organizationSlug, projectSlug);
window.location.href = installUrl;
}
}, [state, organizationSlug, projectSlug]);

useEffect(() => {
if (
envMappingFetcher.data &&
Expand Down Expand Up @@ -749,7 +718,6 @@ export function VercelOnboardingModal({
state === "loading-projects" ||
state === "loading-env-mapping" ||
state === "loading-env-vars" ||
state === "installing" ||
(state === "idle" && !onboardingData);

if (isLoadingState) {
Expand All @@ -758,9 +726,7 @@ export function VercelOnboardingModal({
open={isOpen}
onOpenChange={(open) => {
if (!open && !fromMarketplaceContext) {
if ((state as string) !== "completed") {
trackOnboarding("vercel onboarding abandoned");
}
trackOnboarding("vercel onboarding abandoned");
onClose();
}
}}
Expand All @@ -772,9 +738,30 @@ export function VercelOnboardingModal({
<span>Set up Vercel Integration</span>
</div>
</DialogHeader>
<div className="flex items-center justify-center py-8">
<Spinner color="blue" className="size-6" />
</div>
{onboardingDataUnavailable ? (
<div className="flex flex-col items-start gap-3 py-4">
<Paragraph variant="small">
We couldn't load your Vercel projects. The integration may have been removed or lost
access to this organization on Vercel.
</Paragraph>
<div className="flex items-center gap-2">
{onDataReload && (
<Button variant="secondary/small" onClick={() => onDataReload()}>
Try again
</Button>
)}
{vercelManageAccessUrl && (
<LinkButton to={vercelManageAccessUrl} target="_blank" variant="tertiary/small">
Manage access on Vercel
</LinkButton>
)}
</div>
</div>
) : (
<div className="flex items-center justify-center py-8">
<Spinner color="blue" className="size-6" />
</div>
)}
</DialogContent>
</Dialog>
);
Expand Down
Loading
Loading