clay-server 4.1.0-beta.4 → 4.1.0-beta.6
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/lib/autonomous-run-record.js +32 -0
- package/lib/autonomous-run-scheduler.js +92 -0
- package/lib/durable-scheduler-record.js +61 -0
- package/lib/durable-scheduler-store.js +185 -0
- package/lib/durable-scheduler.js +495 -0
- package/lib/loop-cron.js +47 -0
- package/lib/loop-durable-schedule.js +159 -0
- package/lib/loop-guidance.js +35 -0
- package/lib/loop-registry-occurrence.js +76 -0
- package/lib/project-autonomous-run.js +498 -0
- package/lib/project-connection.js +4 -1
- package/lib/project-full-access.js +86 -0
- package/lib/project-http.js +3 -1
- package/lib/project-loop-interview.js +163 -0
- package/lib/project-loop.js +150 -64
- package/lib/project-pair-autonomous-stop.js +16 -0
- package/lib/project-pair-owned-stop.js +18 -0
- package/lib/project-pair-task-control.js +14 -1
- package/lib/project-scheduled-messages.js +316 -0
- package/lib/project-scheduled-task-execution.js +236 -0
- package/lib/project-scheduled-tasks.js +483 -0
- package/lib/project-session-pair.js +16 -19
- package/lib/project-sessions.js +60 -28
- package/lib/project-user-message.js +24 -18
- package/lib/project.js +260 -52
- package/lib/public/app.js +60 -23
- package/lib/public/css/home-hub.css +15 -2
- package/lib/public/css/home-sidebar.css +50 -2
- package/lib/public/css/input.css +71 -0
- package/lib/public/css/mates.css +0 -1
- package/lib/public/css/pane.css +58 -7
- package/lib/public/css/rewind.css +11 -2
- package/lib/public/css/scheduled-tasks.css +123 -0
- package/lib/public/css/sticky-notes.css +24 -4
- package/lib/public/index.html +19 -134
- package/lib/public/modules/app-loop-ui.js +4 -8
- package/lib/public/modules/app-messages.js +22 -6
- package/lib/public/modules/app-projects.js +2 -0
- package/lib/public/modules/app-rate-limit.js +8 -5
- package/lib/public/modules/autonomous-run.js +285 -0
- package/lib/public/modules/home-sidebar.js +16 -8
- package/lib/public/modules/home-surface.js +5 -0
- package/lib/public/modules/input.js +5 -4
- package/lib/public/modules/loop-interview.js +151 -0
- package/lib/public/modules/project-logs.js +2 -2
- package/lib/public/modules/scheduled-message-state.js +46 -0
- package/lib/public/modules/scheduled-task-edit-state.js +7 -0
- package/lib/public/modules/scheduled-task-engine.js +98 -0
- package/lib/public/modules/scheduled-task-form.js +122 -0
- package/lib/public/modules/scheduled-task-recurrence.js +46 -0
- package/lib/public/modules/scheduled-task-schedule-rule.js +115 -0
- package/lib/public/modules/scheduled-tasks.js +468 -0
- package/lib/public/modules/scheduler-config.js +6 -52
- package/lib/public/modules/scheduler.js +9 -21
- package/lib/public/modules/sidebar.js +0 -11
- package/lib/public/modules/split-view.js +2 -0
- package/lib/public/modules/sticky-notes-browser.js +1 -1
- package/lib/public/modules/sticky-notes.js +117 -4
- package/lib/public/modules/tool-palette-order.js +2 -3
- package/lib/public/modules/tools.js +5 -2
- package/lib/public/style.css +1 -0
- package/lib/record-revision.js +11 -0
- package/lib/schedule-rule.js +151 -0
- package/lib/schedule-validation.js +124 -0
- package/lib/scheduled-run-state.js +87 -0
- package/lib/scheduled-task-records.js +127 -0
- package/lib/scheduler.js +179 -196
- package/lib/sdk-bridge.js +123 -11
- package/lib/sdk-message-processor.js +3 -0
- package/lib/server-durable-scheduler.js +26 -0
- package/lib/server.js +22 -0
- package/lib/session-pair-factory.js +42 -4
- package/lib/session-pair-query-start.js +22 -0
- package/lib/session-query-tool-bridge.js +52 -0
- package/lib/session-split-groups.js +35 -1
- package/lib/sessions.js +51 -3
- package/lib/users-home-surface-preferences.js +2 -1
- package/lib/users-scheduled-task-preferences.js +44 -0
- package/lib/users.js +6 -0
- package/lib/ws-schema.js +25 -0
- package/lib/yoke/adapters/antigravity.js +1 -0
- package/lib/yoke/adapters/claude-worker.js +7 -4
- package/lib/yoke/adapters/claude.js +31 -1
- package/lib/yoke/adapters/codex.js +3 -0
- package/lib/yoke/claude-user-input.js +2 -0
- package/lib/yoke/index.js +2 -0
- package/lib/yoke/mcp-bridge-server.js +7 -1
- package/lib/yoke/session-tool-transport.js +53 -0
- package/lib/yoke/user-input.js +21 -7
- package/package.json +1 -1
- package/lib/public/modules/app-loop-wizard.js +0 -439
package/lib/public/app.js
CHANGED
|
@@ -28,9 +28,11 @@ import { initQrCode, triggerShare } from './modules/qrcode.js';
|
|
|
28
28
|
import { initFileBrowser, loadRootDirectory, refreshTree, handleFsList, handleFsRead, handleDirChanged, refreshIfOpen, handleFileChanged, handleFileHistory, handleGitDiff, handleFileAt, getPendingNavigate, closeFileViewer, resetFileBrowser } from './modules/filebrowser.js';
|
|
29
29
|
import { initGitPanel } from './modules/git-panel.js';
|
|
30
30
|
import { initWorkerPaneLock } from './modules/worker-pane-lock.js';
|
|
31
|
+
import { initAutonomousRun } from './modules/autonomous-run.js';
|
|
32
|
+
import { initLoopInterview } from './modules/loop-interview.js';
|
|
31
33
|
import { initTerminal, openTerminal, closeTerminal, resetTerminals, handleTermList, handleTermCreated, handleTermOutput, handleTermResized, handleTermExited, handleTermClosed, sendTerminalCommand } from './modules/terminal.js';
|
|
32
34
|
import { initContextSources, updateTerminalList, updateBrowserTabList, handleContextSourcesState, getActiveSources, hasActiveSources } from './modules/context-sources.js';
|
|
33
|
-
import { initStickyNotes, handleNotesList, handleNoteCreated, handleNoteUpdated, handleNoteDeleted, hideNotes, showNotes, isNotesVisible, createNote, setBrowserRefresh } from './modules/sticky-notes.js';
|
|
35
|
+
import { initStickyNotes, handleNotesList, handleNoteCreated, handleNoteUpdated, handleNoteDeleted, hideNotes, showNotes, isNotesVisible, createNote, setBrowserRefresh, toggleNotesTemporaryVisibility } from './modules/sticky-notes.js';
|
|
34
36
|
import { initNotesBrowser, openNotesBrowser, closeNotesBrowser, isNotesBrowserOpen, renderNotesBrowser, registerExclusiveClosers } from './modules/sticky-notes-browser.js';
|
|
35
37
|
import { initTheme, getThemeColor, getComputedVar, onThemeChange, getCurrentTheme, getChatLayout } from './modules/theme.js';
|
|
36
38
|
import { initTools, resetToolState, saveToolState, restoreToolState, renderAskUserQuestion, markAskUserAnswered, renderPermissionRequest, markPermissionResolved, markPermissionCancelled, renderElicitationRequest, markElicitationResolved, renderPlanBanner, renderPlanCard, handleTodoWrite, handleTaskCreate, handleTaskUpdate, startThinking, appendThinking, stopThinking, resetThinkingGroup, createToolItem, updateToolExecuting, updateToolResult, markAllToolsDone, addTurnMeta, resetTurnMetaCost, enableMainInput, getTools, getPlanContent, setPlanContent, isPlanFilePath, getTodoTools, updateSubagentActivity, addSubagentToolEntry, markSubagentDone, updateSubagentProgress, initSubagentStop, closeToolGroup, removeToolFromGroup } from './modules/tools.js';
|
|
@@ -39,6 +41,7 @@ import { initProjectSettings, handleInstructionsRead, handleInstructionsWrite, h
|
|
|
39
41
|
import { initSkills, handleSkillInstalled, handleSkillUninstalled } from './modules/skills.js';
|
|
40
42
|
import { initMcp } from './modules/mcp-ui.js';
|
|
41
43
|
import { initScheduler, resetScheduler, handleLoopRegistryUpdated, handleScheduleRunStarted, handleScheduleRunFinished, handleLoopScheduled, openSchedulerToTab, isSchedulerOpen, closeScheduler, enterCraftingMode, exitCraftingMode, handleLoopRegistryFiles, getUpcomingSchedules } from './modules/scheduler.js';
|
|
44
|
+
import { initScheduledTasks, closeScheduledTasks } from './modules/scheduled-tasks.js';
|
|
42
45
|
import { initPlaybook, openPlaybook, getPlaybooks, getPlaybookForTip, isCompleted as isPlaybookCompleted } from './modules/playbook.js';
|
|
43
46
|
import { initSTT } from './modules/stt.js';
|
|
44
47
|
import { initProfile, getProfileLang } from './modules/profile.js';
|
|
@@ -73,7 +76,6 @@ import { initSkillInstall, requireSkills as _siRequireSkills, handleSkillInstall
|
|
|
73
76
|
import { initDebateUi, showDebateConcludeConfirm as _debShowDebateConcludeConfirm, exitDebateConcludeMode as _debExitDebateConcludeMode, handleDebateConcludeSend as _debHandleDebateConcludeSend, showDebateEndedMode as _debShowDebateEndedMode, exitDebateEndedMode as _debExitDebateEndedMode, showDebateUserFloor as _debShowDebateUserFloor, exitDebateFloorMode as _debExitDebateFloorMode, handleDebateFloorSend as _debHandleDebateFloorSend, renderDebateUserFloorDone as _debRenderDebateUserFloorDone, showDebateSticky as _debShowDebateSticky, showDebateBottomBar as _debShowDebateBottomBar, removeDebateBottomBar as _debRemoveDebateBottomBar, sendDebateStickyComment as _debSendDebateStickyComment, updateDebateRound as _debUpdateDebateRound } from './modules/app-debate-ui.js';
|
|
74
77
|
import { initLoopUi, updateLoopInputVisibility as _loopUpdateLoopInputVisibility, updateLoopButton as _loopUpdateLoopButton, showLoopBanner as _loopShowLoopBanner, updateLoopBanner as _loopUpdateLoopBanner, updateRalphBars as _loopUpdateRalphBars, showRalphCraftingBar as _loopShowRalphCraftingBar, showRalphApprovalBar as _loopShowRalphApprovalBar, updateRalphApprovalStatus as _loopUpdateRalphApprovalStatus, openRalphPreviewModal as _loopOpenRalphPreviewModal, showExecModal as _loopShowExecModal, closeExecModal as _loopCloseExecModal, updateExecModalStatus as _loopUpdateExecModalStatus } from './modules/app-loop-ui.js';
|
|
75
78
|
import { initBackgroundTasksUi } from './modules/background-tasks-ui.js';
|
|
76
|
-
import { initLoopWizard, openRalphWizard as _loopOpenRalphWizard, closeRalphWizard as _loopCloseRalphWizard, getWizardSource as _loopGetWizardSource } from './modules/app-loop-wizard.js';
|
|
77
79
|
import { initAppNotifications, handleNotificationsState as _notifHandleState, handleNotificationCreated as _notifHandleCreated, handleNotificationDismissed as _notifHandleDismissed, handleNotificationDismissedAll as _notifHandleDismissedAll } from './modules/app-notifications.js';
|
|
78
80
|
import { initWhatsNew, handleWhatsNewState as _wnHandleState, handleWhatsNewSeenResult as _wnHandleSeenResult } from './modules/whats-new.js';
|
|
79
81
|
import { initWhatsNewArticle, openArticle as openWhatsNewArticle } from './modules/whats-new-article.js';
|
|
@@ -220,7 +222,6 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
220
222
|
// connected, processing, activeSessionId, sessionDrafts -> store
|
|
221
223
|
// loopActive, loopAvailable, loopIteration, loopMaxIterations, loopBannerName,
|
|
222
224
|
// ralphPhase, ralphCraftingSessionId, ralphCraftingSource, ralphFilesReady, ralphPreviewContent -> modules/app-loop-ui.js
|
|
223
|
-
// wizardStep, wizardSource, wizardData, loopModeChoice, promptAuthor, judgeAuthor -> modules/app-loop-wizard.js
|
|
224
225
|
// slashCommands, cliSessionId -> store
|
|
225
226
|
var projectName = ""; // kept for pre-store localStorage init
|
|
226
227
|
// turnCounter -> modules/app-rendering.js
|
|
@@ -269,6 +270,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
269
270
|
splitPanes: null,
|
|
270
271
|
splitGroups: [],
|
|
271
272
|
splitDelegations: {},
|
|
273
|
+
notesTemporarilyHidden: false,
|
|
272
274
|
dmMode: false,
|
|
273
275
|
historyFrom: 0,
|
|
274
276
|
loadingMore: false,
|
|
@@ -284,8 +286,28 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
284
286
|
currentProjectOwnerId: null,
|
|
285
287
|
isOsUsers: false,
|
|
286
288
|
skipPermsEnabled: false,
|
|
289
|
+
autonomousSelectedMode: "normal",
|
|
290
|
+
autonomousArming: false,
|
|
291
|
+
autonomousArmToken: null,
|
|
292
|
+
autonomousArmRequestId: null,
|
|
293
|
+
autonomousArmSessionId: null,
|
|
294
|
+
autonomousActionRequestId: null,
|
|
295
|
+
autonomousActionSessionId: null,
|
|
296
|
+
autonomousCriteria: "",
|
|
297
|
+
autonomousMaxContinuations: 10,
|
|
298
|
+
autonomousMaxMinutes: 60,
|
|
299
|
+
autonomousRun: null,
|
|
300
|
+
autonomousExpanded: false,
|
|
301
|
+
loopInterviewBrief: null,
|
|
302
|
+
loopInterviewEditing: false,
|
|
303
|
+
loopInterviewRunRequestId: null,
|
|
304
|
+
loopInterviewRunSessionId: null,
|
|
305
|
+
loopInterviewStarting: false,
|
|
306
|
+
loopInterviewRequestId: null,
|
|
307
|
+
loopInterviewSessionId: null,
|
|
287
308
|
slashCommands: [],
|
|
288
309
|
processing: false,
|
|
310
|
+
scheduledMessageCorrelation: null,
|
|
289
311
|
activeSessionId: null,
|
|
290
312
|
askUserRequests: {},
|
|
291
313
|
activeBackgroundTasks: [],
|
|
@@ -305,6 +327,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
305
327
|
homeActiveSessionByMate: {},
|
|
306
328
|
homePreferredMateId: null,
|
|
307
329
|
homeSidebarCollapsed: false,
|
|
330
|
+
homeMatesCollapsed: false,
|
|
308
331
|
homeChatScope: "all",
|
|
309
332
|
homeSubSurface: "chat",
|
|
310
333
|
homeDebatesStatus: "idle",
|
|
@@ -344,6 +367,23 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
344
367
|
projectLogsCanDelete: false,
|
|
345
368
|
projectLogsUnread: 0,
|
|
346
369
|
projectLogsSeenRevisions: {},
|
|
370
|
+
scheduledTasksOpen: false,
|
|
371
|
+
scheduledTasksWide: false,
|
|
372
|
+
scheduledTasksFullscreen: false,
|
|
373
|
+
scheduledTaskRecords: [],
|
|
374
|
+
scheduledTaskDraft: null,
|
|
375
|
+
scheduledTaskEditingId: null,
|
|
376
|
+
scheduledTaskNewSessionPending: false,
|
|
377
|
+
scheduledTaskInterviewRequestId: null,
|
|
378
|
+
scheduledTaskActionRequestId: null,
|
|
379
|
+
scheduledTaskListRequest: null,
|
|
380
|
+
scheduledTaskInterviewId: null,
|
|
381
|
+
scheduledTaskExpandedId: null,
|
|
382
|
+
scheduledTaskDeleteId: null,
|
|
383
|
+
scheduledTaskDraftForm: null,
|
|
384
|
+
scheduledTaskEditForm: null,
|
|
385
|
+
scheduledTaskCreateMenuOpen: false,
|
|
386
|
+
scheduledTaskManualRequest: null,
|
|
347
387
|
installedTools: [],
|
|
348
388
|
capsulesEnabled: false,
|
|
349
389
|
capsulesPreferenceLoaded: false,
|
|
@@ -480,7 +520,6 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
480
520
|
switchProject: function (slug) { switchProject(slug); },
|
|
481
521
|
openTerminal: function () { openTerminal(); },
|
|
482
522
|
showHomeHub: function () { showHomeHub(); },
|
|
483
|
-
openRalphWizard: function (source) { openRalphWizard(source); },
|
|
484
523
|
getUpcomingSchedules: getUpcomingSchedules,
|
|
485
524
|
get multiUser() { return store.get('isMultiUserMode'); },
|
|
486
525
|
get myUserId() { return store.get('myUserId'); },
|
|
@@ -501,6 +540,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
501
540
|
// mcp-ui.js / etc.) attach click handlers by ID.
|
|
502
541
|
initToolPalettes();
|
|
503
542
|
initProjectLogs();
|
|
543
|
+
initScheduledTasks();
|
|
504
544
|
initSidebar(sidebarCtx);
|
|
505
545
|
var wsGetter = function () { return _getWsRef(); };
|
|
506
546
|
initMateSidebar(wsGetter);
|
|
@@ -688,7 +728,8 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
688
728
|
|
|
689
729
|
initLoopUi();
|
|
690
730
|
initBackgroundTasksUi();
|
|
691
|
-
|
|
731
|
+
initAutonomousRun();
|
|
732
|
+
initLoopInterview();
|
|
692
733
|
|
|
693
734
|
// --- Notifications module ---
|
|
694
735
|
initAppNotifications();
|
|
@@ -975,8 +1016,6 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
975
1016
|
if (msBtn) msBtn.style.display = "none";
|
|
976
1017
|
}
|
|
977
1018
|
if (!_perms.scheduledTasks) {
|
|
978
|
-
var schBtn = document.getElementById("home-scheduler-btn");
|
|
979
|
-
if (schBtn) schBtn.style.display = "none";
|
|
980
1019
|
var schToolBtn = document.getElementById("scheduler-btn");
|
|
981
1020
|
if (schToolBtn) schToolBtn.style.display = "none";
|
|
982
1021
|
}
|
|
@@ -1119,13 +1158,14 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
1119
1158
|
setBrowserRefresh(function () { if (isNotesBrowserOpen()) renderNotesBrowser(); });
|
|
1120
1159
|
// Opening the browser claims the single right workbench slot. Registered here
|
|
1121
1160
|
// so the browser module never imports the other tools.
|
|
1122
|
-
registerExclusiveClosers([closeProjectLogs,
|
|
1161
|
+
registerExclusiveClosers([closeProjectLogs, closeScheduledTasks, closeFileViewer, closeTerminal]);
|
|
1123
1162
|
|
|
1124
1163
|
// --- Sticky Notes sidebar button (create new note) ---
|
|
1125
1164
|
var stickyNotesSidebarBtn = $("sticky-notes-sidebar-btn");
|
|
1126
1165
|
if (stickyNotesSidebarBtn) {
|
|
1127
1166
|
stickyNotesSidebarBtn.addEventListener("click", function () {
|
|
1128
1167
|
closeProjectLogs();
|
|
1168
|
+
closeScheduledTasks();
|
|
1129
1169
|
if (isSchedulerOpen()) closeScheduler();
|
|
1130
1170
|
if (isNotesBrowserOpen()) closeNotesBrowser();
|
|
1131
1171
|
showNotes();
|
|
@@ -1133,12 +1173,20 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
1133
1173
|
});
|
|
1134
1174
|
}
|
|
1135
1175
|
|
|
1176
|
+
var stickyNotesToggleButtons = document.querySelectorAll("#sticky-notes-toggle-btn");
|
|
1177
|
+
for (var stickyToggleIndex = 0; stickyToggleIndex < stickyNotesToggleButtons.length; stickyToggleIndex++) {
|
|
1178
|
+
stickyNotesToggleButtons[stickyToggleIndex].addEventListener("click", function () {
|
|
1179
|
+
toggleNotesTemporaryVisibility();
|
|
1180
|
+
});
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1136
1183
|
// Sticky Notes badge click → archive toggle
|
|
1137
1184
|
var stickyNotesBadge = $("sticky-notes-sidebar-count");
|
|
1138
1185
|
if (stickyNotesBadge) {
|
|
1139
1186
|
stickyNotesBadge.addEventListener("click", function (e) {
|
|
1140
1187
|
e.stopPropagation();
|
|
1141
1188
|
closeProjectLogs();
|
|
1189
|
+
closeScheduledTasks();
|
|
1142
1190
|
if (isSchedulerOpen()) closeScheduler();
|
|
1143
1191
|
if (isNotesBrowserOpen()) {
|
|
1144
1192
|
closeNotesBrowser();
|
|
@@ -1152,11 +1200,11 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
1152
1200
|
var fileBrowserBtn = $("file-browser-btn");
|
|
1153
1201
|
var gitPlacardMoreBtn = $("git-placard-more");
|
|
1154
1202
|
var terminalSidebarBtn = $("terminal-sidebar-btn");
|
|
1155
|
-
if (fileBrowserBtn) fileBrowserBtn.addEventListener("click", function () { closeProjectLogs(); if (isNotesBrowserOpen()) closeNotesBrowser(); if (isSchedulerOpen()) closeScheduler(); });
|
|
1156
|
-
if (gitPlacardMoreBtn) gitPlacardMoreBtn.addEventListener("click", function () { closeProjectLogs(); if (isNotesBrowserOpen()) closeNotesBrowser(); if (isSchedulerOpen()) closeScheduler(); });
|
|
1157
|
-
if (terminalSidebarBtn) terminalSidebarBtn.addEventListener("click", function () { closeProjectLogs(); if (isNotesBrowserOpen()) closeNotesBrowser(); if (isSchedulerOpen()) closeScheduler(); });
|
|
1203
|
+
if (fileBrowserBtn) fileBrowserBtn.addEventListener("click", function () { closeProjectLogs(); closeScheduledTasks(); if (isNotesBrowserOpen()) closeNotesBrowser(); if (isSchedulerOpen()) closeScheduler(); });
|
|
1204
|
+
if (gitPlacardMoreBtn) gitPlacardMoreBtn.addEventListener("click", function () { closeProjectLogs(); closeScheduledTasks(); if (isNotesBrowserOpen()) closeNotesBrowser(); if (isSchedulerOpen()) closeScheduler(); });
|
|
1205
|
+
if (terminalSidebarBtn) terminalSidebarBtn.addEventListener("click", function () { closeProjectLogs(); closeScheduledTasks(); if (isNotesBrowserOpen()) closeNotesBrowser(); if (isSchedulerOpen()) closeScheduler(); });
|
|
1158
1206
|
|
|
1159
|
-
// ---
|
|
1207
|
+
// --- Legacy scheduled Loop UI ---
|
|
1160
1208
|
function updateLoopInputVisibility(loop) { _loopUpdateLoopInputVisibility(loop); }
|
|
1161
1209
|
function updateLoopButton() { _loopUpdateLoopButton(); }
|
|
1162
1210
|
function showLoopBanner(show) { _loopShowLoopBanner(show); }
|
|
@@ -1193,9 +1241,6 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
1193
1241
|
});
|
|
1194
1242
|
}
|
|
1195
1243
|
|
|
1196
|
-
// --- Ralph Wizard (delegated to app-loop-wizard.js) ---
|
|
1197
|
-
function openRalphWizard(source) { _loopOpenRalphWizard(source); }
|
|
1198
|
-
function closeRalphWizard() { _loopCloseRalphWizard(); }
|
|
1199
1244
|
|
|
1200
1245
|
// --- Debate UI (delegated to app-debate-ui.js) ---
|
|
1201
1246
|
// debateStickyState, debateHandRaiseOpen, debateFloorMode, debateConcludeMode, debateEndedMode -> modules/app-debate-ui.js
|
|
@@ -1229,14 +1274,6 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
1229
1274
|
get activeSessionId() { return store.get('activeSessionId'); },
|
|
1230
1275
|
basePath: basePath,
|
|
1231
1276
|
currentSlug: currentSlug, // init-time snapshot, scheduler uses for initial setup
|
|
1232
|
-
openRalphWizard: function (source) { openRalphWizard(source); },
|
|
1233
|
-
requireClayRalph: function (cb) {
|
|
1234
|
-
requireSkills({
|
|
1235
|
-
title: "Skill Installation Required",
|
|
1236
|
-
reason: "This feature requires the following skill to be installed.",
|
|
1237
|
-
skills: [{ name: "clay-ralph", url: "https://github.com/chadbyte/clay-ralph", scope: "global" }]
|
|
1238
|
-
}, cb);
|
|
1239
|
-
},
|
|
1240
1277
|
getProjects: function () { return getCachedProjects(); },
|
|
1241
1278
|
});
|
|
1242
1279
|
|
|
@@ -9,6 +9,7 @@ body.home-active #mate-sidebar-column,
|
|
|
9
9
|
body.home-active #sidebar-resize-handle,
|
|
10
10
|
body.home-active #mate-sidebar-resize-handle,
|
|
11
11
|
body.home-active #sidebar-overlay,
|
|
12
|
+
body.home-active #mobile-tab-bar,
|
|
12
13
|
body.home-active .title-bar-content,
|
|
13
14
|
body.home-active #user-island { display: none !important; }
|
|
14
15
|
|
|
@@ -935,7 +936,7 @@ body.home-surface-boot-pending #connect-overlay.hidden {
|
|
|
935
936
|
}
|
|
936
937
|
|
|
937
938
|
@media (max-width: 900px) {
|
|
938
|
-
#home-hub { padding: calc(6px + var(--safe-top)) 8px calc(
|
|
939
|
+
#home-hub { padding: calc(6px + var(--safe-top)) 8px calc(8px + var(--safe-bottom, 0px)); }
|
|
939
940
|
|
|
940
941
|
.home-hub-inner {
|
|
941
942
|
height: 100%;
|
|
@@ -980,9 +981,21 @@ body.home-surface-boot-pending #connect-overlay.hidden {
|
|
|
980
981
|
}
|
|
981
982
|
|
|
982
983
|
@media (max-width: 768px) {
|
|
984
|
+
#home-hub:not(.dock-split):not(.dock-focus) .home-mate-chat-stage {
|
|
985
|
+
padding-top: 52px;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
#home-hub:not(.dock-split):not(.dock-focus) .home-mate-chat-messages {
|
|
989
|
+
padding-top: 8px;
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
#home-hub:not(.dock-split):not(.dock-focus) .home-mate-chat-composer-frame {
|
|
993
|
+
margin-bottom: 0;
|
|
994
|
+
}
|
|
995
|
+
|
|
983
996
|
#home-hub.dock-split,
|
|
984
997
|
#home-hub.dock-focus {
|
|
985
|
-
padding: var(--safe-top) 0
|
|
998
|
+
padding: var(--safe-top) 0 var(--safe-bottom, 0px);
|
|
986
999
|
}
|
|
987
1000
|
|
|
988
1001
|
.home-workspace { flex-direction: column; }
|
|
@@ -223,6 +223,50 @@
|
|
|
223
223
|
padding-left: 7px;
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
+
.home-sidebar-mate-toggle {
|
|
227
|
+
display: flex;
|
|
228
|
+
align-items: center;
|
|
229
|
+
justify-content: space-between;
|
|
230
|
+
width: 100%;
|
|
231
|
+
min-height: 25px;
|
|
232
|
+
border: 0;
|
|
233
|
+
background: transparent;
|
|
234
|
+
color: var(--text-dimmer);
|
|
235
|
+
font: inherit;
|
|
236
|
+
font-size: 9px;
|
|
237
|
+
font-weight: 680;
|
|
238
|
+
letter-spacing: 0.09em;
|
|
239
|
+
line-height: 1.2;
|
|
240
|
+
text-align: left;
|
|
241
|
+
text-transform: uppercase;
|
|
242
|
+
cursor: pointer;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.home-sidebar-mate-toggle:hover,
|
|
246
|
+
.home-sidebar-mate-toggle:focus-visible {
|
|
247
|
+
color: var(--text-secondary);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.home-sidebar-mate-toggle:focus-visible {
|
|
251
|
+
outline: 2px solid var(--accent);
|
|
252
|
+
outline-offset: -2px;
|
|
253
|
+
border-radius: 5px;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.home-sidebar-mate-toggle .lucide {
|
|
257
|
+
width: 12px;
|
|
258
|
+
height: 12px;
|
|
259
|
+
transition: transform 140ms ease;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.home-sidebar-mate-toggle[aria-expanded="false"] .lucide {
|
|
263
|
+
transform: rotate(-90deg);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.home-sidebar-mates-collapsed .home-mate-list {
|
|
267
|
+
display: none;
|
|
268
|
+
}
|
|
269
|
+
|
|
226
270
|
.home-mate-list {
|
|
227
271
|
flex: 0 0 var(--home-mate-list-height);
|
|
228
272
|
display: flex;
|
|
@@ -693,7 +737,7 @@
|
|
|
693
737
|
position: absolute;
|
|
694
738
|
z-index: 8;
|
|
695
739
|
top: calc(8px + var(--safe-top));
|
|
696
|
-
bottom: calc(
|
|
740
|
+
bottom: calc(8px + var(--safe-bottom, 0px));
|
|
697
741
|
left: 8px;
|
|
698
742
|
width: min(320px, calc(100vw - 24px));
|
|
699
743
|
padding: 6px;
|
|
@@ -701,6 +745,10 @@
|
|
|
701
745
|
border-radius: 12px;
|
|
702
746
|
box-shadow: 12px 18px 44px rgba(var(--shadow-rgb), 0.22);
|
|
703
747
|
}
|
|
748
|
+
.home-sidebar-mate-toggle {
|
|
749
|
+
width: 100%;
|
|
750
|
+
min-height: 36px;
|
|
751
|
+
}
|
|
704
752
|
.home-sidebar-backdrop {
|
|
705
753
|
position: absolute;
|
|
706
754
|
z-index: 7;
|
|
@@ -710,7 +758,7 @@
|
|
|
710
758
|
background: rgba(var(--shadow-rgb), 0.13);
|
|
711
759
|
}
|
|
712
760
|
#home-hub.home-sidebar-collapsed .home-sidebar-backdrop { display: none; }
|
|
713
|
-
.home-conversations-sheet { align-items: flex-end; padding: 8px 8px calc(
|
|
761
|
+
.home-conversations-sheet { align-items: flex-end; padding: 8px 8px calc(8px + var(--safe-bottom, 0px)); }
|
|
714
762
|
.home-conversations-sheet-panel { width: 100%; max-height: calc(100vh - 84px); border-radius: 14px 14px 10px 10px; }
|
|
715
763
|
}
|
|
716
764
|
|
package/lib/public/css/input.css
CHANGED
|
@@ -747,6 +747,77 @@
|
|
|
747
747
|
position: relative;
|
|
748
748
|
}
|
|
749
749
|
|
|
750
|
+
/* Until complete keeps the composer's visual language: compact, quiet, and
|
|
751
|
+
explicit about the Driver assessment rather than presenting a second app. */
|
|
752
|
+
.execution-mode-wrap { position: relative; flex: none; }
|
|
753
|
+
.execution-mode-wrap.hidden { display: none; }
|
|
754
|
+
#loop-interview-btn { flex: none; }
|
|
755
|
+
#loop-interview-btn.arming { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
|
|
756
|
+
#loop-interview-card { max-width: var(--content-width); max-height: min(260px, 35vh); overflow-y: auto; margin: 0 auto 8px; padding: 12px 14px; border: 1px solid var(--border-subtle); border-radius: 12px; background: var(--surface); }
|
|
757
|
+
#loop-interview-card.hidden { display: none; }
|
|
758
|
+
.loop-interview-objective, .loop-interview-criteria { margin-top: 6px; white-space: pre-wrap; }
|
|
759
|
+
.loop-interview-criteria { color: var(--text-muted); font-size: 12px; }
|
|
760
|
+
.loop-interview-limits, .loop-interview-disclosure { margin-top: 6px; color: var(--text-muted); font-size: 11px; }
|
|
761
|
+
.loop-interview-actions { display: flex; gap: 8px; margin-top: 10px; }
|
|
762
|
+
.loop-interview-actions button { padding: 5px 10px; border: 1px solid var(--border-subtle); border-radius: 7px; background: transparent; color: var(--text); cursor: pointer; }
|
|
763
|
+
#execution-mode-btn {
|
|
764
|
+
display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 9px;
|
|
765
|
+
border: 1px solid var(--border-subtle); border-radius: 9px; background: transparent;
|
|
766
|
+
color: var(--text-muted); font: inherit; font-size: 11px; cursor: pointer;
|
|
767
|
+
transition: color .15s ease, border-color .15s ease, background .15s ease;
|
|
768
|
+
}
|
|
769
|
+
#execution-mode-btn:hover:not(:disabled) { color: var(--text); border-color: var(--border); }
|
|
770
|
+
#execution-mode-btn.active { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); background: color-mix(in srgb, var(--accent) 8%, transparent); }
|
|
771
|
+
#execution-mode-btn:disabled { cursor: default; opacity: .45; }
|
|
772
|
+
#execution-mode-btn .lucide { width: 12px; height: 12px; }
|
|
773
|
+
#execution-mode-btn .lucide:last-child { width: 10px; height: 10px; }
|
|
774
|
+
.execution-mode-popover {
|
|
775
|
+
position: absolute; z-index: 80; right: 0; bottom: calc(100% + 8px); width: min(310px, calc(100vw - 32px));
|
|
776
|
+
padding: 7px; border: 1px solid var(--border); border-radius: 14px; background: var(--bg-elevated, var(--bg));
|
|
777
|
+
box-shadow: 0 18px 48px rgba(0, 0, 0, .18);
|
|
778
|
+
}
|
|
779
|
+
.execution-mode-popover.hidden { display: none; }
|
|
780
|
+
.execution-mode-option, .execution-mode-enable { width: 100%; border: 0; font: inherit; cursor: pointer; }
|
|
781
|
+
.execution-mode-option { display: flex; align-items: baseline; justify-content: space-between; padding: 9px 10px; border-radius: 9px; background: transparent; color: var(--text); text-align: left; }
|
|
782
|
+
.execution-mode-option:hover { background: rgba(var(--overlay-rgb), .06); }
|
|
783
|
+
.execution-mode-option span, .execution-until-settings > div > span { color: var(--text-muted); font-size: 11px; }
|
|
784
|
+
.execution-until-settings { margin-top: 5px; padding: 11px; border: 1px solid color-mix(in srgb, var(--accent) 26%, var(--border)); border-radius: 10px; background: color-mix(in srgb, var(--accent) 5%, transparent); }
|
|
785
|
+
.execution-until-settings > div:first-child { display: flex; flex-direction: column; gap: 2px; margin-bottom: 10px; }
|
|
786
|
+
.execution-until-settings label { display: flex; flex-direction: column; gap: 5px; color: var(--text-muted); font-size: 10px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; }
|
|
787
|
+
.execution-until-settings textarea, .execution-until-settings input { box-sizing: border-box; width: 100%; border: 1px solid var(--border); border-radius: 7px; background: var(--input-bg); color: var(--text); font: inherit; font-size: 12px; text-transform: none; letter-spacing: 0; outline: none; }
|
|
788
|
+
.execution-until-settings textarea { padding: 7px 8px; resize: vertical; min-height: 50px; }
|
|
789
|
+
.execution-until-settings input { height: 30px; padding: 0 7px; }
|
|
790
|
+
.execution-until-settings textarea:focus, .execution-until-settings input:focus { border-color: var(--accent); }
|
|
791
|
+
.execution-limit-row { display: grid !important; grid-template-columns: 1fr 1fr; gap: 8px; margin: 9px 0 !important; }
|
|
792
|
+
.execution-mode-enable { padding: 8px 10px; border-radius: 8px; background: var(--accent); color: var(--bg); font-size: 12px; font-weight: 650; }
|
|
793
|
+
.autonomous-run-status { display: grid; grid-template-columns: 1fr auto; align-items: center; margin: 0 0 6px; border: 1px solid color-mix(in srgb, var(--accent) 26%, var(--border)); border-radius: 10px; background: color-mix(in srgb, var(--accent) 4%, transparent); overflow: hidden; }
|
|
794
|
+
.autonomous-run-status.hidden { display: none; }
|
|
795
|
+
.autonomous-run-summary { display: flex; align-items: center; gap: 8px; min-width: 0; padding: 7px 10px; border: 0; background: transparent; color: var(--text-secondary); font: inherit; font-size: 12px; cursor: pointer; text-align: left; }
|
|
796
|
+
.autonomous-run-summary #autonomous-run-state { font-weight: 650; color: var(--text); }
|
|
797
|
+
#autonomous-run-progress { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-muted); font-size: 11px; }
|
|
798
|
+
.autonomous-run-mark { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent); }
|
|
799
|
+
.autonomous-run-status.terminal .autonomous-run-mark { background: var(--text-muted); box-shadow: none; }
|
|
800
|
+
.autonomous-run-summary .lucide { width: 13px; height: 13px; transition: transform .15s ease; }
|
|
801
|
+
.autonomous-run-status.expanded .autonomous-run-summary .lucide { transform: rotate(180deg); }
|
|
802
|
+
.autonomous-run-actions { display: flex; gap: 5px; padding-right: 7px; }
|
|
803
|
+
.autonomous-run-actions button { border: 1px solid var(--border); border-radius: 7px; padding: 4px 8px; background: transparent; color: var(--text-muted); font: inherit; font-size: 11px; cursor: pointer; }
|
|
804
|
+
.autonomous-run-actions button:hover { color: var(--text); }
|
|
805
|
+
.autonomous-run-actions button.hidden { display: none; }
|
|
806
|
+
.autonomous-run-detail { display: none; grid-column: 1 / -1; padding: 2px 10px 9px; }
|
|
807
|
+
.autonomous-run-status.expanded .autonomous-run-detail { display: block; }
|
|
808
|
+
.autonomous-run-detail-row { display: grid; grid-template-columns: 105px 1fr; gap: 10px; padding: 6px 0; border-top: 1px solid var(--border-subtle); font-size: 11px; white-space: pre-wrap; }
|
|
809
|
+
.autonomous-run-detail-row > span:first-child { color: var(--text-muted); }
|
|
810
|
+
.autonomous-run-detail-row > span:last-child { color: var(--text-secondary); }
|
|
811
|
+
|
|
812
|
+
@media (max-width: 600px) {
|
|
813
|
+
#execution-mode-btn { width: auto; max-width: 116px; padding: 0 7px; justify-content: center; }
|
|
814
|
+
#execution-mode-label { display: inline; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
815
|
+
#execution-mode-btn .lucide:last-child { display: none; }
|
|
816
|
+
.autonomous-run-summary { gap: 6px; }
|
|
817
|
+
#autonomous-run-progress { display: none; }
|
|
818
|
+
.autonomous-run-detail-row { grid-template-columns: 1fr; gap: 3px; }
|
|
819
|
+
}
|
|
820
|
+
|
|
750
821
|
/* Sidebar session-row badge. Formerly shared its rule with the composer's
|
|
751
822
|
background-tasks chip; it is standalone now that the composer bar no longer
|
|
752
823
|
uses a filled numeric badge. */
|
package/lib/public/css/mates.css
CHANGED
|
@@ -2790,7 +2790,6 @@ body.mate-dm-active .activity-inline:not(.mention-activity-bar):not(.mate-pre-ac
|
|
|
2790
2790
|
body.mate-dm-active .title-bar-content #todo-sticky,
|
|
2791
2791
|
body.mate-dm-active .title-bar-content #ralph-sticky,
|
|
2792
2792
|
body.mate-dm-active .dm-header-bar,
|
|
2793
|
-
body.mate-dm-active .title-bar-content .status #sticky-notes-toggle-btn,
|
|
2794
2793
|
body.mate-dm-active .title-bar-content .status #terminal-toggle-btn {
|
|
2795
2794
|
display: none !important;
|
|
2796
2795
|
}
|
package/lib/public/css/pane.css
CHANGED
|
@@ -45,9 +45,11 @@ body.pane-mode #app {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/* Narrow panes cross the mobile breakpoint, but pane mode hides the mobile
|
|
48
|
-
tab bar.
|
|
48
|
+
tab bar. The parent split shell owns the mobile safe-area reservation. */
|
|
49
49
|
body.pane-mode #input-area {
|
|
50
|
-
|
|
50
|
+
/* The parent split shell owns the mobile safe area. Keeping it out of the
|
|
51
|
+
iframe prevents the Driver composer from receiving the inset twice. */
|
|
52
|
+
padding-bottom: 8px;
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
#main-panels {
|
|
@@ -430,9 +432,31 @@ body.pane-mode #input-area {
|
|
|
430
432
|
/* Portrait phones have enough height for two useful panes but not enough
|
|
431
433
|
width for two readable transcripts. Keep the role order independent from
|
|
432
434
|
the persisted member order so the Split Worker stays above its Driver. */
|
|
435
|
+
@media (max-width: 768px) {
|
|
436
|
+
/* The mobile tab bar is fixed outside this flex tree. Reserve its usable
|
|
437
|
+
height once in the parent shell, not independently in either iframe. */
|
|
438
|
+
#main-panels:has(> #split-host.visible) {
|
|
439
|
+
padding-bottom: calc(56px + var(--safe-bottom, 0px));
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
body.keyboard-open #main-panels:has(> #split-host.visible) {
|
|
443
|
+
padding-bottom: 0;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
433
447
|
@media (max-width: 768px) and (orientation: portrait) {
|
|
448
|
+
/* These dimensions are also used by the divider marker below. */
|
|
449
|
+
#split-host.visible {
|
|
450
|
+
--split-shell-inset: 8px;
|
|
451
|
+
--split-pane-gap: 8px;
|
|
452
|
+
--split-pane-gap-half: 4px;
|
|
453
|
+
--split-worker-height: calc(30% - 4.8px);
|
|
454
|
+
}
|
|
455
|
+
|
|
434
456
|
#split-host.visible {
|
|
435
457
|
flex-direction: column;
|
|
458
|
+
gap: var(--split-pane-gap);
|
|
459
|
+
padding: var(--split-shell-inset);
|
|
436
460
|
}
|
|
437
461
|
|
|
438
462
|
.split-pane {
|
|
@@ -453,16 +477,43 @@ body.pane-mode #input-area {
|
|
|
453
477
|
order: 0;
|
|
454
478
|
}
|
|
455
479
|
|
|
456
|
-
|
|
457
|
-
|
|
480
|
+
/* A configured Worker is an execution summary; the Driver keeps the
|
|
481
|
+
generous lower surface for transcript review and composing. Ad-hoc
|
|
482
|
+
splits retain the equal fallback above. */
|
|
483
|
+
.split-pane.split-pane-role-worker {
|
|
484
|
+
flex: 0 0 30%;
|
|
485
|
+
border: 1px solid var(--border-subtle);
|
|
486
|
+
border-radius: 11px;
|
|
487
|
+
background: color-mix(in srgb, var(--bg-alt) 58%, var(--bg));
|
|
488
|
+
overflow: hidden;
|
|
458
489
|
}
|
|
459
490
|
|
|
460
|
-
.split-pane.split-pane-
|
|
461
|
-
|
|
491
|
+
.split-pane-role-worker .split-pane-header {
|
|
492
|
+
height: 26px;
|
|
493
|
+
background: transparent;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.split-pane-role-worker .split-pane-title {
|
|
497
|
+
display: none;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
.split-pane-role-worker .split-pair-live {
|
|
501
|
+
order: 3;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
.split-pane-role-worker .split-pane-close {
|
|
505
|
+
order: 2;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
.split-pane-role-driver {
|
|
509
|
+
flex: 1 1 auto;
|
|
462
510
|
}
|
|
463
511
|
|
|
464
|
-
#split-host.split-delegating::after {
|
|
512
|
+
#split-host:has(.split-pane-role-worker).split-delegating::after {
|
|
465
513
|
content: "↑";
|
|
514
|
+
/* Center on worker bottom + half the gap, accounting for the shell
|
|
515
|
+
inset and the 30% basis being relative to the inset content box. */
|
|
516
|
+
top: calc(var(--split-shell-inset) + var(--split-worker-height) + var(--split-pane-gap-half) - 10px);
|
|
466
517
|
animation-name: pair-divider-flow-up;
|
|
467
518
|
}
|
|
468
519
|
|
|
@@ -428,12 +428,20 @@
|
|
|
428
428
|
.ask-user-other input:focus { border-color: var(--text-dimmer); }
|
|
429
429
|
.ask-user-other input::placeholder { color: var(--text-muted); }
|
|
430
430
|
|
|
431
|
+
.ask-user-actions {
|
|
432
|
+
display: flex;
|
|
433
|
+
align-items: center;
|
|
434
|
+
gap: 8px;
|
|
435
|
+
margin-top: 14px;
|
|
436
|
+
}
|
|
437
|
+
|
|
431
438
|
.ask-user-submit {
|
|
432
439
|
background: var(--accent);
|
|
433
440
|
color: #fff;
|
|
434
441
|
border: none;
|
|
435
442
|
border-radius: 10px;
|
|
436
|
-
|
|
443
|
+
min-height: 36px;
|
|
444
|
+
padding: 8px 18px;
|
|
437
445
|
font-size: 13px;
|
|
438
446
|
font-weight: 600;
|
|
439
447
|
cursor: pointer;
|
|
@@ -448,7 +456,8 @@
|
|
|
448
456
|
background: transparent;
|
|
449
457
|
border: 1px solid var(--border);
|
|
450
458
|
border-radius: 10px;
|
|
451
|
-
|
|
459
|
+
min-height: 36px;
|
|
460
|
+
padding: 8px 18px;
|
|
452
461
|
font-size: 13px;
|
|
453
462
|
font-weight: 500;
|
|
454
463
|
font-family: inherit;
|