@ghenya/clinn 0.7.11 → 0.7.13
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/Logos/StartLogo.txt +1 -1
- package/config.json +1 -1
- package/install.js +132 -0
- package/package.json +3 -1
package/Logos/StartLogo.txt
CHANGED
package/config.json
CHANGED
package/install.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const os = require("os");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const { execSync } = require("child_process");
|
|
8
|
+
|
|
9
|
+
const VER = "0.7.13";
|
|
10
|
+
const G = "\x1b[0;32m", C = "\x1b[0;36m", Y = "\x1b[0;33m", R = "\x1b[0;31m", N = "\x1b[0m", D = "\x1b[2m";
|
|
11
|
+
|
|
12
|
+
const IS_WIN = process.platform === "win32";
|
|
13
|
+
const HOME = os.homedir();
|
|
14
|
+
const SRC = __dirname;
|
|
15
|
+
const CLINN_HOME = path.join(HOME, ".clinn");
|
|
16
|
+
const CLINN_CONFIG = path.join(CLINN_HOME, "config.json");
|
|
17
|
+
|
|
18
|
+
function run(cmd, silent) {
|
|
19
|
+
try { return execSync(cmd, { encoding: "utf-8", stdio: silent ? "pipe" : "inherit" }); }
|
|
20
|
+
catch (_) { return ""; }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function panic(msg) {
|
|
24
|
+
console.error(`${R}${msg}${N}`);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
console.log("");
|
|
29
|
+
console.log(` ${C}============================================${N}`);
|
|
30
|
+
console.log(` ${C} Clinn v${VER} — 安装中...${N}`);
|
|
31
|
+
console.log(` ${C}============================================${N}`);
|
|
32
|
+
console.log("");
|
|
33
|
+
|
|
34
|
+
try { run("node --version", true); } catch (_) { panic("Node.js >= 18 required"); }
|
|
35
|
+
|
|
36
|
+
function ensureClinnDir() {
|
|
37
|
+
if (!fs.existsSync(CLINN_HOME)) fs.mkdirSync(CLINN_HOME, { recursive: true });
|
|
38
|
+
const memDir = path.join(CLINN_HOME, "mem");
|
|
39
|
+
if (!fs.existsSync(memDir)) fs.mkdirSync(memDir, { recursive: true });
|
|
40
|
+
const toolsDir = path.join(CLINN_HOME, "Tools", "custom");
|
|
41
|
+
if (!fs.existsSync(toolsDir)) fs.mkdirSync(toolsDir, { recursive: true });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let oldKey = "";
|
|
45
|
+
if (fs.existsSync(CLINN_CONFIG)) {
|
|
46
|
+
try { oldKey = require(CLINN_CONFIG).llm?.apiKey || ""; } catch (_) {}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function cleanOldShellRC() {
|
|
50
|
+
if (IS_WIN) return;
|
|
51
|
+
for (const f of [".bashrc", ".zshrc", ".bash_profile", ".profile"]) {
|
|
52
|
+
const p = path.join(HOME, f);
|
|
53
|
+
if (!fs.existsSync(p)) continue;
|
|
54
|
+
let content = fs.readFileSync(p, "utf-8");
|
|
55
|
+
const oldLen = content.split("\n").length;
|
|
56
|
+
content = content.split("\n").filter(l => !/clinn/i.test(l)).join("\n");
|
|
57
|
+
if (content.split("\n").length !== oldLen) fs.writeFileSync(p, content, "utf-8");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function cleanOldPATH() {
|
|
62
|
+
if (!IS_WIN) return;
|
|
63
|
+
for (const level of ["User", "Machine"]) {
|
|
64
|
+
let raw = "";
|
|
65
|
+
try {
|
|
66
|
+
raw = execSync(`powershell -NoProfile -Command "[Environment]::GetEnvironmentVariable('Path', '${level}')"`, { encoding: "utf-8", windowsHide: true }).trim();
|
|
67
|
+
} catch (_) { continue; }
|
|
68
|
+
const parts = raw.split(";").filter(p => {
|
|
69
|
+
const lo = p.toLowerCase().replace(/\//g, "\\");
|
|
70
|
+
return lo && !lo.includes("clinn") && !lo.includes("\\Clinn\\");
|
|
71
|
+
});
|
|
72
|
+
const clean = parts.join(";");
|
|
73
|
+
try {
|
|
74
|
+
execSync(`powershell -NoProfile -Command "[Environment]::SetEnvironmentVariable('Path', '${clean.replace(/\\/g, "\\\\")}', '${level}')"`, { windowsHide: true });
|
|
75
|
+
} catch (_) {}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function addToPATH() {
|
|
80
|
+
if (!IS_WIN) return;
|
|
81
|
+
const dest = path.join(process.env.LOCALAPPDATA || "", "Programs", "Clinn");
|
|
82
|
+
for (const level of ["User"]) {
|
|
83
|
+
let raw = "";
|
|
84
|
+
try {
|
|
85
|
+
raw = execSync(`powershell -NoProfile -Command "[Environment]::GetEnvironmentVariable('Path', '${level}')"`, { encoding: "utf-8", windowsHide: true }).trim();
|
|
86
|
+
} catch (_) { continue; }
|
|
87
|
+
if (!raw.toLowerCase().includes(dest.toLowerCase())) {
|
|
88
|
+
raw = raw + ";" + dest;
|
|
89
|
+
try {
|
|
90
|
+
execSync(`powershell -NoProfile -Command "[Environment]::SetEnvironmentVariable('Path', '${raw.replace(/\\/g, "\\\\")}', '${level}')"`, { windowsHide: true });
|
|
91
|
+
} catch (_) {}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
cleanOldShellRC();
|
|
97
|
+
cleanOldPATH();
|
|
98
|
+
|
|
99
|
+
ensureClinnDir();
|
|
100
|
+
|
|
101
|
+
if (!fs.existsSync(CLINN_CONFIG)) {
|
|
102
|
+
const pkgCfg = path.join(SRC, "config.json");
|
|
103
|
+
if (fs.existsSync(pkgCfg)) {
|
|
104
|
+
const cfg = JSON.parse(fs.readFileSync(pkgCfg, "utf-8"));
|
|
105
|
+
if (oldKey && oldKey !== "YOUR_API_KEY" && oldKey !== "YOUR_DEEPSEEK_API_KEY_HERE") {
|
|
106
|
+
cfg.llm.apiKey = oldKey;
|
|
107
|
+
}
|
|
108
|
+
fs.writeFileSync(CLINN_CONFIG, JSON.stringify(cfg, null, 2), "utf-8");
|
|
109
|
+
console.log(` ${G}配置文件已创建:${N} ${D}${CLINN_CONFIG}${N}`);
|
|
110
|
+
}
|
|
111
|
+
} else if (oldKey && oldKey !== "YOUR_API_KEY" && oldKey !== "YOUR_DEEPSEEK_API_KEY_HERE") {
|
|
112
|
+
try {
|
|
113
|
+
const cfg = JSON.parse(fs.readFileSync(CLINN_CONFIG, "utf-8"));
|
|
114
|
+
if (cfg.llm.apiKey !== oldKey) {
|
|
115
|
+
cfg.llm.apiKey = oldKey;
|
|
116
|
+
fs.writeFileSync(CLINN_CONFIG, JSON.stringify(cfg, null, 2), "utf-8");
|
|
117
|
+
}
|
|
118
|
+
} catch (_) {}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
addToPATH();
|
|
122
|
+
|
|
123
|
+
console.log(` ${Y}npm bin shim 已由 npm 自动创建${N}`);
|
|
124
|
+
console.log("");
|
|
125
|
+
console.log(` ${G}============================================${N}`);
|
|
126
|
+
console.log(` ${G} 安装完成! 输入 clinn 即可启动${N}`);
|
|
127
|
+
console.log(` ${G}============================================${N}`);
|
|
128
|
+
console.log("");
|
|
129
|
+
console.log(` 版本: ${C}clinn --version${N}`);
|
|
130
|
+
console.log(` 配置: ${C}${CLINN_CONFIG}${N}`);
|
|
131
|
+
console.log(` 设置Key: ${C}clinn → /api key <你的Key>${N}`);
|
|
132
|
+
console.log("");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ghenya/clinn",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.13",
|
|
4
4
|
"description": "终端原生 AI 编程助手 — DeepSeek 驱动,50+ 工具,对话记忆,虚拟浏览器",
|
|
5
5
|
"main": "Src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -14,10 +14,12 @@
|
|
|
14
14
|
"bin/",
|
|
15
15
|
"config.json",
|
|
16
16
|
"README.md",
|
|
17
|
+
"install.js",
|
|
17
18
|
"install.sh",
|
|
18
19
|
"install.bat"
|
|
19
20
|
],
|
|
20
21
|
"scripts": {
|
|
22
|
+
"postinstall": "node install.js",
|
|
21
23
|
"start": "node Src/index.js",
|
|
22
24
|
"lint": "node --check Src/index.js && node --check Src/agent.js && node --check Src/llm.js && node --check Tools/index.js && node --check Tools/extended_tools.js && node --check Tools/search_tools.js && node --check Tools/browser.js && node --check Mem/index.js && node --check Mem/history.js"
|
|
23
25
|
},
|