lark-coding-assistant 0.2.5 → 0.2.7
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 +2 -0
- package/dist/cli.js +26 -1
- package/dist/cli.js.map +1 -1
- package/dist/daemon-entry.js +50 -6
- package/dist/daemon-entry.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -230,6 +230,8 @@ lca daemon restart
|
|
|
230
230
|
|
|
231
231
|
`daemon stop/restart` 只断开或恢复飞书连接,不停止受管 tmux session。顶层 `stop [name]` 才会停止对应 agent 和 tmux session。
|
|
232
232
|
|
|
233
|
+
电脑休眠或网络暂时断开时,飞书长连接会自动重连;这不会停止 daemon 或受管 tmux session。唤醒后等待连接恢复即可,只有明确执行 `lca daemon stop` 才会停止 daemon。
|
|
234
|
+
|
|
233
235
|
`lca status` 会先显示 daemon 状态,再用一个表格列出全部 session;session 按 `codex`、`traex`、`claude` 分组排序,每个 session 占一行,当前连接使用 `●` 标记。表格同时显示终端状态、tmux 状态和绝对工作目录。使用 `lca status <name>` 可只查看指定 session;daemon 不可用时仍会读取本地状态,并将无法确认的运行信息明确标出。
|
|
234
236
|
|
|
235
237
|
## 绑定规则
|
package/dist/cli.js
CHANGED
|
@@ -939,8 +939,10 @@ 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}`
|
|
@@ -1449,7 +1451,11 @@ async function attachLocal(name) {
|
|
|
1449
1451
|
const state = await store.loadState();
|
|
1450
1452
|
const config = await store.loadConfig();
|
|
1451
1453
|
const session = state.sessions?.[name];
|
|
1452
|
-
if (!session)
|
|
1454
|
+
if (!session) {
|
|
1455
|
+
const exitEvent2 = state.recentSessionExits?.[name];
|
|
1456
|
+
if (exitEvent2?.reason === "agent-session-conflict") throw sessionConflictError(exitEvent2);
|
|
1457
|
+
throw new AppError("SESSION_NOT_FOUND", `no managed session: ${name}`, { sessionId: name });
|
|
1458
|
+
}
|
|
1453
1459
|
if (!config) throw new AppError("NOT_INITIALIZED", "not initialized");
|
|
1454
1460
|
try {
|
|
1455
1461
|
await runFile(config.tmuxBinary, ["has-session", "-t", `=${session.sessionName}`]);
|
|
@@ -1459,10 +1465,13 @@ async function attachLocal(name) {
|
|
|
1459
1465
|
binary: config.tmuxBinary
|
|
1460
1466
|
}, { cause: error });
|
|
1461
1467
|
}
|
|
1468
|
+
const exitEvent2 = (await store.loadState()).recentSessionExits?.[name];
|
|
1469
|
+
if (exitEvent2?.reason === "agent-session-conflict") throw sessionConflictError(exitEvent2);
|
|
1462
1470
|
throw new AppError("SESSION_NOT_FOUND", `managed session is no longer running: ${name}`, {
|
|
1463
1471
|
sessionId: name
|
|
1464
1472
|
}, { cause: error });
|
|
1465
1473
|
}
|
|
1474
|
+
const attachedAt = Date.now();
|
|
1466
1475
|
const child = spawn3(config.tmuxBinary, ["attach-session", "-t", `=${session.sessionName}`], { stdio: "inherit" });
|
|
1467
1476
|
const code = await new Promise((resolveExit, reject) => {
|
|
1468
1477
|
child.once("error", (error) => {
|
|
@@ -1476,8 +1485,24 @@ async function attachLocal(name) {
|
|
|
1476
1485
|
});
|
|
1477
1486
|
child.once("exit", resolveExit);
|
|
1478
1487
|
});
|
|
1488
|
+
const exitEvent = (await store.loadState()).recentSessionExits?.[name];
|
|
1489
|
+
if (exitEvent?.reason === "agent-session-conflict" && exitEvent.occurredAt >= attachedAt) {
|
|
1490
|
+
throw sessionConflictError(exitEvent);
|
|
1491
|
+
}
|
|
1479
1492
|
if (code && code !== 0) process.exitCode = code;
|
|
1480
1493
|
}
|
|
1494
|
+
function sessionConflictError(event) {
|
|
1495
|
+
return new AppError(
|
|
1496
|
+
"AGENT_SESSION_IN_USE",
|
|
1497
|
+
`agent session is already managed by ${event.ownerSessionId}`,
|
|
1498
|
+
{
|
|
1499
|
+
sessionId: event.sessionId,
|
|
1500
|
+
agent: event.agent,
|
|
1501
|
+
agentSessionId: event.agentSessionId,
|
|
1502
|
+
ownerSessionId: event.ownerSessionId
|
|
1503
|
+
}
|
|
1504
|
+
);
|
|
1505
|
+
}
|
|
1481
1506
|
async function runStatus(name) {
|
|
1482
1507
|
try {
|
|
1483
1508
|
const [response, health] = await Promise.all([
|