From 936e6b901343aff61684559be945dd9dc7e26288 Mon Sep 17 00:00:00 2001 From: jiasheng Date: Fri, 26 Sep 2025 18:07:38 +0800 Subject: [PATCH 1/9] feat: support save markdown preview file --- packages/schema/package.json | 18 +++++- packages/schema/src/zmodel-preview.ts | 82 +++++++++++++++++++++++++-- 2 files changed, 93 insertions(+), 7 deletions(-) diff --git a/packages/schema/package.json b/packages/schema/package.json index b5a10cbe9..bd689d94d 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -78,6 +78,11 @@ "command": "zenstack.preview-zmodel", "when": "editorLangId == zmodel", "group": "navigation" + }, + { + "command": "zenstack.save-zmodel-documentation", + "when": "(activeWebviewPanelId == 'markdown.preview' || activeCustomEditorId == 'vscode.markdown.preview.editor') && zenstack.isMarkdownPreview == true", + "group": "navigation" } ], "commandPalette": [ @@ -99,6 +104,11 @@ "title": "ZenStack: Preview ZModel Documentation", "icon": "$(preview)" }, + { + "command": "zenstack.save-zmodel-documentation", + "title": "ZenStack: Save ZModel Documentation", + "icon": "$(save)" + }, { "command": "zenstack.clear-documentation-cache", "title": "ZenStack: Clear Documentation Cache", @@ -116,6 +126,12 @@ "key": "ctrl+shift+v", "mac": "cmd+shift+v", "when": "editorLangId == zmodel" + }, + { + "command": "zenstack.save-zmodel-documentation", + "key": "ctrl+shift+s", + "mac": "cmd+shift+s", + "when": "(activeWebviewPanelId == 'markdown.preview' || activeCustomEditorId == 'vscode.markdown.preview.editor') && zenstack.isMarkdownPreview == true" } ] }, @@ -129,7 +145,7 @@ "bin": { "zenstack": "bin/cli" }, - "main": "./bundle/extension.js", + "main": "./dist/extension.js", "scripts": { "vscode:publish": "vsce publish --no-dependencies", "vscode:prerelease": "vsce publish --no-dependencies --pre-release", diff --git a/packages/schema/src/zmodel-preview.ts b/packages/schema/src/zmodel-preview.ts index 96b1ab518..b3bd55981 100644 --- a/packages/schema/src/zmodel-preview.ts +++ b/packages/schema/src/zmodel-preview.ts @@ -14,6 +14,9 @@ import { API_URL } from './zenstack-auth-provider'; export class ZModelPreview implements vscode.Disposable { private documentationCache: DocumentationCache; private languageClient: LanguageClient; + private lastGeneratedMarkdown: string | null = null; + // use a zero-width space in the file name to make it non-colliding with user file + private readonly previewZModelFileName = `zmodel${'\u200B'}-preview.md`; // Schema for validating the request body private static DocRequestSchema = z.object({ @@ -45,6 +48,17 @@ export class ZModelPreview implements vscode.Disposable { */ initialize(context: vscode.ExtensionContext): void { this.registerCommands(context); + + vscode.window.tabGroups.onDidChangeTabs(() => { + const activeTabLabels = vscode.window.tabGroups.all.filter((group) => + group.activeTab?.label?.endsWith(this.previewZModelFileName) + ); + if (activeTabLabels.length > 0) { + vscode.commands.executeCommand('setContext', 'zenstack.isMarkdownPreview', true); + } else { + vscode.commands.executeCommand('setContext', 'zenstack.isMarkdownPreview', false); + } + }); } /** @@ -58,6 +72,13 @@ export class ZModelPreview implements vscode.Disposable { }) ); + // Register the save documentation command for zmodel files + context.subscriptions.push( + vscode.commands.registerCommand('zenstack.save-zmodel-documentation', async () => { + await this.saveZModelDocumentation(); + }) + ); + // Register cache management commands context.subscriptions.push( vscode.commands.registerCommand('zenstack.clear-documentation-cache', async () => { @@ -103,7 +124,10 @@ export class ZModelPreview implements vscode.Disposable { const markdownContent = await this.generateZModelDocumentation(document); if (markdownContent) { - await this.openMarkdownPreview(markdownContent, document.fileName); + // Store the generated content for potential saving later + this.lastGeneratedMarkdown = markdownContent; + + await this.openMarkdownPreview(markdownContent); } } ); @@ -239,17 +263,14 @@ export class ZModelPreview implements vscode.Disposable { /** * Open markdown preview */ - private async openMarkdownPreview(markdownContent: string, originalFileName: string): Promise { + private async openMarkdownPreview(markdownContent: string): Promise { // Create a temporary markdown file with a descriptive name in the system temp folder - const baseName = path.basename(originalFileName, '.zmodel'); - const tempFileName = `${baseName}-preview.md`; - const tempFilePath = path.join(os.tmpdir(), tempFileName); + const tempFilePath = path.join(os.tmpdir(), this.previewZModelFileName); const tempFile = vscode.Uri.file(tempFilePath); try { // Write the markdown content to the temp file await vscode.workspace.fs.writeFile(tempFile, new TextEncoder().encode(markdownContent)); - // Open the markdown preview side by side await vscode.commands.executeCommand('markdown.showPreviewToSide', tempFile); } catch (error) { @@ -260,6 +281,55 @@ export class ZModelPreview implements vscode.Disposable { } } + /** + * Save ZModel documentation to a user-selected file + */ + async saveZModelDocumentation(): Promise { + // Check if we have cached content first + if (!this.lastGeneratedMarkdown) { + vscode.window.showErrorMessage( + 'No documentation content available to save. Please generate the documentation first by running "Preview ZModel Documentation".' + ); + return; + } + + // Show save dialog + let defaultFilePath = `zmodel-doc.md`; + + const workspaceFolders = vscode.workspace.workspaceFolders; + if (workspaceFolders && workspaceFolders.length > 0) { + const workspacePath = workspaceFolders[0].uri.fsPath; + // If the workspace folder exists, use it + defaultFilePath = path.join(workspacePath, defaultFilePath); + } + + const saveUri = await vscode.window.showSaveDialog({ + defaultUri: vscode.Uri.file(defaultFilePath), + filters: { + Markdown: ['md'], + 'All Files': ['*'], + }, + saveLabel: 'Save Documentation', + }); + + if (!saveUri) { + return; // User cancelled + } + + try { + // Write the markdown content to the selected file + await vscode.workspace.fs.writeFile(saveUri, new TextEncoder().encode(this.lastGeneratedMarkdown)); + // Open and close the saved file to refresh the shown markdown preview + await vscode.commands.executeCommand('vscode.open', saveUri); + await vscode.commands.executeCommand('workbench.action.closeActiveEditor'); + } catch (error) { + console.error('Error saving markdown file:', error); + vscode.window.showErrorMessage( + `Failed to save documentation: ${error instanceof Error ? error.message : String(error)}` + ); + } + } + /** * Check for Mermaid extensions */ From 7ac15039a96cf4aad6d8dc778a9658e4225cb92d Mon Sep 17 00:00:00 2001 From: jiasheng Date: Fri, 26 Sep 2025 18:07:38 +0800 Subject: [PATCH 2/9] feat: support save markdown preview file --- packages/schema/src/res/zmodel-preview-release-notes.html | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/schema/src/res/zmodel-preview-release-notes.html b/packages/schema/src/res/zmodel-preview-release-notes.html index 5f115fd70..262895d87 100644 --- a/packages/schema/src/res/zmodel-preview-release-notes.html +++ b/packages/schema/src/res/zmodel-preview-release-notes.html @@ -63,12 +63,16 @@

🚀 How to Use

  1. Open your .zmodel file
  2. - Click () in the editor toolbar, or simply press + Click () in the editor toolbar, or press Cmd + Shift + V (Mac) or Ctrl + Shift + V (Windows)
  3. Sign in with ZenStack (one-time setup)
  4. -
  5. Enjoy your AI-generated documentation
  6. +
  7. + Click () in the preview toolbar to save the doc, or press + Cmd + Shift + S (Mac) or + Ctrl + Shift + S (Windows) +
From afdb47d08521fedf1d6a4dd540310ff3ab1c68a1 Mon Sep 17 00:00:00 2001 From: jiasheng Date: Fri, 26 Sep 2025 21:57:15 +0800 Subject: [PATCH 3/9] feat(telemetry): integrate telemetry tracking for vscode extension --- packages/schema/src/extension.ts | 6 ++ packages/schema/src/vscode-telemetry.ts | 73 +++++++++++++++++++ packages/schema/src/zenstack-auth-provider.ts | 6 +- packages/schema/src/zmodel-preview.ts | 3 + 4 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 packages/schema/src/vscode-telemetry.ts diff --git a/packages/schema/src/extension.ts b/packages/schema/src/extension.ts index c7abe53be..df762e12a 100644 --- a/packages/schema/src/extension.ts +++ b/packages/schema/src/extension.ts @@ -6,6 +6,7 @@ import { AUTH_PROVIDER_ID, ZenStackAuthenticationProvider } from './zenstack-aut import { DocumentationCache } from './documentation-cache'; import { ZModelPreview } from './zmodel-preview'; import { ReleaseNotesManager } from './release-notes-manager'; +import telemetry from './vscode-telemetry'; // Global variables let client: LanguageClient; @@ -19,13 +20,17 @@ export async function requireAuth(): Promise = {}) { + if (this.mixpanel) { + const payload = { + distinct_id: this.deviceId, + time: new Date(), + $os: this._os_type, + osType: this._os_type, + osRelease: this._os_release, + osPlatform: this._os_platform, + osArch: this._os_arch, + osVersion: this._os_version, + nodeVersion: process.version, + vscodeAppName: this.vscodeAppName, + vscodeVersion: this.vscodeVersion, + vscodeAppHost: this.vscodeAppHost, + ...properties, + }; + this.mixpanel.track(event, payload); + } + } + + identify(userId: string) { + if (this.mixpanel) { + this.mixpanel.track('$identify', { + $identified_id: userId, + $anon_id: this.deviceId, + token: TELEMETRY_TRACKING_TOKEN, + }); + } + } +} +export default new VSCodeTelemetry(); diff --git a/packages/schema/src/zenstack-auth-provider.ts b/packages/schema/src/zenstack-auth-provider.ts index 815913c56..ba7c32a0b 100644 --- a/packages/schema/src/zenstack-auth-provider.ts +++ b/packages/schema/src/zenstack-auth-provider.ts @@ -1,5 +1,5 @@ import * as vscode from 'vscode'; - +import telemetry from './vscode-telemetry'; interface JWTClaims { jti?: string; sub?: string; @@ -150,9 +150,6 @@ export class ZenStackAuthenticationProvider implements vscode.AuthenticationProv } ); } - private generateState(): string { - return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); - } // Handle authentication callback from ZenStack public async handleAuthCallback(callbackUri: vscode.Uri): Promise { @@ -184,6 +181,7 @@ export class ZenStackAuthenticationProvider implements vscode.AuthenticationProv try { // Decode JWT to get claims const claims = this.parseJWTClaims(accessToken); + telemetry.identify(claims.email!); return { id: claims.jti || Math.random().toString(36), accessToken: accessToken, diff --git a/packages/schema/src/zmodel-preview.ts b/packages/schema/src/zmodel-preview.ts index b3bd55981..221b7825b 100644 --- a/packages/schema/src/zmodel-preview.ts +++ b/packages/schema/src/zmodel-preview.ts @@ -7,6 +7,7 @@ import { URI } from 'vscode-uri'; import { DocumentationCache } from './documentation-cache'; import { requireAuth } from './extension'; import { API_URL } from './zenstack-auth-provider'; +import telemetry from './vscode-telemetry'; /** * ZModelPreview class handles ZModel file preview functionality @@ -92,6 +93,7 @@ export class ZModelPreview implements vscode.Disposable { * Preview a ZModel file */ async previewZModelFile(): Promise { + telemetry.track('extension:zmodel-preview'); const editor = vscode.window.activeTextEditor; if (!editor) { @@ -285,6 +287,7 @@ export class ZModelPreview implements vscode.Disposable { * Save ZModel documentation to a user-selected file */ async saveZModelDocumentation(): Promise { + telemetry.track('extension:zmodel-save'); // Check if we have cached content first if (!this.lastGeneratedMarkdown) { vscode.window.showErrorMessage( From dd7ad75a9ee015497c7e0836f4065b372e73daab Mon Sep 17 00:00:00 2001 From: jiasheng Date: Fri, 26 Sep 2025 22:05:26 +0800 Subject: [PATCH 4/9] fix: update main entry point to use bundled extension --- packages/schema/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/schema/package.json b/packages/schema/package.json index bd689d94d..97d7bf6c3 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -145,7 +145,7 @@ "bin": { "zenstack": "bin/cli" }, - "main": "./dist/extension.js", + "main": "./bundle/extension.js", "scripts": { "vscode:publish": "vsce publish --no-dependencies", "vscode:prerelease": "vsce publish --no-dependencies --pre-release", From dc4aee98782a092e18c37582e61818a78aed056c Mon Sep 17 00:00:00 2001 From: jiasheng Date: Sat, 27 Sep 2025 08:56:32 +0800 Subject: [PATCH 5/9] fix comments --- packages/schema/src/vscode-telemetry.ts | 3 ++- packages/schema/src/zmodel-preview.ts | 22 ++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/schema/src/vscode-telemetry.ts b/packages/schema/src/vscode-telemetry.ts index 1d2c876c6..623701030 100644 --- a/packages/schema/src/vscode-telemetry.ts +++ b/packages/schema/src/vscode-telemetry.ts @@ -1,6 +1,6 @@ import { init, Mixpanel } from 'mixpanel'; import * as os from 'os'; -import vscode from 'vscode'; +import * as vscode from 'vscode'; import { getMachineId } from './utils/machine-id-utils'; import { v5 as uuidv5 } from 'uuid'; import { TELEMETRY_TRACKING_TOKEN } from './constants'; @@ -36,6 +36,7 @@ export class VSCodeTelemetry { private getDeviceId() { const hostId = getMachineId(); + // namespace UUID for generating UUIDv5 from DNS 'zenstack.dev' return uuidv5(hostId, '133cac15-3efb-50fa-b5fc-4b90e441e563'); } diff --git a/packages/schema/src/zmodel-preview.ts b/packages/schema/src/zmodel-preview.ts index 221b7825b..53698aa65 100644 --- a/packages/schema/src/zmodel-preview.ts +++ b/packages/schema/src/zmodel-preview.ts @@ -50,16 +50,18 @@ export class ZModelPreview implements vscode.Disposable { initialize(context: vscode.ExtensionContext): void { this.registerCommands(context); - vscode.window.tabGroups.onDidChangeTabs(() => { - const activeTabLabels = vscode.window.tabGroups.all.filter((group) => - group.activeTab?.label?.endsWith(this.previewZModelFileName) - ); - if (activeTabLabels.length > 0) { - vscode.commands.executeCommand('setContext', 'zenstack.isMarkdownPreview', true); - } else { - vscode.commands.executeCommand('setContext', 'zenstack.isMarkdownPreview', false); - } - }); + context.subscriptions.push( + vscode.window.tabGroups.onDidChangeTabs(() => { + const activeTabLabels = vscode.window.tabGroups.all.filter((group) => + group.activeTab?.label?.endsWith(this.previewZModelFileName) + ); + if (activeTabLabels.length > 0) { + vscode.commands.executeCommand('setContext', 'zenstack.isMarkdownPreview', true); + } else { + vscode.commands.executeCommand('setContext', 'zenstack.isMarkdownPreview', false); + } + }) + ); } /** From 1cbc5c1883125aef28ba1ab3b06828f58d8c6b94 Mon Sep 17 00:00:00 2001 From: jiasheng Date: Sat, 27 Sep 2025 09:47:03 +0800 Subject: [PATCH 6/9] fix: CLI build result should not contain the VSCode extension related code --- packages/schema/build/bundle.js | 1 + packages/schema/src/extension.ts | 10 +++++----- .../schema/src/{ => vscode}/documentation-cache.ts | 0 .../schema/src/{ => vscode}/release-notes-manager.ts | 0 .../{ => vscode}/res/zmodel-preview-release-notes.html | 0 packages/schema/src/{ => vscode}/vscode-telemetry.ts | 4 ++-- .../schema/src/{ => vscode}/zenstack-auth-provider.ts | 0 packages/schema/src/{ => vscode}/zmodel-preview.ts | 2 +- packages/schema/tsconfig.json | 2 +- 9 files changed, 10 insertions(+), 9 deletions(-) rename packages/schema/src/{ => vscode}/documentation-cache.ts (100%) rename packages/schema/src/{ => vscode}/release-notes-manager.ts (100%) rename packages/schema/src/{ => vscode}/res/zmodel-preview-release-notes.html (100%) rename packages/schema/src/{ => vscode}/vscode-telemetry.ts (95%) rename packages/schema/src/{ => vscode}/zenstack-auth-provider.ts (100%) rename packages/schema/src/{ => vscode}/zmodel-preview.ts (99%) diff --git a/packages/schema/build/bundle.js b/packages/schema/build/bundle.js index 9c4ee70c0..f123666d1 100644 --- a/packages/schema/build/bundle.js +++ b/packages/schema/build/bundle.js @@ -15,6 +15,7 @@ require('esbuild') }) .then(() => { fs.cpSync('./src/res', 'bundle/res', { force: true, recursive: true }); + fs.cpSync('./src/vscode/res', 'bundle/res', { force: true, recursive: true }); fs.cpSync('../language/syntaxes', 'bundle/syntaxes', { force: true, recursive: true }); }) .then(() => console.log(success)) diff --git a/packages/schema/src/extension.ts b/packages/schema/src/extension.ts index df762e12a..ad1c886e4 100644 --- a/packages/schema/src/extension.ts +++ b/packages/schema/src/extension.ts @@ -2,11 +2,11 @@ import * as vscode from 'vscode'; import * as path from 'path'; import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient/node'; -import { AUTH_PROVIDER_ID, ZenStackAuthenticationProvider } from './zenstack-auth-provider'; -import { DocumentationCache } from './documentation-cache'; -import { ZModelPreview } from './zmodel-preview'; -import { ReleaseNotesManager } from './release-notes-manager'; -import telemetry from './vscode-telemetry'; +import { AUTH_PROVIDER_ID, ZenStackAuthenticationProvider } from './vscode/zenstack-auth-provider'; +import { DocumentationCache } from './vscode/documentation-cache'; +import { ZModelPreview } from './vscode/zmodel-preview'; +import { ReleaseNotesManager } from './vscode/release-notes-manager'; +import telemetry from './vscode/vscode-telemetry'; // Global variables let client: LanguageClient; diff --git a/packages/schema/src/documentation-cache.ts b/packages/schema/src/vscode/documentation-cache.ts similarity index 100% rename from packages/schema/src/documentation-cache.ts rename to packages/schema/src/vscode/documentation-cache.ts diff --git a/packages/schema/src/release-notes-manager.ts b/packages/schema/src/vscode/release-notes-manager.ts similarity index 100% rename from packages/schema/src/release-notes-manager.ts rename to packages/schema/src/vscode/release-notes-manager.ts diff --git a/packages/schema/src/res/zmodel-preview-release-notes.html b/packages/schema/src/vscode/res/zmodel-preview-release-notes.html similarity index 100% rename from packages/schema/src/res/zmodel-preview-release-notes.html rename to packages/schema/src/vscode/res/zmodel-preview-release-notes.html diff --git a/packages/schema/src/vscode-telemetry.ts b/packages/schema/src/vscode/vscode-telemetry.ts similarity index 95% rename from packages/schema/src/vscode-telemetry.ts rename to packages/schema/src/vscode/vscode-telemetry.ts index 623701030..7f5d6de98 100644 --- a/packages/schema/src/vscode-telemetry.ts +++ b/packages/schema/src/vscode/vscode-telemetry.ts @@ -1,9 +1,9 @@ import { init, Mixpanel } from 'mixpanel'; import * as os from 'os'; import * as vscode from 'vscode'; -import { getMachineId } from './utils/machine-id-utils'; +import { getMachineId } from '../utils/machine-id-utils'; import { v5 as uuidv5 } from 'uuid'; -import { TELEMETRY_TRACKING_TOKEN } from './constants'; +import { TELEMETRY_TRACKING_TOKEN } from '../constants'; export type TelemetryEvents = | 'extension:activate' diff --git a/packages/schema/src/zenstack-auth-provider.ts b/packages/schema/src/vscode/zenstack-auth-provider.ts similarity index 100% rename from packages/schema/src/zenstack-auth-provider.ts rename to packages/schema/src/vscode/zenstack-auth-provider.ts diff --git a/packages/schema/src/zmodel-preview.ts b/packages/schema/src/vscode/zmodel-preview.ts similarity index 99% rename from packages/schema/src/zmodel-preview.ts rename to packages/schema/src/vscode/zmodel-preview.ts index 53698aa65..9826bd980 100644 --- a/packages/schema/src/zmodel-preview.ts +++ b/packages/schema/src/vscode/zmodel-preview.ts @@ -5,7 +5,7 @@ import { z } from 'zod'; import { LanguageClient } from 'vscode-languageclient/node'; import { URI } from 'vscode-uri'; import { DocumentationCache } from './documentation-cache'; -import { requireAuth } from './extension'; +import { requireAuth } from '../extension'; import { API_URL } from './zenstack-auth-provider'; import telemetry from './vscode-telemetry'; diff --git a/packages/schema/tsconfig.json b/packages/schema/tsconfig.json index 0cc75a43a..5e01b8ac9 100644 --- a/packages/schema/tsconfig.json +++ b/packages/schema/tsconfig.json @@ -4,5 +4,5 @@ "outDir": "dist" }, "include": ["src/**/*.ts"], - "exclude": ["src/extension.ts"] + "exclude": ["src/extension.ts", "src/vscode/**/*.ts"] } From abc8efb650155188c1cfd5ba2162de2ea3365b2c Mon Sep 17 00:00:00 2001 From: jiasheng Date: Sat, 27 Sep 2025 10:17:29 +0800 Subject: [PATCH 7/9] feat: add telemetry token replacement for bundle process --- packages/schema/build/bundle.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/packages/schema/build/bundle.js b/packages/schema/build/bundle.js index f123666d1..ca8fc4d48 100644 --- a/packages/schema/build/bundle.js +++ b/packages/schema/build/bundle.js @@ -2,6 +2,28 @@ const watch = process.argv.includes('--watch'); const minify = process.argv.includes('--minify'); const success = watch ? 'Watch build succeeded' : 'Build succeeded'; const fs = require('fs'); +const path = require('path'); + +// Replace telemetry token before building +function replaceTelemetryToken() { + const telemetryToken = process.env.TELEMETRY_TRACKING_TOKEN; + if (!telemetryToken) { + console.error('Error: TELEMETRY_TRACKING_TOKEN environment variable is not set'); + process.exit(1); + } + + const constantsPath = path.join(__dirname, '../src/constants.ts'); + let constantsContent = fs.readFileSync(constantsPath, 'utf8'); + + // Replace the placeholder with the actual token + constantsContent = constantsContent.replace('', telemetryToken); + + fs.writeFileSync(constantsPath, constantsContent); + console.log('Telemetry token replaced successfully'); +} + +// Replace the token before building +replaceTelemetryToken(); require('esbuild') .build({ From 9ee7e62654cae62952fc3f75a65528f6e67ba824 Mon Sep 17 00:00:00 2001 From: jiasheng Date: Sat, 27 Sep 2025 13:33:48 +0800 Subject: [PATCH 8/9] fix: update telemetry token replacement to occur after building bundle --- packages/schema/build/bundle.js | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/packages/schema/build/bundle.js b/packages/schema/build/bundle.js index ca8fc4d48..7004aadc9 100644 --- a/packages/schema/build/bundle.js +++ b/packages/schema/build/bundle.js @@ -4,27 +4,19 @@ const success = watch ? 'Watch build succeeded' : 'Build succeeded'; const fs = require('fs'); const path = require('path'); -// Replace telemetry token before building -function replaceTelemetryToken() { +// Replace telemetry token in generated bundle files after building +function replaceTelemetryTokenInBundle() { const telemetryToken = process.env.TELEMETRY_TRACKING_TOKEN; if (!telemetryToken) { console.error('Error: TELEMETRY_TRACKING_TOKEN environment variable is not set'); process.exit(1); } - - const constantsPath = path.join(__dirname, '../src/constants.ts'); - let constantsContent = fs.readFileSync(constantsPath, 'utf8'); - - // Replace the placeholder with the actual token - constantsContent = constantsContent.replace('', telemetryToken); - - fs.writeFileSync(constantsPath, constantsContent); - console.log('Telemetry token replaced successfully'); + const file = 'bundle/extension.js'; + let content = fs.readFileSync(file, 'utf-8'); + content = content.replace('', telemetryToken); + fs.writeFileSync(file, content, 'utf-8'); } -// Replace the token before building -replaceTelemetryToken(); - require('esbuild') .build({ entryPoints: ['src/extension.ts', 'src/language-server/main.ts'], @@ -35,6 +27,10 @@ require('esbuild') sourcemap: !minify, minify, }) + .then(() => { + // Replace the token after building outputs + replaceTelemetryTokenInBundle(); + }) .then(() => { fs.cpSync('./src/res', 'bundle/res', { force: true, recursive: true }); fs.cpSync('./src/vscode/res', 'bundle/res', { force: true, recursive: true }); From 08d048e1cc7fcb9ef4005a04af1b8ea17ef5789f Mon Sep 17 00:00:00 2001 From: jiasheng Date: Sun, 28 Sep 2025 22:11:33 +0800 Subject: [PATCH 9/9] fix: update telemetry token references to use VSCODE_TELEMETRY_TRACKING_TOKEN --- packages/schema/build/bundle.js | 6 +++--- packages/schema/src/vscode/vscode-telemetry.ts | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/schema/build/bundle.js b/packages/schema/build/bundle.js index 7004aadc9..e851b7ce9 100644 --- a/packages/schema/build/bundle.js +++ b/packages/schema/build/bundle.js @@ -6,14 +6,14 @@ const path = require('path'); // Replace telemetry token in generated bundle files after building function replaceTelemetryTokenInBundle() { - const telemetryToken = process.env.TELEMETRY_TRACKING_TOKEN; + const telemetryToken = process.env.VSCODE_TELEMETRY_TRACKING_TOKEN; if (!telemetryToken) { - console.error('Error: TELEMETRY_TRACKING_TOKEN environment variable is not set'); + console.error('Error: VSCODE_TELEMETRY_TRACKING_TOKEN environment variable is not set'); process.exit(1); } const file = 'bundle/extension.js'; let content = fs.readFileSync(file, 'utf-8'); - content = content.replace('', telemetryToken); + content = content.replace('', telemetryToken); fs.writeFileSync(file, content, 'utf-8'); } diff --git a/packages/schema/src/vscode/vscode-telemetry.ts b/packages/schema/src/vscode/vscode-telemetry.ts index 7f5d6de98..a9ffbeb26 100644 --- a/packages/schema/src/vscode/vscode-telemetry.ts +++ b/packages/schema/src/vscode/vscode-telemetry.ts @@ -3,7 +3,8 @@ import * as os from 'os'; import * as vscode from 'vscode'; import { getMachineId } from '../utils/machine-id-utils'; import { v5 as uuidv5 } from 'uuid'; -import { TELEMETRY_TRACKING_TOKEN } from '../constants'; + +export const VSCODE_TELEMETRY_TRACKING_TOKEN = ''; export type TelemetryEvents = | 'extension:activate' @@ -28,7 +29,7 @@ export class VSCodeTelemetry { constructor() { if (vscode.env.isTelemetryEnabled) { - this.mixpanel = init(TELEMETRY_TRACKING_TOKEN, { + this.mixpanel = init(VSCODE_TELEMETRY_TRACKING_TOKEN, { geolocate: true, }); }