Skip to content

Commit b9a1888

Browse files
MattBroclaude
andauthored
feat: open PostHog dashboard after signup (#398)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7afca9f commit b9a1888

2 files changed

Lines changed: 73 additions & 4 deletions

File tree

src/lib/workflows/posthog-integration/index.ts

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import opn from 'opn';
12
import type { WorkflowConfig } from '../workflow-step.js';
23
import type { WorkflowRun } from '../../agent/agent-runner.js';
34
import type { WizardSession } from '../../wizard-session.js';
@@ -15,8 +16,24 @@ import { analytics } from '../../../utils/analytics.js';
1516
import { WIZARD_INTERACTION_EVENT_NAME } from '../../constants.js';
1617
import { getUI } from '../../../ui/index.js';
1718
import { getCloudUrlFromRegion } from '../../../utils/urls.js';
19+
import { requestDeepLink } from '../../../utils/provisioning.js';
20+
import type { CloudRegion } from '../../../utils/types.js';
1821
import { POSTHOG_INTEGRATION_WORKFLOW } from './steps.js';
1922

23+
const DASHBOARD_DEEP_LINK_KEY = 'dashboardDeepLink';
24+
25+
function resolveContinueUrl(
26+
sess: WizardSession,
27+
cloudRegion: CloudRegion | undefined,
28+
deepLink: unknown,
29+
): string | undefined {
30+
if (!sess.signup) return undefined;
31+
if (typeof deepLink === 'string' && deepLink) return deepLink;
32+
if (cloudRegion)
33+
return `${getCloudUrlFromRegion(cloudRegion)}/products?source=wizard`;
34+
return undefined;
35+
}
36+
2037
export const SETUP_REPORT_FILE = 'posthog-setup-report.md';
2138
export const EVENT_PLAN_FILE = '.posthog-events.json';
2239

@@ -165,17 +182,30 @@ Important: Use the detect_package_manager tool (from the wizard-tools MCP server
165182
});
166183
}
167184
}
185+
186+
if (sess.signup) {
187+
const deepLink = await requestDeepLink(
188+
credentials.accessToken,
189+
credentials.host,
190+
);
191+
if (deepLink) {
192+
sess.frameworkContext[DASHBOARD_DEEP_LINK_KEY] = deepLink;
193+
if (process.env.NODE_ENV !== 'test') {
194+
opn(deepLink, { wait: false }).catch(() => {
195+
// opn throws in environments without a browser
196+
});
197+
}
198+
}
199+
}
168200
},
169201

170202
buildOutroData: (sess, credentials, cloudRegion) => {
171203
const envVars = config.environment.getEnvVars(
172204
credentials.projectApiKey,
173205
credentials.host,
174206
);
175-
const continueUrl =
176-
sess.signup && cloudRegion
177-
? `${getCloudUrlFromRegion(cloudRegion)}/products?source=wizard`
178-
: undefined;
207+
const deepLink = sess.frameworkContext[DASHBOARD_DEEP_LINK_KEY];
208+
const continueUrl = resolveContinueUrl(sess, cloudRegion, deepLink);
179209

180210
const changes = [
181211
...config.ui.getOutroChanges(frameworkContext),

src/utils/provisioning.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,3 +216,42 @@ export async function provisionNewAccount(
216216
accountId: tokenData.account?.id ?? '',
217217
};
218218
}
219+
220+
/**
221+
* Request a one-time deep link URL that logs the user into PostHog
222+
* and redirects to their project dashboard.
223+
*/
224+
export async function requestDeepLink(
225+
accessToken: string,
226+
host: string,
227+
): Promise<string | null> {
228+
try {
229+
const baseUrl = host
230+
.replace('us.i.posthog.com', 'us.posthog.com')
231+
.replace('eu.i.posthog.com', 'eu.posthog.com');
232+
233+
const res = await axios.post(
234+
`${baseUrl}/api/agentic/provisioning/deep_links`,
235+
{ purpose: 'dashboard' },
236+
{
237+
headers: {
238+
'Content-Type': 'application/json',
239+
Authorization: `Bearer ${accessToken}`,
240+
'API-Version': API_VERSION,
241+
'User-Agent': WIZARD_USER_AGENT,
242+
},
243+
timeout: 10_000,
244+
},
245+
);
246+
247+
const url = res.data?.url;
248+
if (typeof url === 'string') {
249+
logToFile(`[provisioning] deep link created: ${url}`);
250+
return url;
251+
}
252+
return null;
253+
} catch {
254+
logToFile('[provisioning] deep link request failed, skipping');
255+
return null;
256+
}
257+
}

0 commit comments

Comments
 (0)