@jingyi0605/codingns 0.9.6 → 0.9.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/dist/public/assets/{AdaptiveButlerPage-khJQh6a_.js → AdaptiveButlerPage-DclGPzEx.js} +2 -2
- package/dist/public/assets/{App-If9gThKM.js → App-BxX5mm9o.js} +3 -3
- package/dist/public/assets/{BootstrapPage-DcfYtoLC.js → BootstrapPage-Bl21SsuW.js} +1 -1
- package/dist/public/assets/{ConversationPage-Bfb7GLTM.js → ConversationPage-CmiVCV0q.js} +7 -7
- package/dist/public/assets/{DesktopDetachPreviewPage-CXUPMcBz.js → DesktopDetachPreviewPage-uaOHVsjV.js} +1 -1
- package/dist/public/assets/{DesktopModal-bMdI1jEe.js → DesktopModal-BxsogpLf.js} +1 -1
- package/dist/public/assets/{DesktopWindowPage-D1xwgS-7.js → DesktopWindowPage-Bubfw1nC.js} +1 -1
- package/dist/public/assets/{FileContextPanel-C4syif3B.js → FileContextPanel-DrYWcTkp.js} +1 -1
- package/dist/public/assets/{GitSidebar-DduL9aTV.js → GitSidebar-CQsfJqun.js} +1 -1
- package/dist/public/assets/{MobileCreateSessionSheet-DWPBsEx8.js → MobileCreateSessionSheet-CqtmfVNo.js} +1 -1
- package/dist/public/assets/{MobileSheet-BXvQPkxt.js → MobileSheet-C5IVmUsO.js} +1 -1
- package/dist/public/assets/{MobileTopHeaderFrame-vdYOyaaB.js → MobileTopHeaderFrame-EoBm3-X0.js} +1 -1
- package/dist/public/assets/{MobileWorkspaceSwitcherHeader-DT330cAx.js → MobileWorkspaceSwitcherHeader-BC8MMQs_.js} +1 -1
- package/dist/public/assets/{PluginAccessOverview-C77TeZTK.js → PluginAccessOverview-CrQiQxxZ.js} +1 -1
- package/dist/public/assets/{PluginContainerPage-DdSwOCw-.js → PluginContainerPage-_2u-9thM.js} +1 -1
- package/dist/public/assets/{PluginDetailPage-BK1yTzvO.js → PluginDetailPage-F9cKjSCp.js} +1 -1
- package/dist/public/assets/{PluginsListPage-DAAwSc6W.js → PluginsListPage-BOhcua_4.js} +1 -1
- package/dist/public/assets/{RelayConnectEntryPage-4Yyo2p8b.js → RelayConnectEntryPage-Ck_uZLzj.js} +1 -1
- package/dist/public/assets/{ServerSettingsModal-C_DEisHs.js → ServerSettingsModal-ICd82a_x.js} +1 -1
- package/dist/public/assets/SessionIndexPage-Cox6P6dw.js +1 -0
- package/dist/public/assets/{SettingsPage-CDAVsPr3.js → SettingsPage-BI5cM3j5.js} +1 -1
- package/dist/public/assets/{TerminalManagerPanel-4OR47vcf.js → TerminalManagerPanel-DiVhBQhf.js} +1 -1
- package/dist/public/assets/{TerminalPage-Pvx396YX.js → TerminalPage-DUMUO7Ng.js} +1 -1
- package/dist/public/assets/{TerminalRuntimeFallbackModal-KvG6k4AQ.js → TerminalRuntimeFallbackModal-DGPR_CMh.js} +1 -1
- package/dist/public/assets/{ToolFilesPage-DrYHk0N-.js → ToolFilesPage-m88CAp-r.js} +1 -1
- package/dist/public/assets/{ToolGitPage-Dz1q-Ns_.js → ToolGitPage-DCYpfTsb.js} +1 -1
- package/dist/public/assets/{ToolProcessesPage-CRhphOmM.js → ToolProcessesPage-Bk5ulsyq.js} +1 -1
- package/dist/public/assets/{ToolsHomePage-BJSDLR6T.js → ToolsHomePage-BrTwfjI7.js} +1 -1
- package/dist/public/assets/{WorkbenchLandingPage-BlkxdOLC.js → WorkbenchLandingPage-q4AAmdMV.js} +1 -1
- package/dist/public/assets/{WorkbenchLayout-D-U7ghT0.js → WorkbenchLayout-DD8b-m2G.js} +66 -61
- package/dist/public/assets/{WorkbenchModal-xbx1o6MO.js → WorkbenchModal-CsZeLArg.js} +1 -1
- package/dist/public/assets/WorkbenchShellRoute-BaiW_vfb.js +1 -0
- package/dist/public/assets/WorkbenchShellRoute-CxKYZ6uF.css +1 -0
- package/dist/public/assets/{WorkspaceDebugDetailPage-B4ol2_a5.js → WorkspaceDebugDetailPage-BcUUDEyw.js} +1 -1
- package/dist/public/assets/WorkspaceDetailPage-zEZ1VARA.js +1 -0
- package/dist/public/assets/{WorkspaceHomePage-tmCafatd.js → WorkspaceHomePage-CR0rqS4e.js} +1 -1
- package/dist/public/assets/{client-runtime-manager-Bwau7p1v.js → client-runtime-manager-BgGugw8T.js} +1 -1
- package/dist/public/assets/{index-_OCkVmfl.js → index-CFyk1rgJ.js} +5 -5
- package/dist/public/assets/index-CrU73EIV.css +1 -0
- package/dist/public/assets/{login-direct-candidate-resolver-CKUQ07IA.js → login-direct-candidate-resolver-ty2uOY5y.js} +1 -1
- package/dist/public/assets/{plugin-permission-copy-DIVk5jNp.js → plugin-permission-copy-iK3faI3n.js} +1 -1
- package/dist/public/assets/{plugins-api-DHJVvPZw.js → plugins-api-CmV7aDGA.js} +1 -1
- package/dist/public/assets/{preferences-service-CyxxeBmS.js → preferences-service-BoSmT_ny.js} +1 -1
- package/dist/public/assets/{relay-entry-B5GmiOrR.js → relay-entry-C8k5qsl5.js} +1 -1
- package/dist/public/assets/styles-BhKoKfQ_.css +1 -0
- package/dist/public/assets/{terminal-runtime-meta-DBsyT35T.js → terminal-runtime-meta-okQIDzfA.js} +1 -1
- package/dist/public/assets/{useRegisteredDebugTemplates-wCGD2SLW.js → useRegisteredDebugTemplates-B_vXUtSe.js} +1 -1
- package/dist/public/assets/{workbench-navigation-RyUjchbD.js → workbench-navigation-DoDaQR4z.js} +1 -1
- package/dist/public/index.html +2 -2
- package/dist/server/modules/provider/provider-discovery-runtime.js +16 -1
- package/dist/server/modules/provider/provider-discovery-runtime.js.map +1 -1
- package/dist/server/modules/sessions/codex-app-server-helper-client.js +14 -0
- package/dist/server/modules/sessions/codex-app-server-helper-client.js.map +1 -1
- package/dist/server/modules/sessions/codex-app-server-helper-process.js +59 -0
- package/dist/server/modules/sessions/codex-app-server-helper-process.js.map +1 -1
- package/dist/server/modules/sessions/codex-session-title-generator.d.ts +19 -0
- package/dist/server/modules/sessions/codex-session-title-generator.js +295 -0
- package/dist/server/modules/sessions/codex-session-title-generator.js.map +1 -0
- package/dist/server/modules/sessions/session-history-service.d.ts +5 -0
- package/dist/server/modules/sessions/session-history-service.js +183 -0
- package/dist/server/modules/sessions/session-history-service.js.map +1 -1
- package/dist/server/modules/tasks/task-types.d.ts +1 -0
- package/dist/server/modules/tasks/task-types.js +1 -0
- package/dist/server/modules/tasks/task-types.js.map +1 -1
- package/dist/server/modules/workspace/affairs-lightweight-session-service.js +13 -9
- package/dist/server/modules/workspace/affairs-lightweight-session-service.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/providers/codex.d.ts +7 -0
- package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +596 -6
- package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.d.ts +1 -0
- package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js +249 -6
- package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/types.d.ts +11 -0
- package/package.json +1 -1
- package/dist/public/assets/SessionIndexPage-DyMikN_x.js +0 -1
- package/dist/public/assets/WorkbenchShellRoute-DyWSCHz_.js +0 -1
- package/dist/public/assets/WorkbenchShellRoute-htbkGbtW.css +0 -1
- package/dist/public/assets/WorkspaceDetailPage-DMakfmHR.js +0 -1
- package/dist/public/assets/index-DmUJ8tIw.css +0 -1
- package/dist/public/assets/styles-DkbkRgWw.css +0 -1
- /package/dist/public/assets/{styles-JKFlsYFv.js → styles-DwSuZo1w.js} +0 -0
|
@@ -22,6 +22,7 @@ import { ProviderRuntimeStateService } from "../provider/provider-runtime-state-
|
|
|
22
22
|
import { createTaskManager } from "../tasks/task-manager.js";
|
|
23
23
|
import { HOST_TASK_TYPES } from "../tasks/task-types.js";
|
|
24
24
|
import { CodexAppServerHelperClient } from "./codex-app-server-helper-client.js";
|
|
25
|
+
import { CodexSessionTitleGenerator } from "./codex-session-title-generator.js";
|
|
25
26
|
import { CodingnsProviderSessionDeleteCli } from "./provider-session-delete-cli.js";
|
|
26
27
|
const RECONSTRUCTED_FORK_TARGET_PROVIDERS = new Set(["codex", "claude-code", "opencode"]);
|
|
27
28
|
const FORK_RECONSTRUCTION_PAGE_SIZE = 200;
|
|
@@ -80,6 +81,7 @@ export class SessionHistoryService {
|
|
|
80
81
|
providerDiscoveryHelperClient = getSharedProviderDiscoveryHelperClient();
|
|
81
82
|
providerSessionDiscoveryConfig;
|
|
82
83
|
providerRuntimeStateService;
|
|
84
|
+
codexSessionTitleGenerator;
|
|
83
85
|
sessionProviderConfigService;
|
|
84
86
|
providerControlRepository;
|
|
85
87
|
taskManager;
|
|
@@ -113,6 +115,10 @@ export class SessionHistoryService {
|
|
|
113
115
|
this.sessionProviderConfigService = sessionProviderConfigService;
|
|
114
116
|
this.providerRuntimeStateService = providerRuntimeStateService
|
|
115
117
|
?? new ProviderRuntimeStateService(config);
|
|
118
|
+
this.codexSessionTitleGenerator = new CodexSessionTitleGenerator({
|
|
119
|
+
hostDataRootDir: dirname(config.databasePath),
|
|
120
|
+
codexHomeDir: config.codexHomeDir
|
|
121
|
+
});
|
|
116
122
|
this.providerControlRepository = providerControlRepository ?? {
|
|
117
123
|
get: (providerId) => ({
|
|
118
124
|
providerId: providerId.trim(),
|
|
@@ -228,6 +234,14 @@ export class SessionHistoryService {
|
|
|
228
234
|
}
|
|
229
235
|
});
|
|
230
236
|
}
|
|
237
|
+
if (!this.taskManager.has(HOST_TASK_TYPES.sessionCodexTitleGenerate)) {
|
|
238
|
+
this.taskManager.register({
|
|
239
|
+
taskType: HOST_TASK_TYPES.sessionCodexTitleGenerate,
|
|
240
|
+
executionLane: "external_process",
|
|
241
|
+
timeoutMs: 45_000,
|
|
242
|
+
run: async ({ sessionId }, context) => this.runCodexSessionTitleGeneration(sessionId, context.signal)
|
|
243
|
+
});
|
|
244
|
+
}
|
|
231
245
|
}
|
|
232
246
|
async discoverWorkspaceSessions(workspaceId, userId, options) {
|
|
233
247
|
const maxAgeMs = options?.maxAgeMs ?? 0;
|
|
@@ -447,6 +461,7 @@ export class SessionHistoryService {
|
|
|
447
461
|
async syncSessionTitle(sessionId, signal) {
|
|
448
462
|
const binding = this.getBindingOrThrow(sessionId);
|
|
449
463
|
await this.syncSessionTitleFromProvider(sessionId, binding, signal);
|
|
464
|
+
this.requestCodexTitleGenerationIfNeeded(sessionId, "session_history.sync_session_title");
|
|
450
465
|
}
|
|
451
466
|
async syncWorkspaceSessionTitles(workspaceId, userId, concurrency = 1, signal) {
|
|
452
467
|
const sessions = this.sessionIndexRepository.listByWorkspace(workspaceId, userId);
|
|
@@ -1152,6 +1167,7 @@ export class SessionHistoryService {
|
|
|
1152
1167
|
return null;
|
|
1153
1168
|
}
|
|
1154
1169
|
await this.syncSessionTitleFromProvider(sessionId, binding);
|
|
1170
|
+
this.requestCodexTitleGenerationIfNeeded(sessionId, "session_history.read_recent_history");
|
|
1155
1171
|
const snapshot = this.sessionStatusSnapshotRepository.findBySessionId(sessionId);
|
|
1156
1172
|
this.upsertSnapshot(sessionId, {
|
|
1157
1173
|
syncStatus: "idle",
|
|
@@ -1624,6 +1640,10 @@ export class SessionHistoryService {
|
|
|
1624
1640
|
cleanupDurationMs = Date.now() - cleanupStartedAt;
|
|
1625
1641
|
}
|
|
1626
1642
|
this.workspaceSessionRelations.set(workspaceId, relationMap);
|
|
1643
|
+
this.observeDiscoveredProviderActivity(sessions, discoveredSessionIds, userId, timestamp);
|
|
1644
|
+
for (const persisted of persistedSessions) {
|
|
1645
|
+
this.requestCodexTitleGenerationIfNeeded(persisted.sessionId, "session_history.discover_workspace_sessions.codex_title");
|
|
1646
|
+
}
|
|
1627
1647
|
const listItemsStartedAt = Date.now();
|
|
1628
1648
|
const items = this.sessionIndexRepository.listByWorkspace(workspaceId, userId);
|
|
1629
1649
|
listItemsDurationMs = Date.now() - listItemsStartedAt;
|
|
@@ -1911,6 +1931,72 @@ export class SessionHistoryService {
|
|
|
1911
1931
|
}
|
|
1912
1932
|
return relationMap;
|
|
1913
1933
|
}
|
|
1934
|
+
observeDiscoveredProviderActivity(sessions, discoveredSessionIds, userId, timestamp) {
|
|
1935
|
+
for (const session of sessions) {
|
|
1936
|
+
const providerObservation = session.activityObservation ?? null;
|
|
1937
|
+
if (!providerObservation) {
|
|
1938
|
+
continue;
|
|
1939
|
+
}
|
|
1940
|
+
const sessionId = discoveredSessionIds.get(buildProviderSessionKey(session.provider, session.providerSessionId));
|
|
1941
|
+
if (!sessionId) {
|
|
1942
|
+
continue;
|
|
1943
|
+
}
|
|
1944
|
+
const observedAt = providerObservation.observedAt ?? timestamp;
|
|
1945
|
+
const resolution = this.sessionActivityAuthorityService.observe({
|
|
1946
|
+
sessionId,
|
|
1947
|
+
runId: providerObservation.runId ?? null,
|
|
1948
|
+
runningState: providerObservation.runningState,
|
|
1949
|
+
source: "authoritative_provider_event",
|
|
1950
|
+
confidence: providerObservation.confidence,
|
|
1951
|
+
detail: providerObservation.detail ?? null,
|
|
1952
|
+
interruptSource: providerObservation.runningState === "interrupted" ? "runtime" : null,
|
|
1953
|
+
errorCode: providerObservation.errorCode ?? null,
|
|
1954
|
+
observedAt
|
|
1955
|
+
});
|
|
1956
|
+
const current = this.sessionStateRepository.findBySessionAndUser(sessionId, userId);
|
|
1957
|
+
this.sessionStateRepository.upsert({
|
|
1958
|
+
sessionId,
|
|
1959
|
+
userId,
|
|
1960
|
+
runningState: mapResolvedRunningStateToStored(resolution.runningState, current),
|
|
1961
|
+
activitySource: "runtime",
|
|
1962
|
+
favorite: current?.favorite ?? false,
|
|
1963
|
+
lastEventAt: resolution.lastObservedAt ?? current?.lastEventAt ?? null,
|
|
1964
|
+
completedAt: isTerminalResolvedRunningState(resolution.runningState)
|
|
1965
|
+
? resolution.terminalAt ?? current?.completedAt ?? observedAt
|
|
1966
|
+
: null,
|
|
1967
|
+
lastSeenAt: current?.lastSeenAt ?? null,
|
|
1968
|
+
updatedAt: timestamp
|
|
1969
|
+
});
|
|
1970
|
+
const currentSnapshot = this.sessionStatusSnapshotRepository.findBySessionId(sessionId);
|
|
1971
|
+
const shouldClearFailure = currentSnapshot?.syncStatus === "error"
|
|
1972
|
+
&& providerObservation.runningState !== "failed";
|
|
1973
|
+
this.sessionStatusSnapshotRepository.upsert({
|
|
1974
|
+
sessionId,
|
|
1975
|
+
syncStatus: providerObservation.runningState === "failed"
|
|
1976
|
+
? "error"
|
|
1977
|
+
: shouldClearFailure
|
|
1978
|
+
? "idle"
|
|
1979
|
+
: currentSnapshot?.syncStatus ?? "idle",
|
|
1980
|
+
syncCursor: currentSnapshot?.syncCursor ?? null,
|
|
1981
|
+
lastSyncAt: resolution.lastObservedAt
|
|
1982
|
+
?? resolution.terminalAt
|
|
1983
|
+
?? currentSnapshot?.lastSyncAt
|
|
1984
|
+
?? null,
|
|
1985
|
+
lastErrorCode: providerObservation.runningState === "failed"
|
|
1986
|
+
? providerObservation.errorCode ?? "CODEX_PROVIDER_EVENT_FAILED"
|
|
1987
|
+
: shouldClearFailure
|
|
1988
|
+
? null
|
|
1989
|
+
: currentSnapshot?.lastErrorCode ?? null,
|
|
1990
|
+
lastErrorDetail: providerObservation.runningState === "failed"
|
|
1991
|
+
? providerObservation.detail ?? "Provider reported session failure"
|
|
1992
|
+
: shouldClearFailure
|
|
1993
|
+
? null
|
|
1994
|
+
: currentSnapshot?.lastErrorDetail ?? null,
|
|
1995
|
+
resumedAt: currentSnapshot?.resumedAt ?? null,
|
|
1996
|
+
updatedAt: timestamp
|
|
1997
|
+
});
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
1914
2000
|
enrichSessionItems(workspaceId, items) {
|
|
1915
2001
|
const relationMap = this.workspaceSessionRelations.get(workspaceId);
|
|
1916
2002
|
const projectionBySessionId = this.buildParallelProjectionBySessionId(items);
|
|
@@ -2135,6 +2221,7 @@ export class SessionHistoryService {
|
|
|
2135
2221
|
return;
|
|
2136
2222
|
}
|
|
2137
2223
|
await this.syncSessionTitleFromProvider(sessionId, binding);
|
|
2224
|
+
this.requestCodexTitleGenerationIfNeeded(sessionId, "session_history.publish_history_envelope");
|
|
2138
2225
|
const snapshot = this.sessionStatusSnapshotRepository.findBySessionId(sessionId);
|
|
2139
2226
|
this.upsertSnapshot(sessionId, {
|
|
2140
2227
|
syncStatus: "idle",
|
|
@@ -2187,6 +2274,83 @@ export class SessionHistoryService {
|
|
|
2187
2274
|
updatedAt: nowIso()
|
|
2188
2275
|
});
|
|
2189
2276
|
}
|
|
2277
|
+
requestCodexTitleGenerationIfNeeded(sessionId, source) {
|
|
2278
|
+
if (!this.shouldRequestCodexTitleGeneration(sessionId)) {
|
|
2279
|
+
return;
|
|
2280
|
+
}
|
|
2281
|
+
const handle = this.taskManager.enqueue(HOST_TASK_TYPES.sessionCodexTitleGenerate, {
|
|
2282
|
+
key: sessionId,
|
|
2283
|
+
source,
|
|
2284
|
+
input: {
|
|
2285
|
+
sessionId
|
|
2286
|
+
}
|
|
2287
|
+
});
|
|
2288
|
+
if (handle.deduped) {
|
|
2289
|
+
return;
|
|
2290
|
+
}
|
|
2291
|
+
void handle.promise.catch((error) => {
|
|
2292
|
+
logPerformance("session.codex_title_generate.background_failed", 0, {
|
|
2293
|
+
sessionId,
|
|
2294
|
+
error: error instanceof Error ? error.message : "unknown"
|
|
2295
|
+
}, {
|
|
2296
|
+
thresholdMs: 0,
|
|
2297
|
+
force: true
|
|
2298
|
+
});
|
|
2299
|
+
});
|
|
2300
|
+
}
|
|
2301
|
+
shouldRequestCodexTitleGeneration(sessionId) {
|
|
2302
|
+
const binding = this.sessionBindingRepository.findBySessionId(sessionId);
|
|
2303
|
+
const index = this.sessionIndexRepository.findIndexRecordBySessionId(sessionId);
|
|
2304
|
+
if (!binding || !index || binding.provider !== "codex") {
|
|
2305
|
+
return false;
|
|
2306
|
+
}
|
|
2307
|
+
if (isPendingBindingValue(binding.providerSessionId) || isPendingBindingValue(binding.rawStoreRef)) {
|
|
2308
|
+
return false;
|
|
2309
|
+
}
|
|
2310
|
+
if (index.messageCount <= 0) {
|
|
2311
|
+
return false;
|
|
2312
|
+
}
|
|
2313
|
+
return true;
|
|
2314
|
+
}
|
|
2315
|
+
async runCodexSessionTitleGeneration(sessionId, signal) {
|
|
2316
|
+
const binding = this.sessionBindingRepository.findBySessionId(sessionId);
|
|
2317
|
+
const index = this.sessionIndexRepository.findIndexRecordBySessionId(sessionId);
|
|
2318
|
+
if (!binding || !index || binding.provider !== "codex") {
|
|
2319
|
+
return { title: null };
|
|
2320
|
+
}
|
|
2321
|
+
if (isPendingBindingValue(binding.providerSessionId) || isPendingBindingValue(binding.rawStoreRef)) {
|
|
2322
|
+
return { title: null };
|
|
2323
|
+
}
|
|
2324
|
+
const page = await this.sessionSyncService.readHistory(binding.provider, binding.providerSessionId, binding.rawStoreRef, null, 16, "forward").catch(() => null);
|
|
2325
|
+
if (!page) {
|
|
2326
|
+
return { title: null };
|
|
2327
|
+
}
|
|
2328
|
+
const firstUserMessage = page.messages.find((message) => message.role === "user")?.content ?? null;
|
|
2329
|
+
if (!shouldGenerateCodexSessionTitle(index.title, firstUserMessage)) {
|
|
2330
|
+
return { title: null };
|
|
2331
|
+
}
|
|
2332
|
+
const title = await this.codexSessionTitleGenerator.generate({
|
|
2333
|
+
currentTitle: index.title,
|
|
2334
|
+
messages: page.messages.map((message) => ({
|
|
2335
|
+
role: message.role,
|
|
2336
|
+
content: message.content
|
|
2337
|
+
})),
|
|
2338
|
+
signal
|
|
2339
|
+
});
|
|
2340
|
+
if (!title || !shouldApplyGeneratedCodexSessionTitle(title, firstUserMessage)) {
|
|
2341
|
+
return { title: null };
|
|
2342
|
+
}
|
|
2343
|
+
await this.sessionSyncService.renameSessionTitle(binding.provider, binding.providerSessionId, binding.rawStoreRef, title);
|
|
2344
|
+
const latestIndex = this.sessionIndexRepository.findIndexRecordBySessionId(sessionId);
|
|
2345
|
+
if (latestIndex && shouldGenerateCodexSessionTitle(latestIndex.title, firstUserMessage)) {
|
|
2346
|
+
this.sessionIndexRepository.upsert({
|
|
2347
|
+
...latestIndex,
|
|
2348
|
+
title,
|
|
2349
|
+
updatedAt: nowIso()
|
|
2350
|
+
});
|
|
2351
|
+
}
|
|
2352
|
+
return { title };
|
|
2353
|
+
}
|
|
2190
2354
|
async readFirstUserMessageTitleForSync(binding) {
|
|
2191
2355
|
const pageSize = 20;
|
|
2192
2356
|
const maxPages = 3;
|
|
@@ -4195,6 +4359,25 @@ function shouldSyncSessionTitleFromProvider(provider, currentTitle, firstUserMes
|
|
|
4195
4359
|
}
|
|
4196
4360
|
return false;
|
|
4197
4361
|
}
|
|
4362
|
+
function shouldGenerateCodexSessionTitle(currentTitle, firstUserMessage) {
|
|
4363
|
+
const normalizedTitle = currentTitle?.trim() ?? "";
|
|
4364
|
+
if (!normalizedTitle) {
|
|
4365
|
+
return true;
|
|
4366
|
+
}
|
|
4367
|
+
if (looksLikeGeneratedSessionTitle(normalizedTitle) || isSyntheticCodexSessionTitle(normalizedTitle)) {
|
|
4368
|
+
return true;
|
|
4369
|
+
}
|
|
4370
|
+
const firstUserTitle = normalizeRuntimePromptTitle(firstUserMessage);
|
|
4371
|
+
return Boolean(firstUserTitle && normalizedTitle === firstUserTitle);
|
|
4372
|
+
}
|
|
4373
|
+
function shouldApplyGeneratedCodexSessionTitle(generatedTitle, firstUserMessage) {
|
|
4374
|
+
const normalizedTitle = generatedTitle.trim();
|
|
4375
|
+
const firstUserTitle = normalizeRuntimePromptTitle(firstUserMessage);
|
|
4376
|
+
if (!normalizedTitle) {
|
|
4377
|
+
return false;
|
|
4378
|
+
}
|
|
4379
|
+
return !firstUserTitle || normalizedTitle !== firstUserTitle;
|
|
4380
|
+
}
|
|
4198
4381
|
function looksLikeSyntheticTitleSourceMessage(provider, content) {
|
|
4199
4382
|
const normalizedProvider = provider.trim().toLowerCase();
|
|
4200
4383
|
if (normalizedProvider === "codex") {
|