@skylandnpm/octopus-proxy 0.1.3 → 0.1.5
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 +13 -0
- package/dist/{chunk-3TRTDBUO.js → chunk-JWIM27KY.js} +1 -1
- package/dist/cli.js +67 -6
- package/dist/main.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,8 +11,21 @@ octopus-proxy version
|
|
|
11
11
|
octopus-proxy onboard
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
+
如果升级后 `octopus-proxy version` 仍显示旧版本,运行 `command -v npm`、`npm prefix -g` 和 `command -v octopus-proxy`,确认 npm 的全局安装目录与实际执行的命令属于同一套 Node.js 环境;使用 NVM 与 Homebrew 时尤其要检查这一点。
|
|
15
|
+
|
|
14
16
|
向导默认使用 `https://octopus.wuyehao.com` 作为 Hub 地址;按需可输入其他地址,或用 `--hub-url` 指定。再次运行向导时会读取现有配置,直接回车即可保留各项设置;机器人 Secret 只提示已配置,不在终端显示原值。macOS 上选择编码工具时,向导优先显示已配置或探测到的命令路径,否则给出该工具的 macOS 路径示例;回车后会检查文件可执行性并运行版本命令,失败时要求重新输入。无交互环境可使用 `octopus-proxy onboard --non-interactive`,未提供 `--hub-url` 时也使用该默认地址;完整选项见 `octopus-proxy help`。安装服务后可运行 `octopus-proxy status` 和 `octopus-proxy doctor` 检查状态。
|
|
15
17
|
|
|
18
|
+
添加授权项目时,填写项目 ID 后会询问是否继续添加;直接回车即可结束添加并继续保存配置。
|
|
19
|
+
|
|
20
|
+
如果旧配置中的项目 ID 重复或有错误项,先列出项目,再按序号删除指定项。此命令直接读取原始配置,因此配置校验失败时也能使用;删除前会生成仅当前用户可读的备份。清理完成后检查配置并重启服务:
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
octopus-proxy projects
|
|
24
|
+
octopus-proxy projects --remove 2
|
|
25
|
+
octopus-proxy doctor
|
|
26
|
+
octopus-proxy restart
|
|
27
|
+
```
|
|
28
|
+
|
|
16
29
|
Claw 打开机器人工作区时会通过 Hub 向 Proxy 发送只读 `runtime.snapshot` 命令。响应包含当前运行状态、Hub 和工具设置、授权项目路径,以及工具可提供的模型信息;机器人 Secret、工具密码和提供商凭据不会返回。工作区的“Proxy 信息”按钮可查看这些内容。
|
|
17
30
|
|
|
18
31
|
## Pi agent
|
|
@@ -11645,7 +11645,7 @@ async function loadConfig(path) {
|
|
|
11645
11645
|
const local = new URL(config.tool.baseUrl);
|
|
11646
11646
|
if (!["127.0.0.1", "localhost", "[::1]"].includes(local.hostname) || local.protocol !== "http:") throw new Error("OpenCode must be an HTTP loopback endpoint");
|
|
11647
11647
|
}
|
|
11648
|
-
if (new Set(config.projects.map((p) => p.id)).size !== config.projects.length) throw new Error("
|
|
11648
|
+
if (new Set(config.projects.map((p) => p.id)).size !== config.projects.length) throw new Error("\u9879\u76EE ID \u91CD\u590D\uFF1B\u8FD0\u884C octopus-proxy projects \u67E5\u770B\u9879\u76EE\uFF0C\u518D\u7528 projects --remove <\u5E8F\u53F7> \u5220\u9664\u9519\u8BEF\u9879");
|
|
11649
11649
|
return config;
|
|
11650
11650
|
} catch (error) {
|
|
11651
11651
|
if (error instanceof ConfigError) throw error;
|
package/dist/cli.js
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
runDaemon,
|
|
18
18
|
supportedPlatform,
|
|
19
19
|
systemdUnitPath
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-JWIM27KY.js";
|
|
21
21
|
|
|
22
22
|
// src/cli.ts
|
|
23
23
|
import { spawn } from "node:child_process";
|
|
@@ -454,7 +454,8 @@ var validUrl = (value) => {
|
|
|
454
454
|
return "\u8BF7\u8F93\u5165\u5408\u6CD5 URL\uFF0C\u4F8B\u5982 https://hub.example.com";
|
|
455
455
|
}
|
|
456
456
|
};
|
|
457
|
-
var validId = (value) => /^[a-zA-Z0-9_-]+$/.test(value) ? void 0 : "\u4EC5\u9650\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u4E0B\u5212\u7EBF\u548C\u8FDE\u5B57\u7B26";
|
|
457
|
+
var validId = (value) => !value ? "\u9879\u76EE ID \u4E0D\u80FD\u4E3A\u7A7A" : /^[a-zA-Z0-9_-]+$/.test(value) ? void 0 : "\u4EC5\u9650\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u4E0B\u5212\u7EBF\u548C\u8FDE\u5B57\u7B26";
|
|
458
|
+
var validateProjectId = (value, previousProjects) => validId(value) ?? (previousProjects.some((project) => project.id === value) ? `\u9879\u76EE ID\u300C${value}\u300D\u5DF2\u5B58\u5728\uFF0C\u8BF7\u8F93\u5165\u5176\u4ED6 ID` : void 0);
|
|
458
459
|
var validBotId = (value) => /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value) ? void 0 : "\u8BF7\u8F93\u5165\u673A\u5668\u4EBA UUID";
|
|
459
460
|
var run5 = promisify5(execFile5);
|
|
460
461
|
var MACOS_TOOL_EXAMPLES = {
|
|
@@ -509,7 +510,7 @@ async function runOnboard(opts) {
|
|
|
509
510
|
console.log(` \u5DF2\u786E\u8BA4 ${descriptor.label} \u547D\u4EE4\u53EF\u6267\u884C\uFF1A${toolCommand}`);
|
|
510
511
|
if (toolKind === "opencode") mode = await ask(rl, "OpenCode \u6A21\u5F0F\uFF08managed=\u7531\u4EE3\u7406\u6258\u7BA1\u542F\u52A8\uFF0Cexternal=\u4EC5\u8FDE\u63A5\u5DF2\u6709\u670D\u52A1\uFF09", { default: mode, validate: (value) => value === "managed" || value === "external" ? void 0 : "\u8F93\u5165 managed \u6216 external" });
|
|
511
512
|
if (projects.length) console.log("\n\u5DF2\u6709\u6388\u6743\u9879\u76EE\uFF08\u76F4\u63A5\u56DE\u8F66\u4FDD\u7559\u5404\u9879\uFF09\uFF1A");
|
|
512
|
-
for (const project of projects) {
|
|
513
|
+
for (const [index, project] of projects.entries()) {
|
|
513
514
|
project.name = await ask(rl, " \u9879\u76EE\u540D\u79F0", { default: project.name });
|
|
514
515
|
for (; ; ) {
|
|
515
516
|
project.directory = expandHome(await ask(rl, ` \u300C${project.name}\u300D\u76EE\u5F55\uFF08\u7EDD\u5BF9\u8DEF\u5F84\uFF09`, { default: project.directory }));
|
|
@@ -523,7 +524,7 @@ async function runOnboard(opts) {
|
|
|
523
524
|
}
|
|
524
525
|
break;
|
|
525
526
|
}
|
|
526
|
-
project.id = await ask(rl, " \u9879\u76EE ID", { default: project.id ?? slug(project.name), validate:
|
|
527
|
+
project.id = await ask(rl, " \u9879\u76EE ID", { default: project.id ?? slug(project.name), validate: (value) => validateProjectId(value, projects.slice(0, index)) });
|
|
527
528
|
}
|
|
528
529
|
console.log("\n\u6DFB\u52A0\u6388\u6743\u9879\u76EE\uFF08\u540D\u79F0\u7559\u7A7A\u7ED3\u675F\uFF09\uFF1A");
|
|
529
530
|
for (; ; ) {
|
|
@@ -542,8 +543,14 @@ async function runOnboard(opts) {
|
|
|
542
543
|
}
|
|
543
544
|
break;
|
|
544
545
|
}
|
|
545
|
-
const id = await ask(rl, " \u9879\u76EE ID", { default: slug(name), validate:
|
|
546
|
+
const id = await ask(rl, " \u9879\u76EE ID", { default: slug(name), validate: (value) => validateProjectId(value, projects) });
|
|
546
547
|
projects.push({ id, name, directory });
|
|
548
|
+
const addMore = await ask(rl, " \u7EE7\u7EED\u6DFB\u52A0\u66F4\u591A\u6388\u6743\u9879\u76EE\uFF1F(y/N)", {
|
|
549
|
+
default: "n",
|
|
550
|
+
showDefault: false,
|
|
551
|
+
validate: (value) => /^(y|yes|n|no)$/i.test(value) ? void 0 : "\u8BF7\u8F93\u5165 y \u6216 n"
|
|
552
|
+
});
|
|
553
|
+
if (!/^(y|yes)$/i.test(addMore)) break;
|
|
547
554
|
}
|
|
548
555
|
rl.close();
|
|
549
556
|
if (!projects.length) throw new Error("\u81F3\u5C11\u9700\u8981\u5F55\u5165\u4E00\u4E2A\u6388\u6743\u9879\u76EE");
|
|
@@ -560,6 +567,11 @@ async function runOnboard(opts) {
|
|
|
560
567
|
projects = projects.map((project) => ({ ...project, id: project.id ?? slug(project.name) }));
|
|
561
568
|
const invalid = projects.find((project) => validId(project.id ?? "") !== void 0);
|
|
562
569
|
if (invalid) throw new Error(`\u9879\u76EE\u300C${invalid.name}\u300D\u65E0\u6CD5\u63A8\u5BFC\u51FA\u5408\u6CD5 ID\uFF08\u4EC5\u9650\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u4E0B\u5212\u7EBF\u548C\u8FDE\u5B57\u7B26\uFF09\uFF0C\u8BF7\u8C03\u6574\u540D\u79F0\u6216\u624B\u5DE5\u6307\u5B9A ID`);
|
|
570
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
571
|
+
for (const project of projects) {
|
|
572
|
+
if (seenIds.has(project.id)) throw new Error(`\u9879\u76EE ID\u300C${project.id}\u300D\u91CD\u590D\uFF0C\u8BF7\u8C03\u6574\u9879\u76EE\u540D\u79F0\u6216\u624B\u5DE5\u6307\u5B9A\u4E0D\u540C ID`);
|
|
573
|
+
seenIds.add(project.id);
|
|
574
|
+
}
|
|
563
575
|
if (projects.some((project) => !isAbsolute3(project.directory))) throw new Error("--project \u7684\u76EE\u5F55\u5FC5\u987B\u662F\u7EDD\u5BF9\u8DEF\u5F84");
|
|
564
576
|
const descriptor = describeTool(toolKind);
|
|
565
577
|
toolCommand = toolCommand ? expandHome(toolCommand) : await resolveCommandOnPath(toolKind, toolSearchDirs(toolKind)) ?? descriptor.defaultCommand;
|
|
@@ -613,6 +625,48 @@ async function runOnboard(opts) {
|
|
|
613
625
|
} else console.log("\u5DF2\u8DF3\u8FC7\u670D\u52A1\u5B89\u88C5\uFF1B\u4E4B\u540E\u53EF\u8FD0\u884C octopus-proxy install");
|
|
614
626
|
}
|
|
615
627
|
|
|
628
|
+
// src/projects-command.ts
|
|
629
|
+
import { randomUUID } from "node:crypto";
|
|
630
|
+
import { readFile as readFile2, writeFile as writeFile3 } from "node:fs/promises";
|
|
631
|
+
function asConfig(value) {
|
|
632
|
+
if (typeof value !== "object" || value === null || Array.isArray(value) || !Array.isArray(value.projects)) {
|
|
633
|
+
throw new Error("\u914D\u7F6E\u6587\u4EF6\u7F3A\u5C11 projects \u6570\u7EC4\uFF0C\u65E0\u6CD5\u7BA1\u7406\u6388\u6743\u9879\u76EE");
|
|
634
|
+
}
|
|
635
|
+
return value;
|
|
636
|
+
}
|
|
637
|
+
function display(value) {
|
|
638
|
+
return typeof value === "string" && value.length > 0 ? JSON.stringify(value) : "\uFF08\u7A7A\uFF09";
|
|
639
|
+
}
|
|
640
|
+
async function manageProjects(configPath2, remove) {
|
|
641
|
+
const original = await readFile2(configPath2);
|
|
642
|
+
const config = asConfig(JSON.parse(original.toString("utf8")));
|
|
643
|
+
if (remove === void 0) {
|
|
644
|
+
if (config.projects.length === 0) console.log("\u914D\u7F6E\u4E2D\u6CA1\u6709\u6388\u6743\u9879\u76EE");
|
|
645
|
+
else for (const [index2, entry] of config.projects.entries()) {
|
|
646
|
+
const project = typeof entry === "object" && entry !== null && !Array.isArray(entry) ? entry : {};
|
|
647
|
+
console.log(`${index2 + 1}. ID=${display(project.id)} \u540D\u79F0=${display(project.name)} \u76EE\u5F55=${display(project.directory)}`);
|
|
648
|
+
}
|
|
649
|
+
console.log("\u5220\u9664\u9519\u8BEF\u9879\uFF1Aoctopus-proxy projects --remove <\u5E8F\u53F7>");
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
if (!/^[1-9][0-9]*$/.test(remove)) throw new Error("--remove \u9700\u8981\u4E0A\u65B9\u5217\u8868\u4E2D\u7684\u6B63\u6574\u6570\u5E8F\u53F7");
|
|
653
|
+
const index = Number(remove) - 1;
|
|
654
|
+
if (!Number.isSafeInteger(index) || index >= config.projects.length) throw new Error(`\u9879\u76EE\u5E8F\u53F7\u8D85\u51FA\u8303\u56F4\uFF1A${remove}`);
|
|
655
|
+
if (config.projects.length === 1) throw new Error("\u81F3\u5C11\u9700\u8981\u4FDD\u7559\u4E00\u4E2A\u6388\u6743\u9879\u76EE\uFF1B\u65E0\u6CD5\u5220\u9664\u6700\u540E\u4E00\u9879");
|
|
656
|
+
const backupPath = `${configPath2}.backup-${randomUUID()}`;
|
|
657
|
+
await writeFile3(backupPath, original, { mode: 384, flag: "wx" });
|
|
658
|
+
config.projects.splice(index, 1);
|
|
659
|
+
await atomicJson(configPath2, config);
|
|
660
|
+
console.log(`\u5DF2\u5220\u9664\u7B2C ${remove} \u4E2A\u6388\u6743\u9879\u76EE\uFF1B\u539F\u914D\u7F6E\u5907\u4EFD\uFF1A${backupPath}`);
|
|
661
|
+
try {
|
|
662
|
+
await loadConfig(configPath2);
|
|
663
|
+
console.log("\u914D\u7F6E\u6821\u9A8C\u901A\u8FC7\uFF1B\u8FD0\u884C octopus-proxy restart \u4F7F\u670D\u52A1\u4F7F\u7528\u65B0\u914D\u7F6E");
|
|
664
|
+
} catch (error) {
|
|
665
|
+
console.log(`\u914D\u7F6E\u4ECD\u6709\u9519\u8BEF\uFF1A${error instanceof Error ? error.message : String(error)}`);
|
|
666
|
+
console.log("\u7EE7\u7EED\u6E05\u7406\u540E\u8FD0\u884C octopus-proxy doctor \u68C0\u67E5\u914D\u7F6E");
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
|
|
616
670
|
// src/cli.ts
|
|
617
671
|
var USAGE = `octopus-proxy \u2014 Octopus \u4E3B\u673A\u4EE3\u7406
|
|
618
672
|
|
|
@@ -620,6 +674,7 @@ var USAGE = `octopus-proxy \u2014 Octopus \u4E3B\u673A\u4EE3\u7406
|
|
|
620
674
|
|
|
621
675
|
\u547D\u4EE4:
|
|
622
676
|
onboard \u4EA4\u4E92\u5F0F\u521D\u59CB\u5316\u914D\u7F6E\uFF0C\u5E76\u9ED8\u8BA4\u5B89\u88C5\u7CFB\u7EDF\u670D\u52A1
|
|
677
|
+
projects \u5217\u51FA\u6388\u6743\u9879\u76EE\uFF1B\u53EF\u6309\u5E8F\u53F7\u5220\u9664\u9519\u8BEF\u914D\u7F6E\u9879
|
|
623
678
|
install \u6821\u9A8C\u914D\u7F6E\u540E\u5B89\u88C5/\u66F4\u65B0\u7CFB\u7EDF\u670D\u52A1\uFF08\u5E42\u7B49\uFF0C\u81EA\u52A8\u542F\u52A8\uFF09
|
|
624
679
|
uninstall \u505C\u6B62\u5E76\u79FB\u9664\u7CFB\u7EDF\u670D\u52A1\uFF08\u4FDD\u7559\u914D\u7F6E\u4E0E\u72B6\u6001\u6570\u636E\uFF09
|
|
625
680
|
start \u542F\u52A8\u670D\u52A1
|
|
@@ -650,12 +705,15 @@ install \u9009\u9879:
|
|
|
650
705
|
--force \u91CD\u5199\u670D\u52A1\u5B9A\u4E49\u5E76\u91CD\u542F\uFF08\u914D\u7F6E\u6216\u8DEF\u5F84\u53D8\u5316\u540E\u4F7F\u7528\uFF09
|
|
651
706
|
--node-path <p> \u56FA\u5B9A\u670D\u52A1\u4F7F\u7528\u7684 node \u7EDD\u5BF9\u8DEF\u5F84
|
|
652
707
|
|
|
708
|
+
projects \u9009\u9879:
|
|
709
|
+
--remove <\u5E8F\u53F7> \u5220\u9664\u6307\u5B9A\u9879\u76EE\uFF08\u5148\u8FD0\u884C projects \u67E5\u770B\u5E8F\u53F7\uFF1B\u81EA\u52A8\u5907\u4EFD\u539F\u914D\u7F6E\uFF09
|
|
710
|
+
|
|
653
711
|
doctor / logs \u9009\u9879:
|
|
654
712
|
--fix \u81EA\u52A8\u4FEE\u590D\uFF08\u914D\u7F6E\u6743\u9650\u3001\u670D\u52A1\u5B9A\u4E49\u3001\u542F\u52A8\u670D\u52A1\uFF09
|
|
655
713
|
-f, --follow \u6301\u7EED\u8F93\u51FA\u65E5\u5FD7
|
|
656
714
|
|
|
657
715
|
\u9000\u51FA\u7801: 0 \u6210\u529F\uFF1B1 \u4E00\u822C\u9519\u8BEF\uFF1B78 \u914D\u7F6E\u65E0\u6548\uFF08\u670D\u52A1\u5355\u5143\u5DF2\u914D\u7F6E\u4E0D\u56E0\u6B64\u91CD\u542F\uFF09`;
|
|
658
|
-
var VALUE_FLAGS = /* @__PURE__ */ new Set(["--config", "--node-path", "--hub-url", "--bot-id", "--secret-key", "--state-dir", "--tool", "--tool-command", "--opencode-command", "--project"]);
|
|
716
|
+
var VALUE_FLAGS = /* @__PURE__ */ new Set(["--config", "--node-path", "--hub-url", "--bot-id", "--secret-key", "--state-dir", "--tool", "--tool-command", "--opencode-command", "--project", "--remove"]);
|
|
659
717
|
function parse(argv) {
|
|
660
718
|
const flags2 = {}, projectArgs2 = [];
|
|
661
719
|
let command2;
|
|
@@ -742,6 +800,9 @@ try {
|
|
|
742
800
|
});
|
|
743
801
|
break;
|
|
744
802
|
}
|
|
803
|
+
case "projects":
|
|
804
|
+
await manageProjects(configPath, flags["--remove"]);
|
|
805
|
+
break;
|
|
745
806
|
case "install": {
|
|
746
807
|
const outcome = await installService({ configPath, nodePath: flags["--node-path"], force: flags["--force"] === "true" });
|
|
747
808
|
console.log(outcome.changed ? `\u5DF2\u5B89\u88C5\u5E76\u542F\u52A8\u670D\u52A1\uFF1A${outcome.serviceFile}` : `\u670D\u52A1\u5B9A\u4E49\u4E0E\u914D\u7F6E\u4E00\u81F4\uFF0C\u5DF2\u786E\u4FDD\u8FD0\u884C\uFF1A${outcome.serviceFile}`);
|
package/dist/main.js
CHANGED