opensocrates 1.3.0 → 1.4.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.
@@ -0,0 +1,45 @@
1
+ # Paths are data in environment variables, never interpolated PowerShell code.
2
+ param([ValidateSet('entries','extract','private')][string]$Action)
3
+ $ErrorActionPreference = 'Stop'
4
+ [Console]::OutputEncoding = [Text.UTF8Encoding]::new($false)
5
+ $targetPath = $env:OPENSOCRATES_WINDOWS_PATH
6
+ if ($Action -eq 'private') {
7
+ $item = Get-Item -LiteralPath $targetPath -Force
8
+ if ($item.Attributes -band [IO.FileAttributes]::ReparsePoint) { throw 'Reparse point refused' }
9
+ $sid = [Security.Principal.WindowsIdentity]::GetCurrent().User
10
+ $acl = $item.GetAccessControl()
11
+ if ($acl.GetOwner([Security.Principal.SecurityIdentifier]).Value -ne $sid.Value) { throw 'Foreign owner refused' }
12
+ $acl.SetAccessRuleProtection($true, $false)
13
+ foreach ($rule in @($acl.Access)) { [void]$acl.RemoveAccessRuleSpecific($rule) }
14
+ $inherit = if ($item.PSIsContainer) { 'ContainerInherit,ObjectInherit' } else { 'None' }
15
+ foreach ($identity in @($sid.Value,'S-1-5-18','S-1-5-32-544')) {
16
+ $rule = [Security.AccessControl.FileSystemAccessRule]::new([Security.Principal.SecurityIdentifier]::new($identity), 'FullControl', $inherit, 'None', 'Allow')
17
+ $acl.AddAccessRule($rule)
18
+ }
19
+ $item.SetAccessControl($acl)
20
+ exit 0
21
+ }
22
+ Add-Type -AssemblyName System.IO.Compression.FileSystem
23
+ $zip = [IO.Compression.ZipFile]::OpenRead($targetPath)
24
+ try {
25
+ $names = [Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase)
26
+ $total = 0L
27
+ foreach ($entry in $zip.Entries) {
28
+ $name = $entry.FullName
29
+ $parts = $name.TrimEnd('/').Split('/')
30
+ if (!$name -or $name.Contains('\') -or $name.StartsWith('/') -or $name -match '[\x00-\x1f<>:"|?*]' -or
31
+ ($parts | Where-Object { !$_ -or $_ -eq '.' -or $_ -eq '..' -or $_ -match '[. ]$' -or $_ -match '^(?i:CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(?:\.|$)' }) -or !$names.Add($name.TrimEnd('/'))) { throw 'Unsafe or duplicate ZIP path' }
32
+ if ((($entry.ExternalAttributes -shr 16) -band 0xF000) -eq 0xA000) { throw 'ZIP symlink refused' }
33
+ $total += $entry.Length
34
+ if ($total -gt 2147483648 -or $zip.Entries.Count -gt 20000) { throw 'ZIP limit exceeded' }
35
+ }
36
+ if ($Action -eq 'entries') { ConvertTo-Json -InputObject @($zip.Entries | ForEach-Object { $_.FullName }) -Compress; exit 0 }
37
+ $destination = [IO.Path]::GetFullPath($env:OPENSOCRATES_WINDOWS_DESTINATION).TrimEnd('\') + '\'
38
+ foreach ($entry in $zip.Entries) {
39
+ $output = [IO.Path]::GetFullPath([IO.Path]::Combine($destination,$entry.FullName))
40
+ if (!$output.StartsWith($destination,[StringComparison]::OrdinalIgnoreCase)) { throw 'ZIP path escape' }
41
+ if ($entry.FullName.EndsWith('/')) { [void][IO.Directory]::CreateDirectory($output); continue }
42
+ [void][IO.Directory]::CreateDirectory([IO.Path]::GetDirectoryName($output))
43
+ [IO.Compression.ZipFileExtensions]::ExtractToFile($entry,$output,$false)
44
+ }
45
+ } finally { $zip.Dispose() }
package/package.json CHANGED
@@ -1,22 +1,24 @@
1
1
  {
2
2
  "name": "opensocrates",
3
- "version": "1.3.0",
4
- "description": "Install and manage OpenSocrates for Antigravity, Claude Code, Cowork, Codex, Cursor, Grok Build, and OpenCode.",
3
+ "version": "1.4.0",
4
+ "description": "Install and manage OpenSocrates for Codex on macOS and Windows.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "opensocrates": "installer/opensocrates.mjs"
8
8
  },
9
9
  "files": [
10
10
  "installer/opensocrates.mjs",
11
+ "installer/windows.ps1",
11
12
  "CHANGELOG.md",
12
13
  "SECURITY.md",
13
14
  "VERSION"
14
15
  ],
15
16
  "scripts": {
16
- "test": "node --test installer/opensocrates.test.mjs installer/lifecycle.test.mjs tools/clean_machine_acceptance.test.mjs tools/reinstall_cycle_acceptance.test.mjs tools/opencode_bridge.test.mjs tools/release_gate.test.mjs && npm run test:npx",
17
+ "test": "node --test installer/opensocrates.test.mjs installer/lifecycle.test.mjs tools/clean_machine_acceptance.test.mjs tools/reinstall_cycle_acceptance.test.mjs tools/release_gate.test.mjs && npm run test:npx",
17
18
  "test:npx": "node installer/package-smoke.mjs",
18
19
  "pack:check": "npm pack --dry-run",
19
- "prepublishOnly": "npm test"
20
+ "prepublishOnly": "npm test",
21
+ "test:windows": "node --test installer/windows.test.mjs"
20
22
  },
21
23
  "engines": {
22
24
  "node": ">=20"
@@ -36,17 +38,9 @@
36
38
  },
37
39
  "keywords": [
38
40
  "ai",
39
- "claude",
40
- "claude-code",
41
41
  "codex",
42
- "grok",
43
- "grok-build",
44
- "cowork",
45
- "cursor",
46
- "opencode",
47
42
  "reasoning",
48
43
  "agent",
49
- "antigravity",
50
44
  "installer",
51
45
  "critical-thinking",
52
46
  "socratic"