@mobius-os/mobius 0.3.42 → 0.3.45

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,83 +0,0 @@
1
- import { performance } from 'node:perf_hooks'
2
- import { coalesceMouseEvents, parseMouseEvents } from '../src/components/primitives.js'
3
- import {
4
- createRowAccess, moveAnchorByRows, sliceViewport, tailAnchor,
5
- type RowAnchor,
6
- } from '../src/lib/transcript-viewport.js'
7
-
8
- interface Entry { id: string; rows: number[] }
9
-
10
- let passed = 0
11
- let failed = 0
12
- function ok(condition: boolean, message: string): void {
13
- if (condition) { passed += 1; console.log(` ✓ ${message}`) }
14
- else { failed += 1; console.error(` ✗ ${message}`) }
15
- }
16
-
17
- function access(entries: Entry[]) {
18
- return createRowAccess(entries, entry => entry.id, entry => entry.rows)
19
- }
20
-
21
- function sameAnchor(actual: RowAnchor | null, entryId: string, rowIndex: number): boolean {
22
- return actual?.entryId === entryId && actual.rowIndex === rowIndex
23
- }
24
-
25
- function main(): void {
26
- console.log('\n[VIEWPORT] exact row-level transcript navigation\n')
27
-
28
- const long = access([{ id: 'long', rows: Array.from({ length: 1000 }, (_, i) => i) }])
29
- const tail = tailAnchor(long, 24)
30
- ok(sameAnchor(tail, 'long', 976), '1000-row entry tails at row 976 in a 24-row viewport')
31
- const pageUp = moveAnchorByRows(long, tail, -23)
32
- ok(sameAnchor(pageUp, 'long', 953), 'PageUp moves exactly 23 rows inside one long entry')
33
- ok(sameAnchor(moveAnchorByRows(long, pageUp, 23), 'long', 976), 'PageDown exactly reverses PageUp')
34
-
35
- const mixed = access([
36
- { id: 'a', rows: [0, 1] },
37
- { id: 'b', rows: Array.from({ length: 50 }, (_, i) => i) },
38
- { id: 'c', rows: [0, 1, 2] },
39
- { id: 'd', rows: Array.from({ length: 1000 }, (_, i) => i) },
40
- ])
41
- const crossed = moveAnchorByRows(mixed, { entryId: 'd', entryIndex: 3, rowIndex: 0 }, -4)
42
- ok(sameAnchor(crossed, 'b', 49), 'row navigation crosses mixed-height entry boundaries exactly')
43
- const mixedUp = moveAnchorByRows(mixed, tailAnchor(mixed, 24), -777)
44
- ok(JSON.stringify(moveAnchorByRows(mixed, mixedUp, 777)) === JSON.stringify(tailAnchor(mixed, 24)), 'large mixed-height PageUp/PageDown movement is reversible')
45
-
46
- const startSlice = sliceViewport(long, { entryId: 'long', entryIndex: 0, rowIndex: 0 }, 24)
47
- const middleSlice = sliceViewport(long, { entryId: 'long', entryIndex: 0, rowIndex: 500 }, 24)
48
- const endSlice = sliceViewport(long, tail, 24)
49
- ok(startSlice.rows[0]?.row === 0, 'long entry start is directly accessible')
50
- ok(middleSlice.rows[0]?.row === 500, 'long entry middle is directly accessible')
51
- ok(endSlice.rows.at(-1)?.row === 999, 'long entry end is directly accessible')
52
- ok(startSlice.rows.length === 24 && middleSlice.rows.length === 24 && endSlice.rows.length === 24, 'only viewport-height rows are materialized in each slice')
53
-
54
- const resized = access([{ id: 'long', rows: Array.from({ length: 700 }, (_, i) => i) }])
55
- const restored = sliceViewport(resized, { entryId: 'long', entryIndex: 0, rowIndex: 500 }, 10).anchor
56
- ok(sameAnchor(restored, 'long', 500), 'resize preserves a historical entry/row anchor')
57
- ok(sameAnchor(tailAnchor(resized, 10), 'long', 690), 'tail-follow mode recomputes against the resized layout')
58
-
59
- const appended = access([
60
- { id: 'long', rows: Array.from({ length: 1000 }, (_, i) => i) },
61
- { id: 'new', rows: [0, 1, 2] },
62
- ])
63
- const held = sliceViewport(appended, pageUp, 24).anchor
64
- ok(sameAnchor(held, 'long', 953), 'new entries do not move a historical anchor')
65
- ok(sameAnchor(tailAnchor(appended, 24), 'long', 979), 'tail-follow mode automatically includes newly appended rows')
66
-
67
- const burst = '\x1b[<64;5;5M'.repeat(5)
68
- const coalesced = coalesceMouseEvents(parseMouseEvents(burst))
69
- ok(coalesced.length === 1 && coalesced[0]?.kind === 'wheel' && coalesced[0].delta === 5, 'five wheel events in one input chunk coalesce into one +5 action')
70
- ok(sameAnchor(moveAnchorByRows(long, tail, -3 * (coalesced[0]?.kind === 'wheel' ? coalesced[0].delta : 0)), 'long', 961), 'five wheel notches move exactly 15 rows')
71
-
72
- const thousand = access(Array.from({ length: 1000 }, (_, i) => ({ id: `e-${i}`, rows: [i] })))
73
- for (let i = 0; i < 100; i++) sliceViewport(thousand, moveAnchorByRows(thousand, tailAnchor(thousand, 24), -i), 24)
74
- const started = performance.now()
75
- for (let i = 0; i < 1000; i++) sliceViewport(thousand, moveAnchorByRows(thousand, tailAnchor(thousand, 24), -(i % 900)), 24)
76
- const averageMs = (performance.now() - started) / 1000
77
- ok(averageMs < 5, `1000-entry viewport navigation averages under 5ms (${averageMs.toFixed(3)}ms)`)
78
-
79
- console.log(`\n==== VIEWPORT RESULT: ${passed} passed, ${failed} failed ====\n`)
80
- process.exit(failed === 0 ? 0 : 1)
81
- }
82
-
83
- main()
package/tsconfig.json DELETED
@@ -1,19 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ESNext",
5
- "moduleResolution": "bundler",
6
- "jsx": "react-jsx",
7
- "strict": true,
8
- "esModuleInterop": true,
9
- "skipLibCheck": true,
10
- "resolveJsonModule": true,
11
- "allowImportingTsExtensions": true,
12
- "noEmit": true,
13
- "lib": ["ES2022"],
14
- "types": ["node"],
15
- "baseUrl": ".",
16
- "paths": {}
17
- },
18
- "include": ["src", "tests"]
19
- }
package/uninstall.ps1 DELETED
@@ -1,144 +0,0 @@
1
- #requires -Version 5.1
2
- <#
3
- .SYNOPSIS
4
- Completely uninstall the current-user Mobius TUI installation on Windows.
5
- .DESCRIPTION
6
- Removes the portable Node runtime, npm package, launchers, AIMUX/Python bundle,
7
- saved login and preferences under ~/.mobius, user PATH entries, and both
8
- Explorer "Open in Mobius" context-menu registrations. No administrator rights
9
- are required. Unrelated system Node.js/Python/AIMUX installations are untouched.
10
- .EXAMPLE
11
- irm https://serve.nutshellai.cn/publish/auto/mobiustui/uninstall-v11.ps1 | iex
12
- #>
13
- $ErrorActionPreference = 'Stop'
14
- $ProgressPreference = 'SilentlyContinue'
15
-
16
- function Step($m) { Write-Host "[*] $m" -ForegroundColor Cyan }
17
- function Ok($m) { Write-Host "[OK] $m" -ForegroundColor Green }
18
- function Warn($m) { Write-Host "[!] $m" -ForegroundColor Yellow }
19
- function Err($m) { Write-Host "[X] $m" -ForegroundColor Red }
20
-
21
- function Normalize-PathEntry($value) {
22
- if ([string]::IsNullOrWhiteSpace($value)) { return '' }
23
- return $value.Trim().Trim('"').TrimEnd('\')
24
- }
25
-
26
- function Invoke-MobiusUninstall {
27
- $mobiusHome = Join-Path $env:USERPROFILE '.mobius'
28
- $mobiusBin = Join-Path $mobiusHome 'bin'
29
- $npmGlobal = Join-Path $mobiusHome 'npm-global'
30
- $npmGlobalBin = Join-Path $npmGlobal 'bin'
31
-
32
- Write-Host '=== Mobius TUI Windows 全面卸载(当前用户)===' -ForegroundColor White
33
- Write-Host ''
34
- Warn "将永久删除: $mobiusHome"
35
- Warn '包括登录信息、项目缓存、目录绑定、Issue 偏好、便携 Node、TUI 和 AIMUX/Python bundle。'
36
- Warn '还会删除用户 PATH 中的 Mobius 项和两个“在 Mobius 中打开”右键菜单。'
37
- Write-Host ''
38
-
39
- if ($env:MOBIUS_UNINSTALL_FORCE -ne '1') {
40
- $confirmation = Read-Host '确认全面卸载请输入 UNINSTALL'
41
- if ($confirmation -cne 'UNINSTALL') {
42
- Warn '已取消,没有删除任何内容。'
43
- return
44
- }
45
- }
46
-
47
- Step '停止正在使用便携 Node 的 Mobius 进程...'
48
- $portableProcesses = @(Get-Process node -ErrorAction SilentlyContinue | Where-Object {
49
- try {
50
- $_.Path -and $_.Path.StartsWith($mobiusHome, [System.StringComparison]::OrdinalIgnoreCase)
51
- } catch {
52
- $false
53
- }
54
- })
55
- foreach ($process in $portableProcesses) {
56
- try {
57
- Stop-Process -Id $process.Id -Force -ErrorAction Stop
58
- Ok "已停止进程: node.exe (PID $($process.Id))"
59
- } catch {
60
- Warn "无法停止 PID $($process.Id): $($_.Exception.Message)"
61
- }
62
- }
63
- if ($portableProcesses.Count -eq 0) { Ok '没有正在运行的 Mobius Node 进程。' }
64
- Start-Sleep -Milliseconds 500
65
-
66
- Step '删除 Explorer 右键菜单...'
67
- $contextMenuKeys = @(
68
- 'HKCU:\Software\Classes\Directory\shell\Mobius',
69
- 'HKCU:\Software\Classes\Directory\Background\shell\Mobius'
70
- )
71
- foreach ($key in $contextMenuKeys) {
72
- if (Test-Path $key) { Remove-Item $key -Recurse -Force }
73
- }
74
- Ok '文件夹本身和文件夹空白处的右键菜单已删除。'
75
-
76
- Step '从当前用户 PATH 删除 Mobius 目录...'
77
- $removeEntries = @($mobiusBin, $npmGlobal, $npmGlobalBin) |
78
- ForEach-Object { Normalize-PathEntry $_ }
79
- $userPath = (Get-ItemProperty -Path 'HKCU:\Environment' -Name Path -ErrorAction SilentlyContinue).Path
80
- if ($null -ne $userPath) {
81
- $filteredUserPath = @($userPath -split ';' | Where-Object {
82
- $normalized = Normalize-PathEntry $_
83
- $normalized -and -not ($removeEntries -contains $normalized)
84
- })
85
- Set-ItemProperty -Path 'HKCU:\Environment' -Name Path -Value ($filteredUserPath -join ';')
86
- }
87
- $filteredCurrentPath = @($env:Path -split ';' | Where-Object {
88
- $normalized = Normalize-PathEntry $_
89
- $normalized -and -not ($removeEntries -contains $normalized)
90
- })
91
- $env:Path = $filteredCurrentPath -join ';'
92
- Ok '用户 PATH 已清理。'
93
-
94
- Step '清除 Mobius TUI 用户级环境变量...'
95
- foreach ($name in @('MOBIUS_TUI_HOME', 'MOBIUS_TUI_PYTHON', 'MOBIUS_TUI_PYTHON_BUNDLE_URL')) {
96
- Remove-ItemProperty -Path 'HKCU:\Environment' -Name $name -ErrorAction SilentlyContinue
97
- Remove-Item "Env:$name" -ErrorAction SilentlyContinue
98
- }
99
- Ok 'Mobius TUI 用户级环境变量已清理。'
100
-
101
- Step '删除 Mobius TUI 的全部用户数据和运行时...'
102
- if (Test-Path $mobiusHome) {
103
- $removed = $false
104
- for ($attempt = 1; $attempt -le 4 -and -not $removed; $attempt++) {
105
- Remove-Item $mobiusHome -Recurse -Force -ErrorAction SilentlyContinue
106
- $removed = -not (Test-Path $mobiusHome)
107
- if (-not $removed) { Start-Sleep -Milliseconds (500 * $attempt) }
108
- }
109
- if (-not $removed) {
110
- throw "无法完全删除 $mobiusHome;仍有进程或安全软件占用其中的文件。"
111
- }
112
- }
113
- Ok "已删除: $mobiusHome"
114
-
115
- Step '删除临时安装器和旧错误日志...'
116
- Get-ChildItem $env:TEMP -Filter 'mobius-install-v*.ps1' -ErrorAction SilentlyContinue |
117
- Remove-Item -Force -ErrorAction SilentlyContinue
118
- Remove-Item (Join-Path $env:TEMP 'mobius-install-v10-error.log') -Force -ErrorAction SilentlyContinue
119
- Remove-Item (Join-Path $env:TEMP 'mobius-install-v11-error.log') -Force -ErrorAction SilentlyContinue
120
- Remove-Item (Join-Path $env:TEMP 'mobius-install-v12-error.log') -Force -ErrorAction SilentlyContinue
121
- Remove-Item (Join-Path $env:TEMP 'mobius-install-v13-error.log') -Force -ErrorAction SilentlyContinue
122
- Remove-Item (Join-Path $env:TEMP 'mobius-install-v14-error.log') -Force -ErrorAction SilentlyContinue
123
- Remove-Item (Join-Path $env:TEMP 'mobius-install-v15-error.log') -Force -ErrorAction SilentlyContinue
124
- Remove-Item (Join-Path $env:TEMP 'mobius-uninstall-v11-error.log') -Force -ErrorAction SilentlyContinue
125
- Ok '临时安装文件已清理。'
126
-
127
- Write-Host ''
128
- Write-Host '=== Mobius TUI 已全面卸载 ===' -ForegroundColor Green
129
- Write-Host '请关闭并重新打开 PowerShell/Explorer,使 PATH 和右键菜单刷新。' -ForegroundColor Gray
130
- }
131
-
132
- try {
133
- Invoke-MobiusUninstall
134
- } catch {
135
- $errorLog = Join-Path $env:TEMP 'mobius-uninstall-v11-error.log'
136
- $errorText = $_ | Format-List * -Force | Out-String
137
- $errorText | Set-Content -Path $errorLog -Encoding UTF8
138
- Write-Host ''
139
- Err "Mobius 卸载失败: $($_.Exception.Message)"
140
- Write-Host "完整错误日志: $errorLog" -ForegroundColor Yellow
141
- Write-Host $errorText -ForegroundColor DarkYellow
142
- try { Read-Host '按 Enter 返回 PowerShell(窗口不会自动关闭)' | Out-Null } catch { }
143
- return
144
- }