nikou-cli 0.1.1 → 0.1.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/README.md +2 -2
- package/dist/ai-hook.d.ts +1 -0
- package/dist/ai-hook.js +12 -0
- package/dist/chunk-F3EPGM5N.js +25 -0
- package/dist/index.js +50 -36
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -168,11 +168,11 @@ nikou-cli hook init
|
|
|
168
168
|
安装后也可以用 `ai-hook` 入口完成 Hook 初始化与启动:
|
|
169
169
|
|
|
170
170
|
```bash
|
|
171
|
-
|
|
171
|
+
ai-hook init
|
|
172
172
|
ai-hook
|
|
173
173
|
```
|
|
174
174
|
|
|
175
|
-
|
|
175
|
+
初始化时会提示主节点地址:如果旧配置里已有主节点,直接回车沿用;没有默认值时输入 IP 或域名即可。`ai-hook` 默认等价于 `nikou-cli hook worker codex`;如需 Claude:
|
|
176
176
|
|
|
177
177
|
```bash
|
|
178
178
|
ai-hook claude --model opus
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/ai-hook.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// src/cli-entry.ts
|
|
2
|
+
import path from "path";
|
|
3
|
+
var AI_HOOK_COMMAND_NAMES = /* @__PURE__ */ new Set(["ai-hook", "ai-hook.cmd", "ai-hook.exe"]);
|
|
4
|
+
var HOOK_SUBCOMMANDS = /* @__PURE__ */ new Set(["master", "init", "worker", "log", "help"]);
|
|
5
|
+
function normalizeCliArgs(commandPath, args) {
|
|
6
|
+
const commandName = path.basename(commandPath || "");
|
|
7
|
+
if (!AI_HOOK_COMMAND_NAMES.has(commandName)) {
|
|
8
|
+
return args;
|
|
9
|
+
}
|
|
10
|
+
const [firstArg = "", ...restArgs] = args;
|
|
11
|
+
if (firstArg === "hook") {
|
|
12
|
+
return args;
|
|
13
|
+
}
|
|
14
|
+
if (HOOK_SUBCOMMANDS.has(firstArg)) {
|
|
15
|
+
return ["hook", ...args];
|
|
16
|
+
}
|
|
17
|
+
if (!firstArg || firstArg.startsWith("-")) {
|
|
18
|
+
return ["hook", "worker", "codex", ...args];
|
|
19
|
+
}
|
|
20
|
+
return ["hook", "worker", firstArg, ...restArgs];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
normalizeCliArgs
|
|
25
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
normalizeCliArgs
|
|
4
|
+
} from "./chunk-F3EPGM5N.js";
|
|
2
5
|
|
|
3
6
|
// src/index.ts
|
|
4
7
|
import { Command } from "commander";
|
|
@@ -460,17 +463,17 @@ var TOOL_CONFIG = {
|
|
|
460
463
|
gemini: { filePath: join6(homedir(), ".gemini", "settings.json"), format: "json", jsonPath: ["mcpServers"] },
|
|
461
464
|
opencode: { filePath: join6(homedir(), ".config", "opencode", "opencode.json"), format: "json", jsonPath: ["mcp"] }
|
|
462
465
|
};
|
|
463
|
-
function readJsonFile(
|
|
464
|
-
if (!existsSync5(
|
|
466
|
+
function readJsonFile(path29) {
|
|
467
|
+
if (!existsSync5(path29)) return {};
|
|
465
468
|
try {
|
|
466
|
-
return JSON.parse(readFileSync4(
|
|
469
|
+
return JSON.parse(readFileSync4(path29, "utf-8"));
|
|
467
470
|
} catch {
|
|
468
471
|
return {};
|
|
469
472
|
}
|
|
470
473
|
}
|
|
471
|
-
function writeJsonFile(
|
|
472
|
-
mkdirSync4(dirname2(
|
|
473
|
-
writeFileSync3(
|
|
474
|
+
function writeJsonFile(path29, data) {
|
|
475
|
+
mkdirSync4(dirname2(path29), { recursive: true });
|
|
476
|
+
writeFileSync3(path29, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
474
477
|
}
|
|
475
478
|
function getNestedObj(root, keys) {
|
|
476
479
|
let cur = root;
|
|
@@ -497,10 +500,10 @@ function extractServerFromContent(content, jsonPath) {
|
|
|
497
500
|
return null;
|
|
498
501
|
}
|
|
499
502
|
}
|
|
500
|
-
function readTomlFile(
|
|
501
|
-
if (!existsSync5(
|
|
503
|
+
function readTomlFile(path29) {
|
|
504
|
+
if (!existsSync5(path29)) return "";
|
|
502
505
|
try {
|
|
503
|
-
return readFileSync4(
|
|
506
|
+
return readFileSync4(path29, "utf-8");
|
|
504
507
|
} catch {
|
|
505
508
|
return "";
|
|
506
509
|
}
|
|
@@ -546,9 +549,9 @@ function tomlListServers(toml) {
|
|
|
546
549
|
}
|
|
547
550
|
return results;
|
|
548
551
|
}
|
|
549
|
-
function backupFile(
|
|
550
|
-
if (existsSync5(
|
|
551
|
-
copyFileSync(
|
|
552
|
+
function backupFile(path29) {
|
|
553
|
+
if (existsSync5(path29)) {
|
|
554
|
+
copyFileSync(path29, path29 + ".bak");
|
|
552
555
|
}
|
|
553
556
|
}
|
|
554
557
|
function writeMcpToTool(toolId, serverName, variantContent, force) {
|
|
@@ -14366,6 +14369,23 @@ var DEFAULT_MASTER_HOST_ENV = "NIKOU_HOOK_MASTER_HOST";
|
|
|
14366
14369
|
function resolveHookSection2(config) {
|
|
14367
14370
|
return config.hook ?? config.ai_hook ?? config.aiHook ?? {};
|
|
14368
14371
|
}
|
|
14372
|
+
function resolveConfiguredMasterHost(config) {
|
|
14373
|
+
const hook2 = resolveHookSection2(config);
|
|
14374
|
+
return String(hook2.master_host || hook2.masterHost || "").trim();
|
|
14375
|
+
}
|
|
14376
|
+
function mergeHookInitMasterHost(config, masterHost) {
|
|
14377
|
+
const host = String(masterHost || "").trim();
|
|
14378
|
+
if (!host) {
|
|
14379
|
+
return config;
|
|
14380
|
+
}
|
|
14381
|
+
return {
|
|
14382
|
+
...config,
|
|
14383
|
+
hook: {
|
|
14384
|
+
...config.hook ?? config.ai_hook ?? config.aiHook ?? {},
|
|
14385
|
+
master_host: host
|
|
14386
|
+
}
|
|
14387
|
+
};
|
|
14388
|
+
}
|
|
14369
14389
|
function resolveContextConfigFromHook(hook2) {
|
|
14370
14390
|
return {
|
|
14371
14391
|
enabled: parseBoolean(
|
|
@@ -14411,7 +14431,7 @@ function normalizeHookInitConfig(config, defaults = {}) {
|
|
|
14411
14431
|
const appSecret = String(
|
|
14412
14432
|
config.feishu?.app_secret || config.feishu?.appSecret || config.feishu?.appsecret || ""
|
|
14413
14433
|
).trim();
|
|
14414
|
-
const masterHost =
|
|
14434
|
+
const masterHost = resolveConfiguredMasterHost(config) || String(defaults.defaultMasterHost || "").trim();
|
|
14415
14435
|
const masterPort = parsePositiveInt(hook2.master_port ?? hook2.masterPort, DEFAULT_MASTER_PORT);
|
|
14416
14436
|
const sharedSecret = String(hook2.shared_secret || hook2.sharedSecret || appSecret || "").trim();
|
|
14417
14437
|
const bindAllowedUserIds = parseUserIdList(hook2.bind_allowed_user_ids ?? hook2.bindAllowedUserIds);
|
|
@@ -14456,7 +14476,6 @@ var HookInitCommand = class {
|
|
|
14456
14476
|
async run() {
|
|
14457
14477
|
this.ensureInteractiveTerminal();
|
|
14458
14478
|
const source = this.resolveSourceConfig();
|
|
14459
|
-
const normalized = this.normalizeSourceConfig(source.config);
|
|
14460
14479
|
const migration = loadLegacyMigrationResult(this.logger);
|
|
14461
14480
|
const existingAggregateConfig = this.readJson(DEFAULT_CONFIG_PATH);
|
|
14462
14481
|
const existingMasterConfig = this.readJson(MASTER_CONFIG_PATH);
|
|
@@ -14468,6 +14487,10 @@ var HookInitCommand = class {
|
|
|
14468
14487
|
this.printEnvironmentSummary(source.path, { existingAggregateConfig, existingMasterConfig, existingWorkerConfig }, migration.summary);
|
|
14469
14488
|
const botName = await this.askChoice(rl, "\u7B2C\u4E00\u6B65\uFF1A\u9009\u62E9\u98DE\u4E66\u673A\u5668\u4EBA", BOT_OPTIONS, 0);
|
|
14470
14489
|
await this.askChoice(rl, "\u7B2C\u4E8C\u6B65\uFF1A\u9009\u62E9\u90E8\u7F72\u65B9\u5F0F", DEPLOYMENT_OPTIONS, 0);
|
|
14490
|
+
const masterHost = await this.askMasterHost(rl, source.config);
|
|
14491
|
+
const normalized = this.normalizeSourceConfig(
|
|
14492
|
+
mergeHookInitMasterHost(source.config, masterHost)
|
|
14493
|
+
);
|
|
14471
14494
|
const nextMasterConfig = this.buildMasterConfigPayload(normalized, botName);
|
|
14472
14495
|
const nextWorkerConfig = this.buildWorkerConfigPayload(normalized, botName);
|
|
14473
14496
|
const nextWorkerState = this.buildSeedWorkerState({
|
|
@@ -14584,6 +14607,19 @@ var HookInitCommand = class {
|
|
|
14584
14607
|
console.log(chalk9.yellow("\u8BF7\u8F93\u5165 y \u6216 n\u3002\n"));
|
|
14585
14608
|
}
|
|
14586
14609
|
}
|
|
14610
|
+
async askMasterHost(rl, config) {
|
|
14611
|
+
const defaultHost = resolveConfiguredMasterHost(config) || resolveDefaultMasterHost();
|
|
14612
|
+
while (true) {
|
|
14613
|
+
const label = defaultHost ? `\u7B2C\u4E09\u6B65\uFF1A\u4E3B\u8282\u70B9\u5730\u5740 [\u9ED8\u8BA4 ${defaultHost}]: ` : "\u7B2C\u4E09\u6B65\uFF1A\u4E3B\u8282\u70B9\u5730\u5740: ";
|
|
14614
|
+
const answer = (await rl.question(chalk9.dim(label))).trim();
|
|
14615
|
+
const resolved = answer || defaultHost;
|
|
14616
|
+
if (resolved) {
|
|
14617
|
+
console.log("");
|
|
14618
|
+
return resolved;
|
|
14619
|
+
}
|
|
14620
|
+
console.log(chalk9.yellow("\u4E3B\u8282\u70B9\u5730\u5740\u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u8BF7\u8F93\u5165 IP \u6216\u57DF\u540D\u3002\n"));
|
|
14621
|
+
}
|
|
14622
|
+
}
|
|
14587
14623
|
buildMasterConfigPayload(normalized, botName) {
|
|
14588
14624
|
return {
|
|
14589
14625
|
feishu: {
|
|
@@ -15089,28 +15125,6 @@ async function hookLogAction(query = "", options = {}) {
|
|
|
15089
15125
|
}
|
|
15090
15126
|
}
|
|
15091
15127
|
|
|
15092
|
-
// src/cli-entry.ts
|
|
15093
|
-
import path29 from "path";
|
|
15094
|
-
var AI_HOOK_COMMAND_NAMES = /* @__PURE__ */ new Set(["ai-hook", "ai-hook.cmd", "ai-hook.exe"]);
|
|
15095
|
-
var HOOK_SUBCOMMANDS = /* @__PURE__ */ new Set(["master", "init", "worker", "log", "help"]);
|
|
15096
|
-
function normalizeCliArgs(commandPath, args) {
|
|
15097
|
-
const commandName = path29.basename(commandPath || "");
|
|
15098
|
-
if (!AI_HOOK_COMMAND_NAMES.has(commandName)) {
|
|
15099
|
-
return args;
|
|
15100
|
-
}
|
|
15101
|
-
const [firstArg = "", ...restArgs] = args;
|
|
15102
|
-
if (firstArg === "hook") {
|
|
15103
|
-
return args;
|
|
15104
|
-
}
|
|
15105
|
-
if (HOOK_SUBCOMMANDS.has(firstArg)) {
|
|
15106
|
-
return ["hook", ...args];
|
|
15107
|
-
}
|
|
15108
|
-
if (!firstArg || firstArg.startsWith("-")) {
|
|
15109
|
-
return ["hook", "worker", "codex", ...args];
|
|
15110
|
-
}
|
|
15111
|
-
return ["hook", "worker", firstArg, ...restArgs];
|
|
15112
|
-
}
|
|
15113
|
-
|
|
15114
15128
|
// src/index.ts
|
|
15115
15129
|
var DEFAULT_DEST = ".agents/skills";
|
|
15116
15130
|
var WORKER_BOOLEAN_OPTIONS = /* @__PURE__ */ new Set([
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nikou-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Install Agent Skills and MCP servers, and run distributed AI hook workers.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"nikou-cli": "dist/index.js",
|
|
8
|
-
"ai-hook": "dist/
|
|
8
|
+
"ai-hook": "dist/ai-hook.js"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist"
|
|
12
12
|
],
|
|
13
13
|
"scripts": {
|
|
14
|
-
"build": "tsup src/index.ts --format esm --dts --clean",
|
|
14
|
+
"build": "tsup src/index.ts src/ai-hook.ts --format esm --dts --clean",
|
|
15
15
|
"dev": "tsup src/index.ts --format esm --watch",
|
|
16
16
|
"test": "tsx --test test/**/*.test.ts",
|
|
17
17
|
"privacy-scan": "node scripts/privacy-scan.mjs",
|