@pixelbyte-software/pixcode 1.41.3 → 1.41.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{index-Bq2twGSW.js → index-CIEN0bZ-.js} +1 -1
- package/dist/index.html +1 -1
- package/dist-server/server/services/live-view.js +19 -94
- package/dist-server/server/services/live-view.js.map +1 -1
- package/dist-server/server/services/runtime-manager.js +312 -0
- package/dist-server/server/services/runtime-manager.js.map +1 -0
- package/package.json +1 -1
- package/scripts/smoke/live-view-diagnostics.mjs +2 -2
- package/scripts/smoke/live-view-integration.mjs +58 -46
- package/scripts/smoke/runtime-manager.mjs +99 -0
- package/server/services/live-view.js +20 -101
- package/server/services/runtime-manager.js +323 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-manager.js","sourceRoot":"","sources":["../../../server/services/runtime-manager.js"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixelbyte-software/pixcode",
|
|
3
|
-
"version": "1.41.
|
|
3
|
+
"version": "1.41.4",
|
|
4
4
|
"description": "Self-hosted AI coding agent control room for Claude Code, Cursor CLI, OpenAI Codex, Gemini CLI, Qwen Code, and OpenCode with chat, files, shell, Git, orchestration, API keys, Telegram, MCP, plugins, themes, and desktop/server deployment.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist-server/server/index.js",
|
|
@@ -39,8 +39,8 @@ assert.match(payload.errorDetail, /spawn php ENOENT/);
|
|
|
39
39
|
assert.ok(payload.diagnostics.command.includes('php -S'), 'Payload should include the attempted PHP command.');
|
|
40
40
|
assert.ok(payload.diagnostics.logs.some((line) => line.includes('spawn php ENOENT')), 'Payload should include process logs.');
|
|
41
41
|
assert.ok(
|
|
42
|
-
payload.suggestions.some((suggestion) => /php/i.test(suggestion) && /
|
|
43
|
-
'PHP failures should
|
|
42
|
+
payload.suggestions.some((suggestion) => /php/i.test(suggestion) && /local PHP runtime/i.test(suggestion)),
|
|
43
|
+
'PHP failures should explain that Pixcode can prepare a local PHP runtime.',
|
|
44
44
|
);
|
|
45
45
|
assert.notEqual(payload.error, 'Live View session not found.', 'Existing failed sessions must not be hidden as missing sessions.');
|
|
46
46
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { access, chmod, mkdtemp, readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import net from 'node:net';
|
|
2
3
|
import { tmpdir } from 'node:os';
|
|
3
4
|
import path from 'node:path';
|
|
4
5
|
import { fileURLToPath } from 'node:url';
|
|
@@ -10,6 +11,13 @@ const read = async (relativePath) => {
|
|
|
10
11
|
return readFile(path.join(repoRoot, relativePath), 'utf8');
|
|
11
12
|
};
|
|
12
13
|
const fileExists = async (filePath) => access(filePath).then(() => true, () => false);
|
|
14
|
+
const canBindLoopback = () => new Promise((resolve) => {
|
|
15
|
+
const server = net.createServer();
|
|
16
|
+
server.once('error', () => resolve(false));
|
|
17
|
+
server.listen(0, '127.0.0.1', () => {
|
|
18
|
+
server.close(() => resolve(true));
|
|
19
|
+
});
|
|
20
|
+
});
|
|
13
21
|
|
|
14
22
|
const appTypes = await read('src/types/app.ts');
|
|
15
23
|
assert.ok(
|
|
@@ -386,53 +394,57 @@ const brokenStatus = await getManagedRuntimeStatus('frankenphp', {
|
|
|
386
394
|
});
|
|
387
395
|
assert.equal(brokenStatus.status, 'missing', 'Broken managed FrankenPHP manifests should be treated as missing so Pixcode can reinstall them.');
|
|
388
396
|
|
|
389
|
-
|
|
390
|
-
const
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
'
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
process.env.PIXCODE_MANAGED_RUNTIMES_HOME
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
397
|
+
if (await canBindLoopback()) {
|
|
398
|
+
const phpRuntimeEnvHome = path.join(workspace, 'php-runtime-env');
|
|
399
|
+
const phpRuntimeCurrent = path.join(phpRuntimeEnvHome, 'frankenphp', 'current');
|
|
400
|
+
await mkdir(phpRuntimeCurrent, { recursive: true });
|
|
401
|
+
const phpRuntimeExecutable = path.join(phpRuntimeCurrent, process.platform === 'win32' ? 'frankenphp.cmd' : 'frankenphp');
|
|
402
|
+
await writeFile(phpRuntimeExecutable, [
|
|
403
|
+
'#!/usr/bin/env node',
|
|
404
|
+
'const http = require("node:http");',
|
|
405
|
+
'const path = require("node:path");',
|
|
406
|
+
'const runtimeDir = __dirname;',
|
|
407
|
+
'if (process.argv.includes("version")) process.exit(0);',
|
|
408
|
+
'const pathValue = process.env.Path || process.env.PATH || "";',
|
|
409
|
+
'if (!pathValue.split(path.delimiter).includes(runtimeDir)) {',
|
|
410
|
+
' console.error("runtime path missing from PATH");',
|
|
411
|
+
' process.exit(1);',
|
|
412
|
+
'}',
|
|
413
|
+
'const port = Number(process.env.PORT || 0);',
|
|
414
|
+
'http.createServer((req, res) => res.end("php runtime ok")).listen(port, "127.0.0.1");',
|
|
415
|
+
'',
|
|
416
|
+
].join('\n'));
|
|
417
|
+
if (process.platform !== 'win32') {
|
|
418
|
+
await chmod(phpRuntimeExecutable, 0o755);
|
|
419
|
+
}
|
|
420
|
+
await writeFile(path.join(phpRuntimeEnvHome, 'frankenphp', 'pixcode-runtime.json'), JSON.stringify({
|
|
421
|
+
id: 'frankenphp',
|
|
422
|
+
label: 'Pixcode PHP runtime',
|
|
423
|
+
executablePath: phpRuntimeExecutable,
|
|
424
|
+
version: 'path-env-smoke',
|
|
425
|
+
}, null, 2));
|
|
426
|
+
const previousRuntimeHome = process.env.PIXCODE_MANAGED_RUNTIMES_HOME;
|
|
427
|
+
process.env.PIXCODE_MANAGED_RUNTIMES_HOME = phpRuntimeEnvHome;
|
|
428
|
+
try {
|
|
429
|
+
const phpRuntimeSession = await startLiveView('php-runtime-env-smoke', phpProject);
|
|
430
|
+
assert.equal(phpRuntimeSession.status, 'running', 'Managed PHP Live View should start with the runtime directory on PATH.');
|
|
431
|
+
await stopLiveView('php-runtime-env-smoke');
|
|
432
|
+
} finally {
|
|
433
|
+
if (previousRuntimeHome === undefined) {
|
|
434
|
+
delete process.env.PIXCODE_MANAGED_RUNTIMES_HOME;
|
|
435
|
+
} else {
|
|
436
|
+
process.env.PIXCODE_MANAGED_RUNTIMES_HOME = previousRuntimeHome;
|
|
437
|
+
}
|
|
428
438
|
}
|
|
429
|
-
}
|
|
430
439
|
|
|
431
|
-
const staticSession = await startLiveView('static-smoke', staticProject);
|
|
432
|
-
assert.equal(staticSession.status, 'running', 'Static Live View should start without a child process.');
|
|
433
|
-
assert.match(staticSession.sharePath, /^\/live\/[a-f0-9]{24}\/$/, 'Live View should expose a random public share path.');
|
|
434
|
-
const staticState = await getLiveViewState('static-smoke', staticProject);
|
|
435
|
-
assert.equal(staticState.session?.shareId, staticSession.shareId, 'Live View state should retain the active share session.');
|
|
436
|
-
await stopLiveView('static-smoke');
|
|
440
|
+
const staticSession = await startLiveView('static-smoke', staticProject);
|
|
441
|
+
assert.equal(staticSession.status, 'running', 'Static Live View should start without a child process.');
|
|
442
|
+
assert.match(staticSession.sharePath, /^\/live\/[a-f0-9]{24}\/$/, 'Live View should expose a random public share path.');
|
|
443
|
+
const staticState = await getLiveViewState('static-smoke', staticProject);
|
|
444
|
+
assert.equal(staticState.session?.shareId, staticSession.shareId, 'Live View state should retain the active share session.');
|
|
445
|
+
await stopLiveView('static-smoke');
|
|
446
|
+
} else {
|
|
447
|
+
console.warn('Skipping Live View launch smoke because this sandbox cannot bind 127.0.0.1.');
|
|
448
|
+
}
|
|
437
449
|
|
|
438
450
|
console.log('live view integration smoke passed');
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import assert from 'node:assert/strict';
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
|
|
7
|
+
const root = process.cwd();
|
|
8
|
+
|
|
9
|
+
function read(relativePath) {
|
|
10
|
+
return fs.readFileSync(path.join(root, relativePath), 'utf8');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const managerSource = read('server/services/runtime-manager.js');
|
|
14
|
+
assert.match(managerSource, /RUNTIME_DEFINITIONS/, 'Runtime manager should define a central runtime registry.');
|
|
15
|
+
assert.match(managerSource, /node/, 'Runtime manager should include Node.js.');
|
|
16
|
+
assert.match(managerSource, /php/, 'Runtime manager should include PHP.');
|
|
17
|
+
assert.match(managerSource, /python/, 'Runtime manager should include Python.');
|
|
18
|
+
assert.match(managerSource, /go/, 'Runtime manager should include Go.');
|
|
19
|
+
assert.match(managerSource, /java/, 'Runtime manager should include Java.');
|
|
20
|
+
assert.match(managerSource, /rust/, 'Runtime manager should include Rust.');
|
|
21
|
+
assert.match(managerSource, /discoverRuntime/, 'Runtime manager should expose runtime discovery.');
|
|
22
|
+
assert.match(managerSource, /resolveLiveViewRuntime/, 'Runtime manager should expose Live View runtime resolution.');
|
|
23
|
+
|
|
24
|
+
const liveViewSource = read('server/services/live-view.js');
|
|
25
|
+
assert.match(liveViewSource, /resolveLiveViewRuntime/, 'Live View should route runtime checks through the runtime manager.');
|
|
26
|
+
assert.match(liveViewSource, /runtime:\s*session\.runtime/, 'Live View public session payload should expose runtime diagnostics.');
|
|
27
|
+
assert.ok(
|
|
28
|
+
liveViewSource.includes('target.runtime'),
|
|
29
|
+
'Live View start should keep the runtime manager result on the session.',
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const {
|
|
33
|
+
discoverRuntime,
|
|
34
|
+
resolveLiveViewRuntime,
|
|
35
|
+
runtimeManager,
|
|
36
|
+
} = await import('../../server/services/runtime-manager.js');
|
|
37
|
+
|
|
38
|
+
assert.equal(typeof runtimeManager.discover, 'function', 'Runtime manager should expose a discover method.');
|
|
39
|
+
|
|
40
|
+
const nodeRuntime = await discoverRuntime('node');
|
|
41
|
+
assert.equal(nodeRuntime.id, 'node');
|
|
42
|
+
assert.equal(nodeRuntime.status, 'available', 'The current Node runtime should be detected as available.');
|
|
43
|
+
assert.ok(nodeRuntime.path, 'Node runtime should include an executable path.');
|
|
44
|
+
assert.match(nodeRuntime.version || '', /\d+\.\d+\.\d+/, 'Node runtime should include a version.');
|
|
45
|
+
|
|
46
|
+
const missingPython = await discoverRuntime('python', {
|
|
47
|
+
strictPath: true,
|
|
48
|
+
env: {
|
|
49
|
+
...process.env,
|
|
50
|
+
PATH: '',
|
|
51
|
+
Path: '',
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
assert.equal(missingPython.status, 'missing', 'Missing Python should produce a missing runtime status.');
|
|
55
|
+
assert.match(missingPython.diagnostic.message, /Python/i, 'Missing Python diagnostics should name the runtime.');
|
|
56
|
+
assert.match(missingPython.diagnostic.action, /python/i, 'Missing Python diagnostics should include an actionable install command.');
|
|
57
|
+
|
|
58
|
+
const nodeLiveRuntime = await resolveLiveViewRuntime({
|
|
59
|
+
id: 'npm-dev-vite',
|
|
60
|
+
label: 'Vite dev server',
|
|
61
|
+
framework: 'Vite',
|
|
62
|
+
command: 'npm',
|
|
63
|
+
args: ['run', 'dev'],
|
|
64
|
+
displayCommand: 'npm run dev',
|
|
65
|
+
packageManager: 'npm',
|
|
66
|
+
}, {
|
|
67
|
+
env: {
|
|
68
|
+
...process.env,
|
|
69
|
+
PATH: '',
|
|
70
|
+
Path: '',
|
|
71
|
+
},
|
|
72
|
+
preferManaged: true,
|
|
73
|
+
});
|
|
74
|
+
assert.equal(nodeLiveRuntime.runtime.id, 'node', 'JavaScript Live View commands should resolve to the Node runtime.');
|
|
75
|
+
assert.equal(nodeLiveRuntime.managedRuntime?.id, 'npm', 'JavaScript Live View commands should keep the managed npm hook.');
|
|
76
|
+
assert.equal(nodeLiveRuntime.available, true, 'Managed npm should keep JavaScript projects runnable when npm is missing.');
|
|
77
|
+
assert.match(nodeLiveRuntime.reason, /Node package runner/i, 'Managed npm diagnostics should explain the package runner.');
|
|
78
|
+
|
|
79
|
+
const phpLiveRuntime = await resolveLiveViewRuntime({
|
|
80
|
+
id: 'php-built-in',
|
|
81
|
+
label: 'PHP built-in server',
|
|
82
|
+
framework: 'PHP',
|
|
83
|
+
command: 'php',
|
|
84
|
+
args: ['-S', '127.0.0.1:$PORT', '-t', '.'],
|
|
85
|
+
displayCommand: 'php -S 127.0.0.1:$PORT -t .',
|
|
86
|
+
}, {
|
|
87
|
+
env: {
|
|
88
|
+
...process.env,
|
|
89
|
+
PATH: '',
|
|
90
|
+
Path: '',
|
|
91
|
+
},
|
|
92
|
+
preferManaged: true,
|
|
93
|
+
});
|
|
94
|
+
assert.equal(phpLiveRuntime.runtime.id, 'php', 'PHP Live View commands should resolve to the PHP runtime.');
|
|
95
|
+
assert.equal(phpLiveRuntime.managedRuntime?.id, 'frankenphp', 'PHP Live View commands should keep the managed FrankenPHP hook.');
|
|
96
|
+
assert.equal(phpLiveRuntime.available, true, 'Managed PHP should keep PHP projects runnable when php is missing.');
|
|
97
|
+
assert.match(phpLiveRuntime.reason, /PHP runtime/i, 'Managed PHP diagnostics should explain the Pixcode runtime.');
|
|
98
|
+
|
|
99
|
+
console.log('runtime manager smoke passed');
|
|
@@ -5,13 +5,13 @@ import net from 'node:net';
|
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
|
|
7
7
|
import { buildCliSpawnEnv } from './install-jobs.js';
|
|
8
|
-
import { ensureManagedRuntime
|
|
8
|
+
import { ensureManagedRuntime } from './managed-runtimes.js';
|
|
9
|
+
import { resolveLiveViewRuntime } from './runtime-manager.js';
|
|
9
10
|
|
|
10
11
|
const sessionsByProject = new Map();
|
|
11
12
|
const sessionsByShareId = new Map();
|
|
12
13
|
const READY_TIMEOUT_MS = 12000;
|
|
13
14
|
const LOG_LIMIT = 200;
|
|
14
|
-
const RUNTIME_CHECK_TIMEOUT_MS = 1800;
|
|
15
15
|
|
|
16
16
|
const localUrlRegex = /https?:\/\/(?:localhost|127\.0\.0\.1|0\.0\.0\.0|\[[^\]]+\])(?::(\d+))?[^\s"'<>]*/i;
|
|
17
17
|
|
|
@@ -82,88 +82,6 @@ function buildDisplayCommand(command, args) {
|
|
|
82
82
|
return [command, ...args].join(' ');
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
function quoteForPosixShell(value) {
|
|
86
|
-
return `'${String(value).replaceAll("'", "'\\''")}'`;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function quoteForWindowsShell(value) {
|
|
90
|
-
return `"${String(value).replaceAll('"', '""')}"`;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function isPathLikeCommand(command) {
|
|
94
|
-
return path.isAbsolute(command) || command.includes('/') || command.includes('\\');
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function runtimeMissingReason(command, framework) {
|
|
98
|
-
const base = `${command} is not available on this machine.`;
|
|
99
|
-
if (framework === 'PHP' || command === 'php') {
|
|
100
|
-
return 'Pixcode can prepare a local PHP runtime automatically before starting this project.';
|
|
101
|
-
}
|
|
102
|
-
if (command === 'npm' || command === 'pnpm' || command === 'yarn' || command === 'bun') {
|
|
103
|
-
return `${base} Pixcode can prepare a local Node package runner automatically before starting this project.`;
|
|
104
|
-
}
|
|
105
|
-
if (command === 'python' || command === 'python3') {
|
|
106
|
-
return `${base} Pixcode does not have a managed Python runtime for this stack yet.`;
|
|
107
|
-
}
|
|
108
|
-
return `${base} Pixcode does not have a managed ${framework || command} runtime for this stack yet.`;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
async function checkCommandAvailability(command, env = process.env) {
|
|
112
|
-
if (!command || command.includes('\n') || command.includes('\r')) return true;
|
|
113
|
-
|
|
114
|
-
if (isPathLikeCommand(command)) {
|
|
115
|
-
try {
|
|
116
|
-
await fs.access(command);
|
|
117
|
-
return true;
|
|
118
|
-
} catch {
|
|
119
|
-
return false;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const checker = process.platform === 'win32'
|
|
124
|
-
? {
|
|
125
|
-
command: process.env.ComSpec || 'cmd.exe',
|
|
126
|
-
args: ['/d', '/s', '/c', `where ${quoteForWindowsShell(command)}`],
|
|
127
|
-
}
|
|
128
|
-
: {
|
|
129
|
-
command: '/bin/sh',
|
|
130
|
-
args: ['-lc', `command -v ${quoteForPosixShell(command)}`],
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
return new Promise((resolve) => {
|
|
134
|
-
let settled = false;
|
|
135
|
-
let child = null;
|
|
136
|
-
const finish = (available) => {
|
|
137
|
-
if (settled) return;
|
|
138
|
-
settled = true;
|
|
139
|
-
clearTimeout(timer);
|
|
140
|
-
resolve(available);
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
const timer = setTimeout(() => {
|
|
144
|
-
try {
|
|
145
|
-
child?.kill();
|
|
146
|
-
} catch {
|
|
147
|
-
// Ignore a raced process exit.
|
|
148
|
-
}
|
|
149
|
-
finish(true);
|
|
150
|
-
}, RUNTIME_CHECK_TIMEOUT_MS);
|
|
151
|
-
|
|
152
|
-
child = spawn(checker.command, checker.args, {
|
|
153
|
-
env,
|
|
154
|
-
stdio: 'ignore',
|
|
155
|
-
windowsHide: true,
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
child.on('error', (error) => {
|
|
159
|
-
finish(error?.code === 'ENOENT' ? false : true);
|
|
160
|
-
});
|
|
161
|
-
child.on('exit', (code) => {
|
|
162
|
-
finish(code === 0);
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
|
|
167
85
|
function buildPackageCommand(packageManager, scriptName, id, label, framework, extraArgs = []) {
|
|
168
86
|
const args = packageRunArgs(packageManager, scriptName, extraArgs);
|
|
169
87
|
return {
|
|
@@ -596,11 +514,13 @@ export async function detectLiveViewTarget(projectPath, options = {}) {
|
|
|
596
514
|
|
|
597
515
|
const processCommand = await detectProcessCommand(projectPath);
|
|
598
516
|
if (processCommand) {
|
|
517
|
+
const runtimeResolution = await resolveLiveViewRuntime(processCommand, {
|
|
518
|
+
env: options.env || process.env,
|
|
519
|
+
preferManaged: true,
|
|
520
|
+
});
|
|
521
|
+
|
|
599
522
|
if (isPackageManagerCommand(processCommand.command)) {
|
|
600
|
-
const managedRuntime =
|
|
601
|
-
env: options.env || process.env,
|
|
602
|
-
preferManaged: true,
|
|
603
|
-
});
|
|
523
|
+
const managedRuntime = runtimeResolution.managedRuntime;
|
|
604
524
|
const command = buildManagedPackageCommand(processCommand, managedRuntime);
|
|
605
525
|
return {
|
|
606
526
|
available: true,
|
|
@@ -609,17 +529,13 @@ export async function detectLiveViewTarget(projectPath, options = {}) {
|
|
|
609
529
|
framework: processCommand.framework,
|
|
610
530
|
command,
|
|
611
531
|
managedRuntime,
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
: 'Pixcode will run this project with its managed Node package runner.',
|
|
532
|
+
runtime: runtimeResolution.runtime,
|
|
533
|
+
reason: runtimeResolution.reason,
|
|
615
534
|
};
|
|
616
535
|
}
|
|
617
536
|
|
|
618
537
|
if (processCommand.framework === 'PHP' || processCommand.command === 'php') {
|
|
619
|
-
const managedRuntime =
|
|
620
|
-
env: options.env || process.env,
|
|
621
|
-
preferManaged: true,
|
|
622
|
-
});
|
|
538
|
+
const managedRuntime = runtimeResolution.managedRuntime;
|
|
623
539
|
const command = buildManagedPhpCommand(managedRuntime);
|
|
624
540
|
return {
|
|
625
541
|
available: true,
|
|
@@ -628,14 +544,12 @@ export async function detectLiveViewTarget(projectPath, options = {}) {
|
|
|
628
544
|
framework: command.framework,
|
|
629
545
|
command,
|
|
630
546
|
managedRuntime,
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
: 'Pixcode will run this project with its managed PHP runtime.',
|
|
547
|
+
runtime: runtimeResolution.runtime,
|
|
548
|
+
reason: runtimeResolution.reason,
|
|
634
549
|
};
|
|
635
550
|
}
|
|
636
551
|
|
|
637
|
-
|
|
638
|
-
if (!runtimeAvailable) {
|
|
552
|
+
if (!runtimeResolution.available) {
|
|
639
553
|
return {
|
|
640
554
|
available: false,
|
|
641
555
|
kind: 'process',
|
|
@@ -643,7 +557,8 @@ export async function detectLiveViewTarget(projectPath, options = {}) {
|
|
|
643
557
|
framework: processCommand.framework,
|
|
644
558
|
command: processCommand,
|
|
645
559
|
missingRuntime: processCommand.command,
|
|
646
|
-
|
|
560
|
+
runtime: runtimeResolution.runtime,
|
|
561
|
+
reason: runtimeResolution.reason,
|
|
647
562
|
};
|
|
648
563
|
}
|
|
649
564
|
|
|
@@ -653,6 +568,7 @@ export async function detectLiveViewTarget(projectPath, options = {}) {
|
|
|
653
568
|
label: processCommand.label,
|
|
654
569
|
framework: processCommand.framework,
|
|
655
570
|
command: processCommand,
|
|
571
|
+
runtime: runtimeResolution.runtime,
|
|
656
572
|
};
|
|
657
573
|
}
|
|
658
574
|
|
|
@@ -737,6 +653,7 @@ function publicSession(session) {
|
|
|
737
653
|
label: session.command.label,
|
|
738
654
|
displayCommand: session.command.displayCommand,
|
|
739
655
|
} : null,
|
|
656
|
+
runtime: session.runtime || null,
|
|
740
657
|
managedRuntime: session.managedRuntime || null,
|
|
741
658
|
port: session.port,
|
|
742
659
|
upstreamUrl: session.upstreamUrl,
|
|
@@ -803,6 +720,7 @@ export async function startLiveView(projectName, projectPath, options = {}) {
|
|
|
803
720
|
label: target.label,
|
|
804
721
|
staticRoot: target.staticRoot,
|
|
805
722
|
command: null,
|
|
723
|
+
runtime: null,
|
|
806
724
|
port: null,
|
|
807
725
|
upstreamUrl: null,
|
|
808
726
|
startedAt: new Date().toISOString(),
|
|
@@ -842,6 +760,7 @@ export async function startLiveView(projectName, projectPath, options = {}) {
|
|
|
842
760
|
framework: target.framework,
|
|
843
761
|
label: target.label,
|
|
844
762
|
command,
|
|
763
|
+
runtime: target.runtime || null,
|
|
845
764
|
managedRuntime: runtimeStatus,
|
|
846
765
|
port,
|
|
847
766
|
host: '127.0.0.1',
|