@unieai/code 0.0.1 → 0.0.3
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/LICENSE +16 -17
- package/README.md +40 -0
- package/bin/unieai +18 -177
- package/dist/cli.js +618578 -0
- package/package.json +38 -18
- package/postinstall.mjs +0 -102
package/LICENSE
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
UNIEAI PROPRIETARY LICENSE
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2026 UnieAI. All rights reserved.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
5
|
+
This software and all associated source code, documentation, assets, and related
|
|
6
|
+
materials in this directory are proprietary to UnieAI.
|
|
11
7
|
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
Permission is not granted to use, copy, modify, merge, publish, distribute,
|
|
9
|
+
sublicense, sell, or provide access to this software, in whole or in part,
|
|
10
|
+
except with prior written authorization from UnieAI.
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
12
|
+
Any unauthorized use, reproduction, disclosure, or distribution of this
|
|
13
|
+
software is strictly prohibited.
|
|
14
|
+
|
|
15
|
+
This software is provided on an "AS IS" basis, without warranty of any kind,
|
|
16
|
+
express or implied, including but not limited to warranties of merchantability,
|
|
17
|
+
fitness for a particular purpose, and noninfringement. In no event shall UnieAI
|
|
18
|
+
be liable for any claim, damages, or other liability, whether in an action of
|
|
19
|
+
contract, tort, or otherwise, arising from, out of, or in connection with the
|
|
20
|
+
software or the use of the software.
|
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# UnieAI Code
|
|
2
|
+
|
|
3
|
+
`@unieai/code` is UnieAI's terminal coding agent — a Claude Code-compatible
|
|
4
|
+
Ink TUI that signs into [UnieAI Studio](https://unieai.com) and routes all
|
|
5
|
+
Anthropic-bound traffic through the Studio gateway.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm i -g @unieai/code
|
|
11
|
+
# or: pnpm add -g @unieai/code
|
|
12
|
+
# or: bun add -g @unieai/code
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Use
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
unieai # interactive TUI in the current directory
|
|
19
|
+
unieai login # sign into UnieAI Studio
|
|
20
|
+
unieai -p "refactor this file" # one-shot print mode
|
|
21
|
+
unieai --version
|
|
22
|
+
unieai --help
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
A second bin name, `claude-haha`, is registered as an alias for compatibility
|
|
26
|
+
with the upstream project.
|
|
27
|
+
|
|
28
|
+
## State
|
|
29
|
+
|
|
30
|
+
User state (sessions, plugins, skills, MCP servers, login, theme) lives under
|
|
31
|
+
`~/.unieai` so it stays isolated from any official Claude Code install. Override
|
|
32
|
+
with `UNIEAI_CONFIG_DIR` or `CLAUDE_CONFIG_DIR`.
|
|
33
|
+
|
|
34
|
+
## Requirements
|
|
35
|
+
|
|
36
|
+
- Node.js 18 or later
|
|
37
|
+
|
|
38
|
+
## License
|
|
39
|
+
|
|
40
|
+
Proprietary — © UnieAI. See `LICENSE`.
|
package/bin/unieai
CHANGED
|
@@ -1,187 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
// UnieAI Code — npm entry. Mirrors what bin/claude-haha (bash) does for the
|
|
3
|
+
// source/Bun dev path: keep state isolated under ~/.unieai and capture the
|
|
4
|
+
// invoking cwd so preload.ts can chdir back to the user's project.
|
|
2
5
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
process.env["OPENCODE_" + k.slice(7)] = process.env[k]
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const childProcess = require("child_process")
|
|
12
|
-
const fs = require("fs")
|
|
13
|
-
const path = require("path")
|
|
14
|
-
const os = require("os")
|
|
15
|
-
|
|
16
|
-
function run(target) {
|
|
17
|
-
const result = childProcess.spawnSync(target, process.argv.slice(2), {
|
|
18
|
-
stdio: "inherit",
|
|
19
|
-
})
|
|
20
|
-
if (result.error) {
|
|
21
|
-
console.error(result.error.message)
|
|
22
|
-
process.exit(1)
|
|
23
|
-
}
|
|
24
|
-
const code = typeof result.status === "number" ? result.status : 0
|
|
25
|
-
process.exit(code)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const envPath = process.env.OPENCODE_BIN_PATH
|
|
29
|
-
if (envPath) {
|
|
30
|
-
run(envPath)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const scriptPath = fs.realpathSync(__filename)
|
|
34
|
-
const scriptDir = path.dirname(scriptPath)
|
|
6
|
+
import path from 'node:path'
|
|
7
|
+
import { fileURLToPath } from 'node:url'
|
|
8
|
+
import os from 'node:os'
|
|
9
|
+
import fs from 'node:fs'
|
|
35
10
|
|
|
36
|
-
|
|
37
|
-
const cached = path.join(scriptDir, ".opencode")
|
|
38
|
-
if (fs.existsSync(cached)) {
|
|
39
|
-
run(cached)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const platformMap = {
|
|
43
|
-
darwin: "darwin",
|
|
44
|
-
linux: "linux",
|
|
45
|
-
win32: "windows",
|
|
46
|
-
}
|
|
47
|
-
const archMap = {
|
|
48
|
-
x64: "x64",
|
|
49
|
-
arm64: "arm64",
|
|
50
|
-
arm: "arm",
|
|
51
|
-
}
|
|
11
|
+
const here = path.dirname(fileURLToPath(import.meta.url))
|
|
52
12
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
platform = os.platform()
|
|
13
|
+
if (!process.env.CALLER_DIR) {
|
|
14
|
+
process.env.CALLER_DIR = process.cwd()
|
|
56
15
|
}
|
|
57
|
-
let arch = archMap[os.arch()]
|
|
58
|
-
if (!arch) {
|
|
59
|
-
arch = os.arch()
|
|
60
|
-
}
|
|
61
|
-
const base = "@unieai/code-" + platform + "-" + arch
|
|
62
|
-
const binary = platform === "windows" ? "unieai.exe" : "unieai"
|
|
63
|
-
|
|
64
|
-
function supportsAvx2() {
|
|
65
|
-
if (arch !== "x64") return false
|
|
66
|
-
|
|
67
|
-
if (platform === "linux") {
|
|
68
|
-
try {
|
|
69
|
-
return /(^|\s)avx2(\s|$)/i.test(fs.readFileSync("/proc/cpuinfo", "utf8"))
|
|
70
|
-
} catch {
|
|
71
|
-
return false
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (platform === "darwin") {
|
|
76
|
-
try {
|
|
77
|
-
const result = childProcess.spawnSync("sysctl", ["-n", "hw.optional.avx2_0"], {
|
|
78
|
-
encoding: "utf8",
|
|
79
|
-
timeout: 1500,
|
|
80
|
-
})
|
|
81
|
-
if (result.status !== 0) return false
|
|
82
|
-
return (result.stdout || "").trim() === "1"
|
|
83
|
-
} catch {
|
|
84
|
-
return false
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (platform === "windows") {
|
|
89
|
-
const cmd =
|
|
90
|
-
'(Add-Type -MemberDefinition "[DllImport(""kernel32.dll"")] public static extern bool IsProcessorFeaturePresent(int ProcessorFeature);" -Name Kernel32 -Namespace Win32 -PassThru)::IsProcessorFeaturePresent(40)'
|
|
91
|
-
|
|
92
|
-
for (const exe of ["powershell.exe", "pwsh.exe", "pwsh", "powershell"]) {
|
|
93
|
-
try {
|
|
94
|
-
const result = childProcess.spawnSync(exe, ["-NoProfile", "-NonInteractive", "-Command", cmd], {
|
|
95
|
-
encoding: "utf8",
|
|
96
|
-
timeout: 3000,
|
|
97
|
-
windowsHide: true,
|
|
98
|
-
})
|
|
99
|
-
if (result.status !== 0) continue
|
|
100
|
-
const out = (result.stdout || "").trim().toLowerCase()
|
|
101
|
-
if (out === "true" || out === "1") return true
|
|
102
|
-
if (out === "false" || out === "0") return false
|
|
103
|
-
} catch {
|
|
104
|
-
continue
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return false
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return false
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const names = (() => {
|
|
115
|
-
const avx2 = supportsAvx2()
|
|
116
|
-
const baseline = arch === "x64" && !avx2
|
|
117
|
-
|
|
118
|
-
if (platform === "linux") {
|
|
119
|
-
const musl = (() => {
|
|
120
|
-
try {
|
|
121
|
-
if (fs.existsSync("/etc/alpine-release")) return true
|
|
122
|
-
} catch {
|
|
123
|
-
// ignore
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
try {
|
|
127
|
-
const result = childProcess.spawnSync("ldd", ["--version"], { encoding: "utf8" })
|
|
128
|
-
const text = ((result.stdout || "") + (result.stderr || "")).toLowerCase()
|
|
129
|
-
if (text.includes("musl")) return true
|
|
130
|
-
} catch {
|
|
131
|
-
// ignore
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return false
|
|
135
|
-
})()
|
|
136
|
-
|
|
137
|
-
if (musl) {
|
|
138
|
-
if (arch === "x64") {
|
|
139
|
-
if (baseline) return [`${base}-baseline-musl`, `${base}-musl`, `${base}-baseline`, base]
|
|
140
|
-
return [`${base}-musl`, `${base}-baseline-musl`, base, `${base}-baseline`]
|
|
141
|
-
}
|
|
142
|
-
return [`${base}-musl`, base]
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
if (arch === "x64") {
|
|
146
|
-
if (baseline) return [`${base}-baseline`, base, `${base}-baseline-musl`, `${base}-musl`]
|
|
147
|
-
return [base, `${base}-baseline`, `${base}-musl`, `${base}-baseline-musl`]
|
|
148
|
-
}
|
|
149
|
-
return [base, `${base}-musl`]
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (arch === "x64") {
|
|
153
|
-
if (baseline) return [`${base}-baseline`, base]
|
|
154
|
-
return [base, `${base}-baseline`]
|
|
155
|
-
}
|
|
156
|
-
return [base]
|
|
157
|
-
})()
|
|
158
16
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const modules = path.join(current, "node_modules")
|
|
163
|
-
if (fs.existsSync(modules)) {
|
|
164
|
-
for (const name of names) {
|
|
165
|
-
const candidate = path.join(modules, name, "bin", binary)
|
|
166
|
-
if (fs.existsSync(candidate)) return candidate
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
const parent = path.dirname(current)
|
|
170
|
-
if (parent === current) {
|
|
171
|
-
return
|
|
172
|
-
}
|
|
173
|
-
current = parent
|
|
174
|
-
}
|
|
17
|
+
if (!process.env.CLAUDE_CONFIG_DIR) {
|
|
18
|
+
process.env.CLAUDE_CONFIG_DIR =
|
|
19
|
+
process.env.UNIEAI_CONFIG_DIR || path.join(os.homedir(), '.unieai')
|
|
175
20
|
}
|
|
176
21
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
names.map((n) => `\"${n}\"`).join(" or ") +
|
|
182
|
-
" package",
|
|
183
|
-
)
|
|
184
|
-
process.exit(1)
|
|
22
|
+
try {
|
|
23
|
+
fs.mkdirSync(process.env.CLAUDE_CONFIG_DIR, { recursive: true })
|
|
24
|
+
} catch {
|
|
25
|
+
// best-effort; the CLI surfaces a clearer error if this fails downstream
|
|
185
26
|
}
|
|
186
27
|
|
|
187
|
-
|
|
28
|
+
await import(path.join(here, '..', 'dist', 'cli.js'))
|