Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions packages/cli/src/lib/init/ui/ink-app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -735,16 +735,19 @@ function CompletionScreen({
case "issues":
if (primaryUrl) {
actions.openUrl(primaryUrl);
actions.track("open-sentry");
setNote("Opened Sentry in your browser.");
}
break;
case "agent":
if (agentCommand) {
if (agentQueued) {
store.dequeuePostExitAction(agentCommand);
actions.track("agent-plugin-unqueued");
setNote("");
} else {
store.queuePostExitAction(agentCommand);
actions.track("agent-plugin-queued");
setNote(`Queued — ${agentCommand} runs when you finish.`);
}
}
Expand Down Expand Up @@ -773,6 +776,7 @@ function CompletionScreen({
!key.ctrl && (input === "o" || input === "O"),
run: () => {
actions.openUrl(primaryUrl);
actions.track("open-sentry");
setNote("Opened Sentry in your browser.");
},
},
Expand Down
31 changes: 30 additions & 1 deletion packages/cli/src/lib/init/ui/ink-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import { ReadStream } from "node:tty";

const _require = createRequire(import.meta.url);

import { setTag } from "@sentry/node-core/light";
import { addBreadcrumb, setTag } from "@sentry/node-core/light";
import { FULL_BANNER_LINES } from "../../banner.js";
import { openBrowser } from "../../browser.js";
import { CLI_VERSION } from "../../constants.js";
Expand Down Expand Up @@ -538,6 +538,29 @@ export class InkUI implements WizardUI {
// ignore
});
},
track: (event) => {
// Land completion-screen interactions on the run's `cli.command`
// transaction so we can see, per run, whether the user opened Sentry
// and/or chose to install the agent plugin. Tags are sticky: once a
// user has clicked "install", un-toggling leaves the click recorded.
switch (event) {
case "open-sentry":
setTag("wizard.completion.opened_sentry", "true");
break;
case "agent-plugin-queued":
setTag("wizard.completion.agent_plugin_clicked", "true");
break;
case "agent-plugin-unqueued":
break;
default:
break;
}
addBreadcrumb({
category: "wizard.completion",
message: event,
level: "info",
});
},
},
});
}
Expand Down Expand Up @@ -884,6 +907,12 @@ export class InkUI implements WizardUI {
*/
private async runPostExitActions(): Promise<void> {
const actions = this.store.getSnapshot().postExitActions;
if (actions.length > 0) {
// The agent-plugin installer is the only thing the completion screen
// queues, so a non-empty list here means the user finished with it queued
// and we're about to actually run it — the strongest "installed" signal.
setTag("wizard.completion.agent_plugin_installed", "true");
}
for (const command of actions) {
process.stdout.write(`\n$ ${command}\n`);
await runInheritedCommand(command);
Expand Down
19 changes: 18 additions & 1 deletion packages/cli/src/lib/init/ui/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,31 @@ export type WizardCompletion = {
startCommand?: string;
};

/**
* A completion-screen interaction worth recording on the run's telemetry.
* `open-sentry` covers both the "View my first event" / "Open my Issues feed"
* menu item and the `o` shortcut; the agent-plugin events track the install
* toggle (a queued click is the "did they choose to install the plugin" signal).
*/
export type CompletionActionEvent =
| "open-sentry"
| "agent-plugin-queued"
| "agent-plugin-unqueued";

/**
* Side-effectful actions the completion screen invokes. Provided by `InkUI`
* (which lives in the main bundle) so the pre-bundled Ink sidecar never has to
* import Node built-ins (browser launch) itself.
* import Node built-ins (browser launch) or the Sentry SDK itself.
*/
export type CompletionActions = {
/** Open a URL in the user's browser. Best-effort, non-blocking. */
openUrl: (url: string) => void;
/**
* Record a completion-screen interaction on the run's telemetry. Bound by
* `InkUI` so the Ink sidecar never imports Sentry; the tags land on the
* active `cli.command` transaction like the rest of the `wizard.*` tags.
*/
track: (event: CompletionActionEvent) => void;
};

/**
Expand Down
3 changes: 3 additions & 0 deletions packages/cli/test/lib/init/ui/ink-app.snapshot.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1329,6 +1329,9 @@ describe("completion screen", () => {
openUrl: () => {
// no-op in tests
},
track: () => {
// no-op in tests
},
},
},
});
Expand Down
Loading