clay-server 5.2.0-beta.9 → 5.2.1-beta.1
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/README.md +0 -4
- package/lib/clay-product-control-tools.js +1 -0
- package/lib/clay-product-control.js +14 -11
- package/lib/clay-vendor-usage.js +44 -0
- package/lib/github-star-count.js +147 -0
- package/lib/notes-checklist.js +43 -1
- package/lib/notes.js +2 -1
- package/lib/project-session-notes.js +33 -8
- package/lib/project-sessions.js +63 -24
- package/lib/project-start-protocol.js +29 -0
- package/lib/project-vendor-login.js +2 -0
- package/lib/project.js +5 -1
- package/lib/public/app.js +30 -18
- package/lib/public/css/command-palette.css +12 -2
- package/lib/public/css/contextual-clay.css +1 -1
- package/lib/public/css/filebrowser.css +4 -5
- package/lib/public/css/mate-loading-scene.css +21 -0
- package/lib/public/css/messages.css +30 -11
- package/lib/public/css/overlays.css +67 -256
- package/lib/public/css/project-mate-creation.css +5 -6
- package/lib/public/css/project-start.css +108 -0
- package/lib/public/css/projects-hub.css +53 -14
- package/lib/public/css/right-workbench.css +28 -0
- package/lib/public/css/settings-shell.css +103 -0
- package/lib/public/css/sidebar.css +7 -0
- package/lib/public/css/title-bar.css +99 -0
- package/lib/public/index.html +54 -66
- package/lib/public/modules/account-transport-settings.js +8 -2
- package/lib/public/modules/admin-settings-email.js +7 -2
- package/lib/public/modules/admin-settings-invitations.js +2 -2
- package/lib/public/modules/admin-settings-projects.js +2 -2
- package/lib/public/modules/admin-settings-ui.js +20 -4
- package/lib/public/modules/admin-settings-users.js +4 -4
- package/lib/public/modules/app-home-hub.js +2 -1
- package/lib/public/modules/app-messages.js +10 -2
- package/lib/public/modules/app-projects.js +1 -407
- package/lib/public/modules/app-rate-limit.js +12 -1
- package/lib/public/modules/clay-tool-presentation.js +1 -0
- package/lib/public/modules/contextual-clay.js +3 -1
- package/lib/public/modules/github-star.js +66 -0
- package/lib/public/modules/home-surface-boot.js +0 -1
- package/lib/public/modules/mate-loading-scene.js +17 -0
- package/lib/public/modules/pair-result-status.js +89 -39
- package/lib/public/modules/pane-appearance-bridge.js +59 -0
- package/lib/public/modules/profile.js +11 -3
- package/lib/public/modules/project-mate-creation-workspace.js +13 -4
- package/lib/public/modules/project-session-visibility-settings.js +19 -16
- package/lib/public/modules/project-settings-environment.js +12 -1
- package/lib/public/modules/project-settings.js +119 -129
- package/lib/public/modules/project-start-dialog.js +130 -0
- package/lib/public/modules/project-start-folder-state.js +78 -0
- package/lib/public/modules/project-start-folder-view.js +190 -0
- package/lib/public/modules/project-start-forms.js +66 -0
- package/lib/public/modules/project-start-path.js +60 -0
- package/lib/public/modules/project-start-state.js +54 -0
- package/lib/public/modules/project-start-submit.js +67 -0
- package/lib/public/modules/projects-hub-view.js +32 -44
- package/lib/public/modules/projects-hub.js +39 -28
- package/lib/public/modules/server-settings.js +36 -91
- package/lib/public/modules/settings-project-target.js +56 -0
- package/lib/public/modules/settings-select.js +1 -1
- package/lib/public/modules/settings-shell-registry.js +88 -0
- package/lib/public/modules/settings-shell-view.js +104 -0
- package/lib/public/modules/settings-shell.js +342 -0
- package/lib/public/modules/sidebar-mobile.js +8 -30
- package/lib/public/modules/sidebar-projects.js +2 -1
- package/lib/public/modules/theme.js +31 -3
- package/lib/public/modules/topbar-workbench-controls.js +102 -0
- package/lib/public/modules/user-settings-integrations.js +2 -1
- package/lib/public/modules/user-settings-layout.js +12 -34
- package/lib/public/modules/user-settings-profile.js +1 -1
- package/lib/public/modules/user-settings.js +18 -85
- package/lib/public/modules/vendor-usage-format.js +93 -0
- package/lib/public/modules/vendor-usage-list.js +45 -0
- package/lib/public/modules/vendor-usage-model.js +215 -0
- package/lib/public/modules/vendor-usage-overview.js +323 -0
- package/lib/public/style.css +13 -10
- package/lib/public/welcome-art/conversation-desk.png +0 -0
- package/lib/public/welcome-art/mate-clay.png +0 -0
- package/lib/public/welcome-art/project-clay.png +0 -0
- package/lib/sdk-bridge.js +6 -1
- package/lib/sdk-message-processor.js +9 -1
- package/lib/sdk-quota-snapshot.js +20 -2
- package/lib/server-github-stars.js +39 -0
- package/lib/server-global-ws.js +21 -17
- package/lib/server.js +11 -0
- package/lib/session-notes-mcp-server.js +26 -4
- package/lib/session-notes-writes.js +88 -0
- package/lib/session-visibility.js +20 -8
- package/lib/sessions.js +12 -2
- package/lib/vendor-usage-acp-readers.js +97 -0
- package/lib/vendor-usage-capabilities.js +88 -0
- package/lib/vendor-usage-http-readers.js +214 -0
- package/lib/vendor-usage-metrics.js +47 -0
- package/lib/vendor-usage-native-readers.js +106 -0
- package/lib/vendor-usage-overview.js +406 -0
- package/lib/vendor-usage-service.js +281 -0
- package/lib/ws-schema.js +4 -2
- package/lib/yoke/adapters/claude.js +12 -0
- package/lib/yoke/adapters/codex-query-contract.js +1 -0
- package/lib/yoke/adapters/codex.js +45 -12
- package/lib/yoke/claude-hook-installer.js +1 -0
- package/lib/yoke/codex-dynamic-tool-names.js +80 -0
- package/lib/yoke/codex-model-catalog.js +37 -3
- package/lib/yoke/muse-services.js +16 -3
- package/lib/yoke/providers/claude-model-descriptions.js +22 -2
- package/lib/yoke/vendor-registry.js +6 -2
- package/package.json +2 -1
- package/lib/public/modules/server-settings-navigation.js +0 -39
package/lib/project-sessions.js
CHANGED
|
@@ -5,12 +5,16 @@ var { execFileSync } = require("child_process");
|
|
|
5
5
|
var providerSettings = require("./yoke/settings");
|
|
6
6
|
var updateSnooze = require("./update-snooze");
|
|
7
7
|
var yoke = require("./yoke");
|
|
8
|
+
var startProtocol = require("./project-start-protocol");
|
|
9
|
+
var startReply = startProtocol.withRequestId;
|
|
10
|
+
var browseMeta = startProtocol.browseMeta;
|
|
8
11
|
var sessionVisibility = require("./session-visibility");
|
|
9
12
|
var contextUsageModule = require("./context-usage");
|
|
10
13
|
var sessionDeleteModule = require("./project-session-delete");
|
|
11
14
|
var sessionFoldersModule = require("./project-session-folders");
|
|
12
15
|
var elicitationResponse = require("./project-elicitation-response");
|
|
13
16
|
var sessionCreationModule = require("./project-session-creation");
|
|
17
|
+
var vendorUsageOverviewModule = require("./vendor-usage-overview");
|
|
14
18
|
|
|
15
19
|
function vendorSupportsTui(vendor) {
|
|
16
20
|
var info = yoke.getVendorInfo(vendor);
|
|
@@ -223,6 +227,10 @@ function attachSessions(ctx) {
|
|
|
223
227
|
resolveSessionHome: resolveSessionHome, cancelPendingAskUser: cancelPendingAskUser,
|
|
224
228
|
}));
|
|
225
229
|
|
|
230
|
+
function boundedRequestId(msg) {
|
|
231
|
+
return typeof msg.requestId === "string" ? msg.requestId.substring(0, 200) : undefined;
|
|
232
|
+
}
|
|
233
|
+
|
|
226
234
|
function canAccessProjectSlug(ws, targetSlug) {
|
|
227
235
|
if (!targetSlug) return false;
|
|
228
236
|
if (!usersModule || typeof usersModule.isMultiUser !== "function" || !usersModule.isMultiUser()) return true;
|
|
@@ -361,6 +369,11 @@ function attachSessions(ctx) {
|
|
|
361
369
|
getProjectAccess: getProjectAccess,
|
|
362
370
|
getVendorAvailability: function (ws) { return ctx.getVendorAvailability(ws); },
|
|
363
371
|
});
|
|
372
|
+
var vendorUsage = vendorUsageOverviewModule.attachVendorUsageOverview({
|
|
373
|
+
slug: slug, sm: sm, usersModule: usersModule, clients: clients, sendTo: sendTo, getProjectAccess: getProjectAccess,
|
|
374
|
+
getVendorAvailability: function (ws) { return ctx.getVendorAvailability(ws); },
|
|
375
|
+
adapters: ctx.adapters, osUsers: osUsers, getLinuxUserForWs: ctx.getLinuxUserForWs,
|
|
376
|
+
});
|
|
364
377
|
// Kick off watchers for any TUI sessions already loaded from disk so
|
|
365
378
|
// their titles refresh as soon as Claude Code rewrites the jsonl, even
|
|
366
379
|
// before the user clicks them.
|
|
@@ -755,13 +768,15 @@ function attachSessions(ctx) {
|
|
|
755
768
|
if (msg.type === "set_project_session_visibility_default") {
|
|
756
769
|
sessionVisibility.handleDefaultChange({
|
|
757
770
|
slug: slug, isMate: isMate, osUsers: osUsers, usersModule: usersModule, getProjectAccess: getProjectAccess,
|
|
758
|
-
|
|
771
|
+
getTargetAccess: typeof opts.onGetProjectAccess === "function" ? opts.onGetProjectAccess : null,
|
|
772
|
+
canAccessProjectSlug: canAccessProjectSlug, opts: opts, sendTo: sendTo,
|
|
759
773
|
}, ws, msg);
|
|
760
774
|
return true;
|
|
761
775
|
}
|
|
762
776
|
|
|
763
777
|
if (sessionFolders.handleMessage(ws, msg)) return true;
|
|
764
778
|
if (sessionCreation.handleMessage(ws, msg)) return true;
|
|
779
|
+
if (vendorUsage.handleMessage(ws, msg)) return true;
|
|
765
780
|
|
|
766
781
|
if (msg.type === "bulk_delete_sessions") {
|
|
767
782
|
sessionDelete.bulkDeleteSessions(ws, msg);
|
|
@@ -1656,8 +1671,9 @@ function attachSessions(ctx) {
|
|
|
1656
1671
|
parentDir = path.dirname(absTarget);
|
|
1657
1672
|
prefix = path.basename(absTarget).toLowerCase();
|
|
1658
1673
|
}
|
|
1659
|
-
|
|
1660
|
-
|
|
1674
|
+
var canList = function (candidate) { return !opts.canUsePath || opts.canUsePath(ws._clayUser && ws._clayUser.id, candidate); };
|
|
1675
|
+
if (!canList(parentDir)) {
|
|
1676
|
+
sendTo(ws, startReply(msg, { type: "browse_dir_result", path: msg.path, entries: [], error: "Directory access is not permitted" }));
|
|
1661
1677
|
return true;
|
|
1662
1678
|
}
|
|
1663
1679
|
try {
|
|
@@ -1673,9 +1689,9 @@ function attachSessions(ctx) {
|
|
|
1673
1689
|
dirEntries.push({ name: d.name, path: path.join(parentDir, d.name) });
|
|
1674
1690
|
}
|
|
1675
1691
|
dirEntries.sort(function (a, b) { return a.name.localeCompare(b.name); });
|
|
1676
|
-
sendTo(ws, { type: "browse_dir_result", path: msg.path, entries: dirEntries });
|
|
1692
|
+
sendTo(ws, Object.assign(browseMeta(msg, parentDir, prefix, canList), { type: "browse_dir_result", path: msg.path, entries: dirEntries }));
|
|
1677
1693
|
} catch (e) {
|
|
1678
|
-
sendTo(ws, { type: "browse_dir_result", path: msg.path, entries: [], error: e.message });
|
|
1694
|
+
sendTo(ws, startReply(msg, { type: "browse_dir_result", path: msg.path, entries: [], error: e.message }));
|
|
1679
1695
|
}
|
|
1680
1696
|
return true;
|
|
1681
1697
|
}
|
|
@@ -1685,24 +1701,24 @@ function attachSessions(ctx) {
|
|
|
1685
1701
|
var addPath = (msg.path || "").replace(/^~/, require("./config").REAL_HOME);
|
|
1686
1702
|
var addAbs = path.resolve(addPath);
|
|
1687
1703
|
if (opts.canUsePath && !opts.canUsePath(ws._clayUser && ws._clayUser.id, addAbs)) {
|
|
1688
|
-
sendTo(ws, { type: "add_project_result", ok: false, error: "Directory access is not permitted" });
|
|
1704
|
+
sendTo(ws, startReply(msg, { type: "add_project_result", ok: false, error: "Directory access is not permitted" }));
|
|
1689
1705
|
return true;
|
|
1690
1706
|
}
|
|
1691
1707
|
try {
|
|
1692
1708
|
var addStat = fs.statSync(addAbs);
|
|
1693
1709
|
if (!addStat.isDirectory()) {
|
|
1694
|
-
sendTo(ws, { type: "add_project_result", ok: false, error: "Not a directory" });
|
|
1710
|
+
sendTo(ws, startReply(msg, { type: "add_project_result", ok: false, error: "Not a directory" }));
|
|
1695
1711
|
return true;
|
|
1696
1712
|
}
|
|
1697
1713
|
} catch (e) {
|
|
1698
|
-
sendTo(ws, { type: "add_project_result", ok: false, error: "Directory not found" });
|
|
1714
|
+
sendTo(ws, startReply(msg, { type: "add_project_result", ok: false, error: "Directory not found" }));
|
|
1699
1715
|
return true;
|
|
1700
1716
|
}
|
|
1701
1717
|
if (typeof opts.onAddProject === "function") {
|
|
1702
1718
|
var result = opts.onAddProject(addAbs, ws._clayUser);
|
|
1703
|
-
sendTo(ws, Object.assign({}, result, { type: "add_project_result" }));
|
|
1719
|
+
sendTo(ws, startReply(msg, Object.assign({}, result, { type: "add_project_result" })));
|
|
1704
1720
|
} else {
|
|
1705
|
-
sendTo(ws, { type: "add_project_result", ok: false, error: "Not supported" });
|
|
1721
|
+
sendTo(ws, startReply(msg, { type: "add_project_result", ok: false, error: "Not supported" }));
|
|
1706
1722
|
}
|
|
1707
1723
|
return true;
|
|
1708
1724
|
}
|
|
@@ -1712,7 +1728,7 @@ function attachSessions(ctx) {
|
|
|
1712
1728
|
if (ws._clayUser) {
|
|
1713
1729
|
var cpPerms = usersModule.getEffectivePermissions(ws._clayUser, osUsers);
|
|
1714
1730
|
if (!cpPerms.createProject) {
|
|
1715
|
-
sendTo(ws, { type: "add_project_result", ok: false, error: "You do not have permission to create projects" });
|
|
1731
|
+
sendTo(ws, startReply(msg, { type: "add_project_result", ok: false, error: "You do not have permission to create projects" }));
|
|
1716
1732
|
return true;
|
|
1717
1733
|
}
|
|
1718
1734
|
}
|
|
@@ -1720,14 +1736,14 @@ function attachSessions(ctx) {
|
|
|
1720
1736
|
if (msg.type === "create_project") {
|
|
1721
1737
|
var createName = (msg.name || "").trim();
|
|
1722
1738
|
if (!createName || !/^[a-zA-Z0-9_-]+$/.test(createName)) {
|
|
1723
|
-
sendTo(ws, { type: "add_project_result", ok: false, error: "Invalid name. Use only letters, numbers, dashes, and underscores." });
|
|
1739
|
+
sendTo(ws, startReply(msg, { type: "add_project_result", ok: false, error: "Invalid name. Use only letters, numbers, dashes, and underscores." }));
|
|
1724
1740
|
return true;
|
|
1725
1741
|
}
|
|
1726
1742
|
if (typeof opts.onCreateProject === "function") {
|
|
1727
1743
|
var createResult = opts.onCreateProject(createName, ws._clayUser);
|
|
1728
|
-
sendTo(ws, Object.assign({}, createResult, { type: "add_project_result" }));
|
|
1744
|
+
sendTo(ws, startReply(msg, Object.assign({}, createResult, { type: "add_project_result" })));
|
|
1729
1745
|
} else {
|
|
1730
|
-
sendTo(ws, { type: "add_project_result", ok: false, error: "Not supported" });
|
|
1746
|
+
sendTo(ws, startReply(msg, { type: "add_project_result", ok: false, error: "Not supported" }));
|
|
1731
1747
|
}
|
|
1732
1748
|
return true;
|
|
1733
1749
|
}
|
|
@@ -1736,16 +1752,16 @@ function attachSessions(ctx) {
|
|
|
1736
1752
|
if (msg.type === "clone_project") {
|
|
1737
1753
|
var cloneUrl = (msg.url || "").trim();
|
|
1738
1754
|
if (!cloneUrl || (!/^https?:\/\//.test(cloneUrl) && !/^git@/.test(cloneUrl))) {
|
|
1739
|
-
sendTo(ws, { type: "add_project_result", ok: false, error: "Invalid URL. Use https:// or git@ format." });
|
|
1755
|
+
sendTo(ws, startReply(msg, { type: "add_project_result", ok: false, error: "Invalid URL. Use https:// or git@ format." }));
|
|
1740
1756
|
return true;
|
|
1741
1757
|
}
|
|
1742
|
-
sendTo(ws, { type: "clone_project_progress", status: "cloning" });
|
|
1758
|
+
sendTo(ws, startReply(msg, { type: "clone_project_progress", status: "cloning" }));
|
|
1743
1759
|
if (typeof opts.onCloneProject === "function") {
|
|
1744
1760
|
opts.onCloneProject(cloneUrl, ws._clayUser, function (cloneResult) {
|
|
1745
|
-
sendTo(ws, { type: "add_project_result", ok: cloneResult.ok, slug: cloneResult.slug, error: cloneResult.error });
|
|
1761
|
+
sendTo(ws, startReply(msg, { type: "add_project_result", ok: cloneResult.ok, slug: cloneResult.slug, error: cloneResult.error }));
|
|
1746
1762
|
});
|
|
1747
1763
|
} else {
|
|
1748
|
-
sendTo(ws, { type: "add_project_result", ok: false, error: "Not supported" });
|
|
1764
|
+
sendTo(ws, startReply(msg, { type: "add_project_result", ok: false, error: "Not supported" }));
|
|
1749
1765
|
}
|
|
1750
1766
|
return true;
|
|
1751
1767
|
}
|
|
@@ -1858,30 +1874,41 @@ function attachSessions(ctx) {
|
|
|
1858
1874
|
|
|
1859
1875
|
// --- Set project title (rename) ---
|
|
1860
1876
|
if (msg.type === "set_project_title") {
|
|
1877
|
+
var titleRequestId = boundedRequestId(msg);
|
|
1861
1878
|
if (!msg.slug) {
|
|
1862
|
-
sendTo(ws, { type: "set_project_title_result", ok: false, error: "Missing slug" });
|
|
1879
|
+
sendTo(ws, { type: "set_project_title_result", ok: false, error: "Missing slug", requestId: titleRequestId });
|
|
1880
|
+
return true;
|
|
1881
|
+
}
|
|
1882
|
+
// The target is named by the client; it must be a project this account can access.
|
|
1883
|
+
if (!canAccessProjectSlug(ws, msg.slug)) {
|
|
1884
|
+
sendTo(ws, { type: "set_project_title_result", ok: false, error: "Project access is not permitted", slug: msg.slug, requestId: titleRequestId });
|
|
1863
1885
|
return true;
|
|
1864
1886
|
}
|
|
1865
1887
|
if (typeof opts.onSetProjectTitle === "function") {
|
|
1866
1888
|
var titleResult = opts.onSetProjectTitle(msg.slug, msg.title || null);
|
|
1867
|
-
sendTo(ws, Object.assign({}, titleResult, { type: "set_project_title_result", slug: msg.slug }));
|
|
1889
|
+
sendTo(ws, Object.assign({}, titleResult, { type: "set_project_title_result", slug: msg.slug, requestId: titleRequestId }));
|
|
1868
1890
|
} else {
|
|
1869
|
-
sendTo(ws, { type: "set_project_title_result", ok: false, error: "Not supported" });
|
|
1891
|
+
sendTo(ws, { type: "set_project_title_result", ok: false, error: "Not supported", requestId: titleRequestId });
|
|
1870
1892
|
}
|
|
1871
1893
|
return true;
|
|
1872
1894
|
}
|
|
1873
1895
|
|
|
1874
1896
|
// --- Set project icon (emoji) ---
|
|
1875
1897
|
if (msg.type === "set_project_icon") {
|
|
1898
|
+
var iconRequestId = boundedRequestId(msg);
|
|
1876
1899
|
if (!msg.slug) {
|
|
1877
|
-
sendTo(ws, { type: "set_project_icon_result", ok: false, error: "Missing slug" });
|
|
1900
|
+
sendTo(ws, { type: "set_project_icon_result", ok: false, error: "Missing slug", requestId: iconRequestId });
|
|
1901
|
+
return true;
|
|
1902
|
+
}
|
|
1903
|
+
if (!canAccessProjectSlug(ws, msg.slug)) {
|
|
1904
|
+
sendTo(ws, { type: "set_project_icon_result", ok: false, error: "Project access is not permitted", slug: msg.slug, requestId: iconRequestId });
|
|
1878
1905
|
return true;
|
|
1879
1906
|
}
|
|
1880
1907
|
if (typeof opts.onSetProjectIcon === "function") {
|
|
1881
1908
|
var iconResult = opts.onSetProjectIcon(msg.slug, msg.icon || null);
|
|
1882
|
-
sendTo(ws, { type: "set_project_icon_result", ok: iconResult.ok, slug: msg.slug, error: iconResult.error });
|
|
1909
|
+
sendTo(ws, { type: "set_project_icon_result", ok: iconResult.ok, slug: msg.slug, error: iconResult.error, requestId: iconRequestId });
|
|
1883
1910
|
} else {
|
|
1884
|
-
sendTo(ws, { type: "set_project_icon_result", ok: false, error: "Not supported" });
|
|
1911
|
+
sendTo(ws, { type: "set_project_icon_result", ok: false, error: "Not supported", requestId: iconRequestId });
|
|
1885
1912
|
}
|
|
1886
1913
|
return true;
|
|
1887
1914
|
}
|
|
@@ -2007,6 +2034,18 @@ function attachSessions(ctx) {
|
|
|
2007
2034
|
}
|
|
2008
2035
|
|
|
2009
2036
|
return {
|
|
2037
|
+
invalidateVendorUsage: function () { vendorUsage.invalidateAll(); },
|
|
2038
|
+
// Canonical read-only inspection: the caller has already proven the owner and
|
|
2039
|
+
// project access; the OS user is re-derived from the live user record.
|
|
2040
|
+
readVendorUsage: function (request) {
|
|
2041
|
+
var installed = null;
|
|
2042
|
+
if (Array.isArray(sm.installedVendors)) {
|
|
2043
|
+
installed = Object.create(null);
|
|
2044
|
+
sm.installedVendors.forEach(function (vendor) { installed[vendor] = true; });
|
|
2045
|
+
}
|
|
2046
|
+
var linuxUser = osUsers && request.owner !== "default" ? ctx.getLinuxUserForSession({ ownerId: request.owner }) : null;
|
|
2047
|
+
return vendorUsage.readForOwner({ owner: request.owner, linuxUser: linuxUser, installed: installed, isCurrent: request.isCurrent });
|
|
2048
|
+
},
|
|
2010
2049
|
handleSessionsMessage: handleSessionsMessage,
|
|
2011
2050
|
resolveSessionForView: resolveSessionForView,
|
|
2012
2051
|
sendSessionFoldersState: sessionFolders.sendStateTo,
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Shared reply helpers for the project-start dialog (browse_dir and add/create/clone results).
|
|
2
|
+
// A string requestId on the request is echoed on its reply so the client can drop stale answers.
|
|
3
|
+
|
|
4
|
+
var path = require("path");
|
|
5
|
+
|
|
6
|
+
function requestIdOf(msg) {
|
|
7
|
+
return msg && typeof msg.requestId === "string" && msg.requestId.length <= 64 ? msg.requestId : undefined;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Canonical listing metadata. `dir` is the directory whose children are listed, `prefix` is
|
|
11
|
+
// non-empty when the requested path did not exist or was not a directory, and `parent` is set
|
|
12
|
+
// only when the caller may list the parent as well.
|
|
13
|
+
function browseMeta(msg, dir, prefix, canList) {
|
|
14
|
+
var parent = path.dirname(dir);
|
|
15
|
+
return {
|
|
16
|
+
requestId: requestIdOf(msg),
|
|
17
|
+
dir: dir,
|
|
18
|
+
prefix: prefix || "",
|
|
19
|
+
parent: parent !== dir && (!canList || canList(parent)) ? parent : null,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function withRequestId(msg, payload) {
|
|
24
|
+
var id = requestIdOf(msg);
|
|
25
|
+
if (id !== undefined) payload.requestId = id;
|
|
26
|
+
return payload;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = { requestIdOf: requestIdOf, browseMeta: browseMeta, withRequestId: withRequestId };
|
|
@@ -171,6 +171,8 @@ function attachVendorLogin(ctx) {
|
|
|
171
171
|
// reused by every project, so tearing one down here would kill unrelated
|
|
172
172
|
// sessions; those runtimes pick up new credentials on their own.
|
|
173
173
|
function refreshVendorAuth(vendor, linuxUser) {
|
|
174
|
+
// Cached account usage described the previous credentials.
|
|
175
|
+
if (typeof ctx.onVendorAuthChanged === "function") { try { ctx.onVendorAuthChanged(vendor, linuxUser || null); } catch (e) {} }
|
|
174
176
|
var adapter = adapters[vendor];
|
|
175
177
|
if (!adapter || typeof adapter.shutdown !== "function") return Promise.resolve(false);
|
|
176
178
|
if (adapter.shared) {
|
package/lib/project.js
CHANGED
|
@@ -658,7 +658,8 @@ function createProjectContext(opts) {
|
|
|
658
658
|
var access = opts.getProjectAccess ? opts.getProjectAccess() : { visibility: "public", ownerId: projectOwnerId || null };
|
|
659
659
|
if (!viewer || (opts.canAccessProjectSlug && !opts.canAccessProjectSlug(viewer.id, slug)) || !usersModule.canAccessSession(viewer.id, session, access)) return;
|
|
660
660
|
}
|
|
661
|
-
ws.
|
|
661
|
+
var panePayload = ws._clayPaneActivation ? require('./pane-session-transport').outbound(ws, message, session.localId) : message;
|
|
662
|
+
if (panePayload) ws.send(panePayload === message ? data : JSON.stringify(panePayload));
|
|
662
663
|
});
|
|
663
664
|
},
|
|
664
665
|
authorize: function (session, actor) {
|
|
@@ -2186,6 +2187,7 @@ function createProjectContext(opts) {
|
|
|
2186
2187
|
resolveDefaultAi: opts.resolveDefaultAi,
|
|
2187
2188
|
resolveMateSessionDefaults: opts.resolveMateSessionDefaults,
|
|
2188
2189
|
getVendorAvailability: function (ws) { return _models.getVendorAvailability(ws); },
|
|
2190
|
+
getLinuxUserForWs: getLinuxUserForWs,
|
|
2189
2191
|
canCreateScheduledTaskInterview: function (ws, session) { return !!(_scheduledTasks && _scheduledTasks.canCreateInterview(ws, session)); },
|
|
2190
2192
|
canStartScheduledTaskInterview: function (ws, session) { return !!(_scheduledTasks && _scheduledTasks.canStartInterview(ws, session)); },
|
|
2191
2193
|
onHumanPairStop: function (session) {
|
|
@@ -2398,6 +2400,7 @@ function createProjectContext(opts) {
|
|
|
2398
2400
|
|
|
2399
2401
|
// --- Vendor login flow (delegated to project-vendor-login.js) ---
|
|
2400
2402
|
var _vendorLogin = attachVendorLogin({
|
|
2403
|
+
onVendorAuthChanged: function () { _sessions.invalidateVendorUsage(); },
|
|
2401
2404
|
requestAccess: _requestAccess,
|
|
2402
2405
|
clients: clients,
|
|
2403
2406
|
slug: slug,
|
|
@@ -3039,6 +3042,7 @@ function createProjectContext(opts) {
|
|
|
3039
3042
|
requestProductControlReview: _productControl.requestProductControlReview,
|
|
3040
3043
|
applyProductSessionAction: _productControl.applyProductSessionAction,
|
|
3041
3044
|
inspectProductSessionQueue: _productControl.inspectProductSessionQueue,
|
|
3045
|
+
readVendorUsage: function (request) { return _sessions.readVendorUsage(request); },
|
|
3042
3046
|
inspectProductSessionRuntime: _sessions.sessionRuntimeActions.inspect,
|
|
3043
3047
|
inspectMateLifecycleRuntime: _sessions.sessionRuntimeActions.inspectLifecycle,
|
|
3044
3048
|
inspectDelegatedFollowUp: _delegatedFollowUp.inspectDelegatedFollowUp,
|
package/lib/public/app.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { initStudioBridge } from './modules/clay-studio-bridge.js';
|
|
2
2
|
import { initSharedBrowser } from './modules/shared-browser.js';
|
|
3
|
+
import { initTopbarWorkbenchControls } from './modules/topbar-workbench-controls.js';
|
|
3
4
|
import { initGenerationStop } from './modules/generation-stop.js';
|
|
4
5
|
import { initIssueLinks } from './modules/clay-issue-links.js';
|
|
5
6
|
import { initIssues, closeIssues } from './modules/issues.js';
|
|
@@ -31,7 +32,7 @@ import { initMateMemory, renderMemoryList, hideMemory } from './modules/mate-mem
|
|
|
31
32
|
import { initRewind, setRewindMode, showRewindModal, clearPendingRewindUuid, addRewindButton, onRewindComplete, onRewindError } from './modules/rewind.js';
|
|
32
33
|
import { initNotifications, showDoneNotification, playDoneSound, isNotifAlertEnabled, isNotifSoundEnabled } from './modules/notifications.js';
|
|
33
34
|
import { initInput, clearPendingImages, handleInputSync, autoResize, builtinCommands, sendMessage, hasSendableContent, setScheduleBtnDisabled, setScheduleDelayMs, clearScheduleDelay } from './modules/input.js';
|
|
34
|
-
import { initQrCode
|
|
35
|
+
import { initQrCode } from './modules/qrcode.js';
|
|
35
36
|
import { initFileBrowser, loadRootDirectory, reopenFileViewer, refreshTree, handleFsList, handleFsRead, handleDirChanged, refreshIfOpen, handleFileChanged, handleFileHistory, handleGitDiff, handleFileAt, getPendingNavigate, closeFileViewer, resetFileBrowser } from './modules/filebrowser.js';
|
|
36
37
|
import { initGitPanel } from './modules/git-panel.js';
|
|
37
38
|
import { initWorkerPaneLock } from './modules/worker-pane-lock.js';
|
|
@@ -46,6 +47,7 @@ import { initTheme, getThemeColor, getComputedVar, onThemeChange, getCurrentThem
|
|
|
46
47
|
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';
|
|
47
48
|
import { initServerSettings, updateSettingsStats, updateDaemonConfig, handleSetPinResult, handleKeepAwakeChanged, handleAutoContinueChanged, handleRestartResult, handleShutdownResult, handleSharedEnv, handleSharedEnvSaved } from './modules/server-settings.js';
|
|
48
49
|
import { initProjectSettings } from './modules/project-settings.js';
|
|
50
|
+
import { initSettingsShell, openSettings } from './modules/settings-shell.js';
|
|
49
51
|
import { initSkills, handleSkillInstalled, handleSkillUninstalled } from './modules/skills.js';
|
|
50
52
|
import { initMcp } from './modules/mcp-ui.js';
|
|
51
53
|
import { initScheduler, resetScheduler, handleLoopRegistryUpdated, handleScheduleRunStarted, handleScheduleRunFinished, handleLoopScheduled, openSchedulerToTab, isSchedulerOpen, closeScheduler, enterCraftingMode, exitCraftingMode, handleLoopRegistryFiles, getUpcomingSchedules } from './modules/scheduler.js';
|
|
@@ -63,6 +65,7 @@ import { initProjectLogs, closeProjectLogs } from './modules/project-logs.js';
|
|
|
63
65
|
import { initProjectSwitcher } from './modules/project-switcher.js';
|
|
64
66
|
import { initSplitView } from './modules/split-view.js';
|
|
65
67
|
import { initPaneBridge } from './modules/pane-bridge.js';
|
|
68
|
+
import { initPaneAppearanceBridge } from './modules/pane-appearance-bridge.js';
|
|
66
69
|
import { initAdmin, checkAdminAccess } from './modules/admin.js';
|
|
67
70
|
import { initSessionSearch, toggleSearch, closeSearch, isSearchOpen, handleFindInSessionResults, onHistoryPrepended as onSessionSearchHistoryPrepended } from './modules/session-search.js';
|
|
68
71
|
import { initTooltips, registerTooltip } from './modules/tooltip.js';
|
|
@@ -72,10 +75,15 @@ import { initShellCommand } from './modules/shell-command.js';
|
|
|
72
75
|
import { initConnection, connect as _connConnect, setStatus as _connSetStatus, scheduleReconnect as _connScheduleReconnect, cancelReconnect as _connCancelReconnect } from './modules/app-connection.js';
|
|
73
76
|
import { processMessage as _msgProcessMessage } from './modules/app-messages.js';
|
|
74
77
|
import { getWs as _getWsRef, setWs as _setWsRef } from './modules/ws-ref.js';
|
|
78
|
+
import { initialProjectStart } from './modules/project-start-state.js';
|
|
79
|
+
import { emptyFolderState } from './modules/project-start-folder-state.js';
|
|
80
|
+
import { openAddProjectModal, initProjectStart } from './modules/project-start-dialog.js';
|
|
75
81
|
import { initProjectsHub, showProjectsHub, hideProjectsHub } from './modules/projects-hub.js';
|
|
76
82
|
import { initHomeSurfaceBoot } from './modules/home-surface-boot.js';
|
|
77
83
|
import { rememberHomePrimarySurface } from './modules/home-surface.js';
|
|
78
84
|
import { initRateLimit, handleRateLimitEvent as _rlHandleRateLimitEvent, updateRateLimitUsage as _rlUpdateRateLimitUsage, handleFastModeState as _rlHandleFastModeState, resetRateLimitState } from './modules/app-rate-limit.js';
|
|
85
|
+
import { initVendorUsageOverview } from './modules/vendor-usage-overview.js';
|
|
86
|
+
import { initGithubStar } from './modules/github-star.js';
|
|
79
87
|
import { initCursors, handleRemoteCursorMove as _curHandleRemoteCursorMove, handleRemoteCursorLeave as _curHandleRemoteCursorLeave, handleRemoteSelection as _curHandleRemoteSelection, clearRemoteCursors as _curClearRemoteCursors, initCursorToggle } from './modules/app-cursors.js';
|
|
80
88
|
import { initDefaultAi } from './modules/default-ai.js';
|
|
81
89
|
import { requestDefaultVendor } from './modules/default-vendor.js';
|
|
@@ -97,7 +105,7 @@ import { initProjectMateCreationWorkspace } from './modules/project-mate-creatio
|
|
|
97
105
|
import { initProjectDebatePlanningWorkspace } from './modules/project-debate-planning-workspace.js';
|
|
98
106
|
import { initProjectSessionNavigation } from './modules/project-session-navigation.js';
|
|
99
107
|
import { initPanels, updateConfigChip as _panUpdateConfigChip, getModelEffortLevels as _panGetModelEffortLevels, accumulateUsage as _panAccumulateUsage, updateUsagePanel as _panUpdateUsagePanel, resetUsage as _panResetUsage, toggleUsagePanel as _panToggleUsagePanel, formatTokens as _panFormatTokens, updateStatusPanel as _panUpdateStatusPanel, requestProcessStats as _panRequestProcessStats, toggleStatusPanel as _panToggleStatusPanel, accumulateContext as _panAccumulateContext, updateContextPanel as _panUpdateContextPanel, resetContext as _panResetContext, resetContextData as _panResetContextData, minimizeContext as _panMinimizeContext, expandContext as _panExpandContext, toggleContextPanel as _panToggleContextPanel, getContextView as _panGetContextView, renderCtxPopover as _panRenderCtxPopover, hideCtxPopover as _panHideCtxPopover, formatBytes as _panFormatBytes, formatUptime as _panFormatUptime, getModelSupportsEffort as _panGetModelSupportsEffort, getSessionUsage, setSessionUsage, getContextData, setContextData, setContextView as _panSetContextView, applyContextView as _panApplyContextView } from './modules/app-panels.js';
|
|
100
|
-
import {
|
|
108
|
+
import { updateProjectList as _projUpdateProjectList, renderProjectList as _projRenderProjectList, renderTopbarPresence as _projRenderTopbarPresence, switchProject as _projSwitchProject, resetClientState as _projResetClientState, confirmRemoveProject as _projConfirmRemoveProject, handleRemoveProjectCheckResult as _projHandleRemoveProjectCheckResult, handleRemoveProjectResult as _projHandleRemoveProjectResult, showUpdateAvailable as _projShowUpdateAvailable, getCachedProjects, setCachedProjects, getCachedProjectCount, getCachedRemovedProjects, setCachedRemovedProjects } from './modules/app-projects.js';
|
|
101
109
|
import { initRendering, addToMessages as _renAddToMessages, scrollToBottom as _renScrollToBottom, forceScrollToBottom as _renForceScrollToBottom, addUserMessage as _renAddUserMessage, getMsgTime as _renGetMsgTime, shouldGroupMessage as _renShouldGroupMessage, ensureAssistantBlock as _renEnsureAssistantBlock, addCopyHandler as _renAddCopyHandler, appendDelta as _renAppendDelta, flushStreamBuffer as _renFlushStreamBuffer, finalizeAssistantBlock as _renFinalizeAssistantBlock, addSystemMessage as _renAddSystemMessage, addConflictMessage as _renAddConflictMessage, addContextOverflowMessage as _renAddContextOverflowMessage, showClaudePreThinking as _renShowClaudePreThinking, showMatePreThinking as _renShowMatePreThinking, removeMatePreThinking as _renRemoveMatePreThinking, showSuggestionChips as _renShowSuggestionChips, hideSuggestionChips as _renHideSuggestionChips, getGhostSuggestion as _renGetGhostSuggestion, getTurnCounter, setTurnCounter, getPrependAnchor, setPrependAnchor, getActivityEl, setActivityEl, getIsUserScrolledUp, setIsUserScrolledUp, getStickyBottom, armStickyBottom, disarmStickyBottom } from './modules/app-rendering.js';
|
|
102
110
|
import { initDm, openDm as _dmOpenDm, enterDmMode as _dmEnterDmMode, exitDmMode as _dmExitDmMode, handleMateCreatedInApp as _dmHandleMateCreatedInApp, buildMateInterviewPrompt as _dmBuildMateInterviewPrompt, updateMateIconStatus as _dmUpdateMateIconStatus, connectMateProject as _dmConnectMateProject, disconnectMateProject as _dmDisconnectMateProject, appendDmMessage as _dmAppendDmMessage, showDmTypingIndicator as _dmShowDmTypingIndicator, handleDmSend as _dmHandleDmSend } from './modules/app-dm.js';
|
|
103
111
|
import { initMention, handleMentionStart, handleMentionStream, handleMentionDone, handleMentionError, handleMentionActivity, renderMentionUser, renderMentionResponse } from './modules/mention.js';
|
|
@@ -192,7 +200,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
192
200
|
function updateProjectList(msg) { _projUpdateProjectList(msg); }
|
|
193
201
|
function renderTopbarPresence(serverUsers) { _projRenderTopbarPresence(serverUsers); }
|
|
194
202
|
function renderProjectList() { _projRenderProjectList(); }
|
|
195
|
-
// projectListAddBtn listener -> modules/
|
|
203
|
+
// projectListAddBtn listener -> modules/project-start-dialog.js (initProjectStart)
|
|
196
204
|
|
|
197
205
|
// Prevent Cmd+Z / Cmd+Shift+Z from triggering browser back/forward (Arc, etc.)
|
|
198
206
|
// Always block browser default for Cmd+Z and manually invoke undo/redo via execCommand
|
|
@@ -280,6 +288,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
280
288
|
createStore({
|
|
281
289
|
networkSettings: { loaded: false, busy: false, confirming: false, draft: "", saved: "", status: "", errorKind: "", requestId: 0 },
|
|
282
290
|
vendorLoginBrowser: null,
|
|
291
|
+
githubStarCount: null,
|
|
283
292
|
sharedBrowser: null,
|
|
284
293
|
sharedBrowsers: [],
|
|
285
294
|
mcpSkillsWorkbench: {},
|
|
@@ -324,6 +333,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
324
333
|
splitDelegations: {},
|
|
325
334
|
pairResultStatus: [],
|
|
326
335
|
notesTemporarilyHidden: false,
|
|
336
|
+
pairResultTrayOpen: false,
|
|
327
337
|
dmMode: false,
|
|
328
338
|
historyFrom: 0,
|
|
329
339
|
loadingMore: false,
|
|
@@ -420,7 +430,8 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
420
430
|
projectListLoaded: false,
|
|
421
431
|
projectsAccessLoaded: false,
|
|
422
432
|
projectsHubRestoreRequested: false,
|
|
423
|
-
|
|
433
|
+
projectStart: initialProjectStart(),
|
|
434
|
+
projectStartFolder: emptyFolderState(),
|
|
424
435
|
onboardingStep: 'welcome',
|
|
425
436
|
onboardingIntent: null,
|
|
426
437
|
currentProjectOwnerId: null,
|
|
@@ -645,6 +656,8 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
645
656
|
vendorInfo: {},
|
|
646
657
|
// Rate-limit data is projected only for the displayed session/vendor.
|
|
647
658
|
rateLimitState: {},
|
|
659
|
+
vendorUsageOverview: null,
|
|
660
|
+
vendorUsageOpen: null,
|
|
648
661
|
currentMode: "default",
|
|
649
662
|
effectivePermissionMode: null,
|
|
650
663
|
permissionCapabilities: { auto: false, mcpOverride: false },
|
|
@@ -698,6 +711,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
698
711
|
|
|
699
712
|
// --- Theme (module) ---
|
|
700
713
|
initTheme();
|
|
714
|
+
initPaneAppearanceBridge();
|
|
701
715
|
|
|
702
716
|
// --- Tooltips ---
|
|
703
717
|
initTooltips();
|
|
@@ -789,8 +803,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
789
803
|
switch (action) {
|
|
790
804
|
case "createMate": startClayMateCreation(); break;
|
|
791
805
|
case "openSettings":
|
|
792
|
-
|
|
793
|
-
if (sb) sb.click();
|
|
806
|
+
openSettings();
|
|
794
807
|
break;
|
|
795
808
|
case "showHome": showHomeHub(); break;
|
|
796
809
|
}
|
|
@@ -1162,7 +1175,10 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
1162
1175
|
basePath: basePath,
|
|
1163
1176
|
});
|
|
1164
1177
|
|
|
1165
|
-
// ---
|
|
1178
|
+
// --- Unified full-screen settings shell (Personal, Project, Server panes) ---
|
|
1179
|
+
initSettingsShell();
|
|
1180
|
+
|
|
1181
|
+
// --- User settings (personal pane) ---
|
|
1166
1182
|
initUserSettings({
|
|
1167
1183
|
basePath: basePath,
|
|
1168
1184
|
});
|
|
@@ -1230,11 +1246,11 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
1230
1246
|
}
|
|
1231
1247
|
}
|
|
1232
1248
|
}).catch(function () {});
|
|
1233
|
-
// Hide
|
|
1249
|
+
// Hide update controls for non-admin users in multi-user mode. The settings
|
|
1250
|
+
// gear stays for everyone: Personal and Project settings are not admin-only,
|
|
1251
|
+
// and the shell only offers Server settings to administrators.
|
|
1234
1252
|
checkAdminAccess().then(function (isAdmin) {
|
|
1235
1253
|
if (store.get('isMultiUserMode') && !isAdmin) {
|
|
1236
|
-
var settingsBtn = document.getElementById("server-settings-btn");
|
|
1237
|
-
if (settingsBtn) settingsBtn.style.display = "none";
|
|
1238
1254
|
var updatePill = document.getElementById("update-pill-wrap");
|
|
1239
1255
|
if (updatePill) updatePill.style.display = "none";
|
|
1240
1256
|
}
|
|
@@ -1262,8 +1278,6 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
1262
1278
|
|
|
1263
1279
|
// --- QR code ---
|
|
1264
1280
|
initQrCode();
|
|
1265
|
-
var sharePill = document.getElementById("share-pill");
|
|
1266
|
-
if (sharePill) sharePill.addEventListener("click", triggerShare);
|
|
1267
1281
|
|
|
1268
1282
|
// --- File browser ---
|
|
1269
1283
|
initFileBrowser({
|
|
@@ -1276,6 +1290,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
1276
1290
|
fileViewerEl: $("file-viewer"),
|
|
1277
1291
|
});
|
|
1278
1292
|
initGitPanel();
|
|
1293
|
+
initTopbarWorkbenchControls();
|
|
1279
1294
|
initSharedBrowser();
|
|
1280
1295
|
initStudioBridge();
|
|
1281
1296
|
initWorkerPaneLock();
|
|
@@ -1447,11 +1462,6 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
1447
1462
|
function confirmRemoveProject(slug, name) { _projConfirmRemoveProject(slug, name); }
|
|
1448
1463
|
function handleRemoveProjectCheckResult(msg) { _projHandleRemoveProjectCheckResult(msg); }
|
|
1449
1464
|
function handleRemoveProjectResult(msg) { _projHandleRemoveProjectResult(msg); }
|
|
1450
|
-
function openAddProjectModal() { _projOpenAddProjectModal(); }
|
|
1451
|
-
function closeAddProjectModal() { _projCloseAddProjectModal(); }
|
|
1452
|
-
function handleBrowseDirResult(msg) { _projHandleBrowseDirResult(msg); }
|
|
1453
|
-
function handleAddProjectResult(msg) { _projHandleAddProjectResult(msg); }
|
|
1454
|
-
function handleCloneProgress(msg) { _projHandleCloneProgress(msg); }
|
|
1455
1465
|
|
|
1456
1466
|
// --- PWA install prompt -> modules/app-misc.js (set up in initMisc)
|
|
1457
1467
|
|
|
@@ -1467,9 +1477,11 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
1467
1477
|
|
|
1468
1478
|
// --- Rate Limit module ---
|
|
1469
1479
|
initRateLimit();
|
|
1480
|
+
initVendorUsageOverview();
|
|
1481
|
+
initGithubStar();
|
|
1470
1482
|
|
|
1471
1483
|
// --- Projects module ---
|
|
1472
|
-
|
|
1484
|
+
initProjectStart();
|
|
1473
1485
|
|
|
1474
1486
|
// --- Home Hub module ---
|
|
1475
1487
|
initProjectMateNavigation();
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
/* --- Top bar search bar trigger (Slack-style) --- */
|
|
6
6
|
.cmd-palette-searchbar {
|
|
7
7
|
position: absolute;
|
|
8
|
-
left: 50%;
|
|
9
8
|
transform: translateX(-50%);
|
|
10
9
|
display: flex;
|
|
11
10
|
align-items: center;
|
|
@@ -20,8 +19,19 @@
|
|
|
20
19
|
font-size: 12px;
|
|
21
20
|
color: var(--text-dimmer);
|
|
22
21
|
transition: background 0.15s, border-color 0.15s;
|
|
23
|
-
width
|
|
22
|
+
/* topbar-workbench-controls.js publishes the width the free gap allows. */
|
|
23
|
+
width: var(--top-bar-search-width, min(520px, 40%));
|
|
24
|
+
left: var(--top-bar-search-left, 50%);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* Not enough gap beside the actions: same trigger, icon only. */
|
|
28
|
+
#top-bar.search-icon .cmd-palette-searchbar {
|
|
29
|
+
width: 24px;
|
|
30
|
+
padding: 0;
|
|
31
|
+
justify-content: center;
|
|
24
32
|
}
|
|
33
|
+
#top-bar.search-icon .cmd-palette-searchbar-text,
|
|
34
|
+
#top-bar.search-icon .cmd-palette-searchbar-kbd { display: none; }
|
|
25
35
|
|
|
26
36
|
.cmd-palette-searchbar:hover {
|
|
27
37
|
background: rgba(var(--overlay-rgb), 0.08);
|
|
@@ -81,7 +81,7 @@ html.contextual-pane-boot #connect-overlay { display: none !important; }
|
|
|
81
81
|
#contextual-clay button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; color: var(--text); }
|
|
82
82
|
#contextual-clay button .lucide { width: 15px; height: 15px; }
|
|
83
83
|
#contextual-clay iframe { border: 0; flex: 1; width: 100%; min-height: 0; background: var(--bg); }
|
|
84
|
-
#contextual-clay [data-clay-loading]:not([hidden]) { position: absolute; inset: 0; margin: 0; padding: 18px 12px; display:
|
|
84
|
+
#contextual-clay [data-clay-loading]:not([hidden]) { position: absolute; inset: 0; margin: 0; padding: 18px 12px; display: flex; z-index: 1; color: var(--text-muted); font-size: 13px; background: var(--bg); pointer-events: none; }
|
|
85
85
|
body:is(.contextual-chat-pane, .contextual-clay-native) { --content-width: 760px; }
|
|
86
86
|
body:is(.contextual-chat-pane, .contextual-clay-native) #messages { padding-top: 14px; }
|
|
87
87
|
body:is(.contextual-chat-pane, .contextual-clay-native) #messages .msg-assistant .md-content,
|
|
@@ -390,7 +390,8 @@
|
|
|
390
390
|
|
|
391
391
|
/* --- Panel fullscreen --- */
|
|
392
392
|
@media (min-width: 1024px) {
|
|
393
|
-
|
|
393
|
+
/* Browser, Terminal and Files expand below the session title; see right-workbench.css. */
|
|
394
|
+
#main-column:has(.panel-fullscreen:not(.hidden):not(#shared-browser-panel, #terminal-container, #file-viewer)) > .title-bar-content { display: none; }
|
|
394
395
|
#main-panels:has(.panel-fullscreen:not(.hidden)) > #app { display: none; }
|
|
395
396
|
}
|
|
396
397
|
@media (max-width: 1023px) {
|
|
@@ -1060,15 +1061,13 @@
|
|
|
1060
1061
|
width: 70%;
|
|
1061
1062
|
max-width: 1200px;
|
|
1062
1063
|
}
|
|
1064
|
+
/* Same in-flow region as Browser and Terminal (right-workbench.css). */
|
|
1063
1065
|
#file-viewer.panel-fullscreen {
|
|
1064
|
-
position: fixed;
|
|
1065
|
-
inset: 0;
|
|
1066
1066
|
width: 100%;
|
|
1067
|
-
height:
|
|
1067
|
+
height: 100%;
|
|
1068
1068
|
max-width: none;
|
|
1069
1069
|
min-width: 0;
|
|
1070
1070
|
margin: 0;
|
|
1071
|
-
z-index: 10000;
|
|
1072
1071
|
border: 0;
|
|
1073
1072
|
border-radius: 0;
|
|
1074
1073
|
background: var(--bg);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
.mate-loading {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
align-items: center;
|
|
5
|
+
justify-content: center;
|
|
6
|
+
gap: 12px;
|
|
7
|
+
color: var(--text-muted);
|
|
8
|
+
text-align: center;
|
|
9
|
+
}
|
|
10
|
+
.mate-loading[hidden] { display: none; }
|
|
11
|
+
.mate-loading-scene { position: relative; width: 210px; height: 148px; flex-shrink: 0; }
|
|
12
|
+
.mate-loading-avatar { position: absolute; width: 94px; height: 94px; object-fit: contain; left: 58px; top: 22px; }
|
|
13
|
+
.mate-loading-desk { position: absolute; width: 210px; height: auto; left: 0; bottom: 0; }
|
|
14
|
+
.mate-loading-label { margin: 0; max-width: 100%; font-size: 13px; line-height: 1.5; overflow-wrap: anywhere; }
|
|
15
|
+
.mate-loading-dots { display: flex; gap: 6px; padding: 3px 0; }
|
|
16
|
+
.mate-loading-dots span { width: 6px; height: 6px; border-radius: 45%; background: var(--text-muted); opacity: .45; animation: mate-loading-bob 1.5s ease-in-out infinite; }
|
|
17
|
+
.mate-loading-dots span:nth-child(2) { animation-delay: .18s; }
|
|
18
|
+
.mate-loading-dots span:nth-child(3) { animation-delay: .36s; }
|
|
19
|
+
@keyframes mate-loading-bob { 0%, 60%, 100% { transform: translateY(0); opacity: .4; } 30% { transform: translateY(-4px); opacity: .8; } }
|
|
20
|
+
@media (prefers-reduced-motion: reduce) { .mate-loading-dots span { animation: none; } }
|
|
21
|
+
@media (max-height: 450px) { .mate-loading-scene { zoom: .7; } .mate-loading { gap: 8px; } }
|
|
@@ -1278,23 +1278,42 @@ pre.mermaid-error {
|
|
|
1278
1278
|
.plan-banner.plan-exit { color: var(--success); }
|
|
1279
1279
|
.plan-banner.plan-exit .plan-banner-icon { color: var(--success); }
|
|
1280
1280
|
|
|
1281
|
-
/*
|
|
1282
|
-
.pair-result-status { flex: 0 0 auto;
|
|
1283
|
-
.pair-result-status-
|
|
1284
|
-
.pair-result-status
|
|
1285
|
-
.pair-result-status
|
|
1286
|
-
.pair-result-status
|
|
1287
|
-
.pair-result-status
|
|
1288
|
-
.pair-result-status-
|
|
1289
|
-
.pair-result-status
|
|
1281
|
+
/* Worker recovery notice: one compact, content-width disclosure aligned to the conversation inset. */
|
|
1282
|
+
.pair-result-status { position: relative; flex: 0 0 auto; align-self: flex-start; box-sizing: border-box; width: fit-content; min-width: 0; max-width: calc(100% - 32px); margin: 8px 16px 0; border: 1px solid var(--border-subtle); border-radius: 8px; background: rgba(var(--overlay-rgb), 0.02); color: var(--text-muted); font-size: 12px; line-height: 1.5; }
|
|
1283
|
+
.pair-result-status.is-open { width: min(640px, calc(100% - 32px)); }
|
|
1284
|
+
.pair-result-status-bar { display: flex; align-items: center; gap: 2px; min-height: 30px; padding: 0 2px 0 0; }
|
|
1285
|
+
.pair-result-status button { font: inherit; color: var(--text-secondary); background: transparent; border: 0; border-radius: 6px; cursor: pointer; }
|
|
1286
|
+
.pair-result-status-toggle { display: inline-flex; align-items: center; gap: 6px; min-height: 28px; padding: 0 8px; margin: 1px 0 1px 1px; }
|
|
1287
|
+
.pair-result-status-icon { display: inline-flex; color: var(--text-dimmer); }
|
|
1288
|
+
.pair-result-status-tone-blocked .pair-result-status-icon, .pair-result-status-tone-uncertain .pair-result-status-icon { color: var(--warning); }
|
|
1289
|
+
.pair-result-status .lucide { width: 14px; height: 14px; }
|
|
1290
|
+
.pair-result-status-label { color: var(--text-secondary); font-weight: 500; white-space: nowrap; }
|
|
1291
|
+
.pair-result-status-review { color: var(--text-muted); white-space: nowrap; }
|
|
1292
|
+
.pair-result-status-chevron { display: inline-flex; color: var(--text-dimmer); transition: transform 0.15s; }
|
|
1293
|
+
.pair-result-status.is-open .pair-result-status-chevron { transform: rotate(180deg); }
|
|
1294
|
+
.pair-result-status-state, .pair-result-status-live { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
|
|
1295
|
+
.pair-result-status .pair-result-status-dismiss { display: grid; place-items: center; flex: 0 0 28px; width: 28px; height: 28px; padding: 0; color: var(--text-dimmer); }
|
|
1296
|
+
.pair-result-status button:hover { background: rgba(var(--overlay-rgb), 0.06); color: var(--text); }
|
|
1297
|
+
.pair-result-status button:focus-visible, .pair-result-status summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
|
|
1298
|
+
.pair-result-status-tray { border-radius: 0 0 7px 7px; max-height: min(40vh, 360px); overflow-y: auto; padding: 0 10px 8px; border-top: 1px solid var(--border-subtle); overflow-wrap: anywhere; }
|
|
1299
|
+
.pair-result-status-tray[hidden] { display: none; }
|
|
1300
|
+
.pair-result-status-card { padding: 8px 0; }
|
|
1301
|
+
.pair-result-status-card + .pair-result-status-card { border-top: 1px solid var(--border-subtle); }
|
|
1290
1302
|
.pair-result-status-card > strong, .pair-result-status-card > span { display: block; }
|
|
1291
1303
|
.pair-result-status-card > strong { color: var(--text-secondary); font-weight: 500; margin-bottom: 3px; }
|
|
1292
1304
|
.pair-result-status-card details { margin-top: 7px; }
|
|
1293
1305
|
.pair-result-status-card summary { cursor: pointer; }
|
|
1294
1306
|
.pair-result-status-card pre { max-height: 180px; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere; font: inherit; }
|
|
1295
|
-
.pair-result-status-retry { margin-top: 8px; padding: 4px 8px; }
|
|
1307
|
+
.pair-result-status .pair-result-status-retry { margin-top: 8px; padding: 4px 8px; border: 1px solid var(--border); border-radius: 5px; }
|
|
1296
1308
|
.pair-result-status-retry:disabled { cursor: not-allowed; opacity: 0.55; }
|
|
1297
|
-
@media (
|
|
1309
|
+
@media (prefers-reduced-motion: reduce) { .pair-result-status-chevron { transition: none; } }
|
|
1310
|
+
@media (max-width: 600px) {
|
|
1311
|
+
.pair-result-status { margin: 6px 8px 0; max-width: calc(100% - 16px); }
|
|
1312
|
+
.pair-result-status.is-open { width: calc(100% - 16px); }
|
|
1313
|
+
.pair-result-status-bar { min-height: 36px; }
|
|
1314
|
+
.pair-result-status-toggle { min-height: 34px; }
|
|
1315
|
+
.pair-result-status .pair-result-status-dismiss { flex-basis: 36px; width: 36px; height: 36px; }
|
|
1316
|
+
}
|
|
1298
1317
|
|
|
1299
1318
|
|
|
1300
1319
|
/* --- Plan card --- */
|