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 CHANGED
@@ -168,11 +168,11 @@ nikou-cli hook init
168
168
  安装后也可以用 `ai-hook` 入口完成 Hook 初始化与启动:
169
169
 
170
170
  ```bash
171
- NIKOU_HOOK_MASTER_HOST=203.0.113.10 ai-hook init
171
+ ai-hook init
172
172
  ai-hook
173
173
  ```
174
174
 
175
- 其中 `ai-hook` 默认等价于 `nikou-cli hook worker codex`;如需 Claude:
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
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ normalizeCliArgs
4
+ } from "./chunk-F3EPGM5N.js";
5
+
6
+ // src/ai-hook.ts
7
+ process.argv = [
8
+ process.argv[0],
9
+ "ai-hook",
10
+ ...normalizeCliArgs("ai-hook", process.argv.slice(2))
11
+ ];
12
+ await import("./index.js");
@@ -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(path30) {
464
- if (!existsSync5(path30)) return {};
466
+ function readJsonFile(path29) {
467
+ if (!existsSync5(path29)) return {};
465
468
  try {
466
- return JSON.parse(readFileSync4(path30, "utf-8"));
469
+ return JSON.parse(readFileSync4(path29, "utf-8"));
467
470
  } catch {
468
471
  return {};
469
472
  }
470
473
  }
471
- function writeJsonFile(path30, data) {
472
- mkdirSync4(dirname2(path30), { recursive: true });
473
- writeFileSync3(path30, JSON.stringify(data, null, 2) + "\n", "utf-8");
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(path30) {
501
- if (!existsSync5(path30)) return "";
503
+ function readTomlFile(path29) {
504
+ if (!existsSync5(path29)) return "";
502
505
  try {
503
- return readFileSync4(path30, "utf-8");
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(path30) {
550
- if (existsSync5(path30)) {
551
- copyFileSync(path30, path30 + ".bak");
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 = String(hook2.master_host || hook2.masterHost || defaults.defaultMasterHost || "").trim();
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.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/index.js"
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",