clay-server 2.36.1-beta.1 → 2.36.1-beta.3
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/bin/cli.js +12 -18
- package/lib/project.js +13 -1
- package/lib/public/modules/app-messages.js +5 -1
- package/lib/public/modules/input.js +17 -4
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -1503,11 +1503,9 @@ async function forkDaemon(mode, keepAwake, extraProjects, addCwd, wantOsUsers) {
|
|
|
1503
1503
|
break;
|
|
1504
1504
|
}
|
|
1505
1505
|
}
|
|
1506
|
-
// Restore
|
|
1506
|
+
// Restore project-level settings from previous config
|
|
1507
1507
|
if (prevProjectMap[cwd]) {
|
|
1508
|
-
|
|
1509
|
-
if (prevProjectMap[cwd].allowedUsers) cwdEntry.allowedUsers = prevProjectMap[cwd].allowedUsers;
|
|
1510
|
-
if (prevProjectMap[cwd].ownerId) cwdEntry.ownerId = prevProjectMap[cwd].ownerId;
|
|
1508
|
+
cwdEntry = Object.assign({}, prevProjectMap[cwd], cwdEntry);
|
|
1511
1509
|
}
|
|
1512
1510
|
allProjects.push(cwdEntry);
|
|
1513
1511
|
usedSlugs.push(slug);
|
|
@@ -1522,21 +1520,19 @@ async function forkDaemon(mode, keepAwake, extraProjects, addCwd, wantOsUsers) {
|
|
|
1522
1520
|
var rpSlug = generateSlug(rp.path, usedSlugs);
|
|
1523
1521
|
usedSlugs.push(rpSlug);
|
|
1524
1522
|
var rpEntry = { path: rp.path, slug: rpSlug, title: rp.title || undefined, icon: rp.icon || undefined, addedAt: rp.addedAt || Date.now() };
|
|
1525
|
-
// Restore
|
|
1523
|
+
// Restore project-level settings from previous config
|
|
1526
1524
|
if (prevProjectMap[rp.path]) {
|
|
1527
|
-
|
|
1528
|
-
if (prevProjectMap[rp.path].allowedUsers) rpEntry.allowedUsers = prevProjectMap[rp.path].allowedUsers;
|
|
1529
|
-
if (prevProjectMap[rp.path].ownerId) rpEntry.ownerId = prevProjectMap[rp.path].ownerId;
|
|
1525
|
+
rpEntry = Object.assign({}, prevProjectMap[rp.path], rpEntry);
|
|
1530
1526
|
}
|
|
1531
1527
|
allProjects.push(rpEntry);
|
|
1532
1528
|
}
|
|
1533
1529
|
}
|
|
1534
1530
|
|
|
1535
|
-
var config = {
|
|
1531
|
+
var config = Object.assign({}, prevConfig || {}, {
|
|
1536
1532
|
pid: null,
|
|
1537
1533
|
port: port,
|
|
1538
1534
|
host: host,
|
|
1539
|
-
pinHash: mode === "multi" && cliPin ? generateAuthToken(cliPin) : null,
|
|
1535
|
+
pinHash: mode === "multi" && cliPin ? generateAuthToken(cliPin) : (prevConfig && prevConfig.pinHash) || null,
|
|
1540
1536
|
tls: hasTls,
|
|
1541
1537
|
builtinCert: hasBuiltinCert,
|
|
1542
1538
|
mkcertDetected: mkcertDetected,
|
|
@@ -1548,7 +1544,7 @@ async function forkDaemon(mode, keepAwake, extraProjects, addCwd, wantOsUsers) {
|
|
|
1548
1544
|
mode: mode || "single",
|
|
1549
1545
|
setupCompleted: true,
|
|
1550
1546
|
projects: allProjects,
|
|
1551
|
-
};
|
|
1547
|
+
});
|
|
1552
1548
|
|
|
1553
1549
|
ensureConfigDir();
|
|
1554
1550
|
saveConfig(config);
|
|
@@ -1687,8 +1683,7 @@ async function devMode(mode, keepAwake, existingPinHash, wantOsUsers) {
|
|
|
1687
1683
|
}
|
|
1688
1684
|
// Restore access settings for cwd from previous config
|
|
1689
1685
|
if (prevDevProjectMap[cwd]) {
|
|
1690
|
-
|
|
1691
|
-
if (prevDevProjectMap[cwd].allowedUsers) cwdDevEntry.allowedUsers = prevDevProjectMap[cwd].allowedUsers;
|
|
1686
|
+
cwdDevEntry = Object.assign({}, prevDevProjectMap[cwd], cwdDevEntry);
|
|
1692
1687
|
}
|
|
1693
1688
|
var allProjects = [cwdDevEntry];
|
|
1694
1689
|
var usedSlugs = [slug];
|
|
@@ -1697,15 +1692,14 @@ async function devMode(mode, keepAwake, existingPinHash, wantOsUsers) {
|
|
|
1697
1692
|
var rpSlug = generateSlug(rp.path, usedSlugs);
|
|
1698
1693
|
usedSlugs.push(rpSlug);
|
|
1699
1694
|
var rpDevEntry = { path: rp.path, slug: rpSlug, title: rp.title || undefined, icon: rp.icon || undefined, addedAt: rp.addedAt || Date.now() };
|
|
1700
|
-
// Restore
|
|
1695
|
+
// Restore project-level settings from previous config
|
|
1701
1696
|
if (prevDevProjectMap[rp.path]) {
|
|
1702
|
-
|
|
1703
|
-
if (prevDevProjectMap[rp.path].allowedUsers) rpDevEntry.allowedUsers = prevDevProjectMap[rp.path].allowedUsers;
|
|
1697
|
+
rpDevEntry = Object.assign({}, prevDevProjectMap[rp.path], rpDevEntry);
|
|
1704
1698
|
}
|
|
1705
1699
|
allProjects.push(rpDevEntry);
|
|
1706
1700
|
}
|
|
1707
1701
|
|
|
1708
|
-
var config = {
|
|
1702
|
+
var config = Object.assign({}, prevDevConfig || {}, {
|
|
1709
1703
|
pid: null,
|
|
1710
1704
|
port: port,
|
|
1711
1705
|
host: host,
|
|
@@ -1720,7 +1714,7 @@ async function devMode(mode, keepAwake, existingPinHash, wantOsUsers) {
|
|
|
1720
1714
|
setupCompleted: true,
|
|
1721
1715
|
projects: allProjects,
|
|
1722
1716
|
osUsers: wantOsUsers || (prevDevConfig ? (prevDevConfig.osUsers || false) : false),
|
|
1723
|
-
};
|
|
1717
|
+
});
|
|
1724
1718
|
|
|
1725
1719
|
ensureConfigDir();
|
|
1726
1720
|
saveConfig(config);
|
package/lib/project.js
CHANGED
|
@@ -911,7 +911,19 @@ function createProjectContext(opts) {
|
|
|
911
911
|
var firstModel = vendorModels[0] || "";
|
|
912
912
|
// model value can be string or {value, displayName} object
|
|
913
913
|
var defaultModel = typeof firstModel === "string" ? firstModel : (firstModel.value || "");
|
|
914
|
-
|
|
914
|
+
// Preserve the user's current model selection if it belongs to this
|
|
915
|
+
// vendor, rather than always snapping back to the vendor's default.
|
|
916
|
+
var modelToSend = defaultModel;
|
|
917
|
+
if (sm.currentModel) {
|
|
918
|
+
for (var mi = 0; mi < vendorModels.length; mi++) {
|
|
919
|
+
var mv = typeof vendorModels[mi] === "string" ? vendorModels[mi] : (vendorModels[mi].value || "");
|
|
920
|
+
if (mv === sm.currentModel) {
|
|
921
|
+
modelToSend = sm.currentModel;
|
|
922
|
+
break;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
sendTo(ws, { type: "model_info", model: modelToSend, models: vendorModels, vendor: msg.vendor, availableVendors: sm.availableVendors || [], installedVendors: sm.installedVendors || [] });
|
|
915
927
|
})();
|
|
916
928
|
return;
|
|
917
929
|
}
|
|
@@ -389,7 +389,11 @@ export function processMessage(msg) {
|
|
|
389
389
|
if (_modelVal && typeof _modelVal === "object") _modelVal = _modelVal.value || _modelVal.displayName || "";
|
|
390
390
|
var _miUpdate = { currentModels: msg.models || [] };
|
|
391
391
|
if (Object.prototype.hasOwnProperty.call(msg, "model")) {
|
|
392
|
-
|
|
392
|
+
if (store.get('vendorSelectionLocked') && store.get('currentModel')) {
|
|
393
|
+
// Keep the user's existing selection; only update models list
|
|
394
|
+
} else {
|
|
395
|
+
_miUpdate.currentModel = _modelVal || "";
|
|
396
|
+
}
|
|
393
397
|
} else {
|
|
394
398
|
_miUpdate.currentModel = store.get('currentModel');
|
|
395
399
|
}
|
|
@@ -1078,6 +1078,13 @@ export function initInput(_ctx) {
|
|
|
1078
1078
|
return;
|
|
1079
1079
|
}
|
|
1080
1080
|
e.preventDefault();
|
|
1081
|
+
// While Claude is processing and the user has nothing queued, Enter
|
|
1082
|
+
// must not adopt a ghost suggestion — pressing Enter while waiting
|
|
1083
|
+
// should be a no-op, not a send of a stale suggestion the user never
|
|
1084
|
+
// typed.
|
|
1085
|
+
if (ctx.processing && !hasSendableContent()) {
|
|
1086
|
+
return;
|
|
1087
|
+
}
|
|
1081
1088
|
// If input has no sendable content but ghost suggestion is showing, adopt it.
|
|
1082
1089
|
// Use hasSendableContent() instead of checking inputEl.value alone so that
|
|
1083
1090
|
// pending images, pastes, or files block the ghost-text adoption — otherwise
|
|
@@ -1097,8 +1104,17 @@ export function initInput(_ctx) {
|
|
|
1097
1104
|
ctx.inputEl.setAttribute("enterkeyhint", "enter");
|
|
1098
1105
|
}
|
|
1099
1106
|
|
|
1100
|
-
// Send/Stop button —
|
|
1107
|
+
// Send/Stop button — gate stop vs send on live state. If Claude is
|
|
1108
|
+
// processing and the user has nothing queued, the click is a Stop and
|
|
1109
|
+
// must not adopt a ghost suggestion. Otherwise it's a send.
|
|
1110
|
+
// (regression after #337 / 0753833)
|
|
1101
1111
|
ctx.sendBtn.addEventListener("click", function () {
|
|
1112
|
+
if (ctx.processing && !hasSendableContent()) {
|
|
1113
|
+
if (ctx.connected) {
|
|
1114
|
+
ctx.ws.send(JSON.stringify({ type: "stop" }));
|
|
1115
|
+
}
|
|
1116
|
+
return;
|
|
1117
|
+
}
|
|
1102
1118
|
// Adopt ghost suggestion if input is empty
|
|
1103
1119
|
var ghost = ctx.getGhostSuggestion ? ctx.getGhostSuggestion() : "";
|
|
1104
1120
|
if (!hasSendableContent() && ghost) {
|
|
@@ -1111,9 +1127,6 @@ export function initInput(_ctx) {
|
|
|
1111
1127
|
sendMessage();
|
|
1112
1128
|
return;
|
|
1113
1129
|
}
|
|
1114
|
-
if (ctx.processing && ctx.connected) {
|
|
1115
|
-
ctx.ws.send(JSON.stringify({ type: "stop" }));
|
|
1116
|
-
}
|
|
1117
1130
|
});
|
|
1118
1131
|
ctx.sendBtn.addEventListener("dblclick", function (e) { e.preventDefault(); });
|
|
1119
1132
|
}
|
package/package.json
CHANGED