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.
Files changed (51) hide show
  1. package/README.md +233 -91
  2. package/dist/cli.js +115 -19
  3. package/dist/client/claude-setup.js +97 -0
  4. package/dist/client/codex-setup.js +6 -5
  5. package/dist/client/discord.js +67 -0
  6. package/dist/client/github.js +28 -0
  7. package/dist/client/setup.js +40 -6
  8. package/dist/client/update-package.js +166 -0
  9. package/dist/client/update.js +138 -0
  10. package/dist/client/windows-command.js +54 -0
  11. package/dist/core/browser.js +0 -5
  12. package/dist/core/config.js +1 -0
  13. package/dist/core/doctor.js +5 -1
  14. package/dist/core/vault.js +110 -5
  15. package/dist/discord/http.js +84 -0
  16. package/dist/discord/policy.js +47 -0
  17. package/dist/discord/service.js +349 -0
  18. package/dist/discord/store.js +85 -0
  19. package/dist/github/http.js +93 -0
  20. package/dist/github/policy.js +24 -0
  21. package/dist/github/service.js +185 -0
  22. package/dist/github/store.js +54 -0
  23. package/dist/index.js +1 -1
  24. package/dist/ipc/client.js +74 -6
  25. package/dist/ipc/server.js +38 -3
  26. package/dist/mcp/server.js +25 -2
  27. package/dist/platform/windows/assets/prompt-src.js +160 -38
  28. package/dist/platform/windows/doctor.js +2 -2
  29. package/dist/platform/windows/install.js +4 -0
  30. package/dist/service/control.js +47 -5
  31. package/dist/service/doctor.js +3 -0
  32. package/dist/service/main.js +34 -17
  33. package/dist/service/manage.js +20 -16
  34. package/dist/service/state.js +28 -0
  35. package/dist/service/update/coordinator.js +171 -0
  36. package/dist/service/update/files.js +47 -0
  37. package/dist/service/update/gate.js +21 -0
  38. package/dist/service/update/journal.js +157 -0
  39. package/dist/service/update/native.js +50 -0
  40. package/dist/service/update/network.js +28 -0
  41. package/dist/service/update/protocol.js +28 -0
  42. package/dist/service/update/release.js +102 -0
  43. package/dist/service/update/worker-main.js +116 -0
  44. package/dist/service/update/worker.js +58 -0
  45. package/package.json +1 -1
  46. package/scripts/debug-install.bat +69 -69
  47. package/scripts/desktop-browser.ps1 +110 -103
  48. package/scripts/login-bw.bat +21 -21
  49. package/scripts/migrate.bat +4 -4
  50. package/scripts/start-browser.ps1 +33 -33
  51. 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