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
5 changes: 4 additions & 1 deletion Release.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ If you've updated the bundled packages installed in the enviornment, then we nee
yarn create_env_installer:osx-arm64 && yarn update_binary_sign_list --platform osx-arm64
```

## Step 3: Run the GitHub Actions
## Step 3: Commit your changes
Now, create a new PR branch and commit your changes. This is going to be the branch that we use for the release.

## Step 4: Run the GitHub Actions

1. Run prerelease.yml → Create a new release on GitHub as `pre-release`. Set the release `tag` to the value of target application version and prefix it with `v` (for example `v1.0.0-1` for Mito Desktop version `1.0.0-1`). Release needs to stay as `pre-release` for GitHub Actions to be able to attach installers to the release.

Expand Down
2 changes: 1 addition & 1 deletion auto-release.log
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1760037168
1760566089
42 changes: 21 additions & 21 deletions env_installer/conda-linux-64.lock

Large diffs are not rendered by default.

42 changes: 21 additions & 21 deletions env_installer/conda-linux-aarch64.lock

Large diffs are not rendered by default.

44 changes: 22 additions & 22 deletions env_installer/conda-osx-64.lock

Large diffs are not rendered by default.

44 changes: 22 additions & 22 deletions env_installer/conda-osx-arm64.lock

Large diffs are not rendered by default.

48 changes: 24 additions & 24 deletions env_installer/conda-win-64.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions env_installer/sign-osx-64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ lib/python3.12/lib-dynload/xxlimited.cpython-312-darwin.so
lib/python3.12/lib-dynload/xxlimited_35.cpython-312-darwin.so
lib/python3.12/lib-dynload/xxsubtype.cpython-312-darwin.so
lib/python3.12/lib-dynload/zlib.cpython-312-darwin.so
lib/python3.12/lib2to3/Grammar3.12.11.final.0.pickle
lib/python3.12/lib2to3/PatternGrammar3.12.11.final.0.pickle
lib/python3.12/lib2to3/Grammar3.12.12.final.0.pickle
lib/python3.12/lib2to3/PatternGrammar3.12.12.final.0.pickle
lib/python3.12/site-packages/.DS_Store
lib/python3.12/site-packages/PIL/.dylibs/libXau.6.dylib
lib/python3.12/site-packages/PIL/.dylibs/libavif.16.3.0.dylib
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Mito",
"version": "1.0.0-5",
"version": "1.0.0-6",
"description": "Mito Desktop App",
"main": "./build/out/main/main.js",
"scripts": {
Expand Down Expand Up @@ -224,6 +224,7 @@
},
"dependencies": {
"@lumino/signaling": "^1.10.0",
"@segment/analytics-node": "^2.3.0",
"ejs": "^3.1.10",
"electron-log": "^4.4.8",
"fast-xml-parser": "^4.2.5",
Expand Down
23 changes: 23 additions & 0 deletions src/main/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import {
validatePythonEnvironmentInstallDirectory,
validateSystemPythonPath
} from './env';
import { logEvent } from './telemetry_utils';

export interface IApplication {
createNewEmptySession(): void;
Expand Down Expand Up @@ -761,6 +762,11 @@ export class JupyterApplication implements IApplication, IDisposable {
return;
}
const installPath = envPath || getBundledPythonEnvPath();

// Log installation start
logEvent('desktop_python_install_started');
const installStartTime = Date.now();

await installBundledEnvironment(installPath, {
onInstallStatus: (status, message) => {
event.sender.send(
Expand All @@ -773,6 +779,23 @@ export class JupyterApplication implements IApplication, IDisposable {
const pythonPath = pythonPathForEnvPath(installPath, true);
this._registry.addEnvironment(pythonPath);
this._registry.setDefaultPythonPath(pythonPath);

// Log installation completion
logEvent('desktop_python_install_completed', {
install_time_seconds: (Date.now() - installStartTime) / 1000
});
} else if (status === EnvironmentInstallStatus.Failure) {
// Log installation failure
logEvent('desktop_python_install_failed', {
install_time_seconds: (Date.now() - installStartTime) / 1000,
error: message
});
} else if (status === EnvironmentInstallStatus.Cancelled) {
// Log installation cancellation
logEvent('desktop_python_install_cancelled', {
install_time_seconds: (Date.now() - installStartTime) / 1000,
error: message
});
}
},
get forceOverwrite() {
Expand Down
90 changes: 90 additions & 0 deletions src/main/telemetry_utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import fs from 'fs';
import os from 'os';
import path from 'path';
import crypto from 'crypto';
import { Analytics } from '@segment/analytics-node'
import { isDevMode } from './utils';

const MITO_FOLDER = path.join(os.homedir(), '.mito');
const USER_JSON_FILE = 'user.json';
const TEMP_USER_ID_FILE = 'temp_user_id.txt';

const analytics = new Analytics({
writeKey: '6I7ptc5wcIGC4WZ0N1t0NXvvAbjRGUgX',
flushAt: 1, // Send events immediately
flushInterval: 1000 // Flush every second
});

export const createMitoFolder = () => {
// Create a mito folder, if it doesn't exist
if (!fs.existsSync(MITO_FOLDER)) {
fs.mkdirSync(MITO_FOLDER);
}
}

export const checkIfUserAlreadyMitoUser = () => {
// First look for the mito folder
if (!fs.existsSync(MITO_FOLDER)) {
return { isMitoUser: false, userId: "" };
}

// Then look for the user.json file
const userJsonFile = path.join(MITO_FOLDER, USER_JSON_FILE);
if (!fs.existsSync(userJsonFile)) {
return { isMitoUser: false, userId: null };
}

// Finally, read the user.json file
const userJson = JSON.parse(fs.readFileSync(userJsonFile, 'utf8'));
return { isMitoUser: true, userId: userJson.static_user_id };
}

export const createTempUserId = () => {
// If the temp user id file already exists, return the user id from the file
if (fs.existsSync(path.join(MITO_FOLDER, TEMP_USER_ID_FILE))) {
return fs.readFileSync(path.join(MITO_FOLDER, TEMP_USER_ID_FILE), 'utf8');
}

// Create a temp user id, and save it to a temp file.
// This temp file will be picked up by the mito-ai package
// when it creates the user.json file.
createMitoFolder();
const tempUserId = crypto.randomUUID();
const tempUserIdFile = path.join(MITO_FOLDER, TEMP_USER_ID_FILE);
fs.writeFileSync(tempUserIdFile, tempUserId);
return tempUserId;
}

export const getUserId = () => {
// First check if the user is already a Mito user
const { isMitoUser, userId } = checkIfUserAlreadyMitoUser();
if (isMitoUser) {
return userId;
}
// If not, create a new temp user id
return createTempUserId();
}

export const identifyUser = () => {
analytics.identify({
userId: getUserId(),
traits: {
operating_system: process.platform,
version_mito_desktop: process.env.npm_package_version,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Telemetry Missing Version Data in Electron Builds

The version_mito_desktop telemetry property relies on process.env.npm_package_version. This environment variable is typically only present during npm script execution and may be undefined in a built Electron application, leading to missing version data in telemetry.

Additional Locations (1)

Fix in Cursor Fix in Web

is_dev_mode: isDevMode(),
email: isDevMode() ? 'dev@trymito.io' : undefined
}
});
}

export const logEvent = (event: string, properties: any = {}) => {
analytics.track({
userId: getUserId(),
event: event,
properties: {
...properties,
operating_system: process.platform,
version_mito_desktop: process.env.npm_package_version,
}
});
}
4 changes: 4 additions & 0 deletions src/main/welcomeview/welcomeview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as fs from 'fs';
import { appData } from '../config/appdata';
import { IRegistry } from '../registry';
import { EventTypeMain, EventTypeRenderer } from '../eventtypes';
import { identifyUser, logEvent } from '../telemetry_utils';

const maxRecentItems = 5;

Expand All @@ -20,6 +21,9 @@ interface IRecentSessionListItem {

export class WelcomeView {
constructor(options: WelcomeView.IOptions) {
identifyUser();
logEvent('desktop_welcome_view_loaded');

this._registry = options.registry;
this._isDarkTheme = options.isDarkTheme;
this._view = new BrowserView({
Expand Down
Loading
Loading