alink-cli 0.11.11 → 0.11.13

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
@@ -25,5 +25,6 @@ alink
25
25
  `alink login` 会打开浏览器,支持使用 GitHub 或已有 AgentLink 账号登录并添加当前电脑。原命令 `alink-cli` 继续可用。
26
26
 
27
27
  脚本或排障时可用 `alink status --json` 和 `alink machines --json` 获取结构化的本机连接状态与账号机器数据。daemon 在网络中断、电脑唤醒或 Hub 更新后会自动退避重连,无需手动重启。
28
+ daemon 每次连接 Hub 时都会上报当前 `alink-cli` 包版本,供机器列表展示。
28
29
 
29
30
  [GitHub](https://github.com/baichen99/agentlink) · [提交问题](https://github.com/baichen99/agentlink/issues)
package/bin/agentlink.js CHANGED
@@ -62,6 +62,7 @@ const STATE_DIR = process.env.AGENTLINK_STATE_DIR || join(homedir(), ".agentlink
62
62
  const CREDENTIAL_FILE = join(STATE_DIR, "credential");
63
63
  const SESSION_FILE = join(STATE_DIR, "session");
64
64
  const STATUS_FILE = join(STATE_DIR, "status.json");
65
+ const CLI_VERSION = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
65
66
  const args = process.argv.slice(2);
66
67
  const legacyCredentialCommands = process.env.AGENTLINK_ENABLE_LEGACY_CREDENTIALS === "1";
67
68
  const forceTui = process.env.AGENTLINK_TUI === "1";
@@ -446,6 +447,7 @@ async function doNoTuiStart() {
446
447
  T3CODE_HUB_URL: hub,
447
448
  T3CODE_HUB_MACHINE_TOKEN: machineToken,
448
449
  T3CODE_HUB_ENCKEY: enckey,
450
+ AGENTLINK_CLI_VERSION: CLI_VERSION,
449
451
  },
450
452
  });
451
453
  for (const signal of ["SIGINT", "SIGTERM"]) process.on(signal, () => child.kill(signal));
package/dist/bin.mjs CHANGED
@@ -52047,6 +52047,9 @@ var PtyAdapter = class extends Service$2()("t3/terminal/PtyAdapter") {};
52047
52047
  //#region src/terminal/Manager.ts
52048
52048
  const DEFAULT_COLS = 120;
52049
52049
  const DEFAULT_ROWS = 30;
52050
+ function terminalLocale(environment, platform) {
52051
+ return environment.LC_ALL ?? environment.LC_CTYPE ?? environment.LANG ?? (platform === "darwin" ? "en_US.UTF-8" : "C.UTF-8");
52052
+ }
52050
52053
  var TerminalManager = class extends Service$2()("agentlink/terminal/TerminalManager") {};
52051
52054
  function sessionKey(threadId, terminalId) {
52052
52055
  return `${threadId}\0${terminalId}`;
@@ -52155,7 +52158,11 @@ const layer$7 = effect(TerminalManager, gen(function* () {
52155
52158
  env: {
52156
52159
  ...process.env,
52157
52160
  ...session.env,
52158
- TERM: "xterm-256color"
52161
+ TERM: "xterm-256color",
52162
+ LANG: terminalLocale({
52163
+ ...process.env,
52164
+ ...session.env
52165
+ }, process.platform)
52159
52166
  }
52160
52167
  }));
52161
52168
  if (result$1._tag === "Success") {
@@ -53292,6 +53299,12 @@ function hubHttpUrl(hub) {
53292
53299
  url.hash = "";
53293
53300
  return url.toString().replace(/\/$/, "");
53294
53301
  }
53302
+ function hubRegistration(cliVersion) {
53303
+ return cliVersion ? {
53304
+ type: "register",
53305
+ daemonVersion: cliVersion
53306
+ } : null;
53307
+ }
53295
53308
  function writeHubConnectionStatus(config, connected, stateDir = process.env.AGENTLINK_STATE_DIR || join(homedir(), ".agentlink")) {
53296
53309
  try {
53297
53310
  mkdirSync(stateDir, { recursive: true });
@@ -53306,6 +53319,7 @@ function writeHubConnectionStatus(config, connected, stateDir = process.env.AGEN
53306
53319
  state: connected ? "connected" : "reconnecting",
53307
53320
  hub: config.hubUrl,
53308
53321
  hubConnected: connected,
53322
+ ...process.env.AGENTLINK_CLI_VERSION ? { daemonVersion: process.env.AGENTLINK_CLI_VERSION } : {},
53309
53323
  machineId: machineIdFromToken(config.machineToken) ?? void 0,
53310
53324
  startedAt: typeof current.startedAt === "number" ? current.startedAt : Date.now(),
53311
53325
  ts: Date.now()
@@ -53714,7 +53728,10 @@ const runHubTunnel = (config) => gen(function* () {
53714
53728
  else dropTunnel(framed.tunnelId);
53715
53729
  return;
53716
53730
  }
53717
- }, { onOpen: logInfo("hub tunnel: connected to hub").pipe(tap(() => sync(() => writeHubConnectionStatus(config, true))), tap(() => sync(() => void runFork(upload)))) }).pipe(ensuring(sync(() => writeHubConnectionStatus(config, false))), tapDefect((cause) => logWarning$1("hub tunnel: hub socket defect", { cause: String(cause) })));
53731
+ }, { onOpen: logInfo("hub tunnel: connected to hub").pipe(tap(() => sync(() => {
53732
+ const registration = hubRegistration(process.env.AGENTLINK_CLI_VERSION);
53733
+ if (registration) writeHub(JSON.stringify(registration));
53734
+ })), tap(() => sync(() => writeHubConnectionStatus(config, true))), tap(() => sync(() => void runFork(upload)))) }).pipe(ensuring(sync(() => writeHubConnectionStatus(config, false))), tapDefect((cause) => logWarning$1("hub tunnel: hub socket defect", { cause: String(cause) })));
53718
53735
  yield* logWarning$1("hub tunnel: hub connection closed");
53719
53736
  return yield* fail(/* @__PURE__ */ new Error("hub tunnel closed"));
53720
53737
  }).pipe(scoped, tapError((error) => logWarning$1("hub tunnel: connection error", { error }))), {
@@ -88871,6 +88888,9 @@ effect(RuntimeReceiptBus, makeRuntimeReceiptBusTest);
88871
88888
  //#region src/orchestration/Layers/ProviderRuntimeIngestion.ts
88872
88889
  const providerTurnKey = (threadId, turnId) => `${threadId}:${turnId}`;
88873
88890
  const providerTaskKey = (threadId, taskId) => `${threadId}:${taskId}`;
88891
+ function providerReconciliationFailureDetail(cause) {
88892
+ return cause instanceof Error && cause.message.toLowerCase().includes("active writer") ? "对话正在另一端运行,请等待另一端结束后再继续。" : cause instanceof Error ? cause.message : "Provider snapshot sync failed.";
88893
+ }
88874
88894
  function findTaskTitleInActivities(activities, taskId) {
88875
88895
  if (!activities) return;
88876
88896
  for (let index = activities.length - 1; index >= 0; index -= 1) {
@@ -89880,7 +89900,9 @@ const ProviderRuntimeIngestionLive = effect(ProviderRuntimeIngestionService, gen
89880
89900
  });
89881
89901
  const reconcileThreadUnlocked = fn("reconcileThreadUnlocked")(function* (threadId, options) {
89882
89902
  const thread = yield* resolveThreadShell(threadId);
89883
- if (!thread || thread.session?.providerName !== ProviderDriverKind.make("codex")) return;
89903
+ if (!thread) return;
89904
+ const session = thread.session;
89905
+ if (session?.providerName !== ProviderDriverKind.make("codex")) return;
89884
89906
  const snapshot = yield* providerService.readThread(threadId);
89885
89907
  for (const turn of snapshot.turns) {
89886
89908
  const existing = getOrUndefined(yield* projectionTurnRepository.getByTurnId({
@@ -89892,7 +89914,7 @@ const ProviderRuntimeIngestionLive = effect(ProviderRuntimeIngestionService, gen
89892
89914
  if (isTerminal) {
89893
89915
  const pendingTurnStart = yield* projectionTurnRepository.getPendingTurnStartByThreadId({ threadId });
89894
89916
  if (!(existing?.pendingMessageId !== null && existing?.pendingMessageId !== void 0 ? true : isSome(pendingTurnStart))) {
89895
- const createdAt = turn.startedAt ?? turn.runtimeEvents?.[0]?.createdAt ?? thread.session.updatedAt;
89917
+ const createdAt = turn.startedAt ?? turn.runtimeEvents?.[0]?.createdAt ?? session.updatedAt;
89896
89918
  const providerThreadId = snapshot.providerThreadId ?? String(threadId);
89897
89919
  for (const userMessage of turn.userMessages ?? []) yield* orchestrationEngine.dispatch({
89898
89920
  type: "thread.message.user.import",
@@ -89912,11 +89934,27 @@ const ProviderRuntimeIngestionLive = effect(ProviderRuntimeIngestionService, gen
89912
89934
  });
89913
89935
  }
89914
89936
  if (options?.requireWritable !== true) return;
89915
- yield* providerService.ensureSession(threadId);
89937
+ yield* providerService.ensureSession(threadId).pipe(tapError((cause) => gen(function* () {
89938
+ const updatedAt = formatIso(yield* now$1);
89939
+ const detail = providerReconciliationFailureDetail(cause);
89940
+ yield* orchestrationEngine.dispatch({
89941
+ type: "thread.session.set",
89942
+ commandId: CommandId.make(`provider-writer-acquisition:${threadId}:${yield* crypto.randomUUIDv4}`),
89943
+ threadId,
89944
+ session: {
89945
+ ...session,
89946
+ status: "error",
89947
+ activeTurnId: null,
89948
+ lastError: detail,
89949
+ updatedAt
89950
+ },
89951
+ createdAt: updatedAt
89952
+ });
89953
+ })));
89916
89954
  });
89917
89955
  const reconcileThread = (threadId, options) => withThreadLock(threadId, reconcileThreadUnlocked(threadId, options)).pipe(mapError((cause) => cause instanceof ProviderRuntimeReconciliationError ? cause : new ProviderRuntimeReconciliationError({
89918
89956
  threadId,
89919
- detail: cause instanceof Error && cause.message.toLowerCase().includes("active writer") ? "对话正在另一端运行,请等待另一端结束后再继续。" : cause instanceof Error ? cause.message : "Provider snapshot sync failed.",
89957
+ detail: providerReconciliationFailureDetail(cause),
89920
89958
  cause
89921
89959
  })));
89922
89960
  const processDomainEvent = (_event) => void_$1;