clay-server 3.3.2-beta.3 → 3.4.0-beta.10
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/daemon-projects.js +3 -3
- package/lib/daemon.js +1 -1
- package/lib/project-connection.js +20 -5
- package/lib/project-debate.js +4 -0
- package/lib/project-file-watch.js +77 -16
- package/lib/project-mate-interaction.js +21 -1
- package/lib/project-memory.js +3 -0
- package/lib/project-shell-command.js +160 -0
- package/lib/project-user-message.js +10 -0
- package/lib/project.js +19 -4
- package/lib/public/antigravity-avatar.png +0 -0
- package/lib/public/app.js +28 -0
- package/lib/public/copilot-avatar.svg +5 -0
- package/lib/public/css/command-palette.css +22 -2
- package/lib/public/css/icon-strip.css +29 -13
- package/lib/public/css/input.css +79 -0
- package/lib/public/css/mates.css +7 -0
- package/lib/public/css/menus.css +48 -14
- package/lib/public/css/messages.css +9 -0
- package/lib/public/css/pane.css +4 -0
- package/lib/public/css/pwa-mobile.css +17 -0
- package/lib/public/css/title-bar.css +19 -0
- package/lib/public/grok-avatar.svg +4 -0
- package/lib/public/index.html +43 -4
- package/lib/public/junie-avatar.svg +11 -0
- package/lib/public/kimi-avatar.svg +4 -0
- package/lib/public/modules/app-header.js +4 -0
- package/lib/public/modules/app-messages.js +28 -5
- package/lib/public/modules/app-panels.js +37 -5
- package/lib/public/modules/app-projects.js +3 -1
- package/lib/public/modules/app-rendering.js +22 -1
- package/lib/public/modules/input.js +58 -28
- package/lib/public/modules/mate-sidebar.js +17 -3
- package/lib/public/modules/notifications.js +7 -1
- package/lib/public/modules/pane-bridge.js +11 -0
- package/lib/public/modules/pane-links.js +23 -0
- package/lib/public/modules/project-switcher.js +7 -6
- package/lib/public/modules/shell-command.js +148 -0
- package/lib/public/modules/sidebar-mates.js +7 -1
- package/lib/public/modules/sidebar-mobile.js +2 -1
- package/lib/public/modules/sidebar-projects.js +34 -43
- package/lib/public/modules/sidebar-sessions.js +6 -6
- package/lib/public/modules/split-pair-ui.js +3 -2
- package/lib/public/modules/tools.js +12 -1
- package/lib/public/modules/vendor-priority.js +14 -0
- package/lib/public/modules/vendor-selection.js +20 -0
- package/lib/public/modules/worktree-location.js +17 -0
- package/lib/public/opencode-avatar.svg +4 -0
- package/lib/public/qwen-avatar.svg +4 -0
- package/lib/public/style.css +3 -2
- package/lib/sdk-bridge.js +59 -19
- package/lib/sdk-message-processor.js +10 -1
- package/lib/session-notes-mcp-server.js +7 -1
- package/lib/worktree.js +9 -4
- package/lib/ws-schema.js +3 -0
- package/lib/yoke/acp-agent-profiles.js +238 -0
- package/lib/yoke/acp-driver-runtime.js +50 -0
- package/lib/yoke/acp-event-normalizer.js +179 -0
- package/lib/yoke/acp-process-manager.js +264 -0
- package/lib/yoke/acp-query-handle.js +487 -0
- package/lib/yoke/adapters/acp.js +317 -0
- package/lib/yoke/adapters/antigravity.js +417 -0
- package/lib/yoke/adapters/codex.js +98 -3
- package/lib/yoke/adapters/copilot.js +7 -0
- package/lib/yoke/adapters/grok.js +7 -0
- package/lib/yoke/adapters/junie.js +7 -0
- package/lib/yoke/adapters/kimi.js +7 -0
- package/lib/yoke/adapters/kiro.js +4 -4
- package/lib/yoke/adapters/opencode.js +7 -0
- package/lib/yoke/adapters/qwen.js +7 -0
- package/lib/yoke/codex-app-server.js +25 -8
- package/lib/yoke/index.js +81 -13
- package/lib/yoke/instructions.js +3 -0
- package/lib/yoke/interface.js +2 -0
- package/lib/yoke/kiro-acp-server.js +30 -276
- package/lib/yoke/vendor-registry.js +77 -0
- package/package.json +1 -1
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
// Shared ACP Adapter
|
|
2
|
+
// ------------------
|
|
3
|
+
// Implements the YOKE Adapter contract once for standard ACP agents.
|
|
4
|
+
|
|
5
|
+
var AcpProcessManager = require("../acp-process-manager").AcpProcessManager;
|
|
6
|
+
var createAcpQueryHandle = require("../acp-query-handle").createAcpQueryHandle;
|
|
7
|
+
var profiles = require("../acp-agent-profiles");
|
|
8
|
+
var driverRuntime = require("../acp-driver-runtime");
|
|
9
|
+
var skillDiscovery = require("../skill-discovery");
|
|
10
|
+
|
|
11
|
+
function modelValues(configOptions) {
|
|
12
|
+
var models = [];
|
|
13
|
+
var options = Array.isArray(configOptions) ? configOptions : [];
|
|
14
|
+
for (var i = 0; i < options.length; i++) {
|
|
15
|
+
var option = options[i];
|
|
16
|
+
if (option.category !== "model" && option.id !== "model") continue;
|
|
17
|
+
var values = Array.isArray(option.options) ? option.options : [];
|
|
18
|
+
for (var j = 0; j < values.length; j++) {
|
|
19
|
+
var value = values[j] && values[j].value;
|
|
20
|
+
if (value && models.indexOf(value) === -1) models.push(value);
|
|
21
|
+
}
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
return models;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function createAcpAdapter(vendor, opts) {
|
|
28
|
+
opts = opts || {};
|
|
29
|
+
var driver = opts._profile || opts._driver || profiles.getAcpAgentDriver(vendor);
|
|
30
|
+
if (!driver) throw new Error("[YOKE] Unknown ACP agent driver: " + vendor);
|
|
31
|
+
|
|
32
|
+
var cwd = opts.cwd || process.cwd();
|
|
33
|
+
var binaryPath = opts._binaryPath || profiles.findAcpAgentPath(driver);
|
|
34
|
+
var ProcessManagerCtor = opts._AcpProcessManagerCtor || AcpProcessManager;
|
|
35
|
+
var fetchModels = opts._fetchModels || driver.fetchModels || null;
|
|
36
|
+
var acp = null;
|
|
37
|
+
var initPromise = null;
|
|
38
|
+
var initialized = false;
|
|
39
|
+
var shuttingDown = false;
|
|
40
|
+
var initResult = null;
|
|
41
|
+
var driverState = {};
|
|
42
|
+
var cachedModels = (driver.defaultModels || []).slice();
|
|
43
|
+
var defaultModel = driver.defaultModel || cachedModels[0] || "auto";
|
|
44
|
+
var activeHandles = [];
|
|
45
|
+
var lastActiveAt = Date.now();
|
|
46
|
+
|
|
47
|
+
function context(extra) {
|
|
48
|
+
return Object.assign({
|
|
49
|
+
vendor: vendor,
|
|
50
|
+
cwd: cwd,
|
|
51
|
+
driver: driver,
|
|
52
|
+
acp: acp,
|
|
53
|
+
initResult: initResult,
|
|
54
|
+
adapter: adapter,
|
|
55
|
+
binaryPath: binaryPath,
|
|
56
|
+
driverState: driverState,
|
|
57
|
+
}, extra || {});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function supportsSessionCapability(name) {
|
|
61
|
+
var capabilities = initResult && initResult.agentCapabilities;
|
|
62
|
+
return !!(capabilities && capabilities.sessionCapabilities && capabilities.sessionCapabilities[name]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function canLoadSession() {
|
|
66
|
+
if (driver.sessionResume === false) return false;
|
|
67
|
+
return !!(initResult && initResult.agentCapabilities && initResult.agentCapabilities.loadSession);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function canResumeSession() {
|
|
71
|
+
if (driver.sessionResume === false) return false;
|
|
72
|
+
return supportsSessionCapability("resume");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function capabilities() {
|
|
76
|
+
var base = {
|
|
77
|
+
effort: false,
|
|
78
|
+
midSessionModelSwitch: false,
|
|
79
|
+
fork: false,
|
|
80
|
+
rollback: false,
|
|
81
|
+
sessionListing: false,
|
|
82
|
+
sessionRename: false,
|
|
83
|
+
thinking: true,
|
|
84
|
+
betas: false,
|
|
85
|
+
rewind: false,
|
|
86
|
+
sessionResume: canResumeSession() || canLoadSession(),
|
|
87
|
+
promptSuggestions: false,
|
|
88
|
+
elicitation: false,
|
|
89
|
+
fileCheckpointing: false,
|
|
90
|
+
contextCompacting: false,
|
|
91
|
+
skillSharing: true,
|
|
92
|
+
toolPolicy: ["ask", "allow-all"],
|
|
93
|
+
};
|
|
94
|
+
return driverRuntime.mergeCapabilities(driver, context(), base);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function readyResult() {
|
|
98
|
+
var skills = skillDiscovery.discoverSkills(cwd).map(function(skill) { return skill.name; });
|
|
99
|
+
var result = {
|
|
100
|
+
models: cachedModels.slice(),
|
|
101
|
+
defaultModel: defaultModel,
|
|
102
|
+
skills: skills,
|
|
103
|
+
slashCommands: skills,
|
|
104
|
+
fastModeState: null,
|
|
105
|
+
capabilities: capabilities(),
|
|
106
|
+
};
|
|
107
|
+
return driverRuntime.call(driver, "extendReadyResult", context({ result: result }), function() { return result; }) || result;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function updateModelsFromSession(sessionResult) {
|
|
111
|
+
var discovered = modelValues(sessionResult && sessionResult.configOptions);
|
|
112
|
+
if (!discovered.length) return;
|
|
113
|
+
cachedModels = discovered;
|
|
114
|
+
var configOptions = sessionResult.configOptions;
|
|
115
|
+
for (var i = 0; i < configOptions.length; i++) {
|
|
116
|
+
if (configOptions[i].category === "model" || configOptions[i].id === "model") {
|
|
117
|
+
defaultModel = configOptions[i].currentValue || defaultModel;
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function removeHandle(handle) {
|
|
124
|
+
var index = activeHandles.indexOf(handle);
|
|
125
|
+
if (index !== -1) activeHandles.splice(index, 1);
|
|
126
|
+
lastActiveAt = Date.now();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
var adapter = {
|
|
130
|
+
vendor: vendor,
|
|
131
|
+
|
|
132
|
+
init: function(initOpts) {
|
|
133
|
+
if (shuttingDown) return Promise.reject(new Error(driver.displayName + " adapter is shutting down"));
|
|
134
|
+
if (initialized && acp && acp.started) return Promise.resolve(readyResult());
|
|
135
|
+
if (initPromise) return initPromise;
|
|
136
|
+
|
|
137
|
+
initPromise = (async function() {
|
|
138
|
+
if (!binaryPath) {
|
|
139
|
+
binaryPath = profiles.findAcpAgentPath(driver);
|
|
140
|
+
if (!binaryPath) throw new Error(driver.displayName + " binary not found: " + driver.binaryName);
|
|
141
|
+
}
|
|
142
|
+
var effectiveOpts = Object.assign({}, opts, initOpts || {});
|
|
143
|
+
var prepared = await Promise.all([
|
|
144
|
+
fetchModels ? fetchModels(binaryPath, cwd) : Promise.resolve([]),
|
|
145
|
+
driverRuntime.callAsync(driver, "prepare", context({ initOpts: effectiveOpts }), function() {}),
|
|
146
|
+
]);
|
|
147
|
+
if (fetchModels) {
|
|
148
|
+
var fetched = prepared[0];
|
|
149
|
+
if (Array.isArray(fetched) && fetched.length) {
|
|
150
|
+
cachedModels = fetched;
|
|
151
|
+
if (cachedModels.indexOf(defaultModel) === -1) defaultModel = cachedModels[0];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (shuttingDown) throw new Error(driver.displayName + " adapter is shutting down");
|
|
155
|
+
|
|
156
|
+
var processOptions = driverRuntime.buildParams(driver, "buildProcessOptions", context({ initOpts: effectiveOpts }), {
|
|
157
|
+
args: driver.args || [],
|
|
158
|
+
cwd: cwd,
|
|
159
|
+
env: effectiveOpts.env || null,
|
|
160
|
+
logPrefix: vendor + "-acp",
|
|
161
|
+
});
|
|
162
|
+
await driverRuntime.callAsync(driver, "validateProcessOptions", context({
|
|
163
|
+
initOpts: effectiveOpts,
|
|
164
|
+
processOptions: processOptions,
|
|
165
|
+
}), function() {});
|
|
166
|
+
if (shuttingDown) throw new Error(driver.displayName + " adapter is shutting down");
|
|
167
|
+
acp = new ProcessManagerCtor(binaryPath, processOptions);
|
|
168
|
+
await driverRuntime.callAsync(driver, "registerRequestHandlers", context({ acp: acp }), function() {});
|
|
169
|
+
if (shuttingDown) throw new Error(driver.displayName + " adapter is shutting down");
|
|
170
|
+
await acp.start();
|
|
171
|
+
try {
|
|
172
|
+
if (shuttingDown) throw new Error(driver.displayName + " adapter is shutting down");
|
|
173
|
+
var initializeParams = driverRuntime.buildParams(driver, "buildInitializeParams", context({ acp: acp }), {
|
|
174
|
+
protocolVersion: 1,
|
|
175
|
+
clientInfo: { name: "clay", version: "1.0.0" },
|
|
176
|
+
clientCapabilities: {
|
|
177
|
+
fs: { readTextFile: false, writeTextFile: false },
|
|
178
|
+
session: { configOptions: { boolean: {} } },
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
initResult = await acp.send("initialize", initializeParams, 30000);
|
|
182
|
+
await driverRuntime.callAsync(driver, "onInitialize", context({ acp: acp, initResult: initResult }), function() {});
|
|
183
|
+
if (shuttingDown) throw new Error(driver.displayName + " adapter is shutting down");
|
|
184
|
+
} catch (e) {
|
|
185
|
+
acp.stop();
|
|
186
|
+
acp = null;
|
|
187
|
+
throw e;
|
|
188
|
+
}
|
|
189
|
+
initialized = true;
|
|
190
|
+
lastActiveAt = Date.now();
|
|
191
|
+
return readyResult();
|
|
192
|
+
})().then(function(result) {
|
|
193
|
+
initPromise = null;
|
|
194
|
+
return result;
|
|
195
|
+
}, function(err) {
|
|
196
|
+
initPromise = null;
|
|
197
|
+
initialized = false;
|
|
198
|
+
throw err;
|
|
199
|
+
});
|
|
200
|
+
return initPromise;
|
|
201
|
+
},
|
|
202
|
+
|
|
203
|
+
supportedModels: function() {
|
|
204
|
+
return driverRuntime.callAsync(driver, "supportedModels", context({ models: cachedModels.slice() }), function() {
|
|
205
|
+
if (!fetchModels || !binaryPath) return cachedModels.slice();
|
|
206
|
+
return fetchModels(binaryPath, cwd).then(function(fetched) {
|
|
207
|
+
if (Array.isArray(fetched) && fetched.length) cachedModels = fetched;
|
|
208
|
+
return cachedModels.slice();
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
},
|
|
212
|
+
|
|
213
|
+
createToolServer: function(definition) {
|
|
214
|
+
return driverRuntime.call(driver, "createToolServer", context({ definition: definition }), function() { return null; });
|
|
215
|
+
},
|
|
216
|
+
|
|
217
|
+
createQuery: async function(queryOpts) {
|
|
218
|
+
queryOpts = queryOpts || {};
|
|
219
|
+
if (!initialized || !acp || !acp.started) await adapter.init(queryOpts);
|
|
220
|
+
if (shuttingDown) throw new Error(driver.displayName + " adapter is shutting down");
|
|
221
|
+
var controller = queryOpts.abortController || new AbortController();
|
|
222
|
+
var sharedSkills = skillDiscovery.discoverSkills(queryOpts.cwd || cwd);
|
|
223
|
+
var skillIndex = skillDiscovery.buildSkillIndex(sharedSkills);
|
|
224
|
+
var acpOptions = (queryOpts.adapterOptions && queryOpts.adapterOptions.ACP) || {};
|
|
225
|
+
var handle = null;
|
|
226
|
+
handle = createAcpQueryHandle(acp, {
|
|
227
|
+
vendor: vendor,
|
|
228
|
+
driver: driver,
|
|
229
|
+
cwd: queryOpts.cwd || cwd,
|
|
230
|
+
model: queryOpts.model || defaultModel,
|
|
231
|
+
mode: queryOpts.mode || null,
|
|
232
|
+
systemPrompt: queryOpts.systemPrompt || "",
|
|
233
|
+
appendSystemPrompt: [queryOpts.appendSystemPrompt, skillIndex].filter(function(part) { return !!part; }).join("\n\n"),
|
|
234
|
+
abortController: controller,
|
|
235
|
+
canUseTool: queryOpts.canUseTool || null,
|
|
236
|
+
resumeSessionId: queryOpts.resumeSessionId || null,
|
|
237
|
+
canLoadSession: canLoadSession(),
|
|
238
|
+
canResumeSession: canResumeSession(),
|
|
239
|
+
mcpServers: acpOptions.mcpServers || queryOpts.mcpServers || [],
|
|
240
|
+
onSessionReady: updateModelsFromSession,
|
|
241
|
+
onFinished: function() { removeHandle(handle); },
|
|
242
|
+
});
|
|
243
|
+
activeHandles.push(handle);
|
|
244
|
+
lastActiveAt = Date.now();
|
|
245
|
+
return handle;
|
|
246
|
+
},
|
|
247
|
+
|
|
248
|
+
generateTitle: async function(messages, titleOpts) {
|
|
249
|
+
if (driverRuntime.hasHook(driver, "generateTitle")) {
|
|
250
|
+
return driver.generateTitle(context({ messages: messages, opts: titleOpts }));
|
|
251
|
+
}
|
|
252
|
+
var prompt = "Generate a short descriptive title of 3 to 8 words. Output only the title.\n\n";
|
|
253
|
+
for (var i = 0; i < messages.length; i++) prompt += "User message " + (i + 1) + ": " + messages[i] + "\n";
|
|
254
|
+
var handle = await adapter.createQuery({
|
|
255
|
+
cwd: (titleOpts && titleOpts.cwd) || cwd,
|
|
256
|
+
systemPrompt: "You generate concise conversation titles. Output only the title.",
|
|
257
|
+
canUseTool: function() { return Promise.resolve({ behavior: "deny" }); },
|
|
258
|
+
});
|
|
259
|
+
handle.pushMessage(prompt);
|
|
260
|
+
var title = "";
|
|
261
|
+
try {
|
|
262
|
+
for await (var event of handle) {
|
|
263
|
+
if (event.yokeType === "text_delta" && event.text) title += event.text;
|
|
264
|
+
if (event.yokeType === "result") break;
|
|
265
|
+
}
|
|
266
|
+
} finally {
|
|
267
|
+
handle.close();
|
|
268
|
+
}
|
|
269
|
+
return title.replace(/[\r\n]+/g, " ").replace(/^["'\s]+|["'\s.]+$/g, "").trim();
|
|
270
|
+
},
|
|
271
|
+
|
|
272
|
+
getSessionInfo: function(sessionId, methodOpts) {
|
|
273
|
+
return driverRuntime.callAsync(driver, "getSessionInfo", context({ sessionId: sessionId, opts: methodOpts }), function() { return null; });
|
|
274
|
+
},
|
|
275
|
+
listSessions: function(methodOpts) {
|
|
276
|
+
return driverRuntime.callAsync(driver, "listSessions", context({ opts: methodOpts }), function() { return []; });
|
|
277
|
+
},
|
|
278
|
+
renameSession: function(sessionId, title, methodOpts) {
|
|
279
|
+
return driverRuntime.callAsync(driver, "renameSession", context({ sessionId: sessionId, title: title, opts: methodOpts }), function() {});
|
|
280
|
+
},
|
|
281
|
+
forkSession: function(sessionId, methodOpts) {
|
|
282
|
+
return driverRuntime.callAsync(driver, "forkSession", context({ sessionId: sessionId, opts: methodOpts }), function() { return null; });
|
|
283
|
+
},
|
|
284
|
+
|
|
285
|
+
shutdown: async function() {
|
|
286
|
+
shuttingDown = true;
|
|
287
|
+
var pendingInit = initPromise;
|
|
288
|
+
if (acp) acp.stop();
|
|
289
|
+
if (pendingInit) {
|
|
290
|
+
try { await pendingInit; } catch (e) {}
|
|
291
|
+
}
|
|
292
|
+
var handles = activeHandles.slice();
|
|
293
|
+
for (var i = 0; i < handles.length; i++) handles[i].abort();
|
|
294
|
+
activeHandles = [];
|
|
295
|
+
try {
|
|
296
|
+
if (acp) acp.stop();
|
|
297
|
+
await driverRuntime.callAsync(driver, "onShutdown", context(), function() {});
|
|
298
|
+
} finally {
|
|
299
|
+
acp = null;
|
|
300
|
+
initialized = false;
|
|
301
|
+
shuttingDown = false;
|
|
302
|
+
}
|
|
303
|
+
return true;
|
|
304
|
+
},
|
|
305
|
+
|
|
306
|
+
shutdownIfIdle: function(idleMs) {
|
|
307
|
+
if (!acp || activeHandles.length || Date.now() - lastActiveAt < (idleMs || 0)) return Promise.resolve(false);
|
|
308
|
+
return adapter.shutdown();
|
|
309
|
+
},
|
|
310
|
+
};
|
|
311
|
+
return adapter;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
module.exports = {
|
|
315
|
+
createAcpAdapter: createAcpAdapter,
|
|
316
|
+
modelValues: modelValues,
|
|
317
|
+
};
|