@simonyea/holysheep-cli 2.1.75 → 2.1.77
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/dist/configure-worker.js +257 -2
- package/dist/index.js +284 -252
- package/package.json +2 -2
package/dist/configure-worker.js
CHANGED
|
@@ -4150,16 +4150,265 @@ providers:
|
|
|
4150
4150
|
}
|
|
4151
4151
|
});
|
|
4152
4152
|
|
|
4153
|
+
// src/tools/qwen-code.js
|
|
4154
|
+
var require_qwen_code = __commonJS({
|
|
4155
|
+
"src/tools/qwen-code.js"(exports2, module2) {
|
|
4156
|
+
var fs = require("fs");
|
|
4157
|
+
var path = require("path");
|
|
4158
|
+
var os = require("os");
|
|
4159
|
+
var CONFIG_DIR = path.join(os.homedir(), ".qwen");
|
|
4160
|
+
var CONFIG_FILE = path.join(CONFIG_DIR, ".env");
|
|
4161
|
+
var MARKER_BEGIN = "# >>> HolySheep BEGIN >>>";
|
|
4162
|
+
var MARKER_END = "# <<< HolySheep END <<<";
|
|
4163
|
+
var DEFAULT_OPENAI_MODEL = "gpt-5.5";
|
|
4164
|
+
var DEFAULT_ANTHROPIC_MODEL = "claude-sonnet-4-6";
|
|
4165
|
+
function stripManagedBlock(content) {
|
|
4166
|
+
if (!content) return "";
|
|
4167
|
+
const text = String(content).replace(/\r\n/g, "\n");
|
|
4168
|
+
const re = new RegExp(
|
|
4169
|
+
`(?:^|\\n)\\s*${escapeRegex(MARKER_BEGIN)}[\\s\\S]*?${escapeRegex(MARKER_END)}\\s*(?:\\n|$)`,
|
|
4170
|
+
"g"
|
|
4171
|
+
);
|
|
4172
|
+
return text.replace(re, "\n");
|
|
4173
|
+
}
|
|
4174
|
+
__name(stripManagedBlock, "stripManagedBlock");
|
|
4175
|
+
function escapeRegex(s) {
|
|
4176
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4177
|
+
}
|
|
4178
|
+
__name(escapeRegex, "escapeRegex");
|
|
4179
|
+
function buildManagedBlock(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
4180
|
+
const cleanOpenAi = String(baseUrlOpenAI || "https://api.holysheep.ai/v1").replace(/\/+$/, "");
|
|
4181
|
+
const cleanAnthropic = String(baseUrlAnthropicNoV1 || "https://api.holysheep.ai").replace(/\/+$/, "");
|
|
4182
|
+
return [
|
|
4183
|
+
MARKER_BEGIN,
|
|
4184
|
+
"# Managed by holysheep-cli \u2014 do not edit between markers.",
|
|
4185
|
+
"# Run `hs reset` to remove this block; user-added env lines outside",
|
|
4186
|
+
"# this block are preserved.",
|
|
4187
|
+
`OPENAI_API_KEY=${apiKey}`,
|
|
4188
|
+
`OPENAI_BASE_URL=${cleanOpenAi}`,
|
|
4189
|
+
`OPENAI_MODEL=${DEFAULT_OPENAI_MODEL}`,
|
|
4190
|
+
`ANTHROPIC_BASE_URL=${cleanAnthropic}`,
|
|
4191
|
+
`ANTHROPIC_AUTH_TOKEN=${apiKey}`,
|
|
4192
|
+
`ANTHROPIC_MODEL=${DEFAULT_ANTHROPIC_MODEL}`,
|
|
4193
|
+
MARKER_END
|
|
4194
|
+
].join("\n");
|
|
4195
|
+
}
|
|
4196
|
+
__name(buildManagedBlock, "buildManagedBlock");
|
|
4197
|
+
function readSafe() {
|
|
4198
|
+
try {
|
|
4199
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
4200
|
+
return fs.readFileSync(CONFIG_FILE, "utf8");
|
|
4201
|
+
}
|
|
4202
|
+
} catch {
|
|
4203
|
+
}
|
|
4204
|
+
return "";
|
|
4205
|
+
}
|
|
4206
|
+
__name(readSafe, "readSafe");
|
|
4207
|
+
function writeManaged(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
4208
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
4209
|
+
const existing = readSafe();
|
|
4210
|
+
const stripped = stripManagedBlock(existing);
|
|
4211
|
+
const block = buildManagedBlock(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI);
|
|
4212
|
+
const userPart = stripped.replace(/\n{3,}/g, "\n\n").replace(/^\n+|\n+$/g, "");
|
|
4213
|
+
const out = userPart ? `${userPart}
|
|
4214
|
+
|
|
4215
|
+
${block}
|
|
4216
|
+
` : `${block}
|
|
4217
|
+
`;
|
|
4218
|
+
fs.writeFileSync(CONFIG_FILE, out, { encoding: "utf8", mode: 384 });
|
|
4219
|
+
try {
|
|
4220
|
+
fs.chmodSync(CONFIG_FILE, 384);
|
|
4221
|
+
} catch {
|
|
4222
|
+
}
|
|
4223
|
+
}
|
|
4224
|
+
__name(writeManaged, "writeManaged");
|
|
4225
|
+
module2.exports = {
|
|
4226
|
+
name: "Qwen Code",
|
|
4227
|
+
id: "qwen-code",
|
|
4228
|
+
// See header comment — npx fallback means the CLI is "always available"
|
|
4229
|
+
// from aionui's perspective, so we always want auto-config to run.
|
|
4230
|
+
checkInstalled() {
|
|
4231
|
+
return true;
|
|
4232
|
+
},
|
|
4233
|
+
isConfigured() {
|
|
4234
|
+
const content = readSafe();
|
|
4235
|
+
return content.includes(MARKER_BEGIN) && content.includes(MARKER_END);
|
|
4236
|
+
},
|
|
4237
|
+
configure(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
4238
|
+
if (!apiKey) {
|
|
4239
|
+
throw new Error("qwen-code.configure: apiKey is required");
|
|
4240
|
+
}
|
|
4241
|
+
writeManaged(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI);
|
|
4242
|
+
return {
|
|
4243
|
+
file: CONFIG_FILE,
|
|
4244
|
+
hot: true
|
|
4245
|
+
};
|
|
4246
|
+
},
|
|
4247
|
+
reset() {
|
|
4248
|
+
if (!fs.existsSync(CONFIG_FILE)) return;
|
|
4249
|
+
const stripped = stripManagedBlock(readSafe());
|
|
4250
|
+
const cleaned = stripped.replace(/^\n+|\n+$/g, "");
|
|
4251
|
+
if (cleaned) {
|
|
4252
|
+
fs.writeFileSync(CONFIG_FILE, cleaned + "\n", "utf8");
|
|
4253
|
+
} else {
|
|
4254
|
+
fs.writeFileSync(CONFIG_FILE, "", "utf8");
|
|
4255
|
+
}
|
|
4256
|
+
},
|
|
4257
|
+
getConfigPath() {
|
|
4258
|
+
return CONFIG_FILE;
|
|
4259
|
+
},
|
|
4260
|
+
hint: "Qwen Code \u901A\u8FC7 ~/.qwen/.env \u8BFB\u53D6 OPENAI_API_KEY / OPENAI_BASE_URL / OPENAI_MODEL\uFF1B\u542F\u52A8\u540E\u7ACB\u5373\u751F\u6548",
|
|
4261
|
+
launchCmd: "qwen",
|
|
4262
|
+
installCmd: "npm install -g @qwen-code/qwen-code",
|
|
4263
|
+
docsUrl: "https://qwenlm.github.io/qwen-code-docs/en/users/configuration/auth/",
|
|
4264
|
+
envVarFormat: "openai",
|
|
4265
|
+
// Exposed for tests / future tooling.
|
|
4266
|
+
__internal: {
|
|
4267
|
+
MARKER_BEGIN,
|
|
4268
|
+
MARKER_END,
|
|
4269
|
+
DEFAULT_OPENAI_MODEL,
|
|
4270
|
+
DEFAULT_ANTHROPIC_MODEL,
|
|
4271
|
+
stripManagedBlock,
|
|
4272
|
+
buildManagedBlock
|
|
4273
|
+
}
|
|
4274
|
+
};
|
|
4275
|
+
}
|
|
4276
|
+
});
|
|
4277
|
+
|
|
4278
|
+
// src/tools/codebuddy.js
|
|
4279
|
+
var require_codebuddy = __commonJS({
|
|
4280
|
+
"src/tools/codebuddy.js"(exports2, module2) {
|
|
4281
|
+
var fs = require("fs");
|
|
4282
|
+
var path = require("path");
|
|
4283
|
+
var os = require("os");
|
|
4284
|
+
var CONFIG_DIR = path.join(os.homedir(), ".codebuddy");
|
|
4285
|
+
var CONFIG_FILE = path.join(CONFIG_DIR, ".env");
|
|
4286
|
+
var MARKER_BEGIN = "# >>> HolySheep BEGIN >>>";
|
|
4287
|
+
var MARKER_END = "# <<< HolySheep END <<<";
|
|
4288
|
+
var DEFAULT_OPENAI_MODEL = "gpt-5.5";
|
|
4289
|
+
var DEFAULT_ANTHROPIC_MODEL = "claude-sonnet-4-6";
|
|
4290
|
+
function escapeRegex(s) {
|
|
4291
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4292
|
+
}
|
|
4293
|
+
__name(escapeRegex, "escapeRegex");
|
|
4294
|
+
function stripManagedBlock(content) {
|
|
4295
|
+
if (!content) return "";
|
|
4296
|
+
const text = String(content).replace(/\r\n/g, "\n");
|
|
4297
|
+
const re = new RegExp(
|
|
4298
|
+
`(?:^|\\n)\\s*${escapeRegex(MARKER_BEGIN)}[\\s\\S]*?${escapeRegex(MARKER_END)}\\s*(?:\\n|$)`,
|
|
4299
|
+
"g"
|
|
4300
|
+
);
|
|
4301
|
+
return text.replace(re, "\n");
|
|
4302
|
+
}
|
|
4303
|
+
__name(stripManagedBlock, "stripManagedBlock");
|
|
4304
|
+
function buildManagedBlock(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
4305
|
+
const cleanOpenAi = String(baseUrlOpenAI || "https://api.holysheep.ai/v1").replace(/\/+$/, "");
|
|
4306
|
+
const cleanAnthropic = String(baseUrlAnthropicNoV1 || "https://api.holysheep.ai").replace(/\/+$/, "");
|
|
4307
|
+
return [
|
|
4308
|
+
MARKER_BEGIN,
|
|
4309
|
+
"# Managed by holysheep-cli \u2014 do not edit between markers.",
|
|
4310
|
+
"# Run `hs reset` to remove this block; user-added env lines outside",
|
|
4311
|
+
"# this block (e.g. CODEBUDDY_INTERNET_ENVIRONMENT) are preserved.",
|
|
4312
|
+
`CODEBUDDY_API_KEY=${apiKey}`,
|
|
4313
|
+
`CODEBUDDY_BASE_URL=${cleanOpenAi}`,
|
|
4314
|
+
`OPENAI_API_KEY=${apiKey}`,
|
|
4315
|
+
`OPENAI_BASE_URL=${cleanOpenAi}`,
|
|
4316
|
+
`OPENAI_MODEL=${DEFAULT_OPENAI_MODEL}`,
|
|
4317
|
+
`ANTHROPIC_BASE_URL=${cleanAnthropic}`,
|
|
4318
|
+
`ANTHROPIC_AUTH_TOKEN=${apiKey}`,
|
|
4319
|
+
`ANTHROPIC_MODEL=${DEFAULT_ANTHROPIC_MODEL}`,
|
|
4320
|
+
MARKER_END
|
|
4321
|
+
].join("\n");
|
|
4322
|
+
}
|
|
4323
|
+
__name(buildManagedBlock, "buildManagedBlock");
|
|
4324
|
+
function readSafe() {
|
|
4325
|
+
try {
|
|
4326
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
4327
|
+
return fs.readFileSync(CONFIG_FILE, "utf8");
|
|
4328
|
+
}
|
|
4329
|
+
} catch {
|
|
4330
|
+
}
|
|
4331
|
+
return "";
|
|
4332
|
+
}
|
|
4333
|
+
__name(readSafe, "readSafe");
|
|
4334
|
+
function writeManaged(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
4335
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
4336
|
+
const existing = readSafe();
|
|
4337
|
+
const stripped = stripManagedBlock(existing);
|
|
4338
|
+
const block = buildManagedBlock(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI);
|
|
4339
|
+
const userPart = stripped.replace(/\n{3,}/g, "\n\n").replace(/^\n+|\n+$/g, "");
|
|
4340
|
+
const out = userPart ? `${userPart}
|
|
4341
|
+
|
|
4342
|
+
${block}
|
|
4343
|
+
` : `${block}
|
|
4344
|
+
`;
|
|
4345
|
+
fs.writeFileSync(CONFIG_FILE, out, { encoding: "utf8", mode: 384 });
|
|
4346
|
+
try {
|
|
4347
|
+
fs.chmodSync(CONFIG_FILE, 384);
|
|
4348
|
+
} catch {
|
|
4349
|
+
}
|
|
4350
|
+
}
|
|
4351
|
+
__name(writeManaged, "writeManaged");
|
|
4352
|
+
module2.exports = {
|
|
4353
|
+
name: "CodeBuddy",
|
|
4354
|
+
id: "codebuddy",
|
|
4355
|
+
checkInstalled() {
|
|
4356
|
+
return true;
|
|
4357
|
+
},
|
|
4358
|
+
isConfigured() {
|
|
4359
|
+
const content = readSafe();
|
|
4360
|
+
return content.includes(MARKER_BEGIN) && content.includes(MARKER_END);
|
|
4361
|
+
},
|
|
4362
|
+
configure(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
4363
|
+
if (!apiKey) {
|
|
4364
|
+
throw new Error("codebuddy.configure: apiKey is required");
|
|
4365
|
+
}
|
|
4366
|
+
writeManaged(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI);
|
|
4367
|
+
return {
|
|
4368
|
+
file: CONFIG_FILE,
|
|
4369
|
+
hot: true
|
|
4370
|
+
};
|
|
4371
|
+
},
|
|
4372
|
+
reset() {
|
|
4373
|
+
if (!fs.existsSync(CONFIG_FILE)) return;
|
|
4374
|
+
const stripped = stripManagedBlock(readSafe());
|
|
4375
|
+
const cleaned = stripped.replace(/^\n+|\n+$/g, "");
|
|
4376
|
+
if (cleaned) {
|
|
4377
|
+
fs.writeFileSync(CONFIG_FILE, cleaned + "\n", "utf8");
|
|
4378
|
+
} else {
|
|
4379
|
+
fs.writeFileSync(CONFIG_FILE, "", "utf8");
|
|
4380
|
+
}
|
|
4381
|
+
},
|
|
4382
|
+
getConfigPath() {
|
|
4383
|
+
return CONFIG_FILE;
|
|
4384
|
+
},
|
|
4385
|
+
hint: "CodeBuddy \u9ED8\u8BA4\u8D70 Tencent SSO\uFF08\u8981\u6C42\u4EA4\u4E92\u5F0F /login\uFF09\u3002HolySheep \u5DF2\u628A API Key/Base URL \u5199\u5230 ~/.codebuddy/.env \u4F5C\u4E3A\u7B2C\u4E09\u65B9\u6A21\u5F0F\u5907\u7528\uFF1B\u8981\u542F\u7528\u7B2C\u4E09\u65B9\u8DEF\u7531\uFF0C\u9700\u8981 export \u8FD9\u4E24\u4E2A\u53D8\u91CF\u8FDB\u5F53\u524D shell\uFF08CodeBuddy \u4E0D\u81EA\u52A8\u8BFB .env\uFF09\uFF1Aset -a; source ~/.codebuddy/.env; set +a; export CODEBUDDY_INTERNET_ENVIRONMENT=third_party\u3002CODEBUDDY_INTERNET_ENVIRONMENT \u6211\u4EEC\u6545\u610F\u4E0D\u5199\u5165 .env\uFF0C\u4EE5\u514D\u8986\u76D6\u4E2D\u56FD\u7248/iOA \u7248\u7528\u6237\u9009\u62E9\u3002",
|
|
4386
|
+
launchCmd: "codebuddy",
|
|
4387
|
+
installCmd: "npm install -g @tencent-ai/codebuddy-code",
|
|
4388
|
+
docsUrl: "https://www.codebuddy.ai/docs/cli/env-vars",
|
|
4389
|
+
envVarFormat: "openai",
|
|
4390
|
+
__internal: {
|
|
4391
|
+
MARKER_BEGIN,
|
|
4392
|
+
MARKER_END,
|
|
4393
|
+
DEFAULT_OPENAI_MODEL,
|
|
4394
|
+
DEFAULT_ANTHROPIC_MODEL,
|
|
4395
|
+
stripManagedBlock,
|
|
4396
|
+
buildManagedBlock
|
|
4397
|
+
}
|
|
4398
|
+
};
|
|
4399
|
+
}
|
|
4400
|
+
});
|
|
4401
|
+
|
|
4153
4402
|
// package.json
|
|
4154
4403
|
var require_package = __commonJS({
|
|
4155
4404
|
"package.json"(exports2, module2) {
|
|
4156
4405
|
module2.exports = {
|
|
4157
4406
|
name: "@simonyea/holysheep-cli",
|
|
4158
|
-
version: "2.1.
|
|
4407
|
+
version: "2.1.77",
|
|
4159
4408
|
description: "Claude Code/Cursor/Cline API relay for China \u2014 \xA51=$1, WeChat/Alipay payment, no credit card, no VPN. One command setup for all AI coding tools.",
|
|
4160
4409
|
scripts: {
|
|
4161
4410
|
build: "node scripts/build.mjs",
|
|
4162
|
-
test: "node tests/droid.test.js && node tests/workspace-store.test.js && node tests/runtime-stale-upgrade.test.js && node tests/hermes.test.js && node tests/preflight.test.js && node tests/opencode-auth-purge.test.js && node tests/shell-winpath.test.js && node tests/openclaw-atomic-write.test.js && node tests/openclaw-disable-auth-direct.test.js && node tests/opencode-default-model.test.js && node tests/paths-bundled.test.js && node tests/aionui-runtime-resources.test.js && node tests/aionui-wrapper-claude-proxy.test.js && node tests/aionui-wrapper-probe.test.js && node tests/aionui-wrapper-proxy-integration.test.js && node tests/aionui-wrapper-all-clis-autoconf.test.js && node tests/aionui-wrapper-env-signal.test.js && node tests/aionui-wrapper-csp-rewrite.test.js && node tests/aionui-wrapper-version-status.test.js && node tests/claude-proxy-daemon.test.js && node tests/claude-proxy-vscode-settings.test.js && node tests/claude-proxy-vscode-env.test.js && node tests/acptypes-patch.test.js && node tests/codex-approval-policy.test.js && node tests/version-check.test.js && node tests/runclaude-missing-binary.test.js && node tests/claude-code-configure-preserve.test.js && node tests/webui-claude-proxy-virtual-tool.test.js && node tests/webui-claude-proxy-ui.test.js && node tests/webui-response-consumer.test.js && node tests/webui-claude-proxy-install-gating.test.js && node tests/claude-code-windows-local-bin.test.js && node tests/qwen-code-config.test.js && node tests/codebuddy-config.test.js",
|
|
4411
|
+
test: "node tests/droid.test.js && node tests/workspace-store.test.js && node tests/runtime-stale-upgrade.test.js && node tests/hermes.test.js && node tests/preflight.test.js && node tests/opencode-auth-purge.test.js && node tests/shell-winpath.test.js && node tests/openclaw-atomic-write.test.js && node tests/openclaw-disable-auth-direct.test.js && node tests/opencode-default-model.test.js && node tests/paths-bundled.test.js && node tests/aionui-runtime-resources.test.js && node tests/aionui-wrapper-claude-proxy.test.js && node tests/aionui-wrapper-probe.test.js && node tests/aionui-wrapper-proxy-integration.test.js && node tests/aionui-wrapper-all-clis-autoconf.test.js && node tests/aionui-wrapper-env-signal.test.js && node tests/aionui-wrapper-csp-rewrite.test.js && node tests/aionui-wrapper-version-status.test.js && node tests/claude-proxy-daemon.test.js && node tests/claude-proxy-vscode-settings.test.js && node tests/claude-proxy-vscode-env.test.js && node tests/acptypes-patch.test.js && node tests/codex-approval-policy.test.js && node tests/version-check.test.js && node tests/runclaude-missing-binary.test.js && node tests/claude-code-configure-preserve.test.js && node tests/webui-claude-proxy-virtual-tool.test.js && node tests/webui-claude-proxy-ui.test.js && node tests/webui-response-consumer.test.js && node tests/webui-claude-proxy-install-gating.test.js && node tests/claude-code-windows-local-bin.test.js && node tests/qwen-code-config.test.js && node tests/codebuddy-config.test.js && node tests/hs-reset-routing.test.js && node tests/setup-auto-install-routing.test.js && node tests/upgrade-routing.test.js",
|
|
4163
4412
|
prepublishOnly: "npm run build && npm test && node scripts/check-tarball-size.js"
|
|
4164
4413
|
},
|
|
4165
4414
|
keywords: [
|
|
@@ -4704,6 +4953,12 @@ var require_tools = __commonJS({
|
|
|
4704
4953
|
require_openclaw(),
|
|
4705
4954
|
// 2.1.14: Hermes Agent (Nous Research) — Python/uv based, macOS/Linux/WSL2 only.
|
|
4706
4955
|
require_hermes(),
|
|
4956
|
+
// [v2.1.76] qwen-code + codebuddy: same npx-fallback model as openclaw, so
|
|
4957
|
+
// that `hs reset` actually wipes ~/.qwen/.env and ~/.codebuddy/.env managed
|
|
4958
|
+
// blocks (otherwise the marker comment in those .env files would point to
|
|
4959
|
+
// a no-op command).
|
|
4960
|
+
require_qwen_code(),
|
|
4961
|
+
require_codebuddy(),
|
|
4707
4962
|
require_env_config()
|
|
4708
4963
|
];
|
|
4709
4964
|
}
|
package/dist/index.js
CHANGED
|
@@ -12,11 +12,11 @@ var require_package = __commonJS({
|
|
|
12
12
|
"package.json"(exports2, module2) {
|
|
13
13
|
module2.exports = {
|
|
14
14
|
name: "@simonyea/holysheep-cli",
|
|
15
|
-
version: "2.1.
|
|
15
|
+
version: "2.1.77",
|
|
16
16
|
description: "Claude Code/Cursor/Cline API relay for China \u2014 \xA51=$1, WeChat/Alipay payment, no credit card, no VPN. One command setup for all AI coding tools.",
|
|
17
17
|
scripts: {
|
|
18
18
|
build: "node scripts/build.mjs",
|
|
19
|
-
test: "node tests/droid.test.js && node tests/workspace-store.test.js && node tests/runtime-stale-upgrade.test.js && node tests/hermes.test.js && node tests/preflight.test.js && node tests/opencode-auth-purge.test.js && node tests/shell-winpath.test.js && node tests/openclaw-atomic-write.test.js && node tests/openclaw-disable-auth-direct.test.js && node tests/opencode-default-model.test.js && node tests/paths-bundled.test.js && node tests/aionui-runtime-resources.test.js && node tests/aionui-wrapper-claude-proxy.test.js && node tests/aionui-wrapper-probe.test.js && node tests/aionui-wrapper-proxy-integration.test.js && node tests/aionui-wrapper-all-clis-autoconf.test.js && node tests/aionui-wrapper-env-signal.test.js && node tests/aionui-wrapper-csp-rewrite.test.js && node tests/aionui-wrapper-version-status.test.js && node tests/claude-proxy-daemon.test.js && node tests/claude-proxy-vscode-settings.test.js && node tests/claude-proxy-vscode-env.test.js && node tests/acptypes-patch.test.js && node tests/codex-approval-policy.test.js && node tests/version-check.test.js && node tests/runclaude-missing-binary.test.js && node tests/claude-code-configure-preserve.test.js && node tests/webui-claude-proxy-virtual-tool.test.js && node tests/webui-claude-proxy-ui.test.js && node tests/webui-response-consumer.test.js && node tests/webui-claude-proxy-install-gating.test.js && node tests/claude-code-windows-local-bin.test.js && node tests/qwen-code-config.test.js && node tests/codebuddy-config.test.js",
|
|
19
|
+
test: "node tests/droid.test.js && node tests/workspace-store.test.js && node tests/runtime-stale-upgrade.test.js && node tests/hermes.test.js && node tests/preflight.test.js && node tests/opencode-auth-purge.test.js && node tests/shell-winpath.test.js && node tests/openclaw-atomic-write.test.js && node tests/openclaw-disable-auth-direct.test.js && node tests/opencode-default-model.test.js && node tests/paths-bundled.test.js && node tests/aionui-runtime-resources.test.js && node tests/aionui-wrapper-claude-proxy.test.js && node tests/aionui-wrapper-probe.test.js && node tests/aionui-wrapper-proxy-integration.test.js && node tests/aionui-wrapper-all-clis-autoconf.test.js && node tests/aionui-wrapper-env-signal.test.js && node tests/aionui-wrapper-csp-rewrite.test.js && node tests/aionui-wrapper-version-status.test.js && node tests/claude-proxy-daemon.test.js && node tests/claude-proxy-vscode-settings.test.js && node tests/claude-proxy-vscode-env.test.js && node tests/acptypes-patch.test.js && node tests/codex-approval-policy.test.js && node tests/version-check.test.js && node tests/runclaude-missing-binary.test.js && node tests/claude-code-configure-preserve.test.js && node tests/webui-claude-proxy-virtual-tool.test.js && node tests/webui-claude-proxy-ui.test.js && node tests/webui-response-consumer.test.js && node tests/webui-claude-proxy-install-gating.test.js && node tests/claude-code-windows-local-bin.test.js && node tests/qwen-code-config.test.js && node tests/codebuddy-config.test.js && node tests/hs-reset-routing.test.js && node tests/setup-auto-install-routing.test.js && node tests/upgrade-routing.test.js",
|
|
20
20
|
prepublishOnly: "npm run build && npm test && node scripts/check-tarball-size.js"
|
|
21
21
|
},
|
|
22
22
|
keywords: [
|
|
@@ -4718,6 +4718,255 @@ providers:
|
|
|
4718
4718
|
}
|
|
4719
4719
|
});
|
|
4720
4720
|
|
|
4721
|
+
// src/tools/qwen-code.js
|
|
4722
|
+
var require_qwen_code = __commonJS({
|
|
4723
|
+
"src/tools/qwen-code.js"(exports2, module2) {
|
|
4724
|
+
var fs = require("fs");
|
|
4725
|
+
var path = require("path");
|
|
4726
|
+
var os = require("os");
|
|
4727
|
+
var CONFIG_DIR = path.join(os.homedir(), ".qwen");
|
|
4728
|
+
var CONFIG_FILE = path.join(CONFIG_DIR, ".env");
|
|
4729
|
+
var MARKER_BEGIN = "# >>> HolySheep BEGIN >>>";
|
|
4730
|
+
var MARKER_END = "# <<< HolySheep END <<<";
|
|
4731
|
+
var DEFAULT_OPENAI_MODEL = "gpt-5.5";
|
|
4732
|
+
var DEFAULT_ANTHROPIC_MODEL = "claude-sonnet-4-6";
|
|
4733
|
+
function stripManagedBlock(content) {
|
|
4734
|
+
if (!content) return "";
|
|
4735
|
+
const text = String(content).replace(/\r\n/g, "\n");
|
|
4736
|
+
const re = new RegExp(
|
|
4737
|
+
`(?:^|\\n)\\s*${escapeRegex(MARKER_BEGIN)}[\\s\\S]*?${escapeRegex(MARKER_END)}\\s*(?:\\n|$)`,
|
|
4738
|
+
"g"
|
|
4739
|
+
);
|
|
4740
|
+
return text.replace(re, "\n");
|
|
4741
|
+
}
|
|
4742
|
+
__name(stripManagedBlock, "stripManagedBlock");
|
|
4743
|
+
function escapeRegex(s) {
|
|
4744
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4745
|
+
}
|
|
4746
|
+
__name(escapeRegex, "escapeRegex");
|
|
4747
|
+
function buildManagedBlock(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
4748
|
+
const cleanOpenAi = String(baseUrlOpenAI || "https://api.holysheep.ai/v1").replace(/\/+$/, "");
|
|
4749
|
+
const cleanAnthropic = String(baseUrlAnthropicNoV1 || "https://api.holysheep.ai").replace(/\/+$/, "");
|
|
4750
|
+
return [
|
|
4751
|
+
MARKER_BEGIN,
|
|
4752
|
+
"# Managed by holysheep-cli \u2014 do not edit between markers.",
|
|
4753
|
+
"# Run `hs reset` to remove this block; user-added env lines outside",
|
|
4754
|
+
"# this block are preserved.",
|
|
4755
|
+
`OPENAI_API_KEY=${apiKey}`,
|
|
4756
|
+
`OPENAI_BASE_URL=${cleanOpenAi}`,
|
|
4757
|
+
`OPENAI_MODEL=${DEFAULT_OPENAI_MODEL}`,
|
|
4758
|
+
`ANTHROPIC_BASE_URL=${cleanAnthropic}`,
|
|
4759
|
+
`ANTHROPIC_AUTH_TOKEN=${apiKey}`,
|
|
4760
|
+
`ANTHROPIC_MODEL=${DEFAULT_ANTHROPIC_MODEL}`,
|
|
4761
|
+
MARKER_END
|
|
4762
|
+
].join("\n");
|
|
4763
|
+
}
|
|
4764
|
+
__name(buildManagedBlock, "buildManagedBlock");
|
|
4765
|
+
function readSafe() {
|
|
4766
|
+
try {
|
|
4767
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
4768
|
+
return fs.readFileSync(CONFIG_FILE, "utf8");
|
|
4769
|
+
}
|
|
4770
|
+
} catch {
|
|
4771
|
+
}
|
|
4772
|
+
return "";
|
|
4773
|
+
}
|
|
4774
|
+
__name(readSafe, "readSafe");
|
|
4775
|
+
function writeManaged(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
4776
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
4777
|
+
const existing = readSafe();
|
|
4778
|
+
const stripped = stripManagedBlock(existing);
|
|
4779
|
+
const block = buildManagedBlock(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI);
|
|
4780
|
+
const userPart = stripped.replace(/\n{3,}/g, "\n\n").replace(/^\n+|\n+$/g, "");
|
|
4781
|
+
const out = userPart ? `${userPart}
|
|
4782
|
+
|
|
4783
|
+
${block}
|
|
4784
|
+
` : `${block}
|
|
4785
|
+
`;
|
|
4786
|
+
fs.writeFileSync(CONFIG_FILE, out, { encoding: "utf8", mode: 384 });
|
|
4787
|
+
try {
|
|
4788
|
+
fs.chmodSync(CONFIG_FILE, 384);
|
|
4789
|
+
} catch {
|
|
4790
|
+
}
|
|
4791
|
+
}
|
|
4792
|
+
__name(writeManaged, "writeManaged");
|
|
4793
|
+
module2.exports = {
|
|
4794
|
+
name: "Qwen Code",
|
|
4795
|
+
id: "qwen-code",
|
|
4796
|
+
// See header comment — npx fallback means the CLI is "always available"
|
|
4797
|
+
// from aionui's perspective, so we always want auto-config to run.
|
|
4798
|
+
checkInstalled() {
|
|
4799
|
+
return true;
|
|
4800
|
+
},
|
|
4801
|
+
isConfigured() {
|
|
4802
|
+
const content = readSafe();
|
|
4803
|
+
return content.includes(MARKER_BEGIN) && content.includes(MARKER_END);
|
|
4804
|
+
},
|
|
4805
|
+
configure(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
4806
|
+
if (!apiKey) {
|
|
4807
|
+
throw new Error("qwen-code.configure: apiKey is required");
|
|
4808
|
+
}
|
|
4809
|
+
writeManaged(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI);
|
|
4810
|
+
return {
|
|
4811
|
+
file: CONFIG_FILE,
|
|
4812
|
+
hot: true
|
|
4813
|
+
};
|
|
4814
|
+
},
|
|
4815
|
+
reset() {
|
|
4816
|
+
if (!fs.existsSync(CONFIG_FILE)) return;
|
|
4817
|
+
const stripped = stripManagedBlock(readSafe());
|
|
4818
|
+
const cleaned = stripped.replace(/^\n+|\n+$/g, "");
|
|
4819
|
+
if (cleaned) {
|
|
4820
|
+
fs.writeFileSync(CONFIG_FILE, cleaned + "\n", "utf8");
|
|
4821
|
+
} else {
|
|
4822
|
+
fs.writeFileSync(CONFIG_FILE, "", "utf8");
|
|
4823
|
+
}
|
|
4824
|
+
},
|
|
4825
|
+
getConfigPath() {
|
|
4826
|
+
return CONFIG_FILE;
|
|
4827
|
+
},
|
|
4828
|
+
hint: "Qwen Code \u901A\u8FC7 ~/.qwen/.env \u8BFB\u53D6 OPENAI_API_KEY / OPENAI_BASE_URL / OPENAI_MODEL\uFF1B\u542F\u52A8\u540E\u7ACB\u5373\u751F\u6548",
|
|
4829
|
+
launchCmd: "qwen",
|
|
4830
|
+
installCmd: "npm install -g @qwen-code/qwen-code",
|
|
4831
|
+
docsUrl: "https://qwenlm.github.io/qwen-code-docs/en/users/configuration/auth/",
|
|
4832
|
+
envVarFormat: "openai",
|
|
4833
|
+
// Exposed for tests / future tooling.
|
|
4834
|
+
__internal: {
|
|
4835
|
+
MARKER_BEGIN,
|
|
4836
|
+
MARKER_END,
|
|
4837
|
+
DEFAULT_OPENAI_MODEL,
|
|
4838
|
+
DEFAULT_ANTHROPIC_MODEL,
|
|
4839
|
+
stripManagedBlock,
|
|
4840
|
+
buildManagedBlock
|
|
4841
|
+
}
|
|
4842
|
+
};
|
|
4843
|
+
}
|
|
4844
|
+
});
|
|
4845
|
+
|
|
4846
|
+
// src/tools/codebuddy.js
|
|
4847
|
+
var require_codebuddy = __commonJS({
|
|
4848
|
+
"src/tools/codebuddy.js"(exports2, module2) {
|
|
4849
|
+
var fs = require("fs");
|
|
4850
|
+
var path = require("path");
|
|
4851
|
+
var os = require("os");
|
|
4852
|
+
var CONFIG_DIR = path.join(os.homedir(), ".codebuddy");
|
|
4853
|
+
var CONFIG_FILE = path.join(CONFIG_DIR, ".env");
|
|
4854
|
+
var MARKER_BEGIN = "# >>> HolySheep BEGIN >>>";
|
|
4855
|
+
var MARKER_END = "# <<< HolySheep END <<<";
|
|
4856
|
+
var DEFAULT_OPENAI_MODEL = "gpt-5.5";
|
|
4857
|
+
var DEFAULT_ANTHROPIC_MODEL = "claude-sonnet-4-6";
|
|
4858
|
+
function escapeRegex(s) {
|
|
4859
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4860
|
+
}
|
|
4861
|
+
__name(escapeRegex, "escapeRegex");
|
|
4862
|
+
function stripManagedBlock(content) {
|
|
4863
|
+
if (!content) return "";
|
|
4864
|
+
const text = String(content).replace(/\r\n/g, "\n");
|
|
4865
|
+
const re = new RegExp(
|
|
4866
|
+
`(?:^|\\n)\\s*${escapeRegex(MARKER_BEGIN)}[\\s\\S]*?${escapeRegex(MARKER_END)}\\s*(?:\\n|$)`,
|
|
4867
|
+
"g"
|
|
4868
|
+
);
|
|
4869
|
+
return text.replace(re, "\n");
|
|
4870
|
+
}
|
|
4871
|
+
__name(stripManagedBlock, "stripManagedBlock");
|
|
4872
|
+
function buildManagedBlock(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
4873
|
+
const cleanOpenAi = String(baseUrlOpenAI || "https://api.holysheep.ai/v1").replace(/\/+$/, "");
|
|
4874
|
+
const cleanAnthropic = String(baseUrlAnthropicNoV1 || "https://api.holysheep.ai").replace(/\/+$/, "");
|
|
4875
|
+
return [
|
|
4876
|
+
MARKER_BEGIN,
|
|
4877
|
+
"# Managed by holysheep-cli \u2014 do not edit between markers.",
|
|
4878
|
+
"# Run `hs reset` to remove this block; user-added env lines outside",
|
|
4879
|
+
"# this block (e.g. CODEBUDDY_INTERNET_ENVIRONMENT) are preserved.",
|
|
4880
|
+
`CODEBUDDY_API_KEY=${apiKey}`,
|
|
4881
|
+
`CODEBUDDY_BASE_URL=${cleanOpenAi}`,
|
|
4882
|
+
`OPENAI_API_KEY=${apiKey}`,
|
|
4883
|
+
`OPENAI_BASE_URL=${cleanOpenAi}`,
|
|
4884
|
+
`OPENAI_MODEL=${DEFAULT_OPENAI_MODEL}`,
|
|
4885
|
+
`ANTHROPIC_BASE_URL=${cleanAnthropic}`,
|
|
4886
|
+
`ANTHROPIC_AUTH_TOKEN=${apiKey}`,
|
|
4887
|
+
`ANTHROPIC_MODEL=${DEFAULT_ANTHROPIC_MODEL}`,
|
|
4888
|
+
MARKER_END
|
|
4889
|
+
].join("\n");
|
|
4890
|
+
}
|
|
4891
|
+
__name(buildManagedBlock, "buildManagedBlock");
|
|
4892
|
+
function readSafe() {
|
|
4893
|
+
try {
|
|
4894
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
4895
|
+
return fs.readFileSync(CONFIG_FILE, "utf8");
|
|
4896
|
+
}
|
|
4897
|
+
} catch {
|
|
4898
|
+
}
|
|
4899
|
+
return "";
|
|
4900
|
+
}
|
|
4901
|
+
__name(readSafe, "readSafe");
|
|
4902
|
+
function writeManaged(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
4903
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
4904
|
+
const existing = readSafe();
|
|
4905
|
+
const stripped = stripManagedBlock(existing);
|
|
4906
|
+
const block = buildManagedBlock(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI);
|
|
4907
|
+
const userPart = stripped.replace(/\n{3,}/g, "\n\n").replace(/^\n+|\n+$/g, "");
|
|
4908
|
+
const out = userPart ? `${userPart}
|
|
4909
|
+
|
|
4910
|
+
${block}
|
|
4911
|
+
` : `${block}
|
|
4912
|
+
`;
|
|
4913
|
+
fs.writeFileSync(CONFIG_FILE, out, { encoding: "utf8", mode: 384 });
|
|
4914
|
+
try {
|
|
4915
|
+
fs.chmodSync(CONFIG_FILE, 384);
|
|
4916
|
+
} catch {
|
|
4917
|
+
}
|
|
4918
|
+
}
|
|
4919
|
+
__name(writeManaged, "writeManaged");
|
|
4920
|
+
module2.exports = {
|
|
4921
|
+
name: "CodeBuddy",
|
|
4922
|
+
id: "codebuddy",
|
|
4923
|
+
checkInstalled() {
|
|
4924
|
+
return true;
|
|
4925
|
+
},
|
|
4926
|
+
isConfigured() {
|
|
4927
|
+
const content = readSafe();
|
|
4928
|
+
return content.includes(MARKER_BEGIN) && content.includes(MARKER_END);
|
|
4929
|
+
},
|
|
4930
|
+
configure(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
4931
|
+
if (!apiKey) {
|
|
4932
|
+
throw new Error("codebuddy.configure: apiKey is required");
|
|
4933
|
+
}
|
|
4934
|
+
writeManaged(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI);
|
|
4935
|
+
return {
|
|
4936
|
+
file: CONFIG_FILE,
|
|
4937
|
+
hot: true
|
|
4938
|
+
};
|
|
4939
|
+
},
|
|
4940
|
+
reset() {
|
|
4941
|
+
if (!fs.existsSync(CONFIG_FILE)) return;
|
|
4942
|
+
const stripped = stripManagedBlock(readSafe());
|
|
4943
|
+
const cleaned = stripped.replace(/^\n+|\n+$/g, "");
|
|
4944
|
+
if (cleaned) {
|
|
4945
|
+
fs.writeFileSync(CONFIG_FILE, cleaned + "\n", "utf8");
|
|
4946
|
+
} else {
|
|
4947
|
+
fs.writeFileSync(CONFIG_FILE, "", "utf8");
|
|
4948
|
+
}
|
|
4949
|
+
},
|
|
4950
|
+
getConfigPath() {
|
|
4951
|
+
return CONFIG_FILE;
|
|
4952
|
+
},
|
|
4953
|
+
hint: "CodeBuddy \u9ED8\u8BA4\u8D70 Tencent SSO\uFF08\u8981\u6C42\u4EA4\u4E92\u5F0F /login\uFF09\u3002HolySheep \u5DF2\u628A API Key/Base URL \u5199\u5230 ~/.codebuddy/.env \u4F5C\u4E3A\u7B2C\u4E09\u65B9\u6A21\u5F0F\u5907\u7528\uFF1B\u8981\u542F\u7528\u7B2C\u4E09\u65B9\u8DEF\u7531\uFF0C\u9700\u8981 export \u8FD9\u4E24\u4E2A\u53D8\u91CF\u8FDB\u5F53\u524D shell\uFF08CodeBuddy \u4E0D\u81EA\u52A8\u8BFB .env\uFF09\uFF1Aset -a; source ~/.codebuddy/.env; set +a; export CODEBUDDY_INTERNET_ENVIRONMENT=third_party\u3002CODEBUDDY_INTERNET_ENVIRONMENT \u6211\u4EEC\u6545\u610F\u4E0D\u5199\u5165 .env\uFF0C\u4EE5\u514D\u8986\u76D6\u4E2D\u56FD\u7248/iOA \u7248\u7528\u6237\u9009\u62E9\u3002",
|
|
4954
|
+
launchCmd: "codebuddy",
|
|
4955
|
+
installCmd: "npm install -g @tencent-ai/codebuddy-code",
|
|
4956
|
+
docsUrl: "https://www.codebuddy.ai/docs/cli/env-vars",
|
|
4957
|
+
envVarFormat: "openai",
|
|
4958
|
+
__internal: {
|
|
4959
|
+
MARKER_BEGIN,
|
|
4960
|
+
MARKER_END,
|
|
4961
|
+
DEFAULT_OPENAI_MODEL,
|
|
4962
|
+
DEFAULT_ANTHROPIC_MODEL,
|
|
4963
|
+
stripManagedBlock,
|
|
4964
|
+
buildManagedBlock
|
|
4965
|
+
}
|
|
4966
|
+
};
|
|
4967
|
+
}
|
|
4968
|
+
});
|
|
4969
|
+
|
|
4721
4970
|
// src/tools/env-config.js
|
|
4722
4971
|
var require_env_config = __commonJS({
|
|
4723
4972
|
"src/tools/env-config.js"(exports2, module2) {
|
|
@@ -4886,6 +5135,12 @@ var require_tools = __commonJS({
|
|
|
4886
5135
|
require_openclaw(),
|
|
4887
5136
|
// 2.1.14: Hermes Agent (Nous Research) — Python/uv based, macOS/Linux/WSL2 only.
|
|
4888
5137
|
require_hermes(),
|
|
5138
|
+
// [v2.1.76] qwen-code + codebuddy: same npx-fallback model as openclaw, so
|
|
5139
|
+
// that `hs reset` actually wipes ~/.qwen/.env and ~/.codebuddy/.env managed
|
|
5140
|
+
// blocks (otherwise the marker comment in those .env files would point to
|
|
5141
|
+
// a no-op command).
|
|
5142
|
+
require_qwen_code(),
|
|
5143
|
+
require_codebuddy(),
|
|
4889
5144
|
require_env_config()
|
|
4890
5145
|
];
|
|
4891
5146
|
}
|
|
@@ -4976,7 +5231,13 @@ var require_setup = __commonJS({
|
|
|
4976
5231
|
"gemini-cli": { cmd: "npm install -g @google/gemini-cli", mgr: "npm" },
|
|
4977
5232
|
"opencode": { cmd: "npm install -g opencode-ai", mgr: "npm" },
|
|
4978
5233
|
"openclaw": { cmd: "npm install -g openclaw@latest", mgr: "npm" },
|
|
4979
|
-
"aider": { cmd: "pip install aider-chat", mgr: "pip" }
|
|
5234
|
+
"aider": { cmd: "pip install aider-chat", mgr: "pip" },
|
|
5235
|
+
// [v2.1.77] Qwen Code + CodeBuddy: hs setup install entry. Adapter
|
|
5236
|
+
// checkInstalled() is hardcoded true (npx fallback for AionUI), so the
|
|
5237
|
+
// setup flow needs to detect real PATH separately. canAutoInstall(t.id)
|
|
5238
|
+
// already keys off this dict — adding here is enough.
|
|
5239
|
+
"qwen-code": { cmd: "npm install -g @qwen-code/qwen-code", mgr: "npm" },
|
|
5240
|
+
"codebuddy": { cmd: "npm install -g @tencent-ai/codebuddy-code", mgr: "npm" }
|
|
4980
5241
|
};
|
|
4981
5242
|
function getWindowsImmediateLaunchCmd(tool) {
|
|
4982
5243
|
if (process.platform !== "win32" || !(tool == null ? void 0 : tool.launchCmd)) return null;
|
|
@@ -5699,6 +5960,26 @@ var require_upgrade = __commonJS({
|
|
|
5699
5960
|
versionCmd: "gemini --version",
|
|
5700
5961
|
npmPkg: "@google/gemini-cli",
|
|
5701
5962
|
installCmd: "npm install -g @google/gemini-cli@latest"
|
|
5963
|
+
},
|
|
5964
|
+
// [v2.1.77] Qwen Code: adapter checkInstalled() is hardcoded true (npx
|
|
5965
|
+
// fallback for AionUI), so we must NOT use that here — upgrade uses
|
|
5966
|
+
// commandExists(tool.command) below, which checks real PATH. Same for
|
|
5967
|
+
// CodeBuddy.
|
|
5968
|
+
{
|
|
5969
|
+
name: "Qwen Code",
|
|
5970
|
+
id: "qwen-code",
|
|
5971
|
+
command: "qwen",
|
|
5972
|
+
versionCmd: "qwen --version",
|
|
5973
|
+
npmPkg: "@qwen-code/qwen-code",
|
|
5974
|
+
installCmd: "npm install -g @qwen-code/qwen-code@latest"
|
|
5975
|
+
},
|
|
5976
|
+
{
|
|
5977
|
+
name: "CodeBuddy",
|
|
5978
|
+
id: "codebuddy",
|
|
5979
|
+
command: "codebuddy",
|
|
5980
|
+
versionCmd: "codebuddy --version",
|
|
5981
|
+
npmPkg: "@tencent-ai/codebuddy-code",
|
|
5982
|
+
installCmd: "npm install -g @tencent-ai/codebuddy-code@latest"
|
|
5702
5983
|
}
|
|
5703
5984
|
];
|
|
5704
5985
|
function getLocalVersion(tool) {
|
|
@@ -6550,255 +6831,6 @@ var require_gemini_cli = __commonJS({
|
|
|
6550
6831
|
}
|
|
6551
6832
|
});
|
|
6552
6833
|
|
|
6553
|
-
// src/tools/qwen-code.js
|
|
6554
|
-
var require_qwen_code = __commonJS({
|
|
6555
|
-
"src/tools/qwen-code.js"(exports2, module2) {
|
|
6556
|
-
var fs = require("fs");
|
|
6557
|
-
var path = require("path");
|
|
6558
|
-
var os = require("os");
|
|
6559
|
-
var CONFIG_DIR = path.join(os.homedir(), ".qwen");
|
|
6560
|
-
var CONFIG_FILE = path.join(CONFIG_DIR, ".env");
|
|
6561
|
-
var MARKER_BEGIN = "# >>> HolySheep BEGIN >>>";
|
|
6562
|
-
var MARKER_END = "# <<< HolySheep END <<<";
|
|
6563
|
-
var DEFAULT_OPENAI_MODEL = "gpt-5.5";
|
|
6564
|
-
var DEFAULT_ANTHROPIC_MODEL = "claude-sonnet-4-6";
|
|
6565
|
-
function stripManagedBlock(content) {
|
|
6566
|
-
if (!content) return "";
|
|
6567
|
-
const text = String(content).replace(/\r\n/g, "\n");
|
|
6568
|
-
const re = new RegExp(
|
|
6569
|
-
`(?:^|\\n)\\s*${escapeRegex(MARKER_BEGIN)}[\\s\\S]*?${escapeRegex(MARKER_END)}\\s*(?:\\n|$)`,
|
|
6570
|
-
"g"
|
|
6571
|
-
);
|
|
6572
|
-
return text.replace(re, "\n");
|
|
6573
|
-
}
|
|
6574
|
-
__name(stripManagedBlock, "stripManagedBlock");
|
|
6575
|
-
function escapeRegex(s) {
|
|
6576
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6577
|
-
}
|
|
6578
|
-
__name(escapeRegex, "escapeRegex");
|
|
6579
|
-
function buildManagedBlock(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
6580
|
-
const cleanOpenAi = String(baseUrlOpenAI || "https://api.holysheep.ai/v1").replace(/\/+$/, "");
|
|
6581
|
-
const cleanAnthropic = String(baseUrlAnthropicNoV1 || "https://api.holysheep.ai").replace(/\/+$/, "");
|
|
6582
|
-
return [
|
|
6583
|
-
MARKER_BEGIN,
|
|
6584
|
-
"# Managed by holysheep-cli \u2014 do not edit between markers.",
|
|
6585
|
-
"# Run `hs reset qwen-code` to remove this block; user-added env lines",
|
|
6586
|
-
"# outside this block are preserved.",
|
|
6587
|
-
`OPENAI_API_KEY=${apiKey}`,
|
|
6588
|
-
`OPENAI_BASE_URL=${cleanOpenAi}`,
|
|
6589
|
-
`OPENAI_MODEL=${DEFAULT_OPENAI_MODEL}`,
|
|
6590
|
-
`ANTHROPIC_BASE_URL=${cleanAnthropic}`,
|
|
6591
|
-
`ANTHROPIC_AUTH_TOKEN=${apiKey}`,
|
|
6592
|
-
`ANTHROPIC_MODEL=${DEFAULT_ANTHROPIC_MODEL}`,
|
|
6593
|
-
MARKER_END
|
|
6594
|
-
].join("\n");
|
|
6595
|
-
}
|
|
6596
|
-
__name(buildManagedBlock, "buildManagedBlock");
|
|
6597
|
-
function readSafe() {
|
|
6598
|
-
try {
|
|
6599
|
-
if (fs.existsSync(CONFIG_FILE)) {
|
|
6600
|
-
return fs.readFileSync(CONFIG_FILE, "utf8");
|
|
6601
|
-
}
|
|
6602
|
-
} catch {
|
|
6603
|
-
}
|
|
6604
|
-
return "";
|
|
6605
|
-
}
|
|
6606
|
-
__name(readSafe, "readSafe");
|
|
6607
|
-
function writeManaged(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
6608
|
-
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
6609
|
-
const existing = readSafe();
|
|
6610
|
-
const stripped = stripManagedBlock(existing);
|
|
6611
|
-
const block = buildManagedBlock(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI);
|
|
6612
|
-
const userPart = stripped.replace(/\n{3,}/g, "\n\n").replace(/^\n+|\n+$/g, "");
|
|
6613
|
-
const out = userPart ? `${userPart}
|
|
6614
|
-
|
|
6615
|
-
${block}
|
|
6616
|
-
` : `${block}
|
|
6617
|
-
`;
|
|
6618
|
-
fs.writeFileSync(CONFIG_FILE, out, { encoding: "utf8", mode: 384 });
|
|
6619
|
-
try {
|
|
6620
|
-
fs.chmodSync(CONFIG_FILE, 384);
|
|
6621
|
-
} catch {
|
|
6622
|
-
}
|
|
6623
|
-
}
|
|
6624
|
-
__name(writeManaged, "writeManaged");
|
|
6625
|
-
module2.exports = {
|
|
6626
|
-
name: "Qwen Code",
|
|
6627
|
-
id: "qwen-code",
|
|
6628
|
-
// See header comment — npx fallback means the CLI is "always available"
|
|
6629
|
-
// from aionui's perspective, so we always want auto-config to run.
|
|
6630
|
-
checkInstalled() {
|
|
6631
|
-
return true;
|
|
6632
|
-
},
|
|
6633
|
-
isConfigured() {
|
|
6634
|
-
const content = readSafe();
|
|
6635
|
-
return content.includes(MARKER_BEGIN) && content.includes(MARKER_END);
|
|
6636
|
-
},
|
|
6637
|
-
configure(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
6638
|
-
if (!apiKey) {
|
|
6639
|
-
throw new Error("qwen-code.configure: apiKey is required");
|
|
6640
|
-
}
|
|
6641
|
-
writeManaged(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI);
|
|
6642
|
-
return {
|
|
6643
|
-
file: CONFIG_FILE,
|
|
6644
|
-
hot: true
|
|
6645
|
-
};
|
|
6646
|
-
},
|
|
6647
|
-
reset() {
|
|
6648
|
-
if (!fs.existsSync(CONFIG_FILE)) return;
|
|
6649
|
-
const stripped = stripManagedBlock(readSafe());
|
|
6650
|
-
const cleaned = stripped.replace(/^\n+|\n+$/g, "");
|
|
6651
|
-
if (cleaned) {
|
|
6652
|
-
fs.writeFileSync(CONFIG_FILE, cleaned + "\n", "utf8");
|
|
6653
|
-
} else {
|
|
6654
|
-
fs.writeFileSync(CONFIG_FILE, "", "utf8");
|
|
6655
|
-
}
|
|
6656
|
-
},
|
|
6657
|
-
getConfigPath() {
|
|
6658
|
-
return CONFIG_FILE;
|
|
6659
|
-
},
|
|
6660
|
-
hint: "Qwen Code \u901A\u8FC7 ~/.qwen/.env \u8BFB\u53D6 OPENAI_API_KEY / OPENAI_BASE_URL / OPENAI_MODEL\uFF1B\u542F\u52A8\u540E\u7ACB\u5373\u751F\u6548",
|
|
6661
|
-
launchCmd: "qwen",
|
|
6662
|
-
installCmd: "npm install -g @qwen-code/qwen-code",
|
|
6663
|
-
docsUrl: "https://qwenlm.github.io/qwen-code-docs/en/users/configuration/auth/",
|
|
6664
|
-
envVarFormat: "openai",
|
|
6665
|
-
// Exposed for tests / future tooling.
|
|
6666
|
-
__internal: {
|
|
6667
|
-
MARKER_BEGIN,
|
|
6668
|
-
MARKER_END,
|
|
6669
|
-
DEFAULT_OPENAI_MODEL,
|
|
6670
|
-
DEFAULT_ANTHROPIC_MODEL,
|
|
6671
|
-
stripManagedBlock,
|
|
6672
|
-
buildManagedBlock
|
|
6673
|
-
}
|
|
6674
|
-
};
|
|
6675
|
-
}
|
|
6676
|
-
});
|
|
6677
|
-
|
|
6678
|
-
// src/tools/codebuddy.js
|
|
6679
|
-
var require_codebuddy = __commonJS({
|
|
6680
|
-
"src/tools/codebuddy.js"(exports2, module2) {
|
|
6681
|
-
var fs = require("fs");
|
|
6682
|
-
var path = require("path");
|
|
6683
|
-
var os = require("os");
|
|
6684
|
-
var CONFIG_DIR = path.join(os.homedir(), ".codebuddy");
|
|
6685
|
-
var CONFIG_FILE = path.join(CONFIG_DIR, ".env");
|
|
6686
|
-
var MARKER_BEGIN = "# >>> HolySheep BEGIN >>>";
|
|
6687
|
-
var MARKER_END = "# <<< HolySheep END <<<";
|
|
6688
|
-
var DEFAULT_OPENAI_MODEL = "gpt-5.5";
|
|
6689
|
-
var DEFAULT_ANTHROPIC_MODEL = "claude-sonnet-4-6";
|
|
6690
|
-
function escapeRegex(s) {
|
|
6691
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6692
|
-
}
|
|
6693
|
-
__name(escapeRegex, "escapeRegex");
|
|
6694
|
-
function stripManagedBlock(content) {
|
|
6695
|
-
if (!content) return "";
|
|
6696
|
-
const text = String(content).replace(/\r\n/g, "\n");
|
|
6697
|
-
const re = new RegExp(
|
|
6698
|
-
`(?:^|\\n)\\s*${escapeRegex(MARKER_BEGIN)}[\\s\\S]*?${escapeRegex(MARKER_END)}\\s*(?:\\n|$)`,
|
|
6699
|
-
"g"
|
|
6700
|
-
);
|
|
6701
|
-
return text.replace(re, "\n");
|
|
6702
|
-
}
|
|
6703
|
-
__name(stripManagedBlock, "stripManagedBlock");
|
|
6704
|
-
function buildManagedBlock(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
6705
|
-
const cleanOpenAi = String(baseUrlOpenAI || "https://api.holysheep.ai/v1").replace(/\/+$/, "");
|
|
6706
|
-
const cleanAnthropic = String(baseUrlAnthropicNoV1 || "https://api.holysheep.ai").replace(/\/+$/, "");
|
|
6707
|
-
return [
|
|
6708
|
-
MARKER_BEGIN,
|
|
6709
|
-
"# Managed by holysheep-cli \u2014 do not edit between markers.",
|
|
6710
|
-
"# Run `hs reset codebuddy` to remove this block; user-added env lines",
|
|
6711
|
-
"# outside this block (e.g. CODEBUDDY_INTERNET_ENVIRONMENT) are preserved.",
|
|
6712
|
-
`CODEBUDDY_API_KEY=${apiKey}`,
|
|
6713
|
-
`CODEBUDDY_BASE_URL=${cleanOpenAi}`,
|
|
6714
|
-
`OPENAI_API_KEY=${apiKey}`,
|
|
6715
|
-
`OPENAI_BASE_URL=${cleanOpenAi}`,
|
|
6716
|
-
`OPENAI_MODEL=${DEFAULT_OPENAI_MODEL}`,
|
|
6717
|
-
`ANTHROPIC_BASE_URL=${cleanAnthropic}`,
|
|
6718
|
-
`ANTHROPIC_AUTH_TOKEN=${apiKey}`,
|
|
6719
|
-
`ANTHROPIC_MODEL=${DEFAULT_ANTHROPIC_MODEL}`,
|
|
6720
|
-
MARKER_END
|
|
6721
|
-
].join("\n");
|
|
6722
|
-
}
|
|
6723
|
-
__name(buildManagedBlock, "buildManagedBlock");
|
|
6724
|
-
function readSafe() {
|
|
6725
|
-
try {
|
|
6726
|
-
if (fs.existsSync(CONFIG_FILE)) {
|
|
6727
|
-
return fs.readFileSync(CONFIG_FILE, "utf8");
|
|
6728
|
-
}
|
|
6729
|
-
} catch {
|
|
6730
|
-
}
|
|
6731
|
-
return "";
|
|
6732
|
-
}
|
|
6733
|
-
__name(readSafe, "readSafe");
|
|
6734
|
-
function writeManaged(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
6735
|
-
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
6736
|
-
const existing = readSafe();
|
|
6737
|
-
const stripped = stripManagedBlock(existing);
|
|
6738
|
-
const block = buildManagedBlock(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI);
|
|
6739
|
-
const userPart = stripped.replace(/\n{3,}/g, "\n\n").replace(/^\n+|\n+$/g, "");
|
|
6740
|
-
const out = userPart ? `${userPart}
|
|
6741
|
-
|
|
6742
|
-
${block}
|
|
6743
|
-
` : `${block}
|
|
6744
|
-
`;
|
|
6745
|
-
fs.writeFileSync(CONFIG_FILE, out, { encoding: "utf8", mode: 384 });
|
|
6746
|
-
try {
|
|
6747
|
-
fs.chmodSync(CONFIG_FILE, 384);
|
|
6748
|
-
} catch {
|
|
6749
|
-
}
|
|
6750
|
-
}
|
|
6751
|
-
__name(writeManaged, "writeManaged");
|
|
6752
|
-
module2.exports = {
|
|
6753
|
-
name: "CodeBuddy",
|
|
6754
|
-
id: "codebuddy",
|
|
6755
|
-
checkInstalled() {
|
|
6756
|
-
return true;
|
|
6757
|
-
},
|
|
6758
|
-
isConfigured() {
|
|
6759
|
-
const content = readSafe();
|
|
6760
|
-
return content.includes(MARKER_BEGIN) && content.includes(MARKER_END);
|
|
6761
|
-
},
|
|
6762
|
-
configure(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI) {
|
|
6763
|
-
if (!apiKey) {
|
|
6764
|
-
throw new Error("codebuddy.configure: apiKey is required");
|
|
6765
|
-
}
|
|
6766
|
-
writeManaged(apiKey, baseUrlAnthropicNoV1, baseUrlOpenAI);
|
|
6767
|
-
return {
|
|
6768
|
-
file: CONFIG_FILE,
|
|
6769
|
-
hot: true
|
|
6770
|
-
};
|
|
6771
|
-
},
|
|
6772
|
-
reset() {
|
|
6773
|
-
if (!fs.existsSync(CONFIG_FILE)) return;
|
|
6774
|
-
const stripped = stripManagedBlock(readSafe());
|
|
6775
|
-
const cleaned = stripped.replace(/^\n+|\n+$/g, "");
|
|
6776
|
-
if (cleaned) {
|
|
6777
|
-
fs.writeFileSync(CONFIG_FILE, cleaned + "\n", "utf8");
|
|
6778
|
-
} else {
|
|
6779
|
-
fs.writeFileSync(CONFIG_FILE, "", "utf8");
|
|
6780
|
-
}
|
|
6781
|
-
},
|
|
6782
|
-
getConfigPath() {
|
|
6783
|
-
return CONFIG_FILE;
|
|
6784
|
-
},
|
|
6785
|
-
hint: "CodeBuddy \u901A\u8FC7 ~/.codebuddy/.env \u8BFB\u53D6 CODEBUDDY_API_KEY / CODEBUDDY_BASE_URL\uFF08\u7B2C\u4E09\u65B9\u6A21\u5F0F\uFF09\uFF1B\u4E2D\u56FD\u7248/iOA \u7248\u7528\u6237\u8BF7\u81EA\u884C\u8BBE\u7F6E CODEBUDDY_INTERNET_ENVIRONMENT",
|
|
6786
|
-
launchCmd: "codebuddy",
|
|
6787
|
-
installCmd: "npm install -g @tencent-ai/codebuddy-code",
|
|
6788
|
-
docsUrl: "https://www.codebuddy.ai/docs/cli/env-vars",
|
|
6789
|
-
envVarFormat: "openai",
|
|
6790
|
-
__internal: {
|
|
6791
|
-
MARKER_BEGIN,
|
|
6792
|
-
MARKER_END,
|
|
6793
|
-
DEFAULT_OPENAI_MODEL,
|
|
6794
|
-
DEFAULT_ANTHROPIC_MODEL,
|
|
6795
|
-
stripManagedBlock,
|
|
6796
|
-
buildManagedBlock
|
|
6797
|
-
}
|
|
6798
|
-
};
|
|
6799
|
-
}
|
|
6800
|
-
});
|
|
6801
|
-
|
|
6802
6834
|
// src/webui/workspace-store.js
|
|
6803
6835
|
var require_workspace_store = __commonJS({
|
|
6804
6836
|
"src/webui/workspace-store.js"(exports2, module2) {
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simonyea/holysheep-cli",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.77",
|
|
4
4
|
"description": "Claude Code/Cursor/Cline API relay for China — ¥1=$1, WeChat/Alipay payment, no credit card, no VPN. One command setup for all AI coding tools.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "node scripts/build.mjs",
|
|
7
|
-
"test": "node tests/droid.test.js && node tests/workspace-store.test.js && node tests/runtime-stale-upgrade.test.js && node tests/hermes.test.js && node tests/preflight.test.js && node tests/opencode-auth-purge.test.js && node tests/shell-winpath.test.js && node tests/openclaw-atomic-write.test.js && node tests/openclaw-disable-auth-direct.test.js && node tests/opencode-default-model.test.js && node tests/paths-bundled.test.js && node tests/aionui-runtime-resources.test.js && node tests/aionui-wrapper-claude-proxy.test.js && node tests/aionui-wrapper-probe.test.js && node tests/aionui-wrapper-proxy-integration.test.js && node tests/aionui-wrapper-all-clis-autoconf.test.js && node tests/aionui-wrapper-env-signal.test.js && node tests/aionui-wrapper-csp-rewrite.test.js && node tests/aionui-wrapper-version-status.test.js && node tests/claude-proxy-daemon.test.js && node tests/claude-proxy-vscode-settings.test.js && node tests/claude-proxy-vscode-env.test.js && node tests/acptypes-patch.test.js && node tests/codex-approval-policy.test.js && node tests/version-check.test.js && node tests/runclaude-missing-binary.test.js && node tests/claude-code-configure-preserve.test.js && node tests/webui-claude-proxy-virtual-tool.test.js && node tests/webui-claude-proxy-ui.test.js && node tests/webui-response-consumer.test.js && node tests/webui-claude-proxy-install-gating.test.js && node tests/claude-code-windows-local-bin.test.js && node tests/qwen-code-config.test.js && node tests/codebuddy-config.test.js",
|
|
7
|
+
"test": "node tests/droid.test.js && node tests/workspace-store.test.js && node tests/runtime-stale-upgrade.test.js && node tests/hermes.test.js && node tests/preflight.test.js && node tests/opencode-auth-purge.test.js && node tests/shell-winpath.test.js && node tests/openclaw-atomic-write.test.js && node tests/openclaw-disable-auth-direct.test.js && node tests/opencode-default-model.test.js && node tests/paths-bundled.test.js && node tests/aionui-runtime-resources.test.js && node tests/aionui-wrapper-claude-proxy.test.js && node tests/aionui-wrapper-probe.test.js && node tests/aionui-wrapper-proxy-integration.test.js && node tests/aionui-wrapper-all-clis-autoconf.test.js && node tests/aionui-wrapper-env-signal.test.js && node tests/aionui-wrapper-csp-rewrite.test.js && node tests/aionui-wrapper-version-status.test.js && node tests/claude-proxy-daemon.test.js && node tests/claude-proxy-vscode-settings.test.js && node tests/claude-proxy-vscode-env.test.js && node tests/acptypes-patch.test.js && node tests/codex-approval-policy.test.js && node tests/version-check.test.js && node tests/runclaude-missing-binary.test.js && node tests/claude-code-configure-preserve.test.js && node tests/webui-claude-proxy-virtual-tool.test.js && node tests/webui-claude-proxy-ui.test.js && node tests/webui-response-consumer.test.js && node tests/webui-claude-proxy-install-gating.test.js && node tests/claude-code-windows-local-bin.test.js && node tests/qwen-code-config.test.js && node tests/codebuddy-config.test.js && node tests/hs-reset-routing.test.js && node tests/setup-auto-install-routing.test.js && node tests/upgrade-routing.test.js",
|
|
8
8
|
"prepublishOnly": "npm run build && npm test && node scripts/check-tarball-size.js"
|
|
9
9
|
},
|
|
10
10
|
"keywords": [
|