Skip to content

Commit 1fc96a8

Browse files
committed
feat: add one-time rating nudge and resolve dependency vulnerabilities for v1.3.0
Show a single, non-repeating notification after 20 successful launches asking for a Marketplace/Open VSX rating, using the native extension.open command so it works correctly across VS Code, Cursor, Windsurf, and Antigravity. The launch counter and shown flag live only in local extension state; nothing is tracked or transmitted. Also resolved all 4 reported high-severity dependency vulnerabilities (fast-uri, js-yaml, linkify-it, brace-expansion), all transitive through the @vscode/vsce build tool and never shipped with the packaged extension.
1 parent d3dd1bf commit 1fc96a8

8 files changed

Lines changed: 94 additions & 21 deletions

File tree

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@ All notable changes to this project are documented here. The format is based on
55

66
## [Unreleased]
77

8+
## [1.3.0] - 2026-07-24
9+
10+
### Added
11+
12+
- Added a one-time rating nudge shown after 20 successful launches, stored only in local extension
13+
state and never repeated regardless of the response.
14+
15+
### Fixed
16+
17+
- Resolved all reported dependency vulnerabilities in the build/release toolchain (`fast-uri`,
18+
`js-yaml`, `linkify-it`, `brace-expansion`, all transitive through `@vscode/vsce`); none of these
19+
ship with or run inside the packaged extension.
20+
821
## [1.2.0] - 2026-07-24
922

1023
### Added

CITATION.cff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ authors:
55
- family-names: Gasperini
66
given-names: Michael
77
url: "https://github.com/TheStreamCode/super-cli"
8-
version: "1.2.0"
8+
version: "1.3.0"
99
license: MIT

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ defined explicitly for Windows, macOS, and Linux; WSL deliberately selects the L
8989
changes your shell profile.
9090
- **Native integrated terminal.** Each agent runs in a real VS Code terminal, inheriting your
9191
shell, `PATH`, and environment. No bundled emulator, no runtime dependencies.
92+
- **One-time rating nudge.** After 20 successful launches, Super CLI shows a single notification
93+
asking for a Marketplace rating. It never repeats after that, however you respond, and the launch
94+
count lives only in this extension's local state — nothing is sent anywhere.
9295

9396
## Adding or overriding an agent
9497

@@ -223,7 +226,9 @@ Bug reports, feature requests, and contributions are welcome on
223226

224227
This extension does not collect telemetry, analytics, or personal data. It never installs CLIs or
225228
modifies shell profiles; it only runs launch and user-requested update commands in your integrated
226-
terminal, plus bounded version commands when you explicitly run Agent Doctor.
229+
terminal, plus bounded version commands when you explicitly run Agent Doctor. The only state it
230+
keeps locally is your configuration (favorite, hidden built-ins) and a launch counter used solely to
231+
show the one-time rating nudge described above — neither is ever transmitted anywhere.
227232

228233
Keep credentials in each CLI's supported credential store or environment configuration rather than
229234
embedding them directly in launch, update, or version command strings.

package-lock.json

Lines changed: 15 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"displayName": "Super CLI: Claude Code, Codex & AI Agent Launcher",
44
"description": "Launch Claude Code, Codex CLI, Copilot CLI, Google Antigravity, OpenCode, Kiro, OpenClaw, Qoder CLI and other AI coding agents from one VS Code sidebar.",
55
"publisher": "mikesoft",
6-
"version": "1.2.0",
6+
"version": "1.3.0",
77
"repository": {
88
"type": "git",
99
"url": "https://github.com/TheStreamCode/super-cli.git"

src/agent-view.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ export function shouldOfferFavoriteAfterLaunch(
3131
return offerFavorite && launched && selectedId !== favoriteId;
3232
}
3333

34+
/** Successful launches before the one-time rating prompt is offered. */
35+
export const RATING_PROMPT_LAUNCH_THRESHOLD = 20;
36+
37+
/** Returns whether a successful launch should trigger the one-time rating prompt. */
38+
export function shouldOfferRatingAfterLaunch(launchCount: number, ratingPromptShown: boolean): boolean {
39+
return !ratingPromptShown && launchCount >= RATING_PROMPT_LAUNCH_THRESHOLD;
40+
}
41+
3442
function sortAgents(agents: readonly Agent[]): Agent[] {
3543
return [...agents].sort(compareAgentsByLabel);
3644
}

src/extension.ts

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ import {
99
resolveAgents,
1010
resolveCommandPlatform,
1111
} from './agents.js';
12-
import { buildAgentSections, compareAgentsByLabel, shouldOfferFavoriteAfterLaunch } from './agent-view.js';
12+
import {
13+
buildAgentSections,
14+
compareAgentsByLabel,
15+
shouldOfferFavoriteAfterLaunch,
16+
shouldOfferRatingAfterLaunch,
17+
} from './agent-view.js';
1318
import { executableExistsOnPath, isExecutableFile } from './command-utils.js';
1419
import { buildDoctorReport, inspectAgents, type DoctorResult } from './doctor.js';
1520
import { resolveAgentIcon } from './icons.js';
@@ -197,9 +202,42 @@ export function activate(context: vscode.ExtensionContext): void {
197202
}
198203
};
199204

205+
// Offers a one-time, local-only rating prompt once the user has launched agents enough to be a
206+
// genuine fan. No usage data ever leaves the machine: the launch count and prompt-shown flag are
207+
// both stored in this extension's own globalState. Fire-and-forget like the update-completion
208+
// notice in terminal.ts, so a pending toast never blocks the launch command itself.
209+
const maybeOfferRatingPrompt = (): void => {
210+
const launchCount = context.globalState.get<number>('launchCount', 0) + 1;
211+
void context.globalState.update('launchCount', launchCount);
212+
213+
const ratingPromptShown = context.globalState.get<boolean>('hasShownRatingPrompt', false);
214+
if (!shouldOfferRatingAfterLaunch(launchCount, ratingPromptShown)) {
215+
return;
216+
}
217+
218+
void context.globalState.update('hasShownRatingPrompt', true);
219+
void vscode.window.showInformationMessage(
220+
'Enjoying Super CLI? A quick rating helps other developers find it.',
221+
'Rate Super CLI',
222+
).then((choice) => {
223+
if (choice === 'Rate Super CLI') {
224+
void vscode.commands.executeCommand('extension.open', context.extension.id);
225+
}
226+
});
227+
};
228+
229+
const launchAndMaybeOfferRating = async (agent: Agent): Promise<boolean> => {
230+
const launched = await launchAgent(agent, context, terminalSequence++);
231+
if (launched) {
232+
maybeOfferRatingPrompt();
233+
}
234+
235+
return launched;
236+
};
237+
200238
const launchWithStatusGuard = async (agent: Agent): Promise<boolean> => {
201239
if (installStatus.get(agent.id) !== false) {
202-
return launchAgent(agent, context, terminalSequence++);
240+
return launchAndMaybeOfferRating(agent);
203241
}
204242

205243
const actions = agent.installationDocumentationUrl
@@ -215,7 +253,7 @@ export function activate(context: vscode.ExtensionContext): void {
215253
} else if (selection === 'Open Settings') {
216254
await openExtensionSettings(context);
217255
} else if (selection === 'Launch Anyway') {
218-
return launchAgent(agent, context, terminalSequence++);
256+
return launchAndMaybeOfferRating(agent);
219257
}
220258

221259
return false;

test/agent-view.test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ const {
55
buildAgentGroups,
66
buildAgentSections,
77
shouldOfferFavoriteAfterLaunch,
8+
shouldOfferRatingAfterLaunch,
9+
RATING_PROMPT_LAUNCH_THRESHOLD,
810
} = require('../out/agent-view.js');
911

1012
const agents = [
@@ -53,3 +55,10 @@ test('favorite prompt is offered only after a successful launch', () => {
5355
assert.equal(shouldOfferFavoriteAfterLaunch(false, true, 'codex', ''), false);
5456
assert.equal(shouldOfferFavoriteAfterLaunch(true, true, 'codex', 'codex'), false);
5557
});
58+
59+
test('rating prompt is offered exactly once, only once the launch threshold is reached', () => {
60+
assert.equal(shouldOfferRatingAfterLaunch(RATING_PROMPT_LAUNCH_THRESHOLD - 1, false), false);
61+
assert.equal(shouldOfferRatingAfterLaunch(RATING_PROMPT_LAUNCH_THRESHOLD, false), true);
62+
assert.equal(shouldOfferRatingAfterLaunch(RATING_PROMPT_LAUNCH_THRESHOLD + 100, false), true);
63+
assert.equal(shouldOfferRatingAfterLaunch(RATING_PROMPT_LAUNCH_THRESHOLD, true), false);
64+
});

0 commit comments

Comments
 (0)