@walkhi/code-relax 0.1.0-beta.100 → 0.1.0-beta.101

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.
@@ -1 +1 @@
1
- {"layout":"npm-platform-packages","version":"0.1.0-beta.100"}
1
+ {"layout":"npm-platform-packages","version":"0.1.0-beta.101"}
@@ -15,6 +15,9 @@ if (-not $package -or $Executable -ne (Join-Path $package.InstallLocation 'app/C
15
15
  if ([Environment]::GetEnvironmentVariable('CODEX_APP_SERVER_WS_URL', 'User') -ne $AppServerUrl) {
16
16
  throw 'Desktop app-server environment differs from the workstation; run relax setup to repair it.'
17
17
  }
18
+ if ([Environment]::GetEnvironmentVariable('CODEX_APP_SERVER_USE_LOCAL_DAEMON', 'User') -ne '1') {
19
+ throw 'Desktop browser session environment is not configured; run relax setup to repair it.'
20
+ }
18
21
  if ([Environment]::GetEnvironmentVariable('CODEX_APP_SERVER_FORCE_CLI', 'User') -eq '1' -or
19
22
  [Environment]::GetEnvironmentVariable('CODEX_APP_SERVER_FORCE_CLI', 'Machine') -eq '1') {
20
23
  throw 'CODEX_APP_SERVER_FORCE_CLI=1 prevents Desktop from connecting to the workstation.'
@@ -0,0 +1,38 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs';
3
+ import { readRecord, writeRecord } from '../../service-lifecycle.mjs';
4
+ import { runScript } from './desktop-host.mjs';
5
+
6
+ // Desktop 26.1027.6604.0 gates cua_repl's session environment on this flag.
7
+ // MSIX activation does not inherit the caller's environment block.
8
+ const name = 'CODEX_APP_SERVER_USE_LOCAL_DAEMON';
9
+ const ownershipFile = 'managed-desktop-browser-environment.json';
10
+ async function environment(action, value) {
11
+ const args = ['-Action', action, '-Name', name];
12
+ if (value != null) args.push('-Value', value);
13
+ return JSON.parse(await runScript('user-environment.ps1', args));
14
+ }
15
+
16
+ export async function configureDesktopBrowserEnvironment(stateRoot) {
17
+ const current = await environment('Read');
18
+ if (current.userValue === '1') return; // Do not claim an existing user setting.
19
+ const ownershipPath = path.join(stateRoot, ownershipFile);
20
+ // Save before writing so a failed write/broadcast can still be undone.
21
+ writeRecord(ownershipPath, { name, value: '1', previousValue: current.userValue ?? null });
22
+ const applied = await environment('Set', '1');
23
+ if (applied.userValue !== '1') throw new Error('Desktop browser environment verification failed.');
24
+ }
25
+
26
+ export async function restoreDesktopBrowserEnvironment(stateRoot) {
27
+ const ownershipPath = path.join(stateRoot, ownershipFile);
28
+ const ownership = readRecord(ownershipPath);
29
+ if (ownership?.name !== name || ownership.value !== '1') return;
30
+ const current = await environment('Read');
31
+ if (current.userValue === ownership.value) {
32
+ const previous = ownership.previousValue;
33
+ const restored = await environment(previous ? 'Set' : 'Clear', previous);
34
+ if ((restored.userValue || null) !== (previous || null)) throw new Error('Desktop browser environment restore failed.');
35
+ }
36
+ // A value changed by the user is preserved when management ends.
37
+ fs.rmSync(ownershipPath, { force: true });
38
+ }
@@ -6,6 +6,7 @@ import path from 'node:path';
6
6
  import { managedEndpointUrl, readManagedEndpoint } from '../../managed-endpoint.mjs';
7
7
  import { runtimePaths } from './runtime-paths.mjs';
8
8
  import { sharedServiceUrl } from './service-host.mjs';
9
+ import { configureDesktopBrowserEnvironment } from './desktop-browser-environment.mjs';
9
10
  const exec = promisify(execFile);
10
11
  const directory = path.dirname(fileURLToPath(import.meta.url));
11
12
  export const powershell = path.join(process.env.SystemRoot || 'C:\\Windows', 'System32/WindowsPowerShell/v1.0/powershell.exe');
@@ -19,9 +20,10 @@ export const desktopHost = {
19
20
  sharedServiceUrl,
20
21
  ownsListener: async (expected, url) => JSON.parse(await runScript('desktop-info.ps1', ['-ProcessId', String(expected.pid), '-Expected', JSON.stringify(expected), '-AppServerUrl', url, '-CheckListener'])),
21
22
  start: startWindowsProcess,
22
- startDesktop: (executable, environment) => {
23
+ startDesktop: async (executable, environment) => {
23
24
  const url = managedEndpointUrl(environment.CODEX_APP_SERVER_WS_URL);
24
25
  if (!url || url !== readManagedEndpoint(runtimePaths().stateRoot)) throw new Error('Desktop 内核地址与工作站不一致。');
26
+ await configureDesktopBrowserEnvironment(runtimePaths().stateRoot);
25
27
  return runScript('activate-desktop.ps1', [
26
28
  '-Executable', executable, '-AppServerUrl', url,
27
29
  ]);
@@ -3,6 +3,7 @@ import fs from 'node:fs';
3
3
  import { readRecord, writeRecord } from '../../service-lifecycle.mjs';
4
4
  import { runScript } from './desktop-host.mjs';
5
5
  import { managedEndpointUrl } from '../../managed-endpoint.mjs';
6
+ import { configureDesktopBrowserEnvironment, restoreDesktopBrowserEnvironment } from './desktop-browser-environment.mjs';
6
7
 
7
8
  const ownershipFile = 'managed-environment.json';
8
9
 
@@ -22,6 +23,7 @@ export async function configureManagedEnvironment(stateRoot, url) {
22
23
  throw new Error(`用户已有 CODEX_APP_SERVER_WS_URL=${current.userValue};未覆盖该配置。`);
23
24
  }
24
25
  if (current.userValue === url) {
26
+ await configureDesktopBrowserEnvironment(stateRoot);
25
27
  const owned = ownership?.value === url;
26
28
  return { configured: true, value: current.userValue, changed: false, owned };
27
29
  }
@@ -29,10 +31,12 @@ export async function configureManagedEnvironment(stateRoot, url) {
29
31
  if (applied.userValue !== url) throw new Error('CODEX_APP_SERVER_WS_URL 写入后读回不一致。');
30
32
  writeRecord(ownershipPath, { name: 'CODEX_APP_SERVER_WS_URL', value: url,
31
33
  configuredAt: new Date().toISOString() });
34
+ await configureDesktopBrowserEnvironment(stateRoot);
32
35
  return { configured: true, value: applied.userValue, changed: true, owned: true };
33
36
  }
34
37
 
35
38
  export async function clearManagedEnvironment(stateRoot) {
39
+ await restoreDesktopBrowserEnvironment(stateRoot);
36
40
  const ownershipPath = path.join(stateRoot, ownershipFile);
37
41
  const ownership = readRecord(ownershipPath);
38
42
  const current = await readManagedEnvironment();
@@ -1,10 +1,11 @@
1
- param(
1
+ param(
2
2
  [ValidateSet('Read', 'Set', 'Clear')][string]$Action = 'Read',
3
- [string]$Value = ''
3
+ [string]$Value = '',
4
+ [ValidateSet('CODEX_APP_SERVER_WS_URL', 'CODEX_APP_SERVER_USE_LOCAL_DAEMON')]
5
+ [string]$Name = 'CODEX_APP_SERVER_WS_URL'
4
6
  )
5
7
  $ErrorActionPreference = 'Stop'
6
8
  [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding($false)
7
- $name = 'CODEX_APP_SERVER_WS_URL'
8
9
 
9
10
  function Broadcast-EnvironmentChange {
10
11
  if (-not ('CodeRelax.EnvironmentBroadcast' -as [type])) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@walkhi/code-relax",
3
- "version": "0.1.0-beta.100",
3
+ "version": "0.1.0-beta.101",
4
4
  "private": false,
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",