clay-server 3.8.0-beta.1 → 3.8.0-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/lib/builtin-mates.js +14 -14
- package/lib/mates.js +2 -6
- package/lib/project-mate-interaction.js +7 -7
- package/lib/project-session-pair.js +84 -4
- package/lib/project-sessions.js +1 -1
- package/lib/project-user-mention.js +4 -4
- package/lib/project-worker-proposal.js +1 -1
- package/lib/project.js +4 -3
- package/lib/public/css/avatar-imprints.css +46 -0
- package/lib/public/css/icon-strip.css +3 -3
- package/lib/public/css/pane.css +1 -7
- package/lib/public/css/profile.css +123 -95
- package/lib/public/css/session-actions.css +40 -9
- package/lib/public/css/user-settings.css +1 -1
- package/lib/public/index.html +2 -2
- package/lib/public/modules/app-cursors.js +2 -2
- package/lib/public/modules/app-dm.js +1 -8
- package/lib/public/modules/app-messages.js +2 -2
- package/lib/public/modules/app-projects.js +7 -6
- package/lib/public/modules/app-rate-limit.js +0 -1
- package/lib/public/modules/app-rendering.js +0 -3
- package/lib/public/modules/avatar-imprint.js +134 -0
- package/lib/public/modules/avatar.js +25 -19
- package/lib/public/modules/debate.js +10 -5
- package/lib/public/modules/mate-sidebar.js +2 -2
- package/lib/public/modules/mention.js +26 -16
- package/lib/public/modules/profile.js +73 -190
- package/lib/public/modules/session-actions.js +5 -3
- package/lib/public/modules/sidebar-mates.js +5 -4
- package/lib/public/modules/sidebar-sessions.js +1 -1
- package/lib/public/modules/split-pair-ui.js +2 -8
- package/lib/public/style.css +1 -0
- package/lib/server-auth.js +2 -2
- package/lib/server-dm.js +8 -8
- package/lib/server-mates.js +3 -3
- package/lib/server-settings.js +2 -2
- package/lib/server.js +5 -4
- package/lib/session-pair-mcp-server.js +16 -1
- package/lib/users.js +4 -4
- package/package.json +1 -1
package/lib/builtin-mates.js
CHANGED
|
@@ -18,8 +18,8 @@ var BUILTIN_MATES = [
|
|
|
18
18
|
key: "clay",
|
|
19
19
|
displayName: "Clay",
|
|
20
20
|
bio: "Your workspace memory. Searches every session, project, and decision you've made and answers from the receipts. The chat surface for the home screen.",
|
|
21
|
-
avatarColor: "#
|
|
22
|
-
avatarStyle: "
|
|
21
|
+
avatarColor: "#5857fc",
|
|
22
|
+
avatarStyle: "imprint",
|
|
23
23
|
avatarCustom: "/clay-studio-symbol.png", // Clay is the app — use the app symbol
|
|
24
24
|
avatarLocked: true,
|
|
25
25
|
primary: true, // code-managed, auto-updated on startup
|
|
@@ -48,8 +48,8 @@ var BUILTIN_MATES = [
|
|
|
48
48
|
key: "ally",
|
|
49
49
|
displayName: "Ally",
|
|
50
50
|
bio: "Chief of staff. Quiet, sharp, sees across every mate. Knows what Arch decided yesterday, what Buzz pitched last week, and what you said three weeks ago.",
|
|
51
|
-
avatarColor: "#
|
|
52
|
-
avatarStyle: "
|
|
51
|
+
avatarColor: "#5857fc",
|
|
52
|
+
avatarStyle: "imprint",
|
|
53
53
|
avatarCustom: "/mates/ally.png",
|
|
54
54
|
avatarLocked: true,
|
|
55
55
|
archived: true, // skip seeding for new users; demote on existing
|
|
@@ -69,8 +69,8 @@ var BUILTIN_MATES = [
|
|
|
69
69
|
key: "arch",
|
|
70
70
|
displayName: "Arch",
|
|
71
71
|
bio: "Architect. Stubborn about structure, patient about everything else. Draws boxes and arrows before anyone writes code, and is annoyingly right about which ones will break.",
|
|
72
|
-
avatarColor: "#
|
|
73
|
-
avatarStyle: "
|
|
72
|
+
avatarColor: "#5857fc",
|
|
73
|
+
avatarStyle: "imprint",
|
|
74
74
|
seedData: {
|
|
75
75
|
relationship: "colleague",
|
|
76
76
|
activity: ["planning", "reviewing"],
|
|
@@ -87,8 +87,8 @@ var BUILTIN_MATES = [
|
|
|
87
87
|
key: "rush",
|
|
88
88
|
displayName: "Rush",
|
|
89
89
|
bio: "Shipper. Impatient in the best way. Cuts your scope in half, ships it before lunch, and somehow it's better than the original plan.",
|
|
90
|
-
avatarColor: "#
|
|
91
|
-
avatarStyle: "
|
|
90
|
+
avatarColor: "#5857fc",
|
|
91
|
+
avatarStyle: "imprint",
|
|
92
92
|
seedData: {
|
|
93
93
|
relationship: "colleague",
|
|
94
94
|
activity: ["coding", "planning"],
|
|
@@ -105,8 +105,8 @@ var BUILTIN_MATES = [
|
|
|
105
105
|
key: "ward",
|
|
106
106
|
displayName: "Ward",
|
|
107
107
|
bio: "Guardian. Quietly anxious in a productive way. Reads error logs for fun and asks \"what happens when the input is null?\" before anyone else thinks of it.",
|
|
108
|
-
avatarColor: "#
|
|
109
|
-
avatarStyle: "
|
|
108
|
+
avatarColor: "#5857fc",
|
|
109
|
+
avatarStyle: "imprint",
|
|
110
110
|
seedData: {
|
|
111
111
|
relationship: "reviewer",
|
|
112
112
|
activity: ["reviewing", "testing"],
|
|
@@ -123,8 +123,8 @@ var BUILTIN_MATES = [
|
|
|
123
123
|
key: "pixel",
|
|
124
124
|
displayName: "Pixel",
|
|
125
125
|
bio: "Designer. Obsessed with the details nobody else notices. Sees the 2px misalignment, the confusing label, the flow that makes sense to the builder but not the user.",
|
|
126
|
-
avatarColor: "#
|
|
127
|
-
avatarStyle: "
|
|
126
|
+
avatarColor: "#5857fc",
|
|
127
|
+
avatarStyle: "imprint",
|
|
128
128
|
seedData: {
|
|
129
129
|
relationship: "colleague",
|
|
130
130
|
activity: ["designing", "reviewing"],
|
|
@@ -141,8 +141,8 @@ var BUILTIN_MATES = [
|
|
|
141
141
|
key: "buzz",
|
|
142
142
|
displayName: "Buzz",
|
|
143
143
|
bio: "Marketer. Competitive, trend-obsessed, always watching what others are doing. Researches your market, tracks what people search for, and turns \"we built a thing\" into a story people care about.",
|
|
144
|
-
avatarColor: "#
|
|
145
|
-
avatarStyle: "
|
|
144
|
+
avatarColor: "#5857fc",
|
|
145
|
+
avatarStyle: "imprint",
|
|
146
146
|
seedData: {
|
|
147
147
|
relationship: "colleague",
|
|
148
148
|
activity: ["writing", "marketing"],
|
package/lib/mates.js
CHANGED
|
@@ -121,10 +121,6 @@ function createMate(ctx, seedData) {
|
|
|
121
121
|
var id = generateMateId();
|
|
122
122
|
var userId = ctx ? ctx.userId : null;
|
|
123
123
|
|
|
124
|
-
// Pick a random avatar color from a pleasant palette
|
|
125
|
-
var colors = ["#6c5ce7", "#00b894", "#e17055", "#0984e3", "#fdcb6e", "#e84393", "#00cec9", "#ff7675"];
|
|
126
|
-
var colorIdx = crypto.randomBytes(1)[0] % colors.length;
|
|
127
|
-
|
|
128
124
|
var mate = {
|
|
129
125
|
id: id,
|
|
130
126
|
name: null,
|
|
@@ -134,8 +130,8 @@ function createMate(ctx, seedData) {
|
|
|
134
130
|
vendor: (seedData && seedData.vendor) || "claude",
|
|
135
131
|
profile: {
|
|
136
132
|
displayName: null,
|
|
137
|
-
avatarColor:
|
|
138
|
-
avatarStyle: "
|
|
133
|
+
avatarColor: "#5857fc",
|
|
134
|
+
avatarStyle: "imprint",
|
|
139
135
|
avatarSeed: crypto.randomBytes(4).toString("hex"),
|
|
140
136
|
},
|
|
141
137
|
bio: null,
|
|
@@ -39,14 +39,14 @@ function attachMateInteraction(ctx) {
|
|
|
39
39
|
vendor: "claude",
|
|
40
40
|
name: "Claude Code",
|
|
41
41
|
avatarColor: "#cc785c",
|
|
42
|
-
avatarStyle: "
|
|
42
|
+
avatarStyle: "imprint",
|
|
43
43
|
avatarSeed: "plain-claude",
|
|
44
44
|
},
|
|
45
45
|
"plain:codex": {
|
|
46
46
|
vendor: "codex",
|
|
47
47
|
name: "Codex",
|
|
48
48
|
avatarColor: "#10a37f",
|
|
49
|
-
avatarStyle: "
|
|
49
|
+
avatarStyle: "imprint",
|
|
50
50
|
avatarSeed: "plain-codex",
|
|
51
51
|
},
|
|
52
52
|
};
|
|
@@ -554,8 +554,8 @@ function attachMateInteraction(ctx) {
|
|
|
554
554
|
}
|
|
555
555
|
|
|
556
556
|
var mateName = (mate.profile && mate.profile.displayName) || mate.name || "Mate";
|
|
557
|
-
var avatarColor = (mate.profile && mate.profile.avatarColor) || "#
|
|
558
|
-
var avatarStyle = (mate.profile && mate.profile.avatarStyle) || "
|
|
557
|
+
var avatarColor = (mate.profile && mate.profile.avatarColor) || "#5857fc";
|
|
558
|
+
var avatarStyle = (mate.profile && mate.profile.avatarStyle) || "imprint";
|
|
559
559
|
var avatarSeed = (mate.profile && mate.profile.avatarSeed) || mate.id;
|
|
560
560
|
|
|
561
561
|
// Build full mention text (include pasted content)
|
|
@@ -800,11 +800,11 @@ function attachMateInteraction(ctx) {
|
|
|
800
800
|
|
|
801
801
|
function getMateProfile(mateCtx, mateId) {
|
|
802
802
|
var mate = matesModule.getMate(mateCtx, mateId);
|
|
803
|
-
if (!mate) return { name: "Mate", avatarColor: "#
|
|
803
|
+
if (!mate) return { name: "Mate", avatarColor: "#5857fc", avatarStyle: "imprint", avatarSeed: mateId };
|
|
804
804
|
return {
|
|
805
805
|
name: (mate.profile && mate.profile.displayName) || mate.name || "Mate",
|
|
806
|
-
avatarColor: (mate.profile && mate.profile.avatarColor) || "#
|
|
807
|
-
avatarStyle: (mate.profile && mate.profile.avatarStyle) || "
|
|
806
|
+
avatarColor: (mate.profile && mate.profile.avatarColor) || "#5857fc",
|
|
807
|
+
avatarStyle: (mate.profile && mate.profile.avatarStyle) || "imprint",
|
|
808
808
|
avatarSeed: (mate.profile && mate.profile.avatarSeed) || mateId,
|
|
809
809
|
};
|
|
810
810
|
}
|
|
@@ -203,9 +203,13 @@ function attachSessionPair(ctx) {
|
|
|
203
203
|
async function sendToPartner(args, caller) {
|
|
204
204
|
try {
|
|
205
205
|
if (caller && caller._delegatedBy) throw new Error("delegated turns cannot delegate to another session");
|
|
206
|
-
var resolved = groupAndPartner(caller);
|
|
207
206
|
var message = typeof args.message === "string" ? args.message.trim() : "";
|
|
208
207
|
if (!message) throw new Error("message is required");
|
|
208
|
+
var created = null;
|
|
209
|
+
if (caller && !store.groupForMember(caller.localId)) {
|
|
210
|
+
created = createWorkerForDriver(caller, args);
|
|
211
|
+
}
|
|
212
|
+
var resolved = groupAndPartner(caller);
|
|
209
213
|
var wait = args.wait !== false;
|
|
210
214
|
var timeout = Number.isFinite(args.timeoutSeconds) ? Math.floor(args.timeoutSeconds) : 300;
|
|
211
215
|
timeout = Math.max(1, Math.min(900, timeout));
|
|
@@ -243,9 +247,14 @@ function attachSessionPair(ctx) {
|
|
|
243
247
|
if (!wait) {
|
|
244
248
|
token.detached = true;
|
|
245
249
|
monitorPartner(resolved.group, caller, partner, token);
|
|
246
|
-
return toolResult({ status: "running", partnerId: partner.localId, hint: "The completed result will be pushed back automatically. Use read_partner only for an interim status check." });
|
|
250
|
+
return toolResult({ status: "running", partnerId: partner.localId, workerCreated: !!created, hint: "The completed result will be pushed back automatically. Use read_partner only for an interim status check." });
|
|
251
|
+
}
|
|
252
|
+
var completed = await waitForPartner(resolved.group, caller, partner, token, timeout);
|
|
253
|
+
if (created) {
|
|
254
|
+
completed.workerCreated = true;
|
|
255
|
+
completed.partnerId = partner.localId;
|
|
247
256
|
}
|
|
248
|
-
return toolResult(
|
|
257
|
+
return toolResult(completed);
|
|
249
258
|
} catch (e) {
|
|
250
259
|
if (caller) {
|
|
251
260
|
var group = store.groupForMember(caller.localId);
|
|
@@ -277,10 +286,46 @@ function attachSessionPair(ctx) {
|
|
|
277
286
|
}
|
|
278
287
|
}
|
|
279
288
|
|
|
289
|
+
function interruptPartner(args, caller) {
|
|
290
|
+
try {
|
|
291
|
+
var resolved = groupAndPartner(caller);
|
|
292
|
+
var partner = resolved.partner;
|
|
293
|
+
if (!partner.isProcessing && !partner._queryStarting) {
|
|
294
|
+
return toolResult({ status: "idle", partnerId: partner.localId, title: partner.title || "New Session" });
|
|
295
|
+
}
|
|
296
|
+
partner.taskStopRequested = true;
|
|
297
|
+
if (partner.abortController) partner.abortController.abort();
|
|
298
|
+
return toolResult({ status: "interrupting", partnerId: partner.localId, title: partner.title || "New Session" });
|
|
299
|
+
} catch (e) {
|
|
300
|
+
return toolError(e);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function closePartner(args, caller) {
|
|
305
|
+
try {
|
|
306
|
+
var resolved = groupAndPartner(caller);
|
|
307
|
+
var partner = resolved.partner;
|
|
308
|
+
var interrupted = !!(partner.isProcessing || partner._queryStarting);
|
|
309
|
+
if (interrupted) {
|
|
310
|
+
partner.taskStopRequested = true;
|
|
311
|
+
if (partner.abortController) partner.abortController.abort();
|
|
312
|
+
}
|
|
313
|
+
if (partner._pairDelegation) finishDelegation(resolved.group, caller, partner, partner._pairDelegation);
|
|
314
|
+
var ws = { _clayUser: caller.ownerId ? { id: caller.ownerId } : null };
|
|
315
|
+
var result = store.dissolve(ws, { id: resolved.group.id });
|
|
316
|
+
if (!result.ok) throw new Error(result.error || "could not close the Worker pair");
|
|
317
|
+
return toolResult({ status: "closed", partnerId: partner.localId, interrupted: interrupted, historyPreserved: true });
|
|
318
|
+
} catch (e) {
|
|
319
|
+
return toolError(e);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
280
323
|
function getToolDefs(boundSession) {
|
|
281
324
|
if (!boundSession) return pairMcp.getToolDefs({
|
|
282
325
|
send: function () { return toolError(new Error("send_to_partner requires a session-bound tool server")); },
|
|
283
326
|
read: function () { return toolError(new Error("read_partner requires a session-bound tool server")); },
|
|
327
|
+
interrupt: function () { return toolError(new Error("interrupt_partner requires a session-bound tool server")); },
|
|
328
|
+
close: function () { return toolError(new Error("close_partner requires a session-bound tool server")); },
|
|
284
329
|
});
|
|
285
330
|
// Mount whenever we have a bound session: MCP servers are fixed for the
|
|
286
331
|
// lifetime of a query, and Claude queries live across turns, so gating on
|
|
@@ -295,6 +340,8 @@ function attachSessionPair(ctx) {
|
|
|
295
340
|
var tools = pairMcp.getToolDefs({
|
|
296
341
|
send: function (args) { return sendToPartner(args, boundSession); },
|
|
297
342
|
read: function (args) { return readPartner(args, boundSession); },
|
|
343
|
+
interrupt: function (args) { return interruptPartner(args, boundSession); },
|
|
344
|
+
close: function (args) { return closePartner(args, boundSession); },
|
|
298
345
|
});
|
|
299
346
|
return tools.concat(workerProposal.getToolDefs(boundSession));
|
|
300
347
|
}
|
|
@@ -343,6 +390,37 @@ function attachSessionPair(ctx) {
|
|
|
343
390
|
return { driver: driver, worker: worker, group: result.group };
|
|
344
391
|
}
|
|
345
392
|
|
|
393
|
+
function createWorkerForDriver(driver, args) {
|
|
394
|
+
if (ctx.isMate) throw new Error("Pair sessions are only available in projects");
|
|
395
|
+
var installed = sm.installedVendors || [];
|
|
396
|
+
if (installed.length === 0) throw new Error("no coding agent is installed for a Worker session");
|
|
397
|
+
var vendor = typeof args.workerVendor === "string" ? args.workerVendor.trim() : "";
|
|
398
|
+
if (vendor) validateVendor(vendor);
|
|
399
|
+
if (!vendor) {
|
|
400
|
+
if (installed.indexOf("codex") !== -1 && driver.vendor !== "codex") vendor = "codex";
|
|
401
|
+
else {
|
|
402
|
+
vendor = installed[0];
|
|
403
|
+
for (var i = 0; i < installed.length; i++) {
|
|
404
|
+
if (installed[i] !== driver.vendor) { vendor = installed[i]; break; }
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
var ws = {
|
|
409
|
+
_clayActiveSession: driver.localId,
|
|
410
|
+
_clayUser: driver.ownerId ? { id: driver.ownerId } : null,
|
|
411
|
+
};
|
|
412
|
+
var created = createPairRecord(ws, {
|
|
413
|
+
driver: { sessionId: driver.localId },
|
|
414
|
+
worker: {
|
|
415
|
+
vendor: vendor,
|
|
416
|
+
model: typeof args.workerModel === "string" ? args.workerModel : "",
|
|
417
|
+
effort: typeof args.workerEffort === "string" ? args.workerEffort : "",
|
|
418
|
+
},
|
|
419
|
+
});
|
|
420
|
+
sm.sendToSession(driver, { type: "pair_session_created", ok: true, group: created.group });
|
|
421
|
+
return created;
|
|
422
|
+
}
|
|
423
|
+
|
|
346
424
|
function createPair(ws, msg) {
|
|
347
425
|
try {
|
|
348
426
|
var created = createPairRecord(ws, msg);
|
|
@@ -390,7 +468,9 @@ function attachSessionPair(ctx) {
|
|
|
390
468
|
var group = store.groupForMember(session.localId);
|
|
391
469
|
var pairPrompt = "";
|
|
392
470
|
if (group && group.pair && group.pair.driverId === session.localId) {
|
|
393
|
-
pairPrompt = "You are the Driver in a two-agent pair. The tools send_to_partner and
|
|
471
|
+
pairPrompt = "You are the Driver in a two-agent pair. The tools send_to_partner, read_partner, interrupt_partner, and close_partner are provided directly to you. Use send_to_partner to delegate concrete bounded work to the Worker. The human may also message or stop the Worker directly; treat that intervention as authoritative. Use close_partner immediately when the human asks to close, dismiss, or remove the Worker pane; it preserves the session history. A completed Worker turn leaves the Worker session available for more work. Use interrupt_partner when execution must stop or change direction but the pair should remain open; its work is partial and unverified until you review it. If review or user feedback requires corrections to the Worker's implementation, delegate a follow-up turn to that Worker instead of editing the Worker-owned files yourself. If the Worker is no longer available, keep the work in the visible Worker flow and use send_to_partner again after the stale pair is removed; never substitute a background session. If a non-waiting delegation finishes later, Clay pushes the result back and resumes you automatically; use read_partner only when you need an interim status check. Integrate and verify the final outcome. Do not search the project for implementations of these tools, and do not delegate work that must be performed sequentially in this same session.";
|
|
472
|
+
} else if (!group && !ctx.isMate) {
|
|
473
|
+
pairPrompt = "When the user asks you to open or use a visible Worker, call send_to_partner directly. Clay will create the paired Worker session and open it in the right pane automatically before delivering the task. Do not ask the user to start split mode and do not use a background sub-agent as a substitute for a visible Worker.";
|
|
394
474
|
}
|
|
395
475
|
return [pairPrompt, workerProposal.getSystemPrompt(session)].filter(Boolean).join("\n\n");
|
|
396
476
|
}
|
package/lib/project-sessions.js
CHANGED
|
@@ -1391,7 +1391,7 @@ function attachSessions(ctx) {
|
|
|
1391
1391
|
type: msg.type,
|
|
1392
1392
|
userId: u.id,
|
|
1393
1393
|
displayName: p.name || u.displayName || u.username,
|
|
1394
|
-
avatarStyle: p.avatarStyle || "
|
|
1394
|
+
avatarStyle: p.avatarStyle || "imprint",
|
|
1395
1395
|
avatarSeed: p.avatarSeed || u.username,
|
|
1396
1396
|
avatarCustom: p.avatarCustom || "",
|
|
1397
1397
|
};
|
|
@@ -47,9 +47,9 @@ function attachUserMention(ctx) {
|
|
|
47
47
|
var u = ws._clayUser;
|
|
48
48
|
var p = u.profile || {};
|
|
49
49
|
return {
|
|
50
|
-
style: p.avatarStyle || "
|
|
50
|
+
style: p.avatarStyle || "imprint",
|
|
51
51
|
seed: p.avatarSeed || u.username || u.id,
|
|
52
|
-
color: p.avatarColor || "#
|
|
52
|
+
color: p.avatarColor || "#5857fc",
|
|
53
53
|
custom: p.avatarCustom || "",
|
|
54
54
|
};
|
|
55
55
|
}
|
|
@@ -63,9 +63,9 @@ function attachUserMention(ctx) {
|
|
|
63
63
|
id: u.id,
|
|
64
64
|
name: p.name || u.displayName || u.username || "User",
|
|
65
65
|
username: u.username,
|
|
66
|
-
avatarStyle: p.avatarStyle || "
|
|
66
|
+
avatarStyle: p.avatarStyle || "imprint",
|
|
67
67
|
avatarSeed: p.avatarSeed || u.username,
|
|
68
|
-
avatarColor: p.avatarColor || "#
|
|
68
|
+
avatarColor: p.avatarColor || "#5857fc",
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -247,7 +247,7 @@ function attachWorkerProposal(ctx) {
|
|
|
247
247
|
});
|
|
248
248
|
var followup;
|
|
249
249
|
if (result.status === "complete") {
|
|
250
|
-
followup = "[Worker execution completed]\nReview and verify the Worker's result. The Worker session remains available: if the implementation needs corrections or additional edits, send a follow-up with send_to_partner instead of taking over the Worker-owned files yourself. If that Worker is no longer available,
|
|
250
|
+
followup = "[Worker execution completed]\nReview and verify the Worker's result. The Worker session remains available: if the implementation needs corrections or additional edits, send a follow-up with send_to_partner instead of taking over the Worker-owned files yourself. If that Worker is no longer available, keep the work in the visible Worker flow and use send_to_partner again after the stale pair is removed; never substitute a background session.\n\n" + (result.response || "The Worker completed without a text summary.");
|
|
251
251
|
} else if (result.status === "interrupted") {
|
|
252
252
|
followup = "[Worker execution interrupted]\nThe user interrupted the Worker mid-turn. Its work is PARTIAL and unverified — do not treat it as finished. Review what was done and decide next steps with the user.";
|
|
253
253
|
} else if (result.status === "running") {
|
package/lib/project.js
CHANGED
|
@@ -344,7 +344,7 @@ function createProjectContext(opts) {
|
|
|
344
344
|
id: u.id,
|
|
345
345
|
displayName: p.name || u.displayName || u.username,
|
|
346
346
|
username: u.username,
|
|
347
|
-
avatarStyle: p.avatarStyle || "
|
|
347
|
+
avatarStyle: p.avatarStyle || "imprint",
|
|
348
348
|
avatarSeed: p.avatarSeed || u.username,
|
|
349
349
|
avatarCustom: p.avatarCustom || "",
|
|
350
350
|
});
|
|
@@ -1277,8 +1277,9 @@ function createProjectContext(opts) {
|
|
|
1277
1277
|
id: u.id,
|
|
1278
1278
|
displayName: p.name || u.displayName || u.username,
|
|
1279
1279
|
username: u.username,
|
|
1280
|
-
avatarStyle: p.avatarStyle || "
|
|
1280
|
+
avatarStyle: p.avatarStyle || "imprint",
|
|
1281
1281
|
avatarSeed: p.avatarSeed || u.username,
|
|
1282
|
+
avatarColor: p.avatarColor || "#5857fc",
|
|
1282
1283
|
avatarCustom: p.avatarCustom || "",
|
|
1283
1284
|
});
|
|
1284
1285
|
}
|
|
@@ -1827,7 +1828,7 @@ function createProjectContext(opts) {
|
|
|
1827
1828
|
id: u.id,
|
|
1828
1829
|
displayName: p.name || u.displayName || u.username,
|
|
1829
1830
|
username: u.username,
|
|
1830
|
-
avatarStyle: p.avatarStyle || "
|
|
1831
|
+
avatarStyle: p.avatarStyle || "imprint",
|
|
1831
1832
|
avatarSeed: p.avatarSeed || u.username,
|
|
1832
1833
|
avatarCustom: p.avatarCustom || "",
|
|
1833
1834
|
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/* Clay Imprints use one consistent, pressed-square silhouette everywhere. */
|
|
2
|
+
.activity-inline-avatar,
|
|
3
|
+
.ask-mate-avatar,
|
|
4
|
+
.client-avatar,
|
|
5
|
+
.debate-info-avatar,
|
|
6
|
+
.debate-panel-item-avatar,
|
|
7
|
+
.debate-panelist-avatar,
|
|
8
|
+
.debate-speaker-avatar,
|
|
9
|
+
.delegated-card-avatar,
|
|
10
|
+
.dm-bubble-avatar,
|
|
11
|
+
.dm-header-avatar,
|
|
12
|
+
.dm-msg-avatar,
|
|
13
|
+
.dm-picker-mates-marquee-avatar,
|
|
14
|
+
.dm-user-picker-avatar,
|
|
15
|
+
.home-chat-avatar,
|
|
16
|
+
.home-hub-mate-avatar,
|
|
17
|
+
.icon-strip-me-avatar,
|
|
18
|
+
.icon-strip-user-avatar,
|
|
19
|
+
.input-mention-chip-avatar,
|
|
20
|
+
.mate-collapsed-avatar,
|
|
21
|
+
.mate-mobile-avatar,
|
|
22
|
+
.mate-profile-avatar,
|
|
23
|
+
.mate-sidebar-avatar,
|
|
24
|
+
.mention-avatar,
|
|
25
|
+
.mention-item-avatar,
|
|
26
|
+
.mobile-chat-chip-avatar,
|
|
27
|
+
.notif-banner-avatar,
|
|
28
|
+
.profile-avatar-custom-preview,
|
|
29
|
+
.profile-popover-avatar-img,
|
|
30
|
+
.project-switcher-avatar,
|
|
31
|
+
.remote-cursor-avatar,
|
|
32
|
+
.rewind-avatar,
|
|
33
|
+
.session-presence-avatar,
|
|
34
|
+
.sidebar-presence-avatar,
|
|
35
|
+
.us-account-avatar,
|
|
36
|
+
.us-account-avatar-img,
|
|
37
|
+
.user-island-avatar,
|
|
38
|
+
.user-island-avatar img {
|
|
39
|
+
border-radius: 26% !important;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.session-presence-avatar,
|
|
43
|
+
.sidebar-presence-avatar,
|
|
44
|
+
.client-avatar {
|
|
45
|
+
box-shadow: 0 0 0 1px rgba(var(--overlay-rgb), 0.12);
|
|
46
|
+
}
|
|
@@ -206,10 +206,10 @@
|
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
.icon-strip-item.active::before {
|
|
209
|
-
background: var(--bg);
|
|
209
|
+
background: color-mix(in srgb, var(--brand-indigo) 6%, var(--bg));
|
|
210
210
|
box-shadow:
|
|
211
|
-
0
|
|
212
|
-
0 1px 3px rgba(var(--shadow-rgb), 0.
|
|
211
|
+
0 5px 14px color-mix(in srgb, var(--brand-indigo) 28%, transparent),
|
|
212
|
+
0 1px 3px rgba(var(--shadow-rgb), 0.14);
|
|
213
213
|
}
|
|
214
214
|
|
|
215
215
|
.icon-strip-item.active {
|
package/lib/public/css/pane.css
CHANGED
|
@@ -137,13 +137,7 @@ body.pane-mode #input-area {
|
|
|
137
137
|
.split-pair-role-driver { color: var(--accent); background: color-mix(in srgb, var(--accent) 13%, transparent); }
|
|
138
138
|
.split-pair-role-worker { color: var(--text-secondary); background: var(--bg-alt); }
|
|
139
139
|
|
|
140
|
-
/*
|
|
141
|
-
button.split-pair-role {
|
|
142
|
-
border: 0;
|
|
143
|
-
cursor: pointer;
|
|
144
|
-
font-family: inherit;
|
|
145
|
-
}
|
|
146
|
-
button.split-pair-role:hover { filter: brightness(1.25); }
|
|
140
|
+
/* Pair roles are status labels. Control remains with the Driver through MCP. */
|
|
147
141
|
|
|
148
142
|
/* Ad-hoc splits: role assignment in each pane header. ALWAYS fully
|
|
149
143
|
visible; hover/opacity gating made the control undiscoverable. */
|