1- import { createContext , useContext , useState } from "react" ;
1+ import { CheckIcon , SparklesIcon } from "@heroicons/react/20/solid" ;
2+ import { createContext , useContext , useRef , useState } from "react" ;
23import { useAppOrigin } from "~/hooks/useAppOrigin" ;
34import { useProject } from "~/hooks/useProject" ;
45import { useTriggerCliTag } from "~/hooks/useTriggerCliTag" ;
6+ import { Button } from "./primitives/Buttons" ;
57import {
68 ClientTabs ,
79 ClientTabsContent ,
@@ -10,6 +12,7 @@ import {
1012} from "./primitives/ClientTabs" ;
1113import { ClipboardField } from "./primitives/ClipboardField" ;
1214import { Header3 } from "./primitives/Headers" ;
15+ import { SimpleTooltip } from "./primitives/Tooltip" ;
1316
1417type PackageManagerContextType = {
1518 activePackageManager : string ;
@@ -36,26 +39,23 @@ function usePackageManager() {
3639 return context ;
3740}
3841
39- function getApiUrlArg ( ) {
42+ function useApiUrl ( ) {
4043 const appOrigin = useAppOrigin ( ) ;
4144
42- let apiUrl : string | undefined = undefined ;
43-
4445 switch ( appOrigin ) {
4546 case "https://cloud.trigger.dev" :
46- // don't display the arg, use the CLI default
47- break ;
47+ return undefined ;
4848 case "https://test-cloud.trigger.dev" :
49- apiUrl = "https://test-api.trigger.dev" ;
50- break ;
49+ return "https://test-api.trigger.dev" ;
5150 case "https://internal.trigger.dev" :
52- apiUrl = "https://internal-api.trigger.dev" ;
53- break ;
51+ return "https://internal-api.trigger.dev" ;
5452 default :
55- apiUrl = appOrigin ;
56- break ;
53+ return appOrigin ;
5754 }
55+ }
5856
57+ function getApiUrlArg ( ) {
58+ const apiUrl = useApiUrl ( ) ;
5959 return apiUrl ? `-a ${ apiUrl } ` : undefined ;
6060}
6161
@@ -117,6 +117,86 @@ export function InitCommandV3({ title }: TabsProps) {
117117 ) ;
118118}
119119
120+ function buildAgentSetupPrompt ( {
121+ projectRef,
122+ apiUrl,
123+ cliTag,
124+ } : {
125+ projectRef : string ;
126+ apiUrl : string | undefined ;
127+ cliTag : string ;
128+ } ) {
129+ const apiUrlArg = apiUrl ? ` -a ${ apiUrl } ` : "" ;
130+ const apiUrlLine = apiUrl ? `\nTrigger.dev API URL: ${ apiUrl } ` : "" ;
131+
132+ return `Set up Trigger.dev in this project.
133+
134+ Trigger.dev runs your background tasks. This is an existing codebase — add Trigger.dev to it and get one task running in the development environment.
135+
136+ Project reference: ${ projectRef } ${ apiUrlLine }
137+
138+ How to do it:
139+ 1. If you have the Trigger.dev MCP server available, use its "initialize_project" tool with the project reference above.
140+ 2. Otherwise run this and follow its output:
141+ npx trigger.dev@${ cliTag } init -p ${ projectRef } ${ apiUrlArg }
142+ 3. If you set it up by hand, follow https://trigger.dev/docs/manual-setup and make sure you end up with:
143+ - "@trigger.dev/sdk" installed (latest) and "@trigger.dev/build" as a dev dependency
144+ - a trigger.config.ts with: import { defineConfig } from "@trigger.dev/sdk", project: "${ projectRef } ", dirs: ["./src/trigger"], and a maxDuration
145+ - a src/trigger/ directory with at least one exported task created with task() from "@trigger.dev/sdk"
146+ - trigger.config.ts added to tsconfig "include", and ".trigger" added to .gitignore
147+
148+ Golden rules:
149+ - Import from "@trigger.dev/sdk". Never "@trigger.dev/sdk/v3" or the deprecated client.defineJob.
150+ - Export every task, including subtasks.
151+ - Use the built-in fetch, not node-fetch.
152+ - Never wrap wait.*, triggerAndWait, or batchTriggerAndWait in Promise.all.
153+
154+ Two steps I have to do myself — ask me when you need them:
155+ - Running "npx trigger.dev@${ cliTag } login" (it opens a browser).
156+ - Giving you the development TRIGGER_SECRET_KEY from the dashboard to put in .env.
157+
158+ When you're done, run "npx trigger.dev@${ cliTag } dev" and confirm the task shows up in the Trigger.dev dashboard.` ;
159+ }
160+
161+ export function InitAgentPromptV3 ( ) {
162+ const project = useProject ( ) ;
163+ const apiUrl = useApiUrl ( ) ;
164+ const cliTag = useTriggerCliTag ( ) ;
165+ const [ copied , setCopied ] = useState ( false ) ;
166+ const timeoutRef = useRef < ReturnType < typeof setTimeout > | null > ( null ) ;
167+
168+ const onCopy = ( ) => {
169+ const prompt = buildAgentSetupPrompt ( {
170+ projectRef : project . externalRef ,
171+ apiUrl,
172+ cliTag,
173+ } ) ;
174+ setCopied ( true ) ;
175+ if ( timeoutRef . current ) clearTimeout ( timeoutRef . current ) ;
176+ timeoutRef . current = setTimeout ( ( ) => setCopied ( false ) , 2000 ) ;
177+ void navigator . clipboard . writeText ( prompt ) . catch ( ( ) => { } ) ;
178+ } ;
179+
180+ return (
181+ < SimpleTooltip
182+ asChild
183+ tabbable
184+ button = {
185+ < Button
186+ type = "button"
187+ variant = "primary/medium"
188+ LeadingIcon = { copied ? CheckIcon : SparklesIcon }
189+ leadingIconClassName = { copied ? "text-success" : undefined }
190+ onClick = { onCopy }
191+ >
192+ { copied ? "Copied prompt" : "Copy AI agent prompt" }
193+ </ Button >
194+ }
195+ content = "Copies a setup prompt to paste into Claude Code, Cursor, or any coding agent"
196+ />
197+ ) ;
198+ }
199+
120200export function TriggerDevStepV3 ( { title } : TabsProps ) {
121201 const triggerCliTag = useTriggerCliTag ( ) ;
122202 const { activePackageManager, setActivePackageManager } = usePackageManager ( ) ;
0 commit comments