termdock 1.4.77 → 1.4.79
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/client/assets/{ModelPreview-MUquuQ7M.js → ModelPreview-Ctt5O84G.js} +1 -1
- package/dist/client/assets/{abnfDiagram-VRR7QNED-bSAQDoRq.js → abnfDiagram-VRR7QNED-2-Vk-uHF.js} +1 -1
- package/dist/client/assets/{arc-CRXZasqt.js → arc-BC6EcxRV.js} +1 -1
- package/dist/client/assets/{architectureDiagram-ZJ3FMSHR-B5lW2XVL.js → architectureDiagram-ZJ3FMSHR-DrNR18UU.js} +1 -1
- package/dist/client/assets/{blockDiagram-677ZJIJ3-BnvUlbML.js → blockDiagram-677ZJIJ3-CEIlwBXq.js} +1 -1
- package/dist/client/assets/{c4Diagram-LMCZKHZV-Dh43i8Od.js → c4Diagram-LMCZKHZV-BA8_HWcI.js} +1 -1
- package/dist/client/assets/channel-C358_iSm.js +1 -0
- package/dist/client/assets/{chunk-2Q5K7J3B-Br9F2z9G.js → chunk-2Q5K7J3B-UA9G57BK.js} +1 -1
- package/dist/client/assets/{chunk-32BRIVSS-CR_BEEo8.js → chunk-32BRIVSS-DbHqJEu-.js} +1 -1
- package/dist/client/assets/{chunk-5VM5RSS4-RSFWgHJK.js → chunk-5VM5RSS4-pGzDDSb3.js} +1 -1
- package/dist/client/assets/{chunk-EX3LRPZG-BojU9tp1.js → chunk-EX3LRPZG-C0yXZOTU.js} +1 -1
- package/dist/client/assets/{chunk-JWPE2WC7-Da5LKO28.js → chunk-JWPE2WC7-BtDDBeQD.js} +1 -1
- package/dist/client/assets/{chunk-MOJQB5TN-CnH9HN8z.js → chunk-MOJQB5TN-HC3bHHdR.js} +1 -1
- package/dist/client/assets/{chunk-RYQCIY6F-OAjuTT8n.js → chunk-RYQCIY6F-zL7eDN0a.js} +1 -1
- package/dist/client/assets/{chunk-V7JOEXUC-BeH2Mdv7.js → chunk-V7JOEXUC-CVTjMYIZ.js} +1 -1
- package/dist/client/assets/{chunk-VR4S4FIN-BK51NinF.js → chunk-VR4S4FIN-Bh1RANew.js} +1 -1
- package/dist/client/assets/{chunk-XXDRQBXY-Df-77sm7.js → chunk-XXDRQBXY-BtEXiXB8.js} +1 -1
- package/dist/client/assets/classDiagram-OUVF2IWQ-BJJG-Pnf.js +1 -0
- package/dist/client/assets/classDiagram-v2-EOCWNBFH-BJJG-Pnf.js +1 -0
- package/dist/client/assets/{cose-bilkent-JH36ORCC-C-FtawL2.js → cose-bilkent-JH36ORCC-DUTcoWBN.js} +1 -1
- package/dist/client/assets/{cynefin-VYW2F7L2-O7CaDQi8.js → cynefin-VYW2F7L2-CcbSv45f.js} +1 -1
- package/dist/client/assets/{cynefinDiagram-TSTJHNR4-B0fJizeX.js → cynefinDiagram-TSTJHNR4-BGf515TH.js} +1 -1
- package/dist/client/assets/{dagre-VKFMJZFB-BsIwc1IF.js → dagre-VKFMJZFB-QI_lDICR.js} +1 -1
- package/dist/client/assets/{diagram-FQU43EPY-GDwMRBsa.js → diagram-FQU43EPY-BCLtTsT9.js} +1 -1
- package/dist/client/assets/{diagram-G47NLZAW-Chv4syax.js → diagram-G47NLZAW-_yBnM1q_.js} +1 -1
- package/dist/client/assets/{diagram-NH7WQ7WH-Dh1F6AVi.js → diagram-NH7WQ7WH-XlYe1OWX.js} +1 -1
- package/dist/client/assets/{diagram-OA4YK3LP-CU3z6ul5.js → diagram-OA4YK3LP-BereD6t7.js} +1 -1
- package/dist/client/assets/{diagram-WEI45ONY-CYug818o.js → diagram-WEI45ONY-2nxjGQ_U.js} +1 -1
- package/dist/client/assets/{ebnfDiagram-CCIWWBDH-zzKMHZmD.js → ebnfDiagram-CCIWWBDH-Cne6J8Re.js} +1 -1
- package/dist/client/assets/{erDiagram-Q63AITRT-4yv9ci2k.js → erDiagram-Q63AITRT-B38mH0Dz.js} +1 -1
- package/dist/client/assets/{flowDiagram-23GEKE2U-CJj8uFtp.js → flowDiagram-23GEKE2U-Br3s8LhK.js} +1 -1
- package/dist/client/assets/{ganttDiagram-NO4QXBWP-WhZonF-5.js → ganttDiagram-NO4QXBWP-DRcCUswk.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-IHSO6WYX-DCmdLenS.js → gitGraphDiagram-IHSO6WYX-C2vtZMRF.js} +1 -1
- package/dist/client/assets/{index-ILJW_1zc.js → index-CLBhM0iA.js} +56 -56
- package/dist/client/assets/{infoDiagram-FWYZ7A6U-0HrqatQe.js → infoDiagram-FWYZ7A6U-D8wyLDDC.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-FXEZZL3T-DCPrrLNa.js → ishikawaDiagram-FXEZZL3T-kH1-N7T8.js} +1 -1
- package/dist/client/assets/{journeyDiagram-5HDEW3XC-CY0RHb4b.js → journeyDiagram-5HDEW3XC-1CmM2XJ1.js} +1 -1
- package/dist/client/assets/{kanban-definition-HUTT4EX6-DcH2OBHS.js → kanban-definition-HUTT4EX6-BWk70F73.js} +1 -1
- package/dist/client/assets/{linear-BidTRUFO.js → linear-CfygukEL.js} +1 -1
- package/dist/client/assets/{mermaid.core-BomIvgGf.js → mermaid.core-DImRwpsu.js} +4 -4
- package/dist/client/assets/{mindmap-definition-LN4V7U3C-BVbGSAMP.js → mindmap-definition-LN4V7U3C-7edZ10k5.js} +1 -1
- package/dist/client/assets/{pegDiagram-2B236MQR-BPDcfuXr.js → pegDiagram-2B236MQR-uontau4f.js} +1 -1
- package/dist/client/assets/{pieDiagram-ENE6RG2P-BEl37TgF.js → pieDiagram-ENE6RG2P-S6s_TLqy.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-ABIIQ3AL-B4Jexgtq.js → quadrantDiagram-ABIIQ3AL-B0cY0YeM.js} +1 -1
- package/dist/client/assets/{railroadDiagram-RFXS5EU6-DCf5cVwA.js → railroadDiagram-RFXS5EU6-BqOLmm4H.js} +1 -1
- package/dist/client/assets/{requirementDiagram-TGXJPOKE-Dutz-kps.js → requirementDiagram-TGXJPOKE-C9fXYfhH.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-HTMAVEWB-C5B7Px5r.js → sankeyDiagram-HTMAVEWB-CI7EhpIN.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-DBY2YBRQ-BAjlNtX7.js → sequenceDiagram-DBY2YBRQ-xYg51Dle.js} +1 -1
- package/dist/client/assets/{sizeCapture-X5ZJPWSS-DxHVj2nI.js → sizeCapture-X5ZJPWSS-B5ynXyfy.js} +1 -1
- package/dist/client/assets/{stateDiagram-2N3HPSRC-h0J5lN0m.js → stateDiagram-2N3HPSRC-BehTEqHr.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-6OUMAXLB-DOY1e3hd.js +1 -0
- package/dist/client/assets/{swimlanes-5IMT3BWC-BVPnl0Ka.js → swimlanes-5IMT3BWC-BUHgtegz.js} +2 -2
- package/dist/client/assets/swimlanesDiagram-G3AALYLV-Cc5uFyAu.js +8 -0
- package/dist/client/assets/{timeline-definition-FHXFAJF6-Cn5XtHKy.js → timeline-definition-FHXFAJF6-DJnmnV28.js} +1 -1
- package/dist/client/assets/{vennDiagram-L72KCM5P-CwBsi2Gg.js → vennDiagram-L72KCM5P-C_ZBj3fr.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-EHGQE667-CZMtiWJm.js → wardleyDiagram-EHGQE667-YGm53tR-.js} +1 -1
- package/dist/client/assets/{xychartDiagram-FW5EYKEG-uGw9wOMW.js → xychartDiagram-FW5EYKEG-7ajuowBQ.js} +1 -1
- package/dist/client/index.html +1 -1
- package/dist/client/sw.js +1 -1
- package/dist/server/agent/autoTitle.js +30 -5
- package/dist/server/agent/renderedTerminalContext.js +94 -0
- package/dist/server/agent/session.js +7 -0
- package/dist/server/cli.js +1 -0
- package/dist/server/routes/terminal.js +85 -16
- package/dist/server/utils/settings.js +14 -0
- package/package.json +2 -1
- package/runtime-manifest.json +3 -3
- package/dist/client/assets/channel-Bm8opuca.js +0 -1
- package/dist/client/assets/classDiagram-OUVF2IWQ-eErPtGt5.js +0 -1
- package/dist/client/assets/classDiagram-v2-EOCWNBFH-eErPtGt5.js +0 -1
- package/dist/client/assets/stateDiagram-v2-6OUMAXLB-CtfvvrUK.js +0 -1
- package/dist/client/assets/swimlanesDiagram-G3AALYLV-CLhM0GwF.js +0 -8
|
@@ -14,7 +14,7 @@ import { getPtyHostManager } from '../ptyhost/manager.js';
|
|
|
14
14
|
import { pathValidator } from '../utils/pathValidator.js';
|
|
15
15
|
import { TERMINAL, TMUX } from '../config.js';
|
|
16
16
|
import { localAccessManager } from '../utils/localAccess.js';
|
|
17
|
-
import { normalizeLocalAccessName, getLocaleSetting, setLocaleSetting, getContextDraftHeightSetting, setContextDraftHeightSetting, getAutoRenameAgentsSetting, setAutoRenameAgentsSetting, getAutoRenameNamerSetting, setAutoRenameNamerSetting, getAutoRenameModelsSetting, setAutoRenameModelsSetting, getAutoRenameIntervalMinutesSetting, setAutoRenameIntervalMinutesSetting, getAutoRenamePromptPreferenceSetting, setAutoRenamePromptPreferenceSetting, } from '../utils/settings.js';
|
|
17
|
+
import { normalizeLocalAccessName, getLocaleSetting, setLocaleSetting, getContextDraftHeightSetting, setContextDraftHeightSetting, getAutoRenameAgentsSetting, setAutoRenameAgentsSetting, getAutoRenameNamerSetting, setAutoRenameNamerSetting, getAutoRenameModelsSetting, setAutoRenameModelsSetting, getAutoRenameIntervalMinutesSetting, setAutoRenameIntervalMinutesSetting, getAutoRenamePromptPreferenceSetting, setAutoRenamePromptPreferenceSetting, getAutoRenamePromptPayloadCharsSetting, setAutoRenamePromptPayloadCharsSetting, } from '../utils/settings.js';
|
|
18
18
|
import { loadContextDraft, saveContextDraft } from '../utils/contextDraft.js';
|
|
19
19
|
import { getOnboardingServerUrl } from '../onboardingServer.js';
|
|
20
20
|
import { getFocusSequence, removeClientFocusState, scanFocusTrackingMode, setClientFocusState, } from '../utils/tmuxFocus.js';
|
|
@@ -29,8 +29,9 @@ import { notifyAgentTransition, notifyTerminalExit } from '../notifications/push
|
|
|
29
29
|
import { setClientViewingSession } from '../notifications/pushViewers.js';
|
|
30
30
|
import { getQuotaStatus, refreshQuota, startQuotaManager, } from '../quota/QuotaManager.js';
|
|
31
31
|
import { TermdockAutoUpdateManager } from '../utils/autoUpdate.js';
|
|
32
|
-
import { AUTO_TITLE_LONG_RUNNING_DELAY_MS, AUTO_TITLE_MIN_CONTEXT_CHARS, cleanTerminalContext, generateAgentTitle, hasSubstantiveAutoTitleContext, isNewAgentSessionId, isAutoTitleReevaluationDue, shouldReplaceAutoTitle, } from '../agent/autoTitle.js';
|
|
32
|
+
import { AUTO_TITLE_LONG_RUNNING_DELAY_MS, AUTO_TITLE_MIN_CONTEXT_CHARS, cleanTerminalContext, generateAgentTitle, hasSubstantiveAutoTitleContext, isLongRunningAutoTitleTurnEligible, isNewAgentSessionId, isAutoTitleReevaluationDue, shouldReplaceAutoTitle, } from '../agent/autoTitle.js';
|
|
33
33
|
import { getTitleNamerCatalog, invalidateTitleNamerCatalog, probePluginTitleNamer } from '../agent/titleNamerCatalog.js';
|
|
34
|
+
import { RenderedTerminalContext } from '../agent/renderedTerminalContext.js';
|
|
34
35
|
const router = express.Router();
|
|
35
36
|
const execFileAsync = promisify(execFile);
|
|
36
37
|
const TERMDOCK_DIR = `${os.homedir()}/.termdock`;
|
|
@@ -2128,10 +2129,42 @@ function detectSessionAgent(session) {
|
|
|
2128
2129
|
}
|
|
2129
2130
|
return null;
|
|
2130
2131
|
}
|
|
2131
|
-
const AUTO_TITLE_CONTEXT_LIMIT = 24_000;
|
|
2132
2132
|
const autoTitlePending = new Set();
|
|
2133
|
-
function appendAutoTitleContext(session, data) {
|
|
2134
|
-
session.
|
|
2133
|
+
function appendAutoTitleContext(sessionId, session, data, schedule) {
|
|
2134
|
+
session.autoTitleTerminal.write(data, (rendered) => {
|
|
2135
|
+
session.autoTitleContext = rendered;
|
|
2136
|
+
if (schedule)
|
|
2137
|
+
maybeScheduleLongRunningAutoTitle(sessionId, session);
|
|
2138
|
+
});
|
|
2139
|
+
}
|
|
2140
|
+
function appendAutoTitlePromptPayload(session, payload) {
|
|
2141
|
+
const maxChars = getAutoRenamePromptPayloadCharsSetting();
|
|
2142
|
+
const bounded = payload.slice(0, maxChars).trim();
|
|
2143
|
+
if (!bounded || session.autoTitlePromptPayloads.at(-1) === bounded)
|
|
2144
|
+
return;
|
|
2145
|
+
session.autoTitlePromptPayloads.push(bounded);
|
|
2146
|
+
session.autoTitlePromptPayloads = session.autoTitlePromptPayloads.slice(-12);
|
|
2147
|
+
while (session.autoTitlePromptPayloads.length > 1
|
|
2148
|
+
&& session.autoTitlePromptPayloads.join('\n').length > maxChars) {
|
|
2149
|
+
session.autoTitlePromptPayloads.shift();
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
function getBoundedAutoTitlePromptPayloads(session) {
|
|
2153
|
+
const maxChars = getAutoRenamePromptPayloadCharsSetting();
|
|
2154
|
+
const selected = [];
|
|
2155
|
+
let used = 0;
|
|
2156
|
+
for (let index = session.autoTitlePromptPayloads.length - 1; index >= 0; index -= 1) {
|
|
2157
|
+
const payload = session.autoTitlePromptPayloads[index].slice(0, maxChars);
|
|
2158
|
+
const separatorChars = selected.length > 0 ? 1 : 0;
|
|
2159
|
+
if (used + separatorChars + payload.length > maxChars)
|
|
2160
|
+
continue;
|
|
2161
|
+
selected.unshift(payload);
|
|
2162
|
+
used += separatorChars + payload.length;
|
|
2163
|
+
}
|
|
2164
|
+
return selected;
|
|
2165
|
+
}
|
|
2166
|
+
async function resolveAutoTitleContext(session) {
|
|
2167
|
+
return cleanTerminalContext(await session.autoTitleTerminal.snapshot());
|
|
2135
2168
|
}
|
|
2136
2169
|
function clearAutoTitleForNewAgentSession(sessionId, session) {
|
|
2137
2170
|
const record = globalSessionState.sessions.find((item) => item.backendSessionId === sessionId);
|
|
@@ -2140,6 +2173,8 @@ function clearAutoTitleForNewAgentSession(sessionId, session) {
|
|
|
2140
2173
|
const next = { ...record, customName: undefined, autoTitle: null };
|
|
2141
2174
|
upsertGlobalSessionRecord(next);
|
|
2142
2175
|
session.autoTitleContext = '';
|
|
2176
|
+
session.autoTitleTerminal.reset();
|
|
2177
|
+
session.autoTitlePromptPayloads = [];
|
|
2143
2178
|
if (next.mode === 'tmux' && next.tmuxSessionName) {
|
|
2144
2179
|
void unsetTmuxOption(next.tmuxSessionName, '@termdock-friendly-name');
|
|
2145
2180
|
}
|
|
@@ -2147,7 +2182,7 @@ function clearAutoTitleForNewAgentSession(sessionId, session) {
|
|
|
2147
2182
|
broadcastClientState();
|
|
2148
2183
|
console.log(`[auto-title] cleared stale title for new agent session in ${sessionId}`);
|
|
2149
2184
|
}
|
|
2150
|
-
async function maybeAutoRenameSession(sessionId, agent,
|
|
2185
|
+
async function maybeAutoRenameSession(sessionId, agent, session, options = {}) {
|
|
2151
2186
|
if (autoTitlePending.has(sessionId))
|
|
2152
2187
|
return false;
|
|
2153
2188
|
if (!getAutoRenameAgentsSetting().includes(agent.slug))
|
|
@@ -2157,14 +2192,17 @@ async function maybeAutoRenameSession(sessionId, agent, rawContext, options = {}
|
|
|
2157
2192
|
return false;
|
|
2158
2193
|
if (record.autoTitle && !options.forceReevaluation && !isAutoTitleReevaluationDue(record.autoTitle.updatedAt, getAutoRenameIntervalMinutesSetting()))
|
|
2159
2194
|
return false;
|
|
2160
|
-
const context =
|
|
2195
|
+
const context = await resolveAutoTitleContext(session);
|
|
2196
|
+
const promptSubmitPayloads = getBoundedAutoTitlePromptPayloads(session);
|
|
2161
2197
|
// A new session gets one cheap attempt after its first real exchange. Short
|
|
2162
2198
|
// conversations ("hi" plus a brief reply) are still valid sessions; the
|
|
2163
2199
|
// one-hour re-evaluation guard below keeps this from becoming noisy after a
|
|
2164
2200
|
// title exists.
|
|
2165
2201
|
if (context.length < AUTO_TITLE_MIN_CONTEXT_CHARS)
|
|
2166
2202
|
return false;
|
|
2167
|
-
const contentHash = createHash('sha256')
|
|
2203
|
+
const contentHash = createHash('sha256')
|
|
2204
|
+
.update(JSON.stringify({ context, promptSubmitPayloads }))
|
|
2205
|
+
.digest('hex');
|
|
2168
2206
|
if (record.autoTitle?.contentHash === contentHash)
|
|
2169
2207
|
return false;
|
|
2170
2208
|
autoTitlePending.add(sessionId);
|
|
@@ -2187,6 +2225,7 @@ async function maybeAutoRenameSession(sessionId, agent, rawContext, options = {}
|
|
|
2187
2225
|
models: validModels,
|
|
2188
2226
|
currentTitle: record.autoTitle ? record.name : undefined,
|
|
2189
2227
|
userPreference: getAutoRenamePromptPreferenceSetting(),
|
|
2228
|
+
promptSubmitPayloads,
|
|
2190
2229
|
});
|
|
2191
2230
|
if (!title)
|
|
2192
2231
|
return false;
|
|
@@ -2239,7 +2278,7 @@ function maybeScheduleLongRunningAutoTitle(sessionId, session) {
|
|
|
2239
2278
|
if (!agent || !getAutoRenameAgentsSetting().includes(agent.slug))
|
|
2240
2279
|
return;
|
|
2241
2280
|
const phase = session.agentSession?.status;
|
|
2242
|
-
if (phase
|
|
2281
|
+
if (!isLongRunningAutoTitleTurnEligible(phase, session.autoTitleObservedPrompt, session.autoTitleTurnActive))
|
|
2243
2282
|
return;
|
|
2244
2283
|
const record = globalSessionState.sessions.find((item) => item.backendSessionId === sessionId);
|
|
2245
2284
|
if (!record || record.autoTitle || record.customName === true)
|
|
@@ -2252,18 +2291,18 @@ function maybeScheduleLongRunningAutoTitle(sessionId, session) {
|
|
|
2252
2291
|
if (liveSession !== session || liveSession.agent?.slug !== agent.slug)
|
|
2253
2292
|
return;
|
|
2254
2293
|
const phase = liveSession.agentSession?.status;
|
|
2255
|
-
if (phase
|
|
2294
|
+
if (!isLongRunningAutoTitleTurnEligible(phase, liveSession.autoTitleObservedPrompt, liveSession.autoTitleTurnActive))
|
|
2256
2295
|
return;
|
|
2257
2296
|
const current = globalSessionState.sessions.find((item) => item.backendSessionId === sessionId);
|
|
2258
2297
|
if (!current || current.autoTitle || current.customName === true)
|
|
2259
2298
|
return;
|
|
2260
|
-
void maybeAutoRenameSession(sessionId, agent, liveSession
|
|
2299
|
+
void maybeAutoRenameSession(sessionId, agent, liveSession).then((generated) => {
|
|
2261
2300
|
if (!generated || terminalSessions.get(sessionId) !== liveSession)
|
|
2262
2301
|
return;
|
|
2263
2302
|
const completedWhileNaming = liveSession.agentSession?.status === 'done'
|
|
2264
2303
|
|| liveSession.agentSession?.status === 'idle';
|
|
2265
2304
|
if (completedWhileNaming) {
|
|
2266
|
-
void maybeAutoRenameSession(sessionId, agent, liveSession
|
|
2305
|
+
void maybeAutoRenameSession(sessionId, agent, liveSession, { forceReevaluation: true });
|
|
2267
2306
|
return;
|
|
2268
2307
|
}
|
|
2269
2308
|
liveSession.autoTitleGeneratedMidTurn = true;
|
|
@@ -2459,22 +2498,36 @@ function applyAgentSignals(sessionId, session, events, notification) {
|
|
|
2459
2498
|
session.autoTitleGeneratedMidTurn = false;
|
|
2460
2499
|
clearAutoTitleForNewAgentSession(sessionId, session);
|
|
2461
2500
|
}
|
|
2501
|
+
if (event.kind === 'session-start') {
|
|
2502
|
+
session.autoTitleObservedPrompt = false;
|
|
2503
|
+
session.autoTitleTurnActive = false;
|
|
2504
|
+
session.autoTitlePromptPayloads = [];
|
|
2505
|
+
}
|
|
2462
2506
|
if (event.kind === 'prompt-submit') {
|
|
2463
2507
|
// Before the first automatic title, keep accumulating short turns until
|
|
2464
2508
|
// there is enough substance to name the session. Once titled, only the
|
|
2465
2509
|
// latest turn is relevant to the conservative re-evaluation path.
|
|
2466
2510
|
const persisted = globalSessionState.sessions.find((item) => item.backendSessionId === sessionId);
|
|
2467
|
-
if (persisted?.autoTitle) {
|
|
2511
|
+
if (!session.autoTitleObservedPrompt || persisted?.autoTitle) {
|
|
2468
2512
|
session.autoTitleContext = '';
|
|
2513
|
+
session.autoTitleTerminal.reset();
|
|
2469
2514
|
}
|
|
2515
|
+
cancelLongRunningAutoTitle(session);
|
|
2516
|
+
session.autoTitleGeneratedMidTurn = false;
|
|
2517
|
+
session.autoTitleObservedPrompt = true;
|
|
2518
|
+
session.autoTitleTurnActive = true;
|
|
2519
|
+
if (event.promptPayload)
|
|
2520
|
+
appendAutoTitlePromptPayload(session, event.promptPayload);
|
|
2470
2521
|
}
|
|
2471
2522
|
applyAgentEvent(state, event);
|
|
2472
2523
|
if (event.kind === 'stop') {
|
|
2473
2524
|
cancelLongRunningAutoTitle(session);
|
|
2525
|
+
session.autoTitleTurnActive = false;
|
|
2474
2526
|
completedTurnAgent = event.agent ?? session.agent;
|
|
2475
2527
|
}
|
|
2476
2528
|
if (event.kind === 'session-end') {
|
|
2477
2529
|
cancelLongRunningAutoTitle(session);
|
|
2530
|
+
session.autoTitleTurnActive = false;
|
|
2478
2531
|
}
|
|
2479
2532
|
if (event.kind === 'session-start' || event.kind === 'session-end' || event.kind === 'stop') {
|
|
2480
2533
|
persistAgentResumeBinding(sessionId, session);
|
|
@@ -2513,7 +2566,7 @@ function applyAgentSignals(sessionId, session, events, notification) {
|
|
|
2513
2566
|
session.autoTitleGeneratedMidTurn = false;
|
|
2514
2567
|
// Let the current PTY chunk reach the rolling context before reading it.
|
|
2515
2568
|
setTimeout(() => {
|
|
2516
|
-
void maybeAutoRenameSession(sessionId, agent, session
|
|
2569
|
+
void maybeAutoRenameSession(sessionId, agent, session, { forceReevaluation });
|
|
2517
2570
|
}, 250).unref?.();
|
|
2518
2571
|
}
|
|
2519
2572
|
}
|
|
@@ -3357,6 +3410,7 @@ function cleanupSession(sessionId, options) {
|
|
|
3357
3410
|
session.dataDisposable?.dispose();
|
|
3358
3411
|
session.exitDisposable?.dispose();
|
|
3359
3412
|
cancelLongRunningAutoTitle(session);
|
|
3413
|
+
session.autoTitleTerminal.dispose();
|
|
3360
3414
|
lastAgentStatusSnapshots.delete(sessionId);
|
|
3361
3415
|
lastGitStatusSnapshots.delete(sessionId);
|
|
3362
3416
|
destroyTmuxControl(session.tmuxControl);
|
|
@@ -3452,6 +3506,7 @@ function applyPtyResize(sessionId, session, cols, rows, source, originClientId)
|
|
|
3452
3506
|
}
|
|
3453
3507
|
session.cols = cleanCols;
|
|
3454
3508
|
session.rows = cleanRows;
|
|
3509
|
+
session.autoTitleTerminal.resize(cleanCols, cleanRows);
|
|
3455
3510
|
session.lastActivity = Date.now();
|
|
3456
3511
|
if (changed) {
|
|
3457
3512
|
markTmuxClientsForScreenSync(sessionId, session);
|
|
@@ -3686,9 +3741,8 @@ function processSessionOutput(sessionId, session, data, opts) {
|
|
|
3686
3741
|
}
|
|
3687
3742
|
}
|
|
3688
3743
|
catch { /* sniff failure should never block data */ }
|
|
3744
|
+
appendAutoTitleContext(sessionId, session, data, opts.broadcast);
|
|
3689
3745
|
if (opts.broadcast) {
|
|
3690
|
-
appendAutoTitleContext(session, data);
|
|
3691
|
-
maybeScheduleLongRunningAutoTitle(sessionId, session);
|
|
3692
3746
|
broadcastEvent(sessionId, seq !== undefined ? { type: 'data', data, seq } : { type: 'data', data });
|
|
3693
3747
|
}
|
|
3694
3748
|
}
|
|
@@ -3860,8 +3914,12 @@ async function spawnTerminalSession(req, input) {
|
|
|
3860
3914
|
agent: null,
|
|
3861
3915
|
agentSession: null,
|
|
3862
3916
|
autoTitleContext: '',
|
|
3917
|
+
autoTitleTerminal: new RenderedTerminalContext(cols, rows),
|
|
3918
|
+
autoTitlePromptPayloads: [],
|
|
3863
3919
|
autoTitleLongRunningTimer: null,
|
|
3864
3920
|
autoTitleGeneratedMidTurn: false,
|
|
3921
|
+
autoTitleObservedPrompt: false,
|
|
3922
|
+
autoTitleTurnActive: false,
|
|
3865
3923
|
lastAgentReviewed: null,
|
|
3866
3924
|
agentLeftAt: null,
|
|
3867
3925
|
gitStatus: null,
|
|
@@ -3944,8 +4002,12 @@ async function adoptPtyHostSessions() {
|
|
|
3944
4002
|
agent: null,
|
|
3945
4003
|
agentSession: null,
|
|
3946
4004
|
autoTitleContext: '',
|
|
4005
|
+
autoTitleTerminal: new RenderedTerminalContext(meta.cols, meta.rows),
|
|
4006
|
+
autoTitlePromptPayloads: [],
|
|
3947
4007
|
autoTitleLongRunningTimer: null,
|
|
3948
4008
|
autoTitleGeneratedMidTurn: false,
|
|
4009
|
+
autoTitleObservedPrompt: false,
|
|
4010
|
+
autoTitleTurnActive: false,
|
|
3949
4011
|
lastAgentReviewed: null,
|
|
3950
4012
|
agentLeftAt: null,
|
|
3951
4013
|
gitStatus: null,
|
|
@@ -4492,6 +4554,7 @@ async function getSettingsPayload() {
|
|
|
4492
4554
|
autoRenameModels: getAutoRenameModelsSetting(),
|
|
4493
4555
|
autoRenameIntervalMinutes: getAutoRenameIntervalMinutesSetting(),
|
|
4494
4556
|
autoRenamePromptPreference: getAutoRenamePromptPreferenceSetting(),
|
|
4557
|
+
autoRenamePromptPayloadChars: getAutoRenamePromptPayloadCharsSetting(),
|
|
4495
4558
|
localAccess: {
|
|
4496
4559
|
...localAccess,
|
|
4497
4560
|
interfaces,
|
|
@@ -4583,6 +4646,12 @@ router.put('/settings', async (req, res) => {
|
|
|
4583
4646
|
if (typeof body.autoRenamePromptPreference === 'string' && body.autoRenamePromptPreference.length <= 2000) {
|
|
4584
4647
|
setAutoRenamePromptPreferenceSetting(body.autoRenamePromptPreference);
|
|
4585
4648
|
}
|
|
4649
|
+
if (typeof body.autoRenamePromptPayloadChars === 'number'
|
|
4650
|
+
&& Number.isInteger(body.autoRenamePromptPayloadChars)
|
|
4651
|
+
&& body.autoRenamePromptPayloadChars >= 1000
|
|
4652
|
+
&& body.autoRenamePromptPayloadChars <= 64_000) {
|
|
4653
|
+
setAutoRenamePromptPayloadCharsSetting(body.autoRenamePromptPayloadChars);
|
|
4654
|
+
}
|
|
4586
4655
|
if (body.localAccess && typeof body.localAccess === 'object') {
|
|
4587
4656
|
const localAccessBody = body.localAccess;
|
|
4588
4657
|
if (localAccessBody.reset === true) {
|
|
@@ -88,6 +88,12 @@ function normalizeSettings(value) {
|
|
|
88
88
|
autoRenamePromptPreference: typeof raw.autoRenamePromptPreference === 'string'
|
|
89
89
|
? raw.autoRenamePromptPreference.trim().slice(0, 2000)
|
|
90
90
|
: '',
|
|
91
|
+
autoRenamePromptPayloadChars: typeof raw.autoRenamePromptPayloadChars === 'number'
|
|
92
|
+
&& Number.isInteger(raw.autoRenamePromptPayloadChars)
|
|
93
|
+
&& raw.autoRenamePromptPayloadChars >= 1000
|
|
94
|
+
&& raw.autoRenamePromptPayloadChars <= 64_000
|
|
95
|
+
? raw.autoRenamePromptPayloadChars
|
|
96
|
+
: 12_000,
|
|
91
97
|
updatedAt: typeof raw.updatedAt === 'number' ? raw.updatedAt : Date.now(),
|
|
92
98
|
};
|
|
93
99
|
}
|
|
@@ -243,6 +249,14 @@ export function setAutoRenamePromptPreferenceSetting(preference) {
|
|
|
243
249
|
settings.autoRenamePromptPreference = preference.trim().slice(0, 2000);
|
|
244
250
|
});
|
|
245
251
|
}
|
|
252
|
+
export function getAutoRenamePromptPayloadCharsSetting() {
|
|
253
|
+
return loadSettings().autoRenamePromptPayloadChars;
|
|
254
|
+
}
|
|
255
|
+
export function setAutoRenamePromptPayloadCharsSetting(chars) {
|
|
256
|
+
return updateSettings((settings) => {
|
|
257
|
+
settings.autoRenamePromptPayloadChars = Math.max(1000, Math.min(64_000, Math.round(chars)));
|
|
258
|
+
});
|
|
259
|
+
}
|
|
246
260
|
export function setAutoRenameModelsSetting(models) {
|
|
247
261
|
return updateSettings((settings) => {
|
|
248
262
|
settings.autoRenameModels = Object.fromEntries(Object.entries(models)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "termdock",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.79",
|
|
4
4
|
"description": "A complete web-based terminal application with modern UI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": ".desktop-dist/main.js",
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
"@xterm/addon-unicode11": "^0.10.0-beta.287",
|
|
64
64
|
"@xterm/addon-web-links": "^0.13.0-beta.287",
|
|
65
65
|
"@xterm/addon-webgl": "^0.20.0-beta.286",
|
|
66
|
+
"@xterm/headless": "^6.1.0-beta.287",
|
|
66
67
|
"@xterm/xterm": "^6.1.0-beta.287",
|
|
67
68
|
"browser-haptic": "^1.0.13",
|
|
68
69
|
"busboy": "^1.6.0",
|
package/runtime-manifest.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"packageName": "termdock",
|
|
4
|
-
"version": "1.4.
|
|
4
|
+
"version": "1.4.79",
|
|
5
5
|
"runtimeProtocolVersion": 1,
|
|
6
6
|
"minimumDesktopVersion": "1.4.46",
|
|
7
7
|
"nodeMajor": 22,
|
|
8
|
-
"dependencyHash": "sha256-
|
|
9
|
-
"serverBundleHash": "sha256-
|
|
8
|
+
"dependencyHash": "sha256-emuXnf9w0kJF3ksMJVvdI0u8oLHKwZJ2/OzHBAXulZs=",
|
|
9
|
+
"serverBundleHash": "sha256-GoAVNoJGFUZfHeQMTYoJXmImgDexm9IpIKEgwniGVy4=",
|
|
10
10
|
"entrypoint": "dist/server/cli.js",
|
|
11
11
|
"clientEntrypoint": "dist/client/index.html"
|
|
12
12
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{U as a,C as n}from"./mermaid.core-BomIvgGf.js";const t=(r,o)=>a.lang.round(n.parse(r)[o]);export{t as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,a as s,c as t,C as e}from"./chunk-V7JOEXUC-BeH2Mdv7.js";import{b as i}from"./mermaid.core-BomIvgGf.js";import"./chunk-5VM5RSS4-RSFWgHJK.js";import"./chunk-XXDRQBXY-Df-77sm7.js";import"./chunk-VR4S4FIN-BK51NinF.js";import"./chunk-32BRIVSS-CR_BEEo8.js";import"./purify.es-CC4Brkr_.js";import"./index-ILJW_1zc.js";import"./react-XDCjal2T.js";import"./dnd-BCFAPC0L.js";import"./terminal-C7X98Amf.js";var g={parser:t,get db(){return new e},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{g as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,a as s,c as t,C as e}from"./chunk-V7JOEXUC-BeH2Mdv7.js";import{b as i}from"./mermaid.core-BomIvgGf.js";import"./chunk-5VM5RSS4-RSFWgHJK.js";import"./chunk-XXDRQBXY-Df-77sm7.js";import"./chunk-VR4S4FIN-BK51NinF.js";import"./chunk-32BRIVSS-CR_BEEo8.js";import"./purify.es-CC4Brkr_.js";import"./index-ILJW_1zc.js";import"./react-XDCjal2T.js";import"./dnd-BCFAPC0L.js";import"./terminal-C7X98Amf.js";var g={parser:t,get db(){return new e},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{g as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{b as r,a as e,s as a,S as i}from"./chunk-EX3LRPZG-BojU9tp1.js";import{b as s}from"./mermaid.core-BomIvgGf.js";import"./chunk-XXDRQBXY-Df-77sm7.js";import"./chunk-VR4S4FIN-BK51NinF.js";import"./chunk-32BRIVSS-CR_BEEo8.js";import"./purify.es-CC4Brkr_.js";import"./index-ILJW_1zc.js";import"./react-XDCjal2T.js";import"./dnd-BCFAPC0L.js";import"./terminal-C7X98Amf.js";var g={parser:a,get db(){return new i(2)},renderer:e,styles:r,init:s(t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")};export{g as diagram};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import{c as r,s as e}from"./flowDiagram-23GEKE2U-CJj8uFtp.js";import{b as o}from"./mermaid.core-BomIvgGf.js";import"./chunk-5VM5RSS4-RSFWgHJK.js";import"./chunk-XXDRQBXY-Df-77sm7.js";import"./chunk-VR4S4FIN-BK51NinF.js";import"./chunk-32BRIVSS-CR_BEEo8.js";import"./purify.es-CC4Brkr_.js";import"./channel-Bm8opuca.js";import"./index-ILJW_1zc.js";import"./react-XDCjal2T.js";import"./dnd-BCFAPC0L.js";import"./terminal-C7X98Amf.js";var a=o(t=>`${e(t)}
|
|
2
|
-
.swimlane.cluster rect {
|
|
3
|
-
stroke: ${t.clusterBorder} !important;
|
|
4
|
-
}
|
|
5
|
-
[data-look="neo"].cluster rect {
|
|
6
|
-
filter: none;
|
|
7
|
-
}
|
|
8
|
-
`,"getStyles"),m=a,v=r({defaultLayout:"swimlane",styles:m});export{v as diagram};
|