novi-cli 1.0.1 → 1.0.2
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.
Potentially problematic release.
This version of novi-cli might be problematic. Click here for more details.
- package/dist/auth/browser-login.js +1 -1
- package/dist/auth/license.js +1 -1
- package/dist/commands/auto.js +1 -1
- package/dist/commands/gateway.js +1 -1
- package/dist/commands/install.js +1 -1
- package/dist/commands/login.js +1 -1
- package/dist/commands/logout.js +1 -1
- package/dist/commands/setup.js +1 -1
- package/dist/commands/update.js +1 -1
- package/dist/index.js +1 -1
- package/dist/relay/device-identity.js +1 -1
- package/dist/relay/relay-client.js +1 -1
- package/dist/relay/relay-daemon.js +1 -1
- package/dist/relay/types.js +1 -1
- package/dist/utils/branding.js +1 -1
- package/dist/utils/config.js +1 -1
- package/package.json +5 -3
- package/scripts/install-novi.ps1 +129 -0
- package/scripts/install-novi.sh +128 -0
- package/scripts/obfuscate.js +113 -0
- package/scripts/rebrand.js +137 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NOVI Rebrand 스크립트 (postinstall)
|
|
3
|
+
* node_modules/openclaw/dist/ 내 사용자에게 보이는 OpenClaw 문구를 NOVI로 치환합니다.
|
|
4
|
+
* openclaw 업데이트 시에도 npm install 후 자동 재적용됩니다.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
const OPENCLAW_DIST = path.join(__dirname, '..', 'node_modules', 'openclaw', 'dist');
|
|
11
|
+
|
|
12
|
+
// 제외 패턴 보호용 (치환하면 안 되는 것들을 placeholder로 보호)
|
|
13
|
+
const PROTECT_PATTERNS = [
|
|
14
|
+
// 환경변수 (OPENCLAW_*)
|
|
15
|
+
{ regex: /OPENCLAW_[A-Z_]+/g, prefix: '__PROTECT_ENV_' },
|
|
16
|
+
// 설정 경로/파일 (.openclaw*, openclaw.json, openclaw.log)
|
|
17
|
+
{ regex: /\.openclaw/g, prefix: '__PROTECT_DOT_' },
|
|
18
|
+
{ regex: /openclaw\.json/g, prefix: '__PROTECT_JSON_' },
|
|
19
|
+
{ regex: /openclaw\.log/g, prefix: '__PROTECT_LOG_' },
|
|
20
|
+
// URL (openclaw.ai)
|
|
21
|
+
{ regex: /openclaw\.ai/g, prefix: '__PROTECT_URL_' },
|
|
22
|
+
// Symbol (openclaw.pluginRegistryState, openclaw.warning-filter)
|
|
23
|
+
{ regex: /openclaw\.[a-z][a-zA-Z-]+/g, prefix: '__PROTECT_SYM_' },
|
|
24
|
+
// 임시 디렉토리 접두사 (openclaw-${uid}, openclaw-)
|
|
25
|
+
{ regex: /openclaw-/g, prefix: '__PROTECT_TMP_' },
|
|
26
|
+
// 로그 디렉토리 (/tmp/openclaw)
|
|
27
|
+
{ regex: /\/tmp\/openclaw/g, prefix: '__PROTECT_TMPDIR_' },
|
|
28
|
+
// 로그 프리픽스 name: "openclaw" (logger 설정)
|
|
29
|
+
{ regex: /name:\s*"openclaw"/g, prefix: '__PROTECT_LOGNAME_' },
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
// 실제 치환 규칙 (순서 중요: 구체적인 것부터)
|
|
33
|
+
const REPLACE_RULES = [
|
|
34
|
+
// 배너 아스키 아트 중앙
|
|
35
|
+
{ from: /🦞 OPENCLAW 🦞/g, to: '🤖 NOVI 🤖' },
|
|
36
|
+
// 배너 타이틀
|
|
37
|
+
{ from: /🦞 OpenClaw/g, to: '🤖 NOVI' },
|
|
38
|
+
// 프로세스 타이틀 (process.title, process$1.title 등)
|
|
39
|
+
{ from: /process(?:\$\d+)?\.title\s*=\s*"openclaw"/g, to: (m) => m.replace('"openclaw"', '"novi"') },
|
|
40
|
+
// 에러 프리픽스
|
|
41
|
+
{ from: /\[openclaw\]/g, to: '[novi]' },
|
|
42
|
+
// 남은 이모지
|
|
43
|
+
{ from: /🦞/g, to: '🤖' },
|
|
44
|
+
// 사용자에게 보이는 "OpenClaw" 텍스트 (보호된 패턴 제외 후 남은 것)
|
|
45
|
+
{ from: /OpenClaw/g, to: 'NOVI' },
|
|
46
|
+
// 소문자 "openclaw" (보호된 패턴 제외 후 남은 것 - 주로 로그/UI 텍스트)
|
|
47
|
+
{ from: /openclaw/g, to: 'novi' },
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 디렉토리 내 모든 JS 파일 재귀 탐색
|
|
52
|
+
*/
|
|
53
|
+
function findJsFiles(dir, files = []) {
|
|
54
|
+
if (!fs.existsSync(dir)) return files;
|
|
55
|
+
const items = fs.readdirSync(dir);
|
|
56
|
+
for (const item of items) {
|
|
57
|
+
const fullPath = path.join(dir, item);
|
|
58
|
+
const stat = fs.statSync(fullPath);
|
|
59
|
+
if (stat.isDirectory()) {
|
|
60
|
+
findJsFiles(fullPath, files);
|
|
61
|
+
} else if (item.endsWith('.js')) {
|
|
62
|
+
files.push(fullPath);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return files;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 파일 내용에서 안전하게 문구 치환
|
|
70
|
+
*/
|
|
71
|
+
function rebrandContent(content) {
|
|
72
|
+
let result = content;
|
|
73
|
+
const protectedMap = new Map(); // placeholder → 원본
|
|
74
|
+
let counter = 0;
|
|
75
|
+
|
|
76
|
+
// 1단계: 제외 패턴을 placeholder로 보호
|
|
77
|
+
for (const { regex, prefix } of PROTECT_PATTERNS) {
|
|
78
|
+
result = result.replace(regex, (match) => {
|
|
79
|
+
const key = `${prefix}${counter++}__`;
|
|
80
|
+
protectedMap.set(key, match);
|
|
81
|
+
return key;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 2단계: 실제 치환 수행
|
|
86
|
+
for (const { from, to } of REPLACE_RULES) {
|
|
87
|
+
if (typeof to === 'function') {
|
|
88
|
+
result = result.replace(from, to);
|
|
89
|
+
} else {
|
|
90
|
+
result = result.replace(from, to);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 3단계: placeholder를 원본으로 복원
|
|
95
|
+
for (const [key, original] of protectedMap) {
|
|
96
|
+
// 전역으로 치환 (같은 placeholder가 여러 번 나올 수 있음)
|
|
97
|
+
result = result.split(key).join(original);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* 메인 실행
|
|
105
|
+
*/
|
|
106
|
+
function main() {
|
|
107
|
+
console.log('\n🤖 NOVI Rebrand: OpenClaw → NOVI 문구 치환 시작...\n');
|
|
108
|
+
|
|
109
|
+
if (!fs.existsSync(OPENCLAW_DIST)) {
|
|
110
|
+
console.log('⚠️ openclaw/dist 폴더 없음 - 스킵 (아직 설치되지 않았을 수 있음)');
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const jsFiles = findJsFiles(OPENCLAW_DIST);
|
|
115
|
+
console.log(`📁 ${jsFiles.length}개 JS 파일 스캔\n`);
|
|
116
|
+
|
|
117
|
+
let patched = 0;
|
|
118
|
+
let unchanged = 0;
|
|
119
|
+
|
|
120
|
+
for (const file of jsFiles) {
|
|
121
|
+
const original = fs.readFileSync(file, 'utf-8');
|
|
122
|
+
const rebranded = rebrandContent(original);
|
|
123
|
+
|
|
124
|
+
if (original !== rebranded) {
|
|
125
|
+
fs.writeFileSync(file, rebranded, 'utf-8');
|
|
126
|
+
console.log(` ✓ ${path.relative(OPENCLAW_DIST, file)}`);
|
|
127
|
+
patched++;
|
|
128
|
+
} else {
|
|
129
|
+
unchanged++;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
console.log(`\n✅ 완료: ${patched}개 파일 치환, ${unchanged}개 변경 없음\n`);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
main();
|
|
137
|
+
|