ework-web 0.10.80 → 0.10.82
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/package.json +1 -1
- package/src/coordination.ts +24 -0
- package/src/index.ts +17 -3
- package/src/schema-mysql.sql +7 -0
package/package.json
CHANGED
package/src/coordination.ts
CHANGED
|
@@ -75,6 +75,30 @@ export interface SessionDaemonInfo {
|
|
|
75
75
|
endpoint: string;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
export interface SessionUidInfo {
|
|
79
|
+
daemonId: number;
|
|
80
|
+
opencodeSessionId: string | null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export async function resolveSessionUid(uid: string): Promise<SessionUidInfo | null> {
|
|
84
|
+
try {
|
|
85
|
+
const rows = await getDB().all<{ daemon_id: number; opencode_session_id: string | null }>(
|
|
86
|
+
`SELECT i.owner_daemon_id AS daemon_id, s.opencode_session_id
|
|
87
|
+
FROM {{d_op_sessions}} s
|
|
88
|
+
JOIN {{d_issues}} i ON i.uid = s.issue_id
|
|
89
|
+
WHERE s.uid = ?
|
|
90
|
+
LIMIT 1`,
|
|
91
|
+
[uid],
|
|
92
|
+
);
|
|
93
|
+
const r = rows[0];
|
|
94
|
+
if (!r || !r.daemon_id) return null;
|
|
95
|
+
return { daemonId: r.daemon_id, opencodeSessionId: r.opencode_session_id && r.opencode_session_id !== "" ? r.opencode_session_id : null };
|
|
96
|
+
} catch (e) {
|
|
97
|
+
log.info(`coordination: session uid resolve failed (${e instanceof Error ? e.message : String(e)})`);
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
78
102
|
export async function getSessionDaemonMap(): Promise<Map<string, SessionDaemonInfo>> {
|
|
79
103
|
try {
|
|
80
104
|
const rows = await getDB().all<{
|
package/src/index.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { homedir } from "os";
|
|
|
6
6
|
import { loadConfig, DB_OVERRIDABLE, parseOverride, resolveTtsBackend } from "./config";
|
|
7
7
|
import type { Config } from "./config";
|
|
8
8
|
import { setConfig, deleteConfig, getConfigAll, initDB, getDB } from "./db";
|
|
9
|
-
import { getActiveDaemons, listAllDaemons, getSessionDaemonMap, resolveDaemonEndpoint, getRunningSessionsForProject } from "./coordination";
|
|
9
|
+
import { getActiveDaemons, listAllDaemons, getSessionDaemonMap, resolveDaemonEndpoint, getRunningSessionsForProject, resolveSessionUid } from "./coordination";
|
|
10
10
|
import { testMysqlConnection, migrateSqliteToMysql, writeMysqlEnv, migrateMysqlToSqlite, writeSqliteEnv, migrateDaemonSqliteToMysql, generateMysqlDDL } from "./db-admin";
|
|
11
11
|
import type { MysqlTargetOpts } from "./db-admin";
|
|
12
12
|
import { checkAuth, makeAuthCookieHeader, clearAuthCookieHeader, loginHTML, sanitizeNext, ensureBootstrapAdmin, ensureBootstrapSystem, isReservedSystemLogin } from "./auth";
|
|
@@ -709,8 +709,22 @@ async function handle(req: Request, url: URL, ip: string, ctx: { authed: boolean
|
|
|
709
709
|
|
|
710
710
|
const sessionView = url.pathname.match(SESSION_VIEW_RE);
|
|
711
711
|
if (sessionView) {
|
|
712
|
-
const [,
|
|
713
|
-
if (!
|
|
712
|
+
const [, rawSid] = sessionView;
|
|
713
|
+
if (!rawSid) return html(errorPage("404", "bad session path"), 404);
|
|
714
|
+
// Daemon-internal session UIDs (36-char uuid) appear in pickup acks before
|
|
715
|
+
// the backend reports its opencode id: redirect once known, hold page if not.
|
|
716
|
+
let sid = rawSid;
|
|
717
|
+
if (!sid.startsWith("ses_")) {
|
|
718
|
+
const uidInfo = await resolveSessionUid(rawSid);
|
|
719
|
+
if (uidInfo?.opencodeSessionId) {
|
|
720
|
+
const qs = new URLSearchParams(url.searchParams);
|
|
721
|
+
qs.set("daemon_id", String(uidInfo.daemonId));
|
|
722
|
+
return Response.redirect(`${url.origin}/sessions/${encodeURIComponent(uidInfo.opencodeSessionId)}?${qs}`, 302);
|
|
723
|
+
}
|
|
724
|
+
if (uidInfo) {
|
|
725
|
+
return html(errorPage("等待启动", "会话已创建,后端会话 ID 尚未生成(正在准备工作目录)。稍后刷新此页。"), 200);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
714
728
|
const desc = url.searchParams.get("asc") !== "1";
|
|
715
729
|
const all = url.searchParams.get("all") === "1";
|
|
716
730
|
const limit = Math.min(5000, Math.max(1, Number(url.searchParams.get("limit")) || 30));
|
package/src/schema-mysql.sql
CHANGED
|
@@ -211,3 +211,10 @@ CREATE TABLE IF NOT EXISTS {{project_members}} (
|
|
|
211
211
|
CONSTRAINT {{fk_pm_user}} FOREIGN KEY (user_login) REFERENCES {{users}}(login) ON DELETE CASCADE
|
|
212
212
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
213
213
|
CREATE INDEX project_members_user ON {{project_members}} (user_login);
|
|
214
|
+
|
|
215
|
+
CREATE TABLE IF NOT EXISTS {{config}} (
|
|
216
|
+
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
217
|
+
akey VARCHAR(255) NOT NULL UNIQUE,
|
|
218
|
+
value TEXT NOT NULL,
|
|
219
|
+
updated_at VARCHAR(40) NOT NULL
|
|
220
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|