synabun 2.0.5 → 2.0.7
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/CHANGELOG.md +40 -0
- package/README.md +2 -1
- package/THIRD-PARTY-LICENSES.md +13 -0
- package/docs/whatsapp.md +151 -16
- package/hooks/claude-code/shared.mjs +6 -3
- package/lib/child-path.js +303 -0
- package/lib/claude-hooks.js +2 -1
- package/lib/data-home-migration.js +2 -0
- package/lib/desktop-app.js +265 -0
- package/lib/external-tools.js +7 -3
- package/lib/log-redact.js +102 -0
- package/lib/packaged-runtime.js +138 -11
- package/mcp-server/dist/http.d.ts +3 -1
- package/mcp-server/dist/http.d.ts.map +1 -1
- package/mcp-server/dist/http.js +15 -4
- package/mcp-server/dist/http.js.map +1 -1
- package/mcp-server/dist/index.d.ts.map +1 -1
- package/mcp-server/dist/index.js +9 -6
- package/mcp-server/dist/index.js.map +1 -1
- package/mcp-server/dist/services/budget-judgments.d.ts +108 -0
- package/mcp-server/dist/services/budget-judgments.d.ts.map +1 -0
- package/mcp-server/dist/services/budget-judgments.js +153 -0
- package/mcp-server/dist/services/budget-judgments.js.map +1 -0
- package/mcp-server/dist/services/codex-config-heal.d.ts +5 -1
- package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
- package/mcp-server/dist/services/codex-config-heal.js +41 -4
- package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
- package/mcp-server/dist/services/identity.d.ts +11 -0
- package/mcp-server/dist/services/identity.d.ts.map +1 -1
- package/mcp-server/dist/services/identity.js +24 -0
- package/mcp-server/dist/services/identity.js.map +1 -1
- package/mcp-server/dist/services/neural-interface.d.ts +13 -0
- package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
- package/mcp-server/dist/services/neural-interface.js +34 -2
- package/mcp-server/dist/services/neural-interface.js.map +1 -1
- package/mcp-server/dist/services/typesafe-config.d.ts +1 -1
- package/mcp-server/dist/services/typesafe-config.d.ts.map +1 -1
- package/mcp-server/dist/services/typesafe-config.js +4 -1
- package/mcp-server/dist/services/typesafe-config.js.map +1 -1
- package/mcp-server/dist/tools/agents.d.ts +10 -7
- package/mcp-server/dist/tools/agents.d.ts.map +1 -1
- package/mcp-server/dist/tools/agents.js +34 -13
- package/mcp-server/dist/tools/agents.js.map +1 -1
- package/mcp-server/dist/tools/whatsapp-send-file.d.ts +17 -0
- package/mcp-server/dist/tools/whatsapp-send-file.d.ts.map +1 -0
- package/mcp-server/dist/tools/whatsapp-send-file.js +44 -0
- package/mcp-server/dist/tools/whatsapp-send-file.js.map +1 -0
- package/mcp-server/dist/tui.js +2 -1
- package/mcp-server/dist/tui.js.map +1 -1
- package/mcp-server/dist/version.d.ts +5 -0
- package/mcp-server/dist/version.d.ts.map +1 -0
- package/mcp-server/dist/version.js +21 -0
- package/mcp-server/dist/version.js.map +1 -0
- package/mcp-server/package-lock.json +2 -2
- package/mcp-server/package.json +1 -1
- package/mcp-server/run.mjs +15 -9
- package/mcp-server/src/http.ts +18 -3
- package/mcp-server/src/index.ts +9 -6
- package/mcp-server/src/services/budget-judgments.ts +183 -0
- package/mcp-server/src/services/codex-config-heal.ts +35 -4
- package/mcp-server/src/services/identity.ts +27 -0
- package/mcp-server/src/services/neural-interface.ts +34 -2
- package/mcp-server/src/services/typesafe-config.ts +4 -1
- package/mcp-server/src/tools/agents.ts +33 -14
- package/mcp-server/src/tools/whatsapp-send-file.ts +51 -0
- package/mcp-server/src/tui.ts +2 -1
- package/mcp-server/src/version.ts +22 -0
- package/neural-interface/i18n/en.json +627 -57
- package/neural-interface/i18n/pt-BR.json +626 -56
- package/neural-interface/lib/account-usage.js +163 -0
- package/neural-interface/lib/assistant-api.js +255 -52
- package/neural-interface/lib/assistant-brains/claude.js +15 -2
- package/neural-interface/lib/assistant-brains/codex.js +3 -0
- package/neural-interface/lib/assistant-brains/opencode.js +17 -4
- package/neural-interface/lib/assistant-budget-planner.js +390 -0
- package/neural-interface/lib/assistant-budget-split.js +408 -0
- package/neural-interface/lib/assistant-budget.js +94 -95
- package/neural-interface/lib/assistant-config.js +62 -14
- package/neural-interface/lib/assistant-dispatch.js +432 -125
- package/neural-interface/lib/assistant-jev.js +26 -3
- package/neural-interface/lib/assistant-persona.js +68 -11
- package/neural-interface/lib/assistant-plan-permissions.js +8 -1
- package/neural-interface/lib/assistant-route-accounts.js +14 -0
- package/neural-interface/lib/assistant-route-gate.js +19 -3
- package/neural-interface/lib/assistant-router.js +373 -42
- package/neural-interface/lib/assistant-runtime.js +307 -47
- package/neural-interface/lib/assistant-user-writer.js +4 -2
- package/neural-interface/lib/augmented-path.js +317 -53
- package/neural-interface/lib/claude-accounts.js +342 -31
- package/neural-interface/lib/claude-agent-bridge.js +90 -3
- package/neural-interface/lib/claude-executable.js +6 -1
- package/neural-interface/lib/claude-model-catalog.js +3 -3
- package/neural-interface/lib/claude-panel-auth.js +221 -0
- package/neural-interface/lib/claude-profile-api-key.js +62 -0
- package/neural-interface/lib/cli-install-api.js +137 -0
- package/neural-interface/lib/cli-install.js +797 -0
- package/neural-interface/lib/cli-path.js +130 -0
- package/neural-interface/lib/cli-resolver.js +744 -0
- package/neural-interface/lib/cli-update-planner.js +143 -7
- package/neural-interface/lib/codex-account-auth.js +178 -0
- package/neural-interface/lib/codex-accounts.js +489 -0
- package/neural-interface/lib/codex-capabilities.js +2 -1
- package/neural-interface/lib/codex-compat-rpc.js +8 -2
- package/neural-interface/lib/codex-mcp-approvals.js +5 -1
- package/neural-interface/lib/codex-panel-auth.js +62 -0
- package/neural-interface/lib/codex-session-settings.js +1 -1
- package/neural-interface/lib/codex-settings-schema.js +120 -0
- package/neural-interface/lib/desktop/config.js +3 -0
- package/neural-interface/lib/git-bash/bzip2.js +339 -0
- package/neural-interface/lib/git-bash/claude-settings.js +73 -0
- package/neural-interface/lib/git-bash/extract-worker.js +34 -0
- package/neural-interface/lib/git-bash/install.js +529 -0
- package/neural-interface/lib/git-bash/licenses/COPYING +360 -0
- package/neural-interface/lib/git-bash/licenses/LGPL-2.1 +511 -0
- package/neural-interface/lib/git-bash/manager.js +268 -0
- package/neural-interface/lib/git-bash/pins.js +206 -0
- package/neural-interface/lib/git-bash/pins.json +34 -0
- package/neural-interface/lib/git-bash/resolver.js +194 -0
- package/neural-interface/lib/git-read.js +34 -2
- package/neural-interface/lib/install-details.js +145 -0
- package/neural-interface/lib/mcp-installer.js +14 -2
- package/neural-interface/lib/native-loop-providers.js +16 -3
- package/neural-interface/lib/native-loop-runtime.js +9 -4
- package/neural-interface/lib/os-path.js +319 -0
- package/neural-interface/lib/provider-panel-api-key-auth.js +92 -0
- package/neural-interface/lib/provider-panel-terminal-auth.js +95 -0
- package/neural-interface/lib/pty-host/core.js +2 -1
- package/neural-interface/lib/pty-host/manager.js +27 -2
- package/neural-interface/lib/remote-policy.js +20 -11
- package/neural-interface/lib/session-title-generator.js +4 -3
- package/neural-interface/lib/system-about.js +340 -0
- package/neural-interface/lib/system-activity.js +66 -0
- package/neural-interface/lib/terminal-env.js +11 -3
- package/neural-interface/lib/terminal-path.js +55 -0
- package/neural-interface/lib/virtual-socket.js +12 -1
- package/neural-interface/lib/whatsapp/baileys-adapter.js +165 -45
- package/neural-interface/lib/whatsapp/bridge.js +78 -34
- package/neural-interface/lib/whatsapp/commands.js +13 -14
- package/neural-interface/lib/whatsapp/config.js +134 -20
- package/neural-interface/lib/whatsapp/fake-baileys.js +99 -14
- package/neural-interface/lib/whatsapp/host-core.js +168 -35
- package/neural-interface/lib/whatsapp/inbound.js +5 -3
- package/neural-interface/lib/whatsapp/local-file.js +524 -0
- package/neural-interface/lib/whatsapp/manager.js +92 -32
- package/neural-interface/lib/whatsapp/paths.js +11 -1
- package/neural-interface/lib/whatsapp/protocol.js +65 -5
- package/neural-interface/lib/whatsapp/redact.js +63 -0
- package/neural-interface/lib/whatsapp/service.js +343 -91
- package/neural-interface/lib/whatsapp/transcription.js +463 -0
- package/neural-interface/package-lock.json +2 -2
- package/neural-interface/package.json +1 -1
- package/neural-interface/public/index.html +2 -0
- package/neural-interface/public/index2d.html +2 -0
- package/neural-interface/public/offline.html +16 -1
- package/neural-interface/public/onboarding.html +96 -2
- package/neural-interface/public/shared/account-i18n.js +7 -0
- package/neural-interface/public/shared/account-menu.js +539 -0
- package/neural-interface/public/shared/account-usage.js +19 -0
- package/neural-interface/public/shared/account-view.js +335 -0
- package/neural-interface/public/shared/agent-runtime-options.js +28 -8
- package/neural-interface/public/shared/assistant/asst-accounts.js +182 -184
- package/neural-interface/public/shared/assistant/asst-api.js +32 -2
- package/neural-interface/public/shared/assistant/asst-brain-picker.js +124 -25
- package/neural-interface/public/shared/assistant/asst-budget.js +259 -303
- package/neural-interface/public/shared/assistant/asst-mascot.js +126 -7
- package/neural-interface/public/shared/assistant/asst-menu.js +15 -3
- package/neural-interface/public/shared/assistant/asst-panel.js +48 -14
- package/neural-interface/public/shared/assistant/asst-render.js +38 -7
- package/neural-interface/public/shared/assistant/asst-route.js +72 -14
- package/neural-interface/public/shared/assistant/asst-routes-editor.js +45 -6
- package/neural-interface/public/shared/assistant/asst-slash.js +1 -1
- package/neural-interface/public/shared/assistant/asst-state.js +1 -1
- package/neural-interface/public/shared/assistant/asst-styles.js +99 -17
- package/neural-interface/public/shared/cdx/cdx-commands.js +4 -1
- package/neural-interface/public/shared/cdx/cdx-features.js +22 -14
- package/neural-interface/public/shared/cdx/cdx-icons.js +2 -0
- package/neural-interface/public/shared/cdx/cdx-panel.js +48 -107
- package/neural-interface/public/shared/cdx/cdx-settings.js +231 -0
- package/neural-interface/public/shared/cdx/cdx-styles.js +128 -107
- package/neural-interface/public/shared/cdx/cdx-tabs.js +261 -664
- package/neural-interface/public/shared/cdx/cdx-ws.js +2 -0
- package/neural-interface/public/shared/claude-account-view.js +3 -0
- package/neural-interface/public/shared/cli-install-view.js +392 -0
- package/neural-interface/public/shared/cli-status.js +282 -22
- package/neural-interface/public/shared/cp/cp-events.js +2 -1
- package/neural-interface/public/shared/cp/cp-styles.js +46 -0
- package/neural-interface/public/shared/desktop-bridge.js +39 -0
- package/neural-interface/public/shared/desktop-titlebar-page.js +59 -0
- package/neural-interface/public/shared/desktop-titlebar-view.js +122 -0
- package/neural-interface/public/shared/desktop-titlebar.js +153 -0
- package/neural-interface/public/shared/desktop-update-view.js +462 -0
- package/neural-interface/public/shared/editor/editor-panel.js +1 -1
- package/neural-interface/public/shared/explorer/fx-main.js +1 -1
- package/neural-interface/public/shared/git-bash-view.js +145 -0
- package/neural-interface/public/shared/html-shell.js +1 -0
- package/neural-interface/public/shared/i18n.js +19 -1
- package/neural-interface/public/shared/install-details-view.js +86 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +32 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +17 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +118 -0
- package/neural-interface/public/shared/pwa-install-page.js +3 -1
- package/neural-interface/public/shared/settings/settings-about-pane.js +271 -0
- package/neural-interface/public/shared/settings/settings-about.js +254 -0
- package/neural-interface/public/shared/settings/settings-ia.js +15 -0
- package/neural-interface/public/shared/showcase-privacy.js +489 -0
- package/neural-interface/public/shared/storage.js +30 -3
- package/neural-interface/public/shared/styles.css +278 -31
- package/neural-interface/public/shared/synabun-mascot.js +48 -2
- package/neural-interface/public/shared/ui-claude-panel.js +212 -213
- package/neural-interface/public/shared/ui-cli-banner.js +355 -0
- package/neural-interface/public/shared/ui-git-bash.js +124 -0
- package/neural-interface/public/shared/ui-judgments.js +10 -1
- package/neural-interface/public/shared/ui-loading.js +30 -6
- package/neural-interface/public/shared/ui-menubar.js +13 -3
- package/neural-interface/public/shared/ui-navbar.js +3 -1
- package/neural-interface/public/shared/ui-provider-auth.js +104 -0
- package/neural-interface/public/shared/ui-provider-terminal-auth.js +223 -0
- package/neural-interface/public/shared/ui-sessions.js +9 -3
- package/neural-interface/public/shared/ui-settings.js +55 -3
- package/neural-interface/public/shared/ui-sidepanel-sessions.js +3 -1
- package/neural-interface/public/shared/ui-sync.js +6 -0
- package/neural-interface/public/shared/ui-terminal.js +17 -0
- package/neural-interface/public/shared/ui-tool-updates.js +5 -0
- package/neural-interface/public/shared/ui-update.js +594 -5
- package/neural-interface/public/shared/ui-whatsapp.js +21 -6
- package/neural-interface/public/shared/whatsapp/wa-view.js +51 -8
- package/neural-interface/public/shared/worker-end.js +2 -0
- package/neural-interface/public/sw.js +1 -1
- package/neural-interface/public/variant/2d/main.js +10 -1
- package/neural-interface/public/variant/3d/main.js +10 -1
- package/neural-interface/server.js +1219 -608
- package/package.json +4 -1
- package/setup.js +9 -8
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// Persistent PATH changes happen only after Add to PATH or Install. Never at
|
|
2
|
+
// detection/spawn time. Dependencies are injectable: tests use temp homes and
|
|
3
|
+
// a fake reg.exe, and never change the host's PATH or startup files.
|
|
4
|
+
import { execFile } from 'node:child_process';
|
|
5
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
6
|
+
import os from 'node:os';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { expandWindowsVars, parseRegQuery, runRegQuery, splitPathValue, osPath as defaultReader } from './os-path.js';
|
|
9
|
+
import { withPathEnv } from './augmented-path.js';
|
|
10
|
+
|
|
11
|
+
export const PATH_BEGIN = '# >>> SynaBun PATH >>>';
|
|
12
|
+
export const PATH_END = '# <<< SynaBun PATH <<<' ;
|
|
13
|
+
export const ENVIRONMENT_BROADCAST = `Add-Type -TypeDefinition 'using System; using System.Runtime.InteropServices; public static class SynaBunEnvironment { [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)] public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam, uint flags, uint timeout, out UIntPtr result); }'; $result = [UIntPtr]::Zero; if ([SynaBunEnvironment]::SendMessageTimeout([IntPtr]0xffff, 0x1a, [UIntPtr]::Zero, 'Environment', 2, 1000, [ref]$result) -eq [IntPtr]::Zero) { throw 'Environment broadcast timed out or failed' }`;
|
|
14
|
+
|
|
15
|
+
export function pathContains(entries, dir, platform = process.platform, env = process.env) {
|
|
16
|
+
const key = value => {
|
|
17
|
+
let text = String(value || '').trim().replace(/^"(.*)"$/, '$1');
|
|
18
|
+
if (platform === 'win32') text = expandWindowsVars(text, env).replace(/\//g, '\\').toLowerCase();
|
|
19
|
+
return text.replace(/[\\/]+$/, '') || '/';
|
|
20
|
+
};
|
|
21
|
+
return entries.some(entry => key(entry) === key(dir));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const quote = value => `'${String(value).replace(/'/g, `'\\''`)}'`;
|
|
25
|
+
const fishQuote = value => `'${String(value).replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
|
|
26
|
+
|
|
27
|
+
/** Replace only our marked block; preserve all other bytes and existing mode/symlinks. */
|
|
28
|
+
export function updatePathBlock(file, dir, { fish = false } = {}) {
|
|
29
|
+
let text = '';
|
|
30
|
+
try { text = readFileSync(file, 'utf8'); } catch (error) { if (error.code !== 'ENOENT') throw error; }
|
|
31
|
+
const start = text.indexOf(PATH_BEGIN);
|
|
32
|
+
const end = start < 0 ? -1 : text.indexOf(PATH_END, start);
|
|
33
|
+
if (start >= 0 && end < 0) throw new Error(`Incomplete SynaBun PATH block in ${file}; repair its closing marker first.`);
|
|
34
|
+
const oldBlock = start < 0 ? '' : text.slice(start, end + PATH_END.length);
|
|
35
|
+
const dirs = [];
|
|
36
|
+
for (const match of oldBlock.matchAll(/^# path: (.+)$/gm)) {
|
|
37
|
+
try { const value = JSON.parse(match[1]); if (typeof value === 'string') dirs.push(value); } catch { /* no generated entry */ }
|
|
38
|
+
}
|
|
39
|
+
if (!dirs.includes(dir)) dirs.push(dir);
|
|
40
|
+
// Shell code needs LF even when surrounding comments/dotfile bytes use CRLF.
|
|
41
|
+
const eol = '\n';
|
|
42
|
+
const lines = [PATH_BEGIN, ...dirs.map(value => `# path: ${JSON.stringify(value)}`)];
|
|
43
|
+
for (const value of dirs) lines.push(fish
|
|
44
|
+
? `fish_add_path --append --path ${fishQuote(value)}`
|
|
45
|
+
: `case ":\$PATH:" in *:${quote(value)}:*) ;; *) export PATH="\$PATH":${quote(value)} ;; esac`);
|
|
46
|
+
lines.push(PATH_END);
|
|
47
|
+
const block = lines.join(eol);
|
|
48
|
+
const next = start < 0 ? text + (text && !text.endsWith('\n') ? eol : '') + block + eol : text.slice(0, start) + block + text.slice(end + PATH_END.length);
|
|
49
|
+
if (next === text) return false;
|
|
50
|
+
mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 });
|
|
51
|
+
writeFileSync(file, next, { encoding: 'utf8', mode: 0o600 });
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function shellPathFiles({ env = process.env, home = env.HOME || os.homedir(), platform = process.platform } = {}) {
|
|
56
|
+
const shell = path.posix.basename(env.SHELL || (platform === 'darwin' ? '/bin/zsh' : '/bin/bash'));
|
|
57
|
+
if (shell === 'fish') return [{ file: path.join(env.XDG_CONFIG_HOME || path.join(home, '.config'), 'fish', 'conf.d', 'synabun.fish'), fish: true }];
|
|
58
|
+
if (shell === 'zsh') {
|
|
59
|
+
const root = env.ZDOTDIR || home;
|
|
60
|
+
const rc = path.join(root, '.zshrc');
|
|
61
|
+
const profile = path.join(root, '.zprofile');
|
|
62
|
+
let loginSourcesRc = false;
|
|
63
|
+
try { loginSourcesRc = /^\s*(?:source|\.)\s+[^\n#]*\.zshrc(?:["']|\s|$)/m.test(readFileSync(profile, 'utf8')); } catch { /* absent */ }
|
|
64
|
+
// CLI wrappers are non-interactive login shells: they need .zprofile
|
|
65
|
+
// unless it already sources .zshrc. Terminal.app reads .zshrc as well.
|
|
66
|
+
return [{ file: rc }, ...loginSourcesRc ? [] : [{ file: profile }]];
|
|
67
|
+
}
|
|
68
|
+
if (shell === 'bash' || shell === 'sh') {
|
|
69
|
+
const login = ['.bash_profile', '.bash_login', '.profile'].map(name => path.join(home, name)).find(existsSync)
|
|
70
|
+
|| path.join(home, platform === 'darwin' ? '.bash_profile' : '.profile');
|
|
71
|
+
return [{ file: path.join(home, '.bashrc') }, { file: login }];
|
|
72
|
+
}
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function createCliPathManager({ platform = process.platform, env = process.env, home = (platform === 'win32' ? env.USERPROFILE : env.HOME) || os.homedir(), reader = defaultReader, execFileImpl = execFile, onChanged = () => {} } = {}) {
|
|
77
|
+
let tail = Promise.resolve(); // serialize read/append/write across tools
|
|
78
|
+
const execute = (file, args) => new Promise((resolve, reject) => {
|
|
79
|
+
try { execFileImpl(file, args, { env: withPathEnv(env, undefined, platform), encoding: 'utf8', windowsHide: true, timeout: 4000, maxBuffer: 1024 * 1024 }, (error, stdout) => error ? reject(error) : resolve(String(stdout || ''))); }
|
|
80
|
+
catch (error) { reject(error); }
|
|
81
|
+
});
|
|
82
|
+
function inspect(status, snapshot = reader.snapshot()) {
|
|
83
|
+
const dir = status?.path ? (platform === 'win32' ? path.win32 : path.posix).dirname(status.path) : null;
|
|
84
|
+
const onPath = dir && snapshot.ok ? pathContains(snapshot.entries, dir, platform, env) : null;
|
|
85
|
+
return { dir, onPath, canAdd: !!dir && status?.state === 'installed' && onPath === false && (platform === 'win32' || shellPathFiles({ env, home, platform }).length > 0) };
|
|
86
|
+
}
|
|
87
|
+
async function addNow(status) {
|
|
88
|
+
if (status?.state !== 'installed' || !status.path) throw Object.assign(new Error('No installed CLI was resolved.'), { status: 409 });
|
|
89
|
+
await reader.refresh({ force: true });
|
|
90
|
+
const state = inspect(status);
|
|
91
|
+
if (state.onPath === true) return { ...state, added: false, changed: false, files: [], warning: null };
|
|
92
|
+
if (state.onPath == null) throw new Error('The persistent PATH could not be read. Re-check and try again.');
|
|
93
|
+
const dir = state.dir;
|
|
94
|
+
if (/[\r\n\0]/.test(dir) || (platform === 'win32' && /[;"%]/.test(dir)) || (platform !== 'win32' && dir.includes(':'))) throw new Error('This CLI folder cannot be represented safely in PATH.');
|
|
95
|
+
let files = [];
|
|
96
|
+
let warning = null;
|
|
97
|
+
let changed = false;
|
|
98
|
+
if (platform === 'win32') {
|
|
99
|
+
const root = env.SystemRoot || env.SYSTEMROOT || 'C:\\Windows';
|
|
100
|
+
const reg = path.win32.join(root, 'System32', 'reg.exe');
|
|
101
|
+
let raw;
|
|
102
|
+
try { raw = parseRegQuery(await runRegQuery('HKCU\\Environment', { env: withPathEnv(env, undefined, platform), execFileImpl })); }
|
|
103
|
+
catch {
|
|
104
|
+
// A missing Path is safe to create only if the key itself can be read.
|
|
105
|
+
raw = parseRegQuery(await execute(reg, ['query', 'HKCU\\Environment']));
|
|
106
|
+
}
|
|
107
|
+
if (raw && pathContains(splitPathValue(raw.value, 'win32'), dir, 'win32', env)) return { ...state, onPath: true, added: false, changed: false, files: [], warning: null };
|
|
108
|
+
const value = raw?.value ? `${raw.value}${raw.value.endsWith(';') ? '' : ';'}${dir}` : dir;
|
|
109
|
+
await execute(reg, ['add', 'HKCU\\Environment', '/v', 'Path', '/t', raw?.type || 'REG_EXPAND_SZ', '/d', value, '/f']);
|
|
110
|
+
changed = true;
|
|
111
|
+
files = ['HKCU\\Environment\\Path'];
|
|
112
|
+
try { await execute(path.win32.join(root, 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe'), ['-NoProfile', '-NonInteractive', '-Command', ENVIRONMENT_BROADCAST]); }
|
|
113
|
+
catch (error) { warning = `PATH saved; environment broadcast failed: ${error.message}`; }
|
|
114
|
+
} else {
|
|
115
|
+
const targets = shellPathFiles({ env, home, platform });
|
|
116
|
+
if (!targets.length) throw Object.assign(new Error('This shell has no supported PATH startup file.'), { status: 422 });
|
|
117
|
+
for (const target of targets) if (updatePathBlock(target.file, dir, target)) { files.push(target.file); changed = true; }
|
|
118
|
+
}
|
|
119
|
+
reader.invalidate();
|
|
120
|
+
await reader.refresh({ force: true });
|
|
121
|
+
onChanged();
|
|
122
|
+
return { dir, onPath: true, added: changed, changed, files, warning };
|
|
123
|
+
}
|
|
124
|
+
function add(status) {
|
|
125
|
+
const result = tail.then(() => addNow(status));
|
|
126
|
+
tail = result.catch(() => {});
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
return { inspect, add };
|
|
130
|
+
}
|