lark-coding-assistant 0.2.6 → 0.2.8

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/dist/cli.js CHANGED
@@ -939,13 +939,28 @@ function formatKnownError(error, context) {
939
939
  }
940
940
  case "AGENT_SESSION_IN_USE": {
941
941
  const ownerSessionId = safeValue(context.ownerSessionId, "\u73B0\u6709 session");
942
+ const agentSessionId = typeof context.agentSessionId === "string" ? safeValue(context.agentSessionId, "") : void 0;
942
943
  return [
943
944
  `\u65E0\u6CD5\u542F\u52A8 session\u300C${sessionId}\u300D\uFF1A\u5BF9\u5E94\u7684 Agent \u539F\u751F session \u5DF2\u7531\u300C${ownerSessionId}\u300D\u8FDE\u63A5\u3002`,
945
+ ...agentSessionId ? ["", `\u539F\u751F session ID\uFF1A${agentSessionId}`] : [],
944
946
  "",
945
947
  "\u8BF7\u76F4\u63A5\u8FDE\u63A5\u73B0\u6709 session\uFF1A",
946
948
  ` lark-coding-assistant attach ${ownerSessionId}`
947
949
  ];
948
950
  }
951
+ case "AGENT_EXITED": {
952
+ const exitStatus = typeof context.exitStatus === "number" ? `\uFF08\u9000\u51FA\u7801 ${context.exitStatus}\uFF09` : "";
953
+ return [
954
+ `Agent \u5DF2\u9000\u51FA${exitStatus}\uFF0Csession\u300C${sessionId}\u300D\u5DF2\u5173\u95ED\u3002`,
955
+ "",
956
+ "\u539F\u59CB\u9519\u8BEF\uFF1A",
957
+ safeValue(context.terminalExcerpt, "Agent \u672A\u8F93\u51FA\u53EF\u7528\u9519\u8BEF\u4FE1\u606F\u3002"),
958
+ "",
959
+ "\u53EF\u67E5\u770B\u65E5\u5FD7\u6216\u91CD\u65B0\u542F\u52A8\uFF1A",
960
+ " lark-coding-assistant logs",
961
+ ` lark-coding-assistant start --name ${sessionId} --agent ${safeValue(context.agent, "codex")}`
962
+ ];
963
+ }
949
964
  case "AGENT_EXITED_DURING_STARTUP": {
950
965
  const exitStatus = typeof context.exitStatus === "number" ? `\uFF08\u9000\u51FA\u7801 ${context.exitStatus}\uFF09` : "";
951
966
  return [
@@ -1449,7 +1464,11 @@ async function attachLocal(name) {
1449
1464
  const state = await store.loadState();
1450
1465
  const config = await store.loadConfig();
1451
1466
  const session = state.sessions?.[name];
1452
- if (!session) throw new AppError("SESSION_NOT_FOUND", `no managed session: ${name}`, { sessionId: name });
1467
+ if (!session) {
1468
+ const exitEvent2 = state.recentSessionExits?.[name];
1469
+ if (exitEvent2) throw sessionExitError(exitEvent2);
1470
+ throw new AppError("SESSION_NOT_FOUND", `no managed session: ${name}`, { sessionId: name });
1471
+ }
1453
1472
  if (!config) throw new AppError("NOT_INITIALIZED", "not initialized");
1454
1473
  try {
1455
1474
  await runFile(config.tmuxBinary, ["has-session", "-t", `=${session.sessionName}`]);
@@ -1459,10 +1478,13 @@ async function attachLocal(name) {
1459
1478
  binary: config.tmuxBinary
1460
1479
  }, { cause: error });
1461
1480
  }
1481
+ const exitEvent2 = (await store.loadState()).recentSessionExits?.[name];
1482
+ if (exitEvent2) throw sessionExitError(exitEvent2);
1462
1483
  throw new AppError("SESSION_NOT_FOUND", `managed session is no longer running: ${name}`, {
1463
1484
  sessionId: name
1464
1485
  }, { cause: error });
1465
1486
  }
1487
+ const attachedAt = Date.now();
1466
1488
  const child = spawn3(config.tmuxBinary, ["attach-session", "-t", `=${session.sessionName}`], { stdio: "inherit" });
1467
1489
  const code = await new Promise((resolveExit, reject) => {
1468
1490
  child.once("error", (error) => {
@@ -1476,8 +1498,37 @@ async function attachLocal(name) {
1476
1498
  });
1477
1499
  child.once("exit", resolveExit);
1478
1500
  });
1501
+ await requestDaemon(paths.socket, { method: "reconcile" }, 2500).catch(() => void 0);
1502
+ const exitEvent = (await store.loadState()).recentSessionExits?.[name];
1503
+ if (exitEvent && exitEvent.occurredAt >= attachedAt) {
1504
+ throw sessionExitError(exitEvent);
1505
+ }
1479
1506
  if (code && code !== 0) process.exitCode = code;
1480
1507
  }
1508
+ function sessionExitError(event) {
1509
+ if (event.reason === "agent-exited") {
1510
+ return new AppError(
1511
+ "AGENT_EXITED",
1512
+ `agent exited: ${event.sessionId}`,
1513
+ {
1514
+ sessionId: event.sessionId,
1515
+ agent: event.agent,
1516
+ exitStatus: event.exitStatus,
1517
+ terminalExcerpt: event.terminalExcerpt
1518
+ }
1519
+ );
1520
+ }
1521
+ return new AppError(
1522
+ "AGENT_SESSION_IN_USE",
1523
+ `agent session is already managed by ${event.ownerSessionId ?? "another session"}`,
1524
+ {
1525
+ sessionId: event.sessionId,
1526
+ agent: event.agent,
1527
+ agentSessionId: event.agentSessionId,
1528
+ ownerSessionId: event.ownerSessionId
1529
+ }
1530
+ );
1531
+ }
1481
1532
  async function runStatus(name) {
1482
1533
  try {
1483
1534
  const [response, health] = await Promise.all([