Skip to content

Commit 8761e11

Browse files
committed
fix: scope css selector normalization and simplify backend launch flow
1 parent d5ab04b commit 8761e11

3 files changed

Lines changed: 60 additions & 60 deletions

File tree

dashboard/vite.config.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,24 @@ import vuetify from 'vite-plugin-vuetify';
55

66
const normalizeNestedTypeSelectorPlugin = {
77
postcssPlugin: 'normalize-nested-type-selector',
8-
Rule(rule: { parent?: { type?: string }; selector?: string }) {
8+
Rule(rule: {
9+
parent?: { type?: string; parent?: unknown; selector?: string };
10+
selector?: string;
11+
source?: { input?: { file?: string; from?: string } };
12+
}) {
913
if (rule.parent?.type !== 'rule' || typeof rule.selector !== 'string') {
1014
return;
1115
}
1216

17+
const sourceFile = String(rule.source?.input?.file || rule.source?.input?.from || '')
18+
.replace(/\\/g, '/')
19+
.toLowerCase();
20+
const isProjectSource = sourceFile.includes('/dashboard/src/');
21+
const isMonacoVendor = sourceFile.includes('/node_modules/monaco-editor/');
22+
if (!isProjectSource && !isMonacoVendor) {
23+
return;
24+
}
25+
1326
const segments = rule.selector
1427
.split(',')
1528
.map((segment) => segment.trim())

desktop/lib/backend-manager.js

Lines changed: 35 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -132,24 +132,19 @@ class BackendManager {
132132
return fs.existsSync(indexPath) ? candidate : null;
133133
}
134134

135-
loadPackagedBackendState() {
135+
getPackagedBackendState() {
136136
if (!this.app.isPackaged) {
137137
return null;
138138
}
139-
if (this.packagedBackendState) {
140-
return this.packagedBackendState;
139+
if (!this.packagedBackendState) {
140+
this.packagedBackendState = resolvePackagedBackendState(
141+
process.resourcesPath,
142+
(message) => this.log(message),
143+
);
141144
}
142-
this.packagedBackendState = resolvePackagedBackendState(
143-
process.resourcesPath,
144-
(message) => this.log(message),
145-
);
146145
return this.packagedBackendState;
147146
}
148147

149-
getPackagedBackendState() {
150-
return this.loadPackagedBackendState();
151-
}
152-
153148
buildDefaultBackendLaunch(webuiDir) {
154149
const args = ['run', 'main.py'];
155150
if (webuiDir) {
@@ -162,46 +157,42 @@ class BackendManager {
162157
};
163158
}
164159

165-
resolveLaunchCommand(webuiDir) {
166-
const customCmd = process.env.ASTRBOT_BACKEND_CMD;
167-
if (customCmd) {
168-
return {
169-
launch: {
170-
cmd: customCmd,
171-
args: [],
172-
shell: true,
173-
},
174-
failureReason: null,
175-
};
176-
}
177-
178-
if (this.app.isPackaged) {
179-
const packagedBackendState = this.getPackagedBackendState();
180-
if (packagedBackendState?.ok && packagedBackendState.config) {
181-
return {
182-
launch: {
183-
cmd: packagedBackendState.config.runtimePythonPath,
184-
args: [packagedBackendState.config.launchScriptPath, ...(webuiDir ? ['--webui-dir', webuiDir] : [])],
185-
shell: false,
186-
},
187-
failureReason: null,
188-
};
189-
}
160+
buildLaunchForPackagedBackend(packagedBackendState, webuiDir) {
161+
if (!packagedBackendState?.ok || !packagedBackendState.config) {
190162
return {
191163
launch: null,
192-
failureReason: packagedBackendState?.failureReason || 'Backend command is not configured.',
164+
failureReason:
165+
packagedBackendState?.failureReason || 'Backend command is not configured.',
193166
};
194167
}
195168

169+
const { runtimePythonPath, launchScriptPath } = packagedBackendState.config;
170+
const args = [launchScriptPath];
171+
if (webuiDir) {
172+
args.push('--webui-dir', webuiDir);
173+
}
196174
return {
197-
launch: this.buildDefaultBackendLaunch(webuiDir),
175+
launch: { cmd: runtimePythonPath, args, shell: false },
198176
failureReason: null,
199177
};
200178
}
201179

202180
resolveBackendConfig() {
203181
const webuiDir = this.resolveWebuiDir();
204-
const { launch, failureReason } = this.resolveLaunchCommand(webuiDir);
182+
let launch = null;
183+
let failureReason = null;
184+
185+
const customCmd = process.env.ASTRBOT_BACKEND_CMD;
186+
if (customCmd) {
187+
launch = { cmd: customCmd, args: [], shell: true };
188+
} else if (this.app.isPackaged) {
189+
({ launch, failureReason } = this.buildLaunchForPackagedBackend(
190+
this.getPackagedBackendState(),
191+
webuiDir,
192+
));
193+
} else {
194+
launch = this.buildDefaultBackendLaunch(webuiDir);
195+
}
205196

206197
const cwd = process.env.ASTRBOT_BACKEND_CWD || this.resolveBackendCwd();
207198
const rootDir = process.env.ASTRBOT_ROOT || this.resolveBackendRoot();
@@ -656,25 +647,6 @@ class BackendManager {
656647
return { imageName, pid: parsedPid };
657648
}
658649

659-
shouldKillUnmanagedProcess({
660-
pid,
661-
processInfo,
662-
backendConfig,
663-
commandLineCache,
664-
}) {
665-
const hasBackendConfig = backendConfig && typeof backendConfig === 'object';
666-
return shouldKillUnmanagedBackendProcess({
667-
pid,
668-
processInfo,
669-
backendConfig,
670-
allowImageOnlyMatch: !hasBackendConfig,
671-
commandLineCache,
672-
spawnSync,
673-
log: (message) => this.log(message),
674-
fallbackCmdRaw: process.env.ASTRBOT_BACKEND_CMD || 'python.exe',
675-
});
676-
}
677-
678650
async stopUnmanagedBackendByPort() {
679651
if (!this.app.isPackaged || process.platform !== 'win32') {
680652
return false;
@@ -718,11 +690,15 @@ class BackendManager {
718690
this.log(`Skip unmanaged cleanup for pid=${pid}: unable to resolve process info.`);
719691
continue;
720692
}
721-
const shouldKill = this.shouldKillUnmanagedProcess({
693+
const shouldKill = shouldKillUnmanagedBackendProcess({
722694
pid,
723695
processInfo,
724696
backendConfig,
697+
allowImageOnlyMatch: !hasBackendConfig,
725698
commandLineCache,
699+
spawnSync,
700+
log: (message) => this.log(message),
701+
fallbackCmdRaw: process.env.ASTRBOT_BACKEND_CMD || 'python.exe',
726702
});
727703
if (!shouldKill) {
728704
continue;

desktop/scripts/runtime-layout-utils.mjs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,13 @@ export const resolveAndValidateRuntimeSource = ({ rootDir, outputDir, runtimeSou
4444

4545
const runtimeNorm = normalizeForCompare(runtimeSourceReal);
4646
const outputNorm = normalizeForCompare(outputDir);
47+
const projectRootNorm = normalizeForCompare(rootDir);
4748
const runtimeIsOutputOrSub =
4849
runtimeNorm === outputNorm || runtimeNorm.startsWith(`${outputNorm}${path.sep}`);
4950
const outputIsRuntimeOrSub =
5051
outputNorm === runtimeNorm || outputNorm.startsWith(`${runtimeNorm}${path.sep}`);
52+
const runtimeContainsProjectRoot =
53+
runtimeNorm === projectRootNorm || projectRootNorm.startsWith(`${runtimeNorm}${path.sep}`);
5154

5255
if (runtimeIsOutputOrSub || outputIsRuntimeOrSub) {
5356
throw new Error(
@@ -56,6 +59,14 @@ export const resolveAndValidateRuntimeSource = ({ rootDir, outputDir, runtimeSou
5659
'Please set ASTRBOT_DESKTOP_CPYTHON_HOME to a separate runtime directory.',
5760
);
5861
}
62+
if (runtimeContainsProjectRoot) {
63+
throw new Error(
64+
`CPython runtime source is too broad and contains the project root. ` +
65+
`runtime=${runtimeSourceReal}, projectRoot=${path.resolve(rootDir)}. ` +
66+
'Please point ASTRBOT_DESKTOP_CPYTHON_HOME (or ASTRBOT_DESKTOP_BACKEND_RUNTIME) ' +
67+
'to a dedicated CPython runtime directory instead of the repository root or its parent.',
68+
);
69+
}
5970

6071
return runtimeSourceReal;
6172
};

0 commit comments

Comments
 (0)