fix: warn when /sessions falls back to live-only list (v0.3.3)

Phone showed 2 sessions because apiProxy catalog failed (pre-0.3.2 inject bug) and live-agent fallback hid cold Web sessions. Surface that mode explicitly.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
owo
2026-08-14 20:22:20 +08:00
co-authored by Cursor
parent 5dbe833205
commit 3566df945b
7 changed files with 16 additions and 7 deletions
+3 -1
View File
@@ -245,7 +245,9 @@ export class TelegramBridge {
}])), }])),
}; };
const body = [ const body = [
`选择工作区(共 ${workspaces.length} 个,与 Web 对齐,已排除归档):`, catalog.complete
? `选择工作区(共 ${workspaces.length} 个,与 Web 对齐,已排除归档):`
: `选择工作区(共 ${workspaces.length} 个)⚠️ 仅运行中的会话(apiProxy 未就绪,完整列表需插件 ≥0.3.2 并重启 dsh web):`,
'', '',
...shown.map((ws, i) => { ...shown.map((ws, i) => {
const n = visibleSessionsForWorkspace(catalog, ws).length; const n = visibleSessionsForWorkspace(catalog, ws).length;
+2
View File
@@ -19,6 +19,8 @@ export interface CatalogSnapshot {
workspaces: WorkspaceRow[]; workspaces: WorkspaceRow[];
sessionsById: Map<string, SessionRow>; sessionsById: Map<string, SessionRow>;
archivedIds: Set<string>; archivedIds: Set<string>;
/** true when loaded from apiProxy (Web-aligned); false for live-agent fallback. */
complete: boolean;
} }
/** Load workspaces + sessions aligned with Web UI (via apiProxy when available). */ /** Load workspaces + sessions aligned with Web UI (via apiProxy when available). */
export declare function loadCatalog(ctx: Context): Promise<CatalogSnapshot | undefined>; export declare function loadCatalog(ctx: Context): Promise<CatalogSnapshot | undefined>;
+2 -2
View File
@@ -58,7 +58,7 @@ export async function loadCatalog(ctx) {
path: w.path, path: w.path,
sessionIds: (w.sessionIds ?? []).map(String), sessionIds: (w.sessionIds ?? []).map(String),
})); }));
return { workspaces, sessionsById, archivedIds }; return { workspaces, sessionsById, archivedIds, complete: true };
} }
/** Sessions visible under one workspace (Web-like filters). */ /** Sessions visible under one workspace (Web-like filters). */
export function visibleSessionsForWorkspace(catalog, workspace) { export function visibleSessionsForWorkspace(catalog, workspace) {
@@ -116,5 +116,5 @@ export function catalogFromLiveAgents(agents, ctx) {
path, path,
sessionIds: bucket.sessionIds, sessionIds: bucket.sessionIds,
})); }));
return { workspaces, sessionsById, archivedIds: new Set() }; return { workspaces, sessionsById, archivedIds: new Set(), complete: false };
} }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "dsh-telegram-channel", "name": "dsh-telegram-channel",
"version": "0.3.2", "version": "0.3.3",
"description": "DeepSeek Harness Telegram mobile remote: workspace→session picker (Web-aligned), /model switch, same trajectory — dsh-plugin", "description": "DeepSeek Harness Telegram mobile remote: workspace→session picker (Web-aligned), /model switch, same trajectory — dsh-plugin",
"keywords": [ "keywords": [
"telegram", "telegram",
+3 -1
View File
@@ -310,7 +310,9 @@ export class TelegramBridge {
}])), }])),
} }
const body = [ const body = [
`选择工作区(共 ${workspaces.length} 个,与 Web 对齐,已排除归档):`, catalog.complete
? `选择工作区(共 ${workspaces.length} 个,与 Web 对齐,已排除归档):`
: `选择工作区(共 ${workspaces.length} 个)⚠️ 仅运行中的会话(apiProxy 未就绪,完整列表需插件 ≥0.3.2 并重启 dsh web):`,
'', '',
...shown.map((ws, i) => { ...shown.map((ws, i) => {
const n = visibleSessionsForWorkspace(catalog, ws).length const n = visibleSessionsForWorkspace(catalog, ws).length
+4 -2
View File
@@ -25,6 +25,8 @@ export interface CatalogSnapshot {
workspaces: WorkspaceRow[] workspaces: WorkspaceRow[]
sessionsById: Map<string, SessionRow> sessionsById: Map<string, SessionRow>
archivedIds: Set<string> archivedIds: Set<string>
/** true when loaded from apiProxy (Web-aligned); false for live-agent fallback. */
complete: boolean
} }
type RpcOk<T> = { result: { ok: true; value: T } } type RpcOk<T> = { result: { ok: true; value: T } }
@@ -107,7 +109,7 @@ export async function loadCatalog(ctx: Context): Promise<CatalogSnapshot | undef
sessionIds: (w.sessionIds ?? []).map(String), sessionIds: (w.sessionIds ?? []).map(String),
})) }))
return { workspaces, sessionsById, archivedIds } return { workspaces, sessionsById, archivedIds, complete: true }
} }
/** Sessions visible under one workspace (Web-like filters). */ /** Sessions visible under one workspace (Web-like filters). */
@@ -170,5 +172,5 @@ export function catalogFromLiveAgents(agents: Agent[], ctx?: Context): CatalogSn
sessionIds: bucket.sessionIds, sessionIds: bucket.sessionIds,
})) }))
return { workspaces, sessionsById, archivedIds: new Set() } return { workspaces, sessionsById, archivedIds: new Set(), complete: false }
} }
+1
View File
@@ -8,6 +8,7 @@ import {
test('visible sessions exclude archived blank and subagent', () => { test('visible sessions exclude archived blank and subagent', () => {
const catalog: CatalogSnapshot = { const catalog: CatalogSnapshot = {
complete: true,
archivedIds: new Set(['arch']), archivedIds: new Set(['arch']),
sessionsById: new Map([ sessionsById: new Map([
['ok', { sessionId: 'ok', title: 'OK', blank: false, running: true, updatedAt: 1 }], ['ok', { sessionId: 'ok', title: 'OK', blank: false, running: true, updatedAt: 1 }],