@limecloud/lime 1.144.1

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 (3) hide show
  1. package/README.md +68 -0
  2. package/bin/lime.js +260 -0
  3. package/package.json +28 -0
package/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # `@limecloud/lime`
2
+
3
+ Lime 的官方命令行入口。CLI、TUI 和 Desktop 共用 App Server JSON-RPC、RuntimeCore 与 canonical Thread/Turn/Item,不包含独立任务 runtime。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ npm install -g @limecloud/lime
9
+ ```
10
+
11
+ 根 npm 包只包含 launcher,并通过 optional dependency 安装当前平台的原生载荷;安装阶段不执行网络下载脚本。平台载荷原子包含 `lime`、`app-server`、`code-mode-host`、Windows sandbox helpers 和所需动态库,保证默认 TUI 与 `exec` 都进入同一 App Server 产品链。
12
+
13
+ 当前发布目标为 macOS arm64/x64、Windows x64 与 Linux x64 GNU。尚无真实构建和运行证据的平台会明确拒绝启动,不发布空壳 optional package。
14
+
15
+ ## 命令
16
+
17
+ ```bash
18
+ # 默认启动交互式 TUI
19
+ lime
20
+
21
+ # 显式启动 TUI
22
+ lime tui
23
+
24
+ # 非交互运行
25
+ lime exec "review this diff"
26
+ lime exec --json "review this diff"
27
+ lime exec --jsonl "review this diff"
28
+
29
+ # 只读检查 execpolicy prefix rules
30
+ lime execpolicy check --rules ./rules/policy.rules --pretty git push origin main
31
+
32
+ # 生成 shell completion
33
+ lime completion zsh > "${fpath[1]}/_lime"
34
+
35
+ # 恢复 canonical Thread
36
+ lime resume
37
+ lime resume <thread-id>
38
+
39
+ # App Server read/control surfaces
40
+ lime thread list
41
+ lime thread show <thread-id> --include-turns
42
+ lime mcp list
43
+ lime skills list
44
+ ```
45
+
46
+ `--json` 输出可读的稳定 JSON;`--jsonl` 输出单行 JSON envelope,二者互斥。`completion` 从同一命令树生成 bash、zsh、fish、PowerShell 和 elvish 脚本。
47
+
48
+ 交互式 TUI 支持 `zh-CN`、`zh-TW`、`en-US`、`ja-JP`、`ko-KR`。可通过默认 `lime`、`lime tui` 或 `lime resume` 的 `--locale <LOCALE>` 指定;未指定时按 `LIME_LOCALE`、`LC_ALL`、`LANG` 解析,未知语言回退到 `en-US`。`exec` 与管理命令的 JSON 合同保持语言无关。
49
+
50
+ 本地连接默认启动同目录或 `PATH` 中的 `app-server`。可用 `LIME_APP_SERVER_BIN` 或 `--app-server <PATH>` 覆盖。需要连接远端 App Server 时使用 Codex 形状的参数:
51
+
52
+ ```bash
53
+ lime exec --remote wss://cloud.example/rpc --remote-auth-token-env LIME_REMOTE_TOKEN "review this diff"
54
+ lime tui --remote ws://127.0.0.1:4500
55
+ ```
56
+
57
+ 远端 token 只从环境变量读取;token 连接要求 `wss://` 或 loopback `ws://`。当前仅提供 transport foundation,不代表生产 Cloud endpoint、租户或账号能力已启用。
58
+
59
+ ## 发布
60
+
61
+ ```bash
62
+ python3 scripts/build_npm_package.py \
63
+ --package lime \
64
+ --release-version 1.140.0 \
65
+ --pack-output dist/lime-npm-1.140.0.tgz
66
+ ```
67
+
68
+ 平台包使用 `--package lime-<platform>-<arch> --vendor-src <vendor-root>` staging。`vendor-root` 必须使用 `vendor/<target-triple>/bin` 布局并包含完整 runtime payload。发布工作流先串行发布四个平台版本,最后发布 `@limecloud/lime` 根版本。
package/bin/lime.js ADDED
@@ -0,0 +1,260 @@
1
+ #!/usr/bin/env node
2
+ // Unified entry point for the Lime CLI.
3
+
4
+ import { spawn } from "node:child_process";
5
+ import { existsSync, readFileSync, realpathSync } from "node:fs";
6
+ import { createRequire } from "node:module";
7
+ import path from "node:path";
8
+ import { fileURLToPath } from "node:url";
9
+
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = path.dirname(__filename);
12
+ const require = createRequire(import.meta.url);
13
+ const limePackageRoot = realpathSync(path.join(__dirname, ".."));
14
+
15
+ const PLATFORM_PACKAGE_BY_TARGET = {
16
+ "x86_64-unknown-linux-gnu": "@limecloud/lime-linux-x64",
17
+ "x86_64-apple-darwin": "@limecloud/lime-darwin-x64",
18
+ "aarch64-apple-darwin": "@limecloud/lime-darwin-arm64",
19
+ "x86_64-pc-windows-msvc": "@limecloud/lime-win32-x64",
20
+ };
21
+
22
+ const { platform, arch } = process;
23
+
24
+ let targetTriple = null;
25
+ switch (platform) {
26
+ case "linux":
27
+ if (arch === "x64") {
28
+ targetTriple = "x86_64-unknown-linux-gnu";
29
+ }
30
+ break;
31
+ case "darwin":
32
+ if (arch === "x64") {
33
+ targetTriple = "x86_64-apple-darwin";
34
+ } else if (arch === "arm64") {
35
+ targetTriple = "aarch64-apple-darwin";
36
+ }
37
+ break;
38
+ case "win32":
39
+ if (arch === "x64") {
40
+ targetTriple = "x86_64-pc-windows-msvc";
41
+ }
42
+ break;
43
+ default:
44
+ break;
45
+ }
46
+
47
+ if (!targetTriple) {
48
+ throw new Error(`Unsupported platform: ${platform} (${arch})`);
49
+ }
50
+
51
+ const platformPackage = PLATFORM_PACKAGE_BY_TARGET[targetTriple];
52
+ if (!platformPackage) {
53
+ throw new Error(`Unsupported target triple: ${targetTriple}`);
54
+ }
55
+
56
+ function findLimeExecutable() {
57
+ let vendorRoot;
58
+ try {
59
+ const packageJsonPath = require.resolve(`${platformPackage}/package.json`);
60
+ vendorRoot = path.join(path.dirname(packageJsonPath), "vendor");
61
+ } catch {
62
+ vendorRoot = path.join(__dirname, "..", "vendor");
63
+ }
64
+
65
+ const limeExecutable = path.join(
66
+ vendorRoot,
67
+ targetTriple,
68
+ "bin",
69
+ process.platform === "win32" ? "lime.exe" : "lime",
70
+ );
71
+ if (existsSync(limeExecutable)) {
72
+ return limeExecutable;
73
+ }
74
+
75
+ const packageManager = detectPackageManager();
76
+ const updateCommand =
77
+ packageManager === "bun"
78
+ ? "bun install -g @limecloud/lime@latest"
79
+ : packageManager === "pnpm"
80
+ ? "pnpm add -g @limecloud/lime@latest"
81
+ : packageManager === "vite-plus"
82
+ ? "vp install -g @limecloud/lime@latest"
83
+ : "npm install -g @limecloud/lime@latest";
84
+ throw new Error(
85
+ `Missing optional dependency ${platformPackage}. Reinstall Lime: ${updateCommand}`,
86
+ );
87
+ }
88
+
89
+ function isPnpmOwnedLimeInstall(nodeModulesDir) {
90
+ if (!existsSync(path.join(nodeModulesDir, ".modules.yaml"))) {
91
+ return false;
92
+ }
93
+
94
+ try {
95
+ return (
96
+ realpathSync(path.join(nodeModulesDir, "@limecloud", "lime")) ===
97
+ limePackageRoot
98
+ );
99
+ } catch {
100
+ return false;
101
+ }
102
+ }
103
+
104
+ function isVitePlusOwnedLimeInstall(packagesDir) {
105
+ if (path.basename(packagesDir) !== "packages") {
106
+ return false;
107
+ }
108
+
109
+ try {
110
+ const metadata = JSON.parse(
111
+ readFileSync(path.join(packagesDir, "@limecloud", "lime.json"), "utf8"),
112
+ );
113
+ if (metadata.name !== "@limecloud/lime") {
114
+ return false;
115
+ }
116
+
117
+ const installId = metadata.installId || "";
118
+ const installDir = installId.startsWith("#")
119
+ ? path.join(packagesDir, `@limecloud/lime${installId}`)
120
+ : path.join(packagesDir, "@limecloud/lime", installId);
121
+ for (const nodeModulesDir of [
122
+ path.join(installDir, "lib", "node_modules"),
123
+ path.join(installDir, "node_modules"),
124
+ ]) {
125
+ const packageRoot = path.join(nodeModulesDir, "@limecloud", "lime");
126
+ if (
127
+ existsSync(packageRoot) &&
128
+ realpathSync(packageRoot) === limePackageRoot
129
+ ) {
130
+ return true;
131
+ }
132
+ }
133
+ } catch {
134
+ // Missing ownership metadata must not prevent Lime from starting.
135
+ }
136
+ return false;
137
+ }
138
+
139
+ function detectPackageManager() {
140
+ const entrypointDir = path.dirname(path.resolve(process.argv[1]));
141
+ for (const startDir of new Set([limePackageRoot, entrypointDir])) {
142
+ const filesystemRoot = path.parse(startDir).root;
143
+ for (
144
+ let currentDir = startDir;
145
+ currentDir !== filesystemRoot;
146
+ currentDir = path.dirname(currentDir)
147
+ ) {
148
+ if (isVitePlusOwnedLimeInstall(currentDir)) {
149
+ return "vite-plus";
150
+ }
151
+ if (isPnpmOwnedLimeInstall(path.join(currentDir, "node_modules"))) {
152
+ return "pnpm";
153
+ }
154
+ }
155
+
156
+ if (isPnpmOwnedLimeInstall(path.join(filesystemRoot, "node_modules"))) {
157
+ return "pnpm";
158
+ }
159
+ }
160
+
161
+ const userAgent = process.env.npm_config_user_agent || "";
162
+ if (/\bbun\//u.test(userAgent)) {
163
+ return "bun";
164
+ }
165
+
166
+ const execPath = process.env.npm_execpath || "";
167
+ if (execPath.includes("bun")) {
168
+ return "bun";
169
+ }
170
+
171
+ if (
172
+ __dirname.includes(".bun/install/global") ||
173
+ __dirname.includes(".bun\\install\\global")
174
+ ) {
175
+ return "bun";
176
+ }
177
+
178
+ return userAgent ? "npm" : null;
179
+ }
180
+
181
+ const binaryPath = findLimeExecutable();
182
+ const packageManager = detectPackageManager();
183
+ const packageManagerEnvVar =
184
+ packageManager === "bun"
185
+ ? "LIME_MANAGED_BY_BUN"
186
+ : packageManager === "pnpm"
187
+ ? "LIME_MANAGED_BY_PNPM"
188
+ : packageManager === "vite-plus"
189
+ ? "LIME_MANAGED_BY_VITE_PLUS"
190
+ : "LIME_MANAGED_BY_NPM";
191
+ const env = {
192
+ ...process.env,
193
+ LIME_MANAGED_PACKAGE_ROOT: limePackageRoot,
194
+ };
195
+ delete env.LIME_MANAGED_BY_NPM;
196
+ delete env.LIME_MANAGED_BY_BUN;
197
+ delete env.LIME_MANAGED_BY_PNPM;
198
+ delete env.LIME_MANAGED_BY_VITE_PLUS;
199
+ env[packageManagerEnvVar] = "1";
200
+
201
+ // macOS strips DYLD_* variables when Node launches the native child. The
202
+ // bundled App Server loads its @rpath libraries from this directory, so pass
203
+ // the package-local runtime directory explicitly to the native process.
204
+ const nativeRuntimeDir = path.dirname(binaryPath);
205
+ if (process.platform === "darwin") {
206
+ env.DYLD_LIBRARY_PATH = [nativeRuntimeDir, env.DYLD_LIBRARY_PATH]
207
+ .filter(Boolean)
208
+ .join(path.delimiter);
209
+ } else if (process.platform === "linux") {
210
+ env.LD_LIBRARY_PATH = [nativeRuntimeDir, env.LD_LIBRARY_PATH]
211
+ .filter(Boolean)
212
+ .join(path.delimiter);
213
+ }
214
+
215
+ const child = spawn(binaryPath, process.argv.slice(2), {
216
+ stdio: "inherit",
217
+ env,
218
+ });
219
+
220
+ child.on("error", (error) => {
221
+ console.error(error);
222
+ process.exit(1);
223
+ });
224
+
225
+ const forwardSignal = (signal) => {
226
+ if (child.killed) {
227
+ return;
228
+ }
229
+ try {
230
+ child.kill(signal);
231
+ } catch {
232
+ // The exit handler below remains the single parent termination owner.
233
+ }
234
+ };
235
+
236
+ const signalHandlers = new Map();
237
+ for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) {
238
+ const handler = () => forwardSignal(signal);
239
+ signalHandlers.set(signal, handler);
240
+ process.on(signal, handler);
241
+ }
242
+
243
+ const childResult = await new Promise((resolve) => {
244
+ child.on("exit", (code, signal) => {
245
+ if (signal) {
246
+ resolve({ type: "signal", signal });
247
+ } else {
248
+ resolve({ type: "code", exitCode: code ?? 1 });
249
+ }
250
+ });
251
+ });
252
+
253
+ if (childResult.type === "signal") {
254
+ for (const [signal, handler] of signalHandlers) {
255
+ process.removeListener(signal, handler);
256
+ }
257
+ process.kill(process.pid, childResult.signal);
258
+ } else {
259
+ process.exit(childResult.exitCode);
260
+ }
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@limecloud/lime",
3
+ "version": "1.144.1",
4
+ "packageManager": "pnpm@9.15.9",
5
+ "description": "Lime CLI is an agent that runs in your terminal.",
6
+ "bin": {
7
+ "lime": "bin/lime.js"
8
+ },
9
+ "type": "module",
10
+ "engines": {
11
+ "node": ">=18"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/limecloud/lime.git",
16
+ "directory": "packages/cli"
17
+ },
18
+ "license": "MIT",
19
+ "files": [
20
+ "bin/lime.js"
21
+ ],
22
+ "optionalDependencies": {
23
+ "@limecloud/lime-linux-x64": "1.144.1-linux-x64",
24
+ "@limecloud/lime-darwin-x64": "1.144.1-darwin-x64",
25
+ "@limecloud/lime-darwin-arm64": "1.144.1-darwin-arm64",
26
+ "@limecloud/lime-win32-x64": "1.144.1-win32-x64"
27
+ }
28
+ }