u-chan-secrets 5.0.0 → 5.1.0
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/README.md +233 -91
- package/dist/cli.js +115 -19
- package/dist/client/claude-setup.js +97 -0
- package/dist/client/codex-setup.js +6 -5
- package/dist/client/discord.js +67 -0
- package/dist/client/github.js +28 -0
- package/dist/client/setup.js +40 -6
- package/dist/client/update-package.js +166 -0
- package/dist/client/update.js +138 -0
- package/dist/client/windows-command.js +54 -0
- package/dist/core/browser.js +0 -5
- package/dist/core/config.js +1 -0
- package/dist/core/doctor.js +5 -1
- package/dist/core/vault.js +110 -5
- package/dist/discord/http.js +84 -0
- package/dist/discord/policy.js +47 -0
- package/dist/discord/service.js +349 -0
- package/dist/discord/store.js +85 -0
- package/dist/github/http.js +93 -0
- package/dist/github/policy.js +24 -0
- package/dist/github/service.js +185 -0
- package/dist/github/store.js +54 -0
- package/dist/index.js +1 -1
- package/dist/ipc/client.js +74 -6
- package/dist/ipc/server.js +38 -3
- package/dist/mcp/server.js +25 -2
- package/dist/platform/windows/assets/prompt-src.js +160 -38
- package/dist/platform/windows/doctor.js +2 -2
- package/dist/platform/windows/install.js +4 -0
- package/dist/service/control.js +47 -5
- package/dist/service/doctor.js +3 -0
- package/dist/service/main.js +34 -17
- package/dist/service/manage.js +20 -16
- package/dist/service/state.js +28 -0
- package/dist/service/update/coordinator.js +171 -0
- package/dist/service/update/files.js +47 -0
- package/dist/service/update/gate.js +21 -0
- package/dist/service/update/journal.js +157 -0
- package/dist/service/update/native.js +50 -0
- package/dist/service/update/network.js +28 -0
- package/dist/service/update/protocol.js +28 -0
- package/dist/service/update/release.js +102 -0
- package/dist/service/update/worker-main.js +116 -0
- package/dist/service/update/worker.js +58 -0
- package/package.json +1 -1
- package/scripts/debug-install.bat +69 -69
- package/scripts/desktop-browser.ps1 +110 -103
- package/scripts/login-bw.bat +21 -21
- package/scripts/migrate.bat +4 -4
- package/scripts/start-browser.ps1 +33 -33
- package/scripts/windows-security/desktop-matrix.mjs +54 -54
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
param([ValidateSet('chrome','edge')][string]$Browser, [switch]$Background, [switch]$CheckOnly, [string]$DesktopOwnerSid)
|
|
2
|
-
$ErrorActionPreference='Stop'
|
|
3
|
-
. (Join-Path $PSScriptRoot 'desktop-browser.ps1')
|
|
4
|
-
if ($DesktopOwnerSid) {
|
|
5
|
-
if (-not $CheckOnly) { throw 'An owner-specific inspection cannot launch a desktop browser.' }
|
|
6
|
-
$observed = 'unknown'
|
|
7
|
-
$kinds = if ($Browser) { @($Browser) } else { @('chrome','edge') }
|
|
8
|
-
foreach ($kind in $kinds) {
|
|
9
|
-
$configuration = Get-UChanOwnerBrowserConfiguration $DesktopOwnerSid $kind
|
|
10
|
-
$candidate = Get-UChanBrowserState $configuration
|
|
11
|
-
if ($candidate -eq 'pass') { 'pass'; return }
|
|
12
|
-
if ($candidate -eq 'fail' -or $candidate -eq 'missing') { $observed = 'fail' }
|
|
13
|
-
}
|
|
14
|
-
$observed; return
|
|
15
|
-
}
|
|
16
|
-
$configuration=Get-UChanBrowserConfiguration $Browser
|
|
17
|
-
$state=Get-UChanBrowserState $configuration
|
|
18
|
-
if ($CheckOnly) { if ($state -eq 'missing') { 'fail' } else { $state }; return }
|
|
19
|
-
if ($state -eq 'pass') { Write-Host ($configuration.Browser + ' dedicated browser is ready.'); return }
|
|
20
|
-
if ($state -ne 'missing') { throw 'The browser endpoint is occupied, mismatched, or unverifiable. Close only the previous dedicated U-Chan browser before switching; keep personal windows open.' }
|
|
21
|
-
if ($configuration.Executables.Count -eq 0) { throw ($configuration.Browser + ' is not installed. Install it or explicitly select the other supported browser.') }
|
|
22
|
-
New-Item -ItemType Directory -Force -Path $configuration.Profile | Out-Null
|
|
23
|
-
$arguments=@(('--remote-debugging-port='+$configuration.Endpoint.Port), '--remote-debugging-address=127.0.0.1', ('--user-data-dir="'+$configuration.Profile+'"'), '--no-first-run')
|
|
24
|
-
if ($Background) { $arguments += '--no-startup-window' }
|
|
25
|
-
Start-Process -FilePath $configuration.Executables[0] -ArgumentList $arguments -WindowStyle Hidden
|
|
26
|
-
$deadline=[DateTime]::UtcNow.AddSeconds(15)
|
|
27
|
-
do {
|
|
28
|
-
Start-Sleep -Milliseconds 300
|
|
29
|
-
$state=Get-UChanBrowserState $configuration
|
|
30
|
-
if ($state -eq 'pass') { Write-Host ($configuration.Browser + ' dedicated browser started.'); return }
|
|
31
|
-
if ($state -eq 'fail') { break }
|
|
32
|
-
} while ([DateTime]::UtcNow -lt $deadline)
|
|
33
|
-
throw 'Selected dedicated browser did not become verifiably ready. Check browser policy and run setup again.'
|
|
1
|
+
param([ValidateSet('chrome','edge')][string]$Browser, [switch]$Background, [switch]$CheckOnly, [string]$DesktopOwnerSid)
|
|
2
|
+
$ErrorActionPreference='Stop'
|
|
3
|
+
. (Join-Path $PSScriptRoot 'desktop-browser.ps1')
|
|
4
|
+
if ($DesktopOwnerSid) {
|
|
5
|
+
if (-not $CheckOnly) { throw 'An owner-specific inspection cannot launch a desktop browser.' }
|
|
6
|
+
$observed = 'unknown'
|
|
7
|
+
$kinds = if ($Browser) { @($Browser) } else { @('chrome','edge') }
|
|
8
|
+
foreach ($kind in $kinds) {
|
|
9
|
+
$configuration = Get-UChanOwnerBrowserConfiguration $DesktopOwnerSid $kind
|
|
10
|
+
$candidate = Get-UChanBrowserState $configuration
|
|
11
|
+
if ($candidate -eq 'pass') { 'pass'; return }
|
|
12
|
+
if ($candidate -eq 'fail' -or $candidate -eq 'missing') { $observed = 'fail' }
|
|
13
|
+
}
|
|
14
|
+
$observed; return
|
|
15
|
+
}
|
|
16
|
+
$configuration=Get-UChanBrowserConfiguration $Browser
|
|
17
|
+
$state=Get-UChanBrowserState $configuration
|
|
18
|
+
if ($CheckOnly) { if ($state -eq 'missing') { 'fail' } else { $state }; return }
|
|
19
|
+
if ($state -eq 'pass') { Write-Host ($configuration.Browser + ' dedicated browser is ready.'); return }
|
|
20
|
+
if ($state -ne 'missing') { throw 'The browser endpoint is occupied, mismatched, or unverifiable. Close only the previous dedicated U-Chan browser before switching; keep personal windows open.' }
|
|
21
|
+
if ($configuration.Executables.Count -eq 0) { throw ($configuration.Browser + ' is not installed. Install it or explicitly select the other supported browser.') }
|
|
22
|
+
New-Item -ItemType Directory -Force -Path $configuration.Profile | Out-Null
|
|
23
|
+
$arguments=@(('--remote-debugging-port='+$configuration.Endpoint.Port), '--remote-debugging-address=127.0.0.1', ('--user-data-dir="'+$configuration.Profile+'"'), '--no-first-run')
|
|
24
|
+
if ($Background) { $arguments += '--no-startup-window' }
|
|
25
|
+
Start-Process -FilePath $configuration.Executables[0] -ArgumentList $arguments -WindowStyle Hidden
|
|
26
|
+
$deadline=[DateTime]::UtcNow.AddSeconds(15)
|
|
27
|
+
do {
|
|
28
|
+
Start-Sleep -Milliseconds 300
|
|
29
|
+
$state=Get-UChanBrowserState $configuration
|
|
30
|
+
if ($state -eq 'pass') { Write-Host ($configuration.Browser + ' dedicated browser started.'); return }
|
|
31
|
+
if ($state -eq 'fail') { break }
|
|
32
|
+
} while ([DateTime]::UtcNow -lt $deadline)
|
|
33
|
+
throw 'Selected dedicated browser did not become verifiably ready. Check browser policy and run setup again.'
|
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
// User-side half of the disposable Windows browser matrix. The administrator runs the SYSTEM fixture separately.
|
|
2
|
-
import fs from 'node:fs/promises'
|
|
3
|
-
import path from 'node:path'
|
|
4
|
-
import os from 'node:os'
|
|
5
|
-
import { fileURLToPath } from 'node:url'
|
|
6
|
-
import { createServer } from 'node:net'
|
|
7
|
-
import { execFile } from 'node:child_process'
|
|
8
|
-
import { promisify } from 'node:util'
|
|
9
|
-
import { chromium } from 'playwright'
|
|
10
|
-
import { Client } from '@modelcontextprotocol/sdk/client/index.js'
|
|
11
|
-
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'
|
|
12
|
-
import { isElevated } from '../../dist/client/codex-setup.js'
|
|
13
|
-
import { inspectDesktopBrowser } from '../../dist/platform/windows/desktop-browser.js'
|
|
14
|
-
const [command, browser, runId] = process.argv.slice(2)
|
|
15
|
-
if (process.platform !== 'win32' || command !== '--prepare' || !['chrome','edge'].includes(browser) || !/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(runId ?? '')) throw new Error('Use --prepare chrome|edge <fresh UUID> on Windows')
|
|
16
|
-
if (await isElevated()) throw new Error('Prepare must run as the non-elevated desktop owner')
|
|
17
|
-
const root = path.join(os.tmpdir(), 'u-chan-v5-matrix-' + runId), home = path.join(root, browser)
|
|
18
|
-
await fs.mkdir(root) // A fresh UUID must never reuse another fixture or personal profile.
|
|
19
|
-
await fs.mkdir(home)
|
|
20
|
-
const port = await new Promise((resolve, reject) => { const server = createServer(); server.once('error', reject); server.listen(0, '127.0.0.1', () => { const selected = server.address().port; server.close(() => resolve(selected)) }) })
|
|
21
|
-
const endpoint = 'http://127.0.0.1:' + port, environment = { ...process.env, U_CHAN_HOME: home, U_CHAN_CDP: endpoint, U_CHAN_BROWSER: browser }
|
|
22
|
-
const report = { runId, browser, ok: false }, exec = promisify(execFile)
|
|
23
|
-
let connection
|
|
24
|
-
try {
|
|
25
|
-
await exec('powershell.exe', ['-NoProfile','-NonInteractive','-ExecutionPolicy','Bypass','-File',fileURLToPath(new URL('../start-browser.ps1',import.meta.url)),'-Browser',browser,'-Background'], { env: environment, windowsHide: true, timeout: 30000 })
|
|
26
|
-
report.desktopIdentity = await inspectDesktopBrowser({ endpoint, browser, profile: path.join(home,browser+'-profile') },environment)
|
|
27
|
-
if (report.desktopIdentity !== 'pass') throw new Error('Disposable browser identity failed')
|
|
28
|
-
connection = await chromium.connectOverCDP(endpoint)
|
|
29
|
-
await fs.writeFile(path.join(root,'prepared.json'),JSON.stringify({runId,browser,home,endpoint}),{flag:'wx'})
|
|
30
|
-
console.log(JSON.stringify({prepared:true,runId,browser,endpoint}))
|
|
31
|
-
const receipt = path.join(process.env.ProgramData ?? 'C:\\ProgramData','UChanSecurityChecks',runId,'report.json'), deadline=Date.now()+600000
|
|
32
|
-
while(Date.now()<deadline&&!await fs.stat(receipt).catch(()=>null))await new Promise(resolve=>setTimeout(resolve,500))
|
|
33
|
-
const native = JSON.parse(await fs.readFile(receipt,'utf8'))
|
|
34
|
-
report.systemFixturePassed = native.ok === true && native.fixtureBrowser === browser && native.desktopIdentity === 'pass'
|
|
35
|
-
const client = new Client({name:'u-chan-browser-matrix',version:'1.0.0'})
|
|
36
|
-
const transport = new StdioClientTransport({command:process.execPath,args:[path.join(path.dirname(process.execPath),'node_modules/npm/bin/npx-cli.js'),'@playwright/mcp@latest','--cdp-endpoint',endpoint],stderr:'pipe'})
|
|
37
|
-
try {
|
|
38
|
-
await client.connect(transport)
|
|
39
|
-
report.playwrightTools=(await client.listTools()).tools.length
|
|
40
|
-
report.sharedBrowserListing=!(await client.callTool({name:'browser_tabs',arguments:{action:'list'}})).isError
|
|
41
|
-
} finally {await client.close().catch(()=>{});await transport.close().catch(()=>{})}
|
|
42
|
-
report.ok=report.systemFixturePassed&&report.playwrightTools>0&&report.sharedBrowserListing
|
|
43
|
-
}catch(error){report.errorType=error.name}
|
|
44
|
-
finally{
|
|
45
|
-
// Only this verified disposable instance may be closed; never enumerate or terminate other browsers.
|
|
46
|
-
if(connection&&await inspectDesktopBrowser({endpoint,browser,profile:path.join(home,browser+'-profile')},environment)==='pass') {
|
|
47
|
-
const session=await connection.newBrowserCDPSession().catch(()=>null)
|
|
48
|
-
await session?.send('Browser.close').catch(()=>{})
|
|
49
|
-
}
|
|
50
|
-
await connection?.close().catch(()=>{})
|
|
51
|
-
await fs.writeFile(path.join(root,'complete.json'),JSON.stringify(report,null,2),{flag:'wx'})
|
|
52
|
-
}
|
|
53
|
-
console.log(JSON.stringify(report))
|
|
54
|
-
if(!report.ok)process.exitCode=1
|
|
1
|
+
// User-side half of the disposable Windows browser matrix. The administrator runs the SYSTEM fixture separately.
|
|
2
|
+
import fs from 'node:fs/promises'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import os from 'node:os'
|
|
5
|
+
import { fileURLToPath } from 'node:url'
|
|
6
|
+
import { createServer } from 'node:net'
|
|
7
|
+
import { execFile } from 'node:child_process'
|
|
8
|
+
import { promisify } from 'node:util'
|
|
9
|
+
import { chromium } from 'playwright'
|
|
10
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js'
|
|
11
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'
|
|
12
|
+
import { isElevated } from '../../dist/client/codex-setup.js'
|
|
13
|
+
import { inspectDesktopBrowser } from '../../dist/platform/windows/desktop-browser.js'
|
|
14
|
+
const [command, browser, runId] = process.argv.slice(2)
|
|
15
|
+
if (process.platform !== 'win32' || command !== '--prepare' || !['chrome','edge'].includes(browser) || !/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(runId ?? '')) throw new Error('Use --prepare chrome|edge <fresh UUID> on Windows')
|
|
16
|
+
if (await isElevated()) throw new Error('Prepare must run as the non-elevated desktop owner')
|
|
17
|
+
const root = path.join(os.tmpdir(), 'u-chan-v5-matrix-' + runId), home = path.join(root, browser)
|
|
18
|
+
await fs.mkdir(root) // A fresh UUID must never reuse another fixture or personal profile.
|
|
19
|
+
await fs.mkdir(home)
|
|
20
|
+
const port = await new Promise((resolve, reject) => { const server = createServer(); server.once('error', reject); server.listen(0, '127.0.0.1', () => { const selected = server.address().port; server.close(() => resolve(selected)) }) })
|
|
21
|
+
const endpoint = 'http://127.0.0.1:' + port, environment = { ...process.env, U_CHAN_HOME: home, U_CHAN_CDP: endpoint, U_CHAN_BROWSER: browser }
|
|
22
|
+
const report = { runId, browser, ok: false }, exec = promisify(execFile)
|
|
23
|
+
let connection
|
|
24
|
+
try {
|
|
25
|
+
await exec('powershell.exe', ['-NoProfile','-NonInteractive','-ExecutionPolicy','Bypass','-File',fileURLToPath(new URL('../start-browser.ps1',import.meta.url)),'-Browser',browser,'-Background'], { env: environment, windowsHide: true, timeout: 30000 })
|
|
26
|
+
report.desktopIdentity = await inspectDesktopBrowser({ endpoint, browser, profile: path.join(home,browser+'-profile') },environment)
|
|
27
|
+
if (report.desktopIdentity !== 'pass') throw new Error('Disposable browser identity failed')
|
|
28
|
+
connection = await chromium.connectOverCDP(endpoint)
|
|
29
|
+
await fs.writeFile(path.join(root,'prepared.json'),JSON.stringify({runId,browser,home,endpoint}),{flag:'wx'})
|
|
30
|
+
console.log(JSON.stringify({prepared:true,runId,browser,endpoint}))
|
|
31
|
+
const receipt = path.join(process.env.ProgramData ?? 'C:\\ProgramData','UChanSecurityChecks',runId,'report.json'), deadline=Date.now()+600000
|
|
32
|
+
while(Date.now()<deadline&&!await fs.stat(receipt).catch(()=>null))await new Promise(resolve=>setTimeout(resolve,500))
|
|
33
|
+
const native = JSON.parse(await fs.readFile(receipt,'utf8'))
|
|
34
|
+
report.systemFixturePassed = native.ok === true && native.fixtureBrowser === browser && native.desktopIdentity === 'pass'
|
|
35
|
+
const client = new Client({name:'u-chan-browser-matrix',version:'1.0.0'})
|
|
36
|
+
const transport = new StdioClientTransport({command:process.execPath,args:[path.join(path.dirname(process.execPath),'node_modules/npm/bin/npx-cli.js'),'@playwright/mcp@latest','--cdp-endpoint',endpoint],stderr:'pipe'})
|
|
37
|
+
try {
|
|
38
|
+
await client.connect(transport)
|
|
39
|
+
report.playwrightTools=(await client.listTools()).tools.length
|
|
40
|
+
report.sharedBrowserListing=!(await client.callTool({name:'browser_tabs',arguments:{action:'list'}})).isError
|
|
41
|
+
} finally {await client.close().catch(()=>{});await transport.close().catch(()=>{})}
|
|
42
|
+
report.ok=report.systemFixturePassed&&report.playwrightTools>0&&report.sharedBrowserListing
|
|
43
|
+
}catch(error){report.errorType=error.name}
|
|
44
|
+
finally{
|
|
45
|
+
// Only this verified disposable instance may be closed; never enumerate or terminate other browsers.
|
|
46
|
+
if(connection&&await inspectDesktopBrowser({endpoint,browser,profile:path.join(home,browser+'-profile')},environment)==='pass') {
|
|
47
|
+
const session=await connection.newBrowserCDPSession().catch(()=>null)
|
|
48
|
+
await session?.send('Browser.close').catch(()=>{})
|
|
49
|
+
}
|
|
50
|
+
await connection?.close().catch(()=>{})
|
|
51
|
+
await fs.writeFile(path.join(root,'complete.json'),JSON.stringify(report,null,2),{flag:'wx'})
|
|
52
|
+
}
|
|
53
|
+
console.log(JSON.stringify(report))
|
|
54
|
+
if(!report.ok)process.exitCode=1
|