@skylandnpm/octopus-proxy 0.1.42 → 0.1.44

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
@@ -98,9 +98,9 @@ octopus-proxy onboard --tool pi
98
98
  octopus-proxy update
99
99
  ```
100
100
 
101
- 命令通过 `npm view @skylandnpm/octopus-proxy@latest version` 查询最新版本。存在新版本时,输入 `y` 或 `yes` 确认覆盖安装;直接回车或输入其他内容会取消。确认后依次停止已安装的服务、使用 npm 全局安装查到的版本、重启服务,并校验安装版本和运行状态后反馈结果。配置、主机身份和已有服务定义会保留;未安装服务时仅更新 npm 包。
101
+ 命令通过 `npm view @skylandnpm/octopus-proxy@latest version` 查询最新版本。存在新版本时,输入 `y` 或 `yes` 确认覆盖安装;直接回车或输入其他内容会取消。确认后使用 npm 全局安装查到的版本,校验安装版本成功后才重启已安装的服务,并检查运行状态后反馈结果。安装期间不会主动停止服务。配置、主机身份和已有服务定义会保留;未安装服务时仅更新 npm 包。
102
102
 
103
- 更新失败时会尝试恢复原先运行的服务,并报告安装及恢复结果;包安装失败不保证旧版本文件完整保留。已安装新版本但重启失败时会单独提示,可运行 `octopus-proxy doctor` 和 `octopus-proxy logs` 排查。此命令用于 npm 全局安装,停止服务前会检查 npm 安装目录是否与当前命令一致;源码、本地安装或 Node.js 环境不一致时会中止并给出提示。
103
+ 安装或版本校验失败时不会触发服务重启;包安装失败不保证旧版本文件完整保留。已安装新版本但重启失败时会单独提示,可运行 `octopus-proxy doctor` 和 `octopus-proxy logs` 排查。此命令用于 npm 全局安装,覆盖安装前会检查 npm 安装目录是否与当前命令一致;源码、本地安装或 Node.js 环境不一致时会中止并给出提示。
104
104
 
105
105
  ## 发布
106
106
 
@@ -14897,7 +14897,7 @@ var OpenCodeAdapter = class {
14897
14897
  this.subscribe(project);
14898
14898
  const op = command.operation, p = command.payload, id = command.sessionId;
14899
14899
  if (op.startsWith("auth.")) return this.authentication(project, op, p);
14900
- const needsSession = op.startsWith("sessions.") && !["sessions.list", "sessions.create", "sessions.status"].includes(op);
14900
+ const needsSession = op.startsWith("sessions.") && !["sessions.list", "sessions.create"].includes(op);
14901
14901
  if (needsSession) {
14902
14902
  if (!id) throw new Error("Session required");
14903
14903
  await this.session(project, id);
@@ -14949,7 +14949,10 @@ var OpenCodeAdapter = class {
14949
14949
  if (!route) throw new Error(`Unsupported OpenCode operation: ${op}`);
14950
14950
  const result = await this.data(project, route[0], route[1], route[2]);
14951
14951
  if (op === "sessions.list") return (Array.isArray(result) ? result : []).map(normalizeSession);
14952
- if (op === "sessions.status") return Object.fromEntries(Object.entries(result ?? {}).map(([key, value]) => [key, { type: value?.type === "running" ? "busy" : value?.type ?? "idle" }]));
14952
+ if (op === "sessions.status") {
14953
+ const value = result?.[id];
14954
+ return { [id]: { type: value?.type === "running" ? "busy" : value?.type ?? "idle" } };
14955
+ }
14953
14956
  if (op === "sessions.messages") return this.media.messages(project, id, (Array.isArray(result) ? result : []).map(normalizeMessage));
14954
14957
  if (["configuration.get", "configuration.providers"].includes(op)) return redact(result);
14955
14958
  if (op.startsWith("sessions.")) return this.media.normalize(project, normalizeSession(result));
@@ -16148,6 +16151,34 @@ var CodexAdapter = class {
16148
16151
  }
16149
16152
  return [...turns.values()];
16150
16153
  }
16154
+ async threadWithTurns(rpc, threadId) {
16155
+ const { thread } = await rpc.request("thread/read", { threadId });
16156
+ const turns = [];
16157
+ const seenCursors = /* @__PURE__ */ new Set();
16158
+ let cursor = null;
16159
+ try {
16160
+ do {
16161
+ const page = await rpc.request("thread/turns/list", {
16162
+ threadId,
16163
+ limit: 100,
16164
+ sortDirection: "asc",
16165
+ itemsView: "full",
16166
+ ...cursor ? { cursor } : {}
16167
+ });
16168
+ turns.push(...page.data);
16169
+ cursor = page.nextCursor ?? null;
16170
+ if (cursor && seenCursors.has(cursor)) break;
16171
+ if (cursor) seenCursors.add(cursor);
16172
+ } while (cursor);
16173
+ return { ...thread, turns };
16174
+ } catch (error) {
16175
+ const message = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();
16176
+ if (message.includes("not materialized")) return { ...thread, turns: [] };
16177
+ const unsupported = message.includes("method not found") || message.includes("unknown method") || message.includes("unsupported") && message.includes("thread/turns/list");
16178
+ if (!unsupported) throw error;
16179
+ return (await rpc.request("thread/read", { threadId, includeTurns: true })).thread;
16180
+ }
16181
+ }
16151
16182
  itemToPart(item) {
16152
16183
  const base = { id: item.id };
16153
16184
  const status = item.status === "completed" ? "completed" : ["failed", "declined"].includes(item.status ?? "") ? "failed" : "running";
@@ -16316,10 +16347,10 @@ var CodexAdapter = class {
16316
16347
  }
16317
16348
  if (op === "sessions.status") {
16318
16349
  if (!id) throw new Error("Session required");
16319
- const thread = await rpc.request("thread/read", { threadId: id, includeTurns: true });
16350
+ const thread = await this.threadWithTurns(rpc, id);
16320
16351
  const expected = await this.workspace.root(project);
16321
- if (thread.thread.cwd !== expected && !await this.index(project).then((index) => index.threadIds.includes(id))) throw new Error("Session belongs to another project");
16322
- const turns = this.mergedTurns(project, id, thread.thread.turns ?? []);
16352
+ if (thread.cwd !== expected && !await this.index(project).then((index) => index.threadIds.includes(id))) throw new Error("Session belongs to another project");
16353
+ const turns = this.mergedTurns(project, id, thread.turns ?? []);
16323
16354
  const status = turns.at(-1)?.status;
16324
16355
  const busy = typeof status === "string" && !["completed", "failed", "interrupted", "cancelled", "canceled"].includes(status.toLowerCase());
16325
16356
  const last = turns.at(-1);
@@ -16327,10 +16358,10 @@ var CodexAdapter = class {
16327
16358
  }
16328
16359
  if (op === "sessions.messages") {
16329
16360
  if (!id) throw new Error("Session required");
16330
- const thread = await rpc.request("thread/read", { threadId: id, includeTurns: true });
16361
+ const thread = await this.threadWithTurns(rpc, id);
16331
16362
  const expected = await this.workspace.root(project);
16332
- if (thread.thread.cwd !== expected && !await this.index(project).then((index) => index.threadIds.includes(id))) throw new Error("Session belongs to another project");
16333
- return this.media.messages(project, id, this.turnsToMessages(this.mergedTurns(project, id, thread.thread.turns ?? [])));
16363
+ if (thread.cwd !== expected && !await this.index(project).then((index) => index.threadIds.includes(id))) throw new Error("Session belongs to another project");
16364
+ return this.media.messages(project, id, this.turnsToMessages(this.mergedTurns(project, id, thread.turns ?? [])));
16334
16365
  }
16335
16366
  if (op === "sessions.prompt") {
16336
16367
  if (!id) throw new Error("Session required");
@@ -16357,7 +16388,7 @@ var CodexAdapter = class {
16357
16388
  await this.session(project, id);
16358
16389
  let turnId = this.activeTurns.get(id);
16359
16390
  if (!turnId) {
16360
- const { thread } = await rpc.request("thread/read", { threadId: id, includeTurns: true });
16391
+ const thread = await this.threadWithTurns(rpc, id);
16361
16392
  turnId = thread.turns?.slice().reverse().find((turn) => turn.status === "inProgress")?.id;
16362
16393
  }
16363
16394
  if (!turnId) return {};
package/dist/cli.js CHANGED
@@ -32,7 +32,7 @@ import {
32
32
  supportedPlatform,
33
33
  systemdUnitPath,
34
34
  toolSearchDirs
35
- } from "./chunk-HB3ETNMW.js";
35
+ } from "./chunk-HDXWS2VW.js";
36
36
 
37
37
  // src/cli.ts
38
38
  import { spawn as spawn2 } from "node:child_process";
@@ -721,7 +721,7 @@ async function confirmUpdate(latest) {
721
721
  if (!stdin2.isTTY) throw new Error("\u66F4\u65B0\u9700\u8981\u5728\u4EA4\u4E92\u5F0F\u7EC8\u7AEF\u4E2D\u786E\u8BA4\uFF1B\u8BF7\u5728\u7EC8\u7AEF\u8FD0\u884C octopus-proxy update");
722
722
  const rl = createInterface2({ input: stdin2, output: stdout2 });
723
723
  try {
724
- return /^(y|yes|是|确认)$/i.test((await rl.question(`\u662F\u5426\u8986\u76D6\u5B89\u88C5 ${proxyVersion} \u2192 ${latest}\uFF1F\u66F4\u65B0\u4F1A\u505C\u6B62\u5E76\u91CD\u542F\u670D\u52A1 [y/N]: `)).trim());
724
+ return /^(y|yes|是|确认)$/i.test((await rl.question(`\u662F\u5426\u8986\u76D6\u5B89\u88C5 ${proxyVersion} \u2192 ${latest}\uFF1F\u5B89\u88C5\u5E76\u6821\u9A8C\u6210\u529F\u540E\u4F1A\u91CD\u542F\u670D\u52A1 [y/N]: `)).trim());
725
725
  } finally {
726
726
  rl.close();
727
727
  }
@@ -768,27 +768,12 @@ async function runUpdate() {
768
768
  }
769
769
  const state = await serviceStatus();
770
770
  try {
771
- if (state.installed) {
772
- console.log("\u6B63\u5728\u505C\u6B62\u670D\u52A1\u2026");
773
- await controlService("stop");
774
- if ((await serviceStatus()).active) throw new Error("\u670D\u52A1\u4ECD\u5728\u8FD0\u884C\uFF0C\u5DF2\u4E2D\u6B62\u8986\u76D6\u5B89\u88C5");
775
- }
776
771
  console.log(`\u6B63\u5728\u5B89\u88C5 ${PACKAGE}@${latest}\u2026`);
777
772
  await installVersion(latest, prefix);
778
773
  const installed = JSON.parse(await readFile3(join3(target, "package.json"), "utf8"));
779
774
  if (installed.version !== latest) throw new Error(`\u5B89\u88C5\u7248\u672C\u6821\u9A8C\u5931\u8D25\uFF1A\u671F\u671B ${latest}\uFF0C\u5B9E\u9645 ${installed.version ?? "\u672A\u77E5"}`);
780
775
  } catch (error) {
781
- let recovery = "";
782
- if (state.active) {
783
- console.log("\u66F4\u65B0\u5931\u8D25\uFF0C\u6B63\u5728\u5C1D\u8BD5\u6062\u590D\u670D\u52A1\u2026");
784
- try {
785
- await restartAndVerify();
786
- recovery = "\uFF1B\u670D\u52A1\u5DF2\u6062\u590D\u8FD0\u884C";
787
- } catch (restartError) {
788
- recovery = `\uFF1B\u670D\u52A1\u6062\u590D\u5931\u8D25\uFF1A${message(restartError)}`;
789
- }
790
- }
791
- throw new Error(`\u66F4\u65B0\u5931\u8D25\uFF1A${message(error)}${recovery}`);
776
+ throw new Error(`\u66F4\u65B0\u5931\u8D25\uFF1A${message(error)}`);
792
777
  }
793
778
  if (state.installed) {
794
779
  console.log("\u5B89\u88C5\u5B8C\u6210\uFF0C\u6B63\u5728\u91CD\u542F\u670D\u52A1\u2026");
@@ -811,7 +796,7 @@ var USAGE = `octopus-proxy \u2014 Octopus \u4E3B\u673A\u4EE3\u7406
811
796
  projects \u5217\u51FA\u6388\u6743\u9879\u76EE\uFF1B\u53EF\u6309\u5E8F\u53F7\u5220\u9664\u9519\u8BEF\u914D\u7F6E\u9879
812
797
  install \u6821\u9A8C\u914D\u7F6E\u540E\u5B89\u88C5/\u66F4\u65B0\u7CFB\u7EDF\u670D\u52A1\uFF08\u5E42\u7B49\uFF0C\u81EA\u52A8\u542F\u52A8\uFF09
813
798
  uninstall \u505C\u6B62\u5E76\u79FB\u9664\u7CFB\u7EDF\u670D\u52A1\uFF08\u4FDD\u7559\u914D\u7F6E\u4E0E\u72B6\u6001\u6570\u636E\uFF09
814
- update \u68C0\u67E5 npm \u6700\u65B0\u7248\u672C\uFF0C\u786E\u8BA4\u540E\u505C\u6B62\u670D\u52A1\u3001\u8986\u76D6\u5B89\u88C5\u5E76\u91CD\u542F
799
+ update \u68C0\u67E5 npm \u6700\u65B0\u7248\u672C\uFF0C\u786E\u8BA4\u540E\u8986\u76D6\u5B89\u88C5\uFF0C\u6821\u9A8C\u6210\u529F\u540E\u91CD\u542F
815
800
  start \u542F\u52A8\u670D\u52A1
816
801
  stop \u505C\u6B62\u670D\u52A1
817
802
  restart \u91CD\u542F\u670D\u52A1
package/dist/main.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  ConfigError,
4
4
  runDaemon
5
- } from "./chunk-HB3ETNMW.js";
5
+ } from "./chunk-HDXWS2VW.js";
6
6
 
7
7
  // src/main.ts
8
8
  runDaemon(process.env.OCTOPUS_PROXY_CONFIG ?? "proxy.json").catch((error) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skylandnpm/octopus-proxy",
3
- "version": "0.1.42",
3
+ "version": "0.1.44",
4
4
  "type": "module",
5
5
  "description": "Octopus host proxy: OpenCode, Codex, ZCode and Pi adapters with service installer CLI",
6
6
  "bin": {