clay-server 5.2.0-beta.4 → 5.2.0-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/account-auth-socket.js +1 -0
- package/lib/builtin-mates.js +17 -14
- package/lib/canonical-clay-record-authority.js +15 -0
- package/lib/canonical-clay-scheduling-authority.js +19 -0
- package/lib/claude-hook-installer.js +1 -239
- package/lib/claude-jsonl-watcher.js +1 -204
- package/lib/clay-mate-chat-receipts.js +26 -0
- package/lib/clay-mate-chat.js +87 -0
- package/lib/clay-mate-knowledge-input.js +26 -0
- package/lib/clay-mate-knowledge.js +95 -0
- package/lib/clay-mate-lifecycle.js +95 -0
- package/lib/clay-product-control-input.js +33 -0
- package/lib/clay-product-control-tools.js +51 -0
- package/lib/clay-product-control.js +237 -0
- package/lib/clay-project-lifecycle.js +154 -0
- package/lib/clay-project-record-input.js +44 -0
- package/lib/clay-project-records.js +83 -0
- package/lib/clay-scheduling-input.js +21 -0
- package/lib/clay-scheduling-receipts.js +26 -0
- package/lib/clay-scheduling.js +119 -0
- package/lib/clay-screen-controls.js +96 -0
- package/lib/clay-skill-install.js +1 -33
- package/lib/clay-workspace-controls.js +83 -0
- package/lib/clay-workspace-input.js +17 -0
- package/lib/clay-workspace-receipts.js +26 -0
- package/lib/cli-sessions.js +1 -300
- package/lib/codex-defaults.js +1 -28
- package/lib/context-usage.js +3 -2
- package/lib/daemon-project-access.js +11 -0
- package/lib/daemon-project-lifecycle-callbacks.js +15 -0
- package/lib/daemon-project-lifecycle.js +262 -0
- package/lib/daemon-projects.js +1 -1
- package/lib/daemon.js +78 -276
- package/lib/default-ai-runtime.js +4 -8
- package/lib/email-mcp-server.js +1 -1
- package/lib/issues-service.js +29 -15
- package/lib/kiro-defaults.js +1 -22
- package/lib/knowledge-db-import.js +5 -4
- package/lib/knowledge-db-service.js +9 -6
- package/lib/knowledge-document-index.js +2 -1
- package/lib/knowledge-product-operations.js +46 -0
- package/lib/mate-creation-mcp-server.js +2 -0
- package/lib/mate-knowledge-canonical-access.js +10 -0
- package/lib/mate-knowledge-service.js +7 -4
- package/lib/mate-lifecycle-service.js +94 -0
- package/lib/mate-message-delivery.js +43 -0
- package/lib/mate-ready-creation.js +9 -1
- package/lib/mate-schedule-input.js +29 -0
- package/lib/mate-schedule-lifecycle.js +151 -0
- package/lib/mate-scheduling.js +103 -0
- package/lib/mates.js +4 -3
- package/lib/mcp-proxy.js +2 -32
- package/lib/mcp-query-bridge.js +1 -1
- package/lib/mcp-source-adapters.js +1 -91
- package/lib/mcp-source-context.js +1 -42
- package/lib/mcp-source-discovery.js +1 -169
- package/lib/mcp-source-plugins.js +1 -68
- package/lib/mcp-source-restrictions.js +1 -47
- package/lib/mcp-tool-policy.js +1 -26
- package/lib/notes-checklist.js +50 -0
- package/lib/notes.js +49 -3
- package/lib/os-user-diagnostics.js +2 -4
- package/lib/os-users.js +24 -70
- package/lib/project-admin-overview.js +51 -0
- package/lib/project-ask-user.js +4 -2
- package/lib/project-connection.js +8 -7
- package/lib/project-delegated-follow-up.js +2 -1
- package/lib/project-directory-claim.js +65 -0
- package/lib/project-file-operations.js +61 -0
- package/lib/project-filesystem.js +13 -87
- package/lib/project-full-access.js +23 -2
- package/lib/project-http.js +4 -4
- package/lib/project-knowledge.js +32 -18
- package/lib/project-lifecycle-operations.js +98 -0
- package/lib/project-lifecycle-process-witness.js +32 -0
- package/lib/project-lifecycle-runtime.js +50 -0
- package/lib/project-linux-access.js +22 -0
- package/lib/project-logs-canonical-clay.js +27 -0
- package/lib/project-logs-clay-query.js +16 -0
- package/lib/project-logs-schema.js +4 -2
- package/lib/project-logs-service.js +8 -7
- package/lib/project-logs.js +1 -0
- package/lib/project-loop.js +1 -0
- package/lib/project-mate-chat-control.js +55 -0
- package/lib/project-mate-creation-proposal.js +18 -3
- package/lib/project-mcp.js +2 -2
- package/lib/project-models.js +14 -31
- package/lib/project-notifications.js +74 -16
- package/lib/project-ownership.js +77 -0
- package/lib/project-pair-result-delivery.js +14 -3
- package/lib/project-pair-usage.js +12 -13
- package/lib/project-pending-message-queue.js +4 -1
- package/lib/project-product-control.js +87 -0
- package/lib/project-product-session-queue.js +46 -0
- package/lib/project-push-access.js +28 -0
- package/lib/project-scheduled-message-queue.js +30 -0
- package/lib/project-scheduled-messages.js +63 -64
- package/lib/project-scheduled-task-control.js +83 -0
- package/lib/project-scheduled-tasks.js +13 -2
- package/lib/project-scheduling-access.js +10 -0
- package/lib/project-session-actions.js +65 -0
- package/lib/project-session-delete.js +8 -1
- package/lib/project-session-github.js +47 -12
- package/lib/project-session-history-actions.js +167 -0
- package/lib/project-session-pair.js +1 -1
- package/lib/project-session-runtime-actions.js +64 -0
- package/lib/project-session-spawn.js +2 -3
- package/lib/project-session-vendor.js +55 -0
- package/lib/project-sessions.js +82 -267
- package/lib/project-user-message.js +31 -1
- package/lib/project-vendor-login.js +6 -36
- package/lib/project-workspace-operations.js +126 -0
- package/lib/project-workspace-query.js +9 -2
- package/lib/project.js +95 -3
- package/lib/public/app.js +1 -0
- package/lib/public/css/clay-tool-activity.css +51 -0
- package/lib/public/css/home-mate-creation.css +5 -0
- package/lib/public/css/messages.css +6 -2
- package/lib/public/css/overlays.css +4 -2
- package/lib/public/css/project-admin-overview.css +13 -0
- package/lib/public/css/session-folders.css +11 -0
- package/lib/public/css/session-github.css +3 -0
- package/lib/public/css/sticky-notes.css +61 -1
- package/lib/public/index.html +1 -1
- package/lib/public/modules/admin-settings-projects.js +6 -2
- package/lib/public/modules/app-connection.js +8 -1
- package/lib/public/modules/app-favicon.js +11 -2
- package/lib/public/modules/app-header.js +4 -2
- package/lib/public/modules/app-loop-ui.js +2 -0
- package/lib/public/modules/app-message-router.js +1 -1
- package/lib/public/modules/app-messages.js +54 -8
- package/lib/public/modules/app-notifications.js +1 -2
- package/lib/public/modules/app-panels.js +61 -123
- package/lib/public/modules/app-projects.js +5 -0
- package/lib/public/modules/app-rate-limit.js +7 -27
- package/lib/public/modules/chat-render-runtime.js +3 -0
- package/lib/public/modules/clay-owner-navigation.js +27 -0
- package/lib/public/modules/clay-tool-activity.js +140 -0
- package/lib/public/modules/clay-tool-presentation.js +338 -0
- package/lib/public/modules/command-palette.js +1 -1
- package/lib/public/modules/default-ai.js +11 -3
- package/lib/public/modules/home-debate-planning.js +5 -5
- package/lib/public/modules/home-mate-chat.js +8 -6
- package/lib/public/modules/home-mate-creation.js +73 -1
- package/lib/public/modules/mcp-connection-view.js +1 -1
- package/lib/public/modules/permission-control.js +5 -4
- package/lib/public/modules/personal-settings-dialog.js +7 -1
- package/lib/public/modules/project-access-recovery.js +17 -0
- package/lib/public/modules/project-admin-overview.js +21 -0
- package/lib/public/modules/scheduler.js +2 -0
- package/lib/public/modules/session-create-form.js +10 -10
- package/lib/public/modules/session-folder-layout.js +1 -1
- package/lib/public/modules/session-folder-view-menu.js +9 -0
- package/lib/public/modules/session-github.js +65 -8
- package/lib/public/modules/settings-defaults.js +27 -28
- package/lib/public/modules/sidebar-session-folders-ui.js +1 -1
- package/lib/public/modules/sticky-note-markdown.js +72 -6
- package/lib/public/modules/sticky-notes-actions.js +30 -0
- package/lib/public/modules/sticky-notes-browser.js +9 -2
- package/lib/public/modules/sticky-notes-card.js +23 -7
- package/lib/public/modules/sticky-notes-checklist.js +71 -0
- package/lib/public/modules/sticky-notes-editor.js +108 -44
- package/lib/public/modules/sticky-notes-shared.js +50 -2
- package/lib/public/modules/sticky-notes-state.js +66 -0
- package/lib/public/modules/sticky-notes.js +34 -51
- package/lib/public/modules/thinking-lifecycle.js +33 -3
- package/lib/public/modules/thinking-view.js +23 -1
- package/lib/public/modules/tools.js +36 -7
- package/lib/public/modules/tui-grab.js +1 -2
- package/lib/public/modules/user-settings-appearance.js +10 -3
- package/lib/public/modules/user-settings-editors.js +1 -1
- package/lib/public/modules/user-settings-layout.js +11 -2
- package/lib/public/modules/user-settings-preferences.js +6 -2
- package/lib/public/modules/user-settings-profile.js +12 -2
- package/lib/public/modules/user-settings.js +3 -2
- package/lib/public/modules/vendor-login-browser.js +5 -3
- package/lib/public/modules/vendor-login.js +2 -2
- package/lib/public/modules/vendor-priority.js +15 -1
- package/lib/public/muse-avatar.svg +4 -0
- package/lib/public/style.css +2 -0
- package/lib/safe-bash-commands.js +3 -45
- package/lib/scheduled-task-records.js +3 -1
- package/lib/scheduler.js +2 -0
- package/lib/sdk-bridge.js +334 -403
- package/lib/sdk-foreground-admission.js +16 -0
- package/lib/sdk-mcp-descriptors.js +2 -37
- package/lib/sdk-message-processor.js +52 -17
- package/lib/sdk-quota-snapshot.js +1 -1
- package/lib/sdk-response-recovery.js +1 -0
- package/lib/sdk-worker.js +2 -677
- package/lib/server-admin.js +63 -16
- package/lib/server-dm.js +1 -1
- package/lib/server-global-ws.js +10 -20
- package/lib/server-home-chat-events.js +7 -3
- package/lib/server-home-chat.js +4 -16
- package/lib/server-home-mate-creation.js +1 -0
- package/lib/server-home-mcp-consent.js +3 -3
- package/lib/server-mates.js +25 -67
- package/lib/server-owner-ui.js +77 -0
- package/lib/server-path-access.js +38 -0
- package/lib/server-project-removal.js +22 -0
- package/lib/server.js +100 -30
- package/lib/session-config-transition.js +45 -0
- package/lib/session-folders.js +7 -2
- package/lib/session-fork-history.js +21 -0
- package/lib/session-github.js +9 -2
- package/lib/session-hygiene.js +3 -35
- package/lib/session-permission-mode.js +4 -3
- package/lib/session-skill-scope.js +11 -0
- package/lib/session-visibility.js +5 -2
- package/lib/sessions.js +27 -89
- package/lib/terminal-manager.js +52 -0
- package/lib/tool-llm.js +1 -1
- package/lib/tui-transcript-index.js +1 -132
- package/lib/users-permissions.js +2 -8
- package/lib/users.js +4 -0
- package/lib/vendor-login-browser.js +1 -11
- package/lib/workspace-query-access.js +4 -1
- package/lib/ws-schema.js +8 -2
- package/lib/yoke/acp-agent-profiles.js +5 -3
- package/lib/yoke/adapters/antigravity.js +3 -14
- package/lib/yoke/adapters/claude-query-contract.js +9 -0
- package/lib/yoke/adapters/claude.js +54 -50
- package/lib/yoke/adapters/codex-query-contract.js +24 -0
- package/lib/yoke/adapters/codex.js +53 -111
- package/lib/yoke/adapters/kiro.js +3 -1
- package/lib/yoke/adapters/muse-query-contract.js +7 -0
- package/lib/yoke/adapters/muse.js +122 -0
- package/lib/yoke/auth-events.js +17 -0
- package/lib/yoke/claude-hook-installer.js +267 -0
- package/lib/yoke/claude-jsonl-watcher.js +204 -0
- package/lib/yoke/claude-maintenance.js +55 -0
- package/lib/yoke/claude-permission-patterns.js +53 -0
- package/lib/yoke/claude-response-recovery.js +155 -0
- package/lib/yoke/claude-transcript-hygiene.js +34 -0
- package/lib/yoke/claude-worker-startup.js +28 -0
- package/lib/yoke/clay-skill-install.js +33 -0
- package/lib/yoke/cli-sessions.js +300 -0
- package/lib/yoke/codex-app-server.js +7 -12
- package/lib/yoke/codex-idle-recovery.js +81 -1
- package/lib/yoke/codex-recovery-admission.js +164 -0
- package/lib/yoke/configuration.js +13 -0
- package/lib/yoke/discovery.js +70 -0
- package/lib/yoke/errors.js +8 -0
- package/lib/yoke/host-environment.js +7 -0
- package/lib/yoke/index.js +9 -51
- package/lib/yoke/interface.js +116 -0
- package/lib/yoke/kiro-acp-server.js +5 -5
- package/lib/yoke/legacy-sessions.js +89 -0
- package/lib/yoke/login-protocol.js +25 -0
- package/lib/yoke/maintenance.js +12 -0
- package/lib/yoke/mcp-proxy.js +32 -0
- package/lib/yoke/mcp-source-adapters.js +91 -0
- package/lib/yoke/mcp-source-context.js +42 -0
- package/lib/yoke/mcp-source-discovery.js +169 -0
- package/lib/yoke/mcp-source-plugins.js +68 -0
- package/lib/yoke/mcp-source-restrictions.js +47 -0
- package/lib/yoke/mcp-tool-policy-normalize.js +28 -0
- package/lib/yoke/model-preferences.js +6 -0
- package/lib/yoke/muse-artifacts.js +36 -0
- package/lib/yoke/muse-controls.js +50 -0
- package/lib/yoke/muse-input.js +64 -0
- package/lib/yoke/muse-items.js +157 -0
- package/lib/yoke/muse-policy.js +52 -0
- package/lib/yoke/muse-query.js +428 -0
- package/lib/yoke/muse-runtime.js +211 -0
- package/lib/yoke/muse-services.js +79 -0
- package/lib/yoke/muse-skills.js +79 -0
- package/lib/yoke/muse-turns.js +71 -0
- package/lib/yoke/options/acp.js +2 -0
- package/lib/yoke/options/antigravity.js +2 -0
- package/lib/yoke/options/claude.js +21 -0
- package/lib/yoke/options/codex-defaults.js +29 -0
- package/lib/yoke/options/codex-settings.js +21 -0
- package/lib/yoke/options/codex.js +6 -0
- package/lib/yoke/options/kiro-defaults.js +22 -0
- package/lib/yoke/options/kiro.js +5 -0
- package/lib/yoke/options/muse.js +5 -0
- package/lib/yoke/provider-contract.js +5 -0
- package/lib/yoke/providers/antigravity-executable.js +8 -0
- package/lib/yoke/providers/claude-executable.js +40 -0
- package/lib/yoke/providers/claude-model-descriptions.js +14 -0
- package/lib/yoke/providers/claude-process.js +97 -0
- package/lib/yoke/providers/claude-provision.js +75 -0
- package/lib/yoke/providers/codex-errors.js +8 -0
- package/lib/yoke/providers/muse-executable.js +17 -0
- package/lib/yoke/provisioning.js +6 -0
- package/lib/yoke/query-options.js +10 -0
- package/lib/yoke/response-recovery.js +41 -0
- package/lib/yoke/sdk-mcp-descriptors.js +37 -0
- package/lib/yoke/sdk-server-factory.js +7 -0
- package/lib/yoke/session-history.js +8 -0
- package/lib/yoke/session-tool-transport.js +34 -13
- package/lib/yoke/settings.js +23 -0
- package/lib/yoke/source-locations.js +4 -0
- package/lib/yoke/title-query.js +18 -7
- package/lib/yoke/tui-transcript-index.js +132 -0
- package/lib/yoke/usage.js +48 -0
- package/lib/yoke/user-input.js +13 -0
- package/lib/yoke/vendor-registry.js +81 -1
- package/package.json +3 -2
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Translate common execution intent at the provider implementation boundary.
|
|
2
|
+
function map(provider, intent) {
|
|
3
|
+
var info = provider && Object.prototype.hasOwnProperty.call(provider, "mapQueryOptions") ? provider : require("./provider-contract").resolve(provider);
|
|
4
|
+
if (info.mapQueryOptions === undefined) return {};
|
|
5
|
+
if (typeof info.mapQueryOptions !== "function") throw new Error("Provider option mapping is unavailable.");
|
|
6
|
+
var options = info.mapQueryOptions(intent || {});
|
|
7
|
+
if (!options || typeof options !== "object" || Array.isArray(options)) throw new Error("Invalid provider option mapping.");
|
|
8
|
+
return options;
|
|
9
|
+
}
|
|
10
|
+
module.exports = { map: map };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Explicit provider implementation, with a live binding to the implementation
|
|
2
|
+
// selected for this session. Stop always reaches the originally bound service.
|
|
3
|
+
function attachResponseRecovery(ctx) {
|
|
4
|
+
var managers = new Map(), bindings = new WeakMap();
|
|
5
|
+
function policy(session) {
|
|
6
|
+
return require('./provider-contract').resolve(ctx.getProvider ? ctx.getProvider(session) : session.vendor || 'claude');
|
|
7
|
+
}
|
|
8
|
+
function manager(session, create) {
|
|
9
|
+
if (!create) return bindings.get(session) || null;
|
|
10
|
+
var factory = policy(session).recoveryFactory;
|
|
11
|
+
var previous = bindings.get(session);
|
|
12
|
+
if (factory === undefined) {
|
|
13
|
+
if (previous) previous.cancel(session);
|
|
14
|
+
bindings.delete(session);
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
if (typeof factory !== 'function') throw new Error('Provider recovery implementation is unavailable.');
|
|
18
|
+
if (!managers.has(factory)) {
|
|
19
|
+
var context = Object.assign({}, ctx, { isCurrentProvider: function(target) { return policy(target).recoveryFactory === factory; } });
|
|
20
|
+
var service = factory(context);
|
|
21
|
+
['begin', 'enqueue', 'event', 'progress', 'cancel', 'current', 'valid', 'stopping', 'dispose'].forEach(function(name) {
|
|
22
|
+
if (!service || typeof service[name] !== 'function') throw new Error('Provider recovery implementation is missing ' + name + '.');
|
|
23
|
+
});
|
|
24
|
+
managers.set(factory, service);
|
|
25
|
+
}
|
|
26
|
+
var selected = managers.get(factory);
|
|
27
|
+
if (previous && previous !== selected) previous.cancel(session);
|
|
28
|
+
bindings.set(session, selected);
|
|
29
|
+
return selected;
|
|
30
|
+
}
|
|
31
|
+
var api = {};
|
|
32
|
+
['begin', 'enqueue', 'event', 'progress', 'cancel', 'current', 'valid', 'stopping'].forEach(function(name) {
|
|
33
|
+
api[name] = function(session) {
|
|
34
|
+
var service = manager(session, name === 'begin' || name === 'enqueue');
|
|
35
|
+
return service ? service[name].apply(service, arguments) : name === 'stopping' || name === 'valid' ? false : null;
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
api.dispose = function() { managers.forEach(function(service) { service.dispose(); }); managers.clear(); bindings = new WeakMap(); };
|
|
39
|
+
return api;
|
|
40
|
+
}
|
|
41
|
+
module.exports = { attachResponseRecovery: attachResponseRecovery };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Extract serializable tool descriptors from MCP server instances.
|
|
2
|
+
// Used for IPC to worker processes (McpSdkServerConfigWithInstance is not serializable).
|
|
3
|
+
function extractMcpDescriptors(mcpServers) {
|
|
4
|
+
if (!mcpServers) return null;
|
|
5
|
+
// Claude's adapter uses Zod v3 for JSON Schema tools; other servers use v4.
|
|
6
|
+
// Use the MCP SDK's version-aware converter for both kinds of registered tool.
|
|
7
|
+
var toJSONSchema = require("@modelcontextprotocol/sdk/server/zod-json-schema-compat.js").toJsonSchemaCompat;
|
|
8
|
+
var descriptors = [];
|
|
9
|
+
var names = Object.keys(mcpServers);
|
|
10
|
+
for (var i = 0; i < names.length; i++) {
|
|
11
|
+
var serverName = names[i];
|
|
12
|
+
var server = mcpServers[serverName];
|
|
13
|
+
if (!server || !server.instance || !server.instance._registeredTools) continue;
|
|
14
|
+
var tools = [];
|
|
15
|
+
var toolNames = Object.keys(server.instance._registeredTools);
|
|
16
|
+
for (var j = 0; j < toolNames.length; j++) {
|
|
17
|
+
var toolName = toolNames[j];
|
|
18
|
+
var toolDef = server.instance._registeredTools[toolName];
|
|
19
|
+
var inputSchema = { type: "object", properties: {} };
|
|
20
|
+
try {
|
|
21
|
+
if (toolDef._clayInputSchema) inputSchema = toolDef._clayInputSchema;
|
|
22
|
+
else if (toolDef.inputSchema) inputSchema = toJSONSchema(toolDef.inputSchema);
|
|
23
|
+
} catch (e) {
|
|
24
|
+
throw new Error("Cannot serialize MCP tool schema " + serverName + "/" + toolName + ": " + e.message);
|
|
25
|
+
}
|
|
26
|
+
tools.push({
|
|
27
|
+
name: toolName,
|
|
28
|
+
description: toolDef.description || toolName,
|
|
29
|
+
inputSchema: inputSchema,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
if (tools.length > 0) descriptors.push({ serverName: serverName, tools: tools });
|
|
33
|
+
}
|
|
34
|
+
return descriptors.length > 0 ? descriptors : null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
module.exports = { extractMcpDescriptors: extractMcpDescriptors };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Shared SDK server envelope; transport projection remains inside YOKE.
|
|
2
|
+
function load() {
|
|
3
|
+
var sdk = require("@anthropic-ai/claude-agent-sdk");
|
|
4
|
+
if (typeof sdk.createSdkMcpServer !== "function" || typeof sdk.tool !== "function") throw new Error("SDK tool server implementation is unavailable.");
|
|
5
|
+
return { createSdkMcpServer: sdk.createSdkMcpServer, tool: sdk.tool };
|
|
6
|
+
}
|
|
7
|
+
module.exports = { load: load };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// A provider fork may return local history or require a provider-owned reader.
|
|
2
|
+
// Absence is an unsupported operation, never an empty successful transcript.
|
|
3
|
+
function read(provider, home, cwd, sessionId) {
|
|
4
|
+
var reader = require("./provider-contract").resolve(provider).readSessionHistory;
|
|
5
|
+
if (typeof reader !== "function") throw new Error("Provider session history reading is unavailable.");
|
|
6
|
+
return reader(home, cwd, sessionId);
|
|
7
|
+
}
|
|
8
|
+
module.exports = { read: read };
|
|
@@ -1,23 +1,39 @@
|
|
|
1
1
|
// Shared production transport facts for query-bound Clay tools.
|
|
2
2
|
|
|
3
3
|
var vendorRegistry = require("./vendor-registry");
|
|
4
|
-
var
|
|
4
|
+
var SCHEDULE_CATALOG_VERSION = 5;
|
|
5
|
+
var MATE_SCHEDULE_TOOLS = ["begin_mate_schedule_interview", "propose_mate_schedule", "list_mate_schedules", "read_mate_schedule", "update_mate_schedule", "cancel_mate_schedule"];
|
|
5
6
|
var SCHEDULE_TOOLS = ["begin_scheduled_task_interview", "propose_scheduled_task", "list_scheduled_tasks", "read_scheduled_task", "update_scheduled_task", "report_scheduled_task_outcome"];
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
// Accept an adapter as well as a registry key. Live adapters can implement the
|
|
9
|
+
// same semantics independently of their name; unknown providers fail closed.
|
|
10
|
+
function contract(provider) {
|
|
11
|
+
if (provider && typeof provider === "object" && provider.queryContract) return provider.queryContract;
|
|
12
|
+
var info = vendorRegistry.getVendorInfo(typeof provider === "string" ? provider : provider && provider.vendor);
|
|
13
|
+
if (info && info.queryContract) return info.queryContract;
|
|
14
|
+
return info && info.sessionBoundTools === true ? { toolTransport: "stdio-mcp", catalogLifetime: "query" } : {};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function capability(provider) {
|
|
18
|
+
var kind = contract(provider).toolTransport || "none";
|
|
19
|
+
if (["sdk-mcp", "dynamic", "stdio-mcp"].indexOf(kind) === -1) kind = "none";
|
|
20
|
+
return { supported: kind !== "none", kind: kind };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function needsRecovery(provider, session, family, version) {
|
|
24
|
+
var policy = contract(provider);
|
|
25
|
+
if (!session.cliSessionId || policy.catalogLifetime !== "conversation") return false;
|
|
26
|
+
if (!family) return true;
|
|
27
|
+
if (typeof policy.catalogVersion !== "function") return true;
|
|
28
|
+
var recorded = policy.catalogVersion(session, family);
|
|
29
|
+
return !Number.isFinite(recorded) || recorded < version;
|
|
13
30
|
}
|
|
14
31
|
|
|
15
32
|
function availableForSession(session) {
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
if (
|
|
19
|
-
|
|
20
|
-
return { available: false, reason: "This Codex conversation predates Clay's scheduled-task tool catalog. Start a new conversation to use the assisted interview; manual task creation remains available here." };
|
|
33
|
+
var provider = session && (session.vendor || "claude");
|
|
34
|
+
if (!capability(provider).supported) return { available: false, reason: "This provider's current Clay adapter does not deliver custom session tools." };
|
|
35
|
+
if (needsRecovery(provider, session, "schedules", SCHEDULE_CATALOG_VERSION)) {
|
|
36
|
+
return { available: false, reason: contract(provider).staleCatalogReason || "This conversation's persisted tool catalog is outdated. Start a new conversation to use the assisted interview." };
|
|
21
37
|
}
|
|
22
38
|
return { available: true, reason: null };
|
|
23
39
|
}
|
|
@@ -38,16 +54,21 @@ function questionToolName(vendor) {
|
|
|
38
54
|
|
|
39
55
|
function bridgeServerForTool(name) {
|
|
40
56
|
if (name === "ask_user_questions") return "yoke-user-input";
|
|
57
|
+
if (MATE_SCHEDULE_TOOLS.indexOf(name) !== -1) return "clay-mate-schedules";
|
|
41
58
|
if (SCHEDULE_TOOLS.indexOf(name) !== -1) return "clay-scheduled-tasks";
|
|
42
59
|
return null;
|
|
43
60
|
}
|
|
44
61
|
|
|
45
62
|
module.exports = {
|
|
63
|
+
contract: contract,
|
|
64
|
+
needsRecovery: needsRecovery,
|
|
46
65
|
capability: capability,
|
|
47
66
|
availableForSession: availableForSession,
|
|
48
|
-
|
|
67
|
+
SCHEDULE_CATALOG_VERSION: SCHEDULE_CATALOG_VERSION,
|
|
68
|
+
CODEX_CATALOG_VERSION: SCHEDULE_CATALOG_VERSION, // Legacy export for existing consumers.
|
|
49
69
|
scheduleToolName: scheduleToolName,
|
|
50
70
|
questionToolName: questionToolName,
|
|
51
71
|
bridgeServerForTool: bridgeServerForTool,
|
|
52
72
|
SCHEDULE_TOOLS: SCHEDULE_TOOLS,
|
|
73
|
+
MATE_SCHEDULE_TOOLS: MATE_SCHEDULE_TOOLS,
|
|
53
74
|
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
function implementations(provider) {
|
|
2
|
+
if (provider) { var policy = require("./provider-contract").resolve(provider); return policy.settings ? [policy.settings] : []; }
|
|
3
|
+
var registry = require("./vendor-registry").VENDOR_REGISTRY;
|
|
4
|
+
return Array.from(new Set(Object.keys(registry).map(function(vendor) { return registry[vendor].settings; }).filter(Boolean)));
|
|
5
|
+
}
|
|
6
|
+
function defaults() {
|
|
7
|
+
var result = {};
|
|
8
|
+
implementations().forEach(function(service) { Object.assign(result, service.defaults()); });
|
|
9
|
+
return result;
|
|
10
|
+
}
|
|
11
|
+
function messages(settings) {
|
|
12
|
+
return implementations().flatMap(function(service) { return service.messages(settings); });
|
|
13
|
+
}
|
|
14
|
+
function change(message, settings, provider) {
|
|
15
|
+
var services = implementations(provider);
|
|
16
|
+
for (var i = 0; i < services.length; i++) {
|
|
17
|
+
if (typeof services[i].change !== "function") throw new Error("Provider settings implementation is unavailable.");
|
|
18
|
+
var result = services[i].change(message, settings);
|
|
19
|
+
if (result) return result;
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
module.exports = { defaults: defaults, messages: messages, change: change };
|
package/lib/yoke/title-query.js
CHANGED
|
@@ -25,12 +25,14 @@ async function generateTitle(adapter, messages, opts, queryOptions) {
|
|
|
25
25
|
opts = opts || {};
|
|
26
26
|
var controller = new AbortController();
|
|
27
27
|
var handle;
|
|
28
|
-
var
|
|
28
|
+
var closing;
|
|
29
29
|
function close() {
|
|
30
|
-
if (handle && !
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
if (handle && !closing) {
|
|
31
|
+
try { closing = Promise.resolve(handle.close()); }
|
|
32
|
+
catch (error) { closing = Promise.reject(error); }
|
|
33
|
+
closing.catch(function () { controller.abort(); });
|
|
33
34
|
}
|
|
35
|
+
return closing;
|
|
34
36
|
}
|
|
35
37
|
var rejectAbort;
|
|
36
38
|
var cancelled = new Promise(function (resolve, reject) { rejectAbort = reject; });
|
|
@@ -39,7 +41,7 @@ async function generateTitle(adapter, messages, opts, queryOptions) {
|
|
|
39
41
|
rejectAbort(new Error("Title request aborted or timed out"));
|
|
40
42
|
close();
|
|
41
43
|
}
|
|
42
|
-
var timer = setTimeout(abort, 30000);
|
|
44
|
+
var timer = setTimeout(abort, opts.timeoutMs || 30000);
|
|
43
45
|
if (opts.signal) opts.signal.addEventListener("abort", abort, { once: true });
|
|
44
46
|
var request = Promise.resolve().then(async function () {
|
|
45
47
|
if (opts.signal && opts.signal.aborted) { abort(); throw new Error("Title request aborted"); }
|
|
@@ -69,12 +71,21 @@ async function generateTitle(adapter, messages, opts, queryOptions) {
|
|
|
69
71
|
}
|
|
70
72
|
throw new Error("Title request ended without a successful result");
|
|
71
73
|
});
|
|
74
|
+
var title;
|
|
75
|
+
var failure;
|
|
72
76
|
try {
|
|
73
|
-
|
|
77
|
+
try { title = await Promise.race([request, cancelled]); }
|
|
78
|
+
catch (error) { failure = error; }
|
|
79
|
+
// Keep the overall deadline armed while cleanup is pending. A late handle
|
|
80
|
+
// still initiates close through the request continuation, with rejection
|
|
81
|
+
// observed by close(), even after this caller has been released.
|
|
82
|
+
try { await Promise.race([close(), cancelled]); }
|
|
83
|
+
catch (error) { if (!failure) failure = error; }
|
|
84
|
+
if (failure) throw failure;
|
|
85
|
+
return title;
|
|
74
86
|
} finally {
|
|
75
87
|
clearTimeout(timer);
|
|
76
88
|
if (opts.signal) opts.signal.removeEventListener("abort", abort);
|
|
77
|
-
close();
|
|
78
89
|
}
|
|
79
90
|
}
|
|
80
91
|
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// tui-transcript-index.js
|
|
2
|
+
//
|
|
3
|
+
// Build a per-session index of assistant text messages from a Claude Code
|
|
4
|
+
// TUI transcript (~/.claude/projects/{encoded-cwd}/{cliSessionId}.jsonl).
|
|
5
|
+
//
|
|
6
|
+
// The TUI message-grab feature uses this index on the client to map a
|
|
7
|
+
// hovered xterm region back to its original markdown source. We only
|
|
8
|
+
// extract assistant text blocks. Tool calls and tool results render in
|
|
9
|
+
// the terminal in a shape that's quite different from their JSONL form,
|
|
10
|
+
// so matching them would be noisy and not particularly useful.
|
|
11
|
+
//
|
|
12
|
+
// Codex sessions don't write transcripts at all; callers should skip
|
|
13
|
+
// indexing for non-claude vendors.
|
|
14
|
+
|
|
15
|
+
var fs = require("fs");
|
|
16
|
+
var path = require("path");
|
|
17
|
+
var utils = require("../utils");
|
|
18
|
+
var { REAL_HOME } = require("../config");
|
|
19
|
+
|
|
20
|
+
var encodeCwd = utils.encodeCwd;
|
|
21
|
+
|
|
22
|
+
// Min length of a normalized assistant message to bother indexing.
|
|
23
|
+
// Anything shorter ("ok", "sure", "yes") would generate too many false
|
|
24
|
+
// positives when matched against a hovered terminal block.
|
|
25
|
+
var MIN_MATCH_LEN = 20;
|
|
26
|
+
|
|
27
|
+
// Claude Code writes its JSONL under the *running user's* home, which
|
|
28
|
+
// is not the daemon's home in OS-isolation mode (where each Clay user
|
|
29
|
+
// gets a real Linux account like /home/clay-name). Callers from the
|
|
30
|
+
// project context resolve the session owner's home and pass it in;
|
|
31
|
+
// when no home is provided we fall back to REAL_HOME for single-user
|
|
32
|
+
// installs.
|
|
33
|
+
function transcriptFilePath(home, cwd, cliSessionId) {
|
|
34
|
+
if (!cwd || !cliSessionId) return null;
|
|
35
|
+
var base = home || REAL_HOME;
|
|
36
|
+
return path.join(base, ".claude", "projects", encodeCwd(cwd), cliSessionId + ".jsonl");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// matchKey is just whitespace-normalized raw markdown. We intentionally
|
|
40
|
+
// do NOT strip markdown decoration here.
|
|
41
|
+
//
|
|
42
|
+
// Reasoning: TUI rendering drops markdown markers (**bold** -> bold,
|
|
43
|
+
// `code` -> code, [text](url) -> text, etc.) and the visible text is
|
|
44
|
+
// therefore always a substring of the JSONL source's character stream.
|
|
45
|
+
// If we strip server-side we risk getting the rules wrong on corner
|
|
46
|
+
// cases (double-backtick code spans, list-bullet rendering quirks,
|
|
47
|
+
// nested formatting) and the resulting matchKey diverges from both
|
|
48
|
+
// sides at once. Leaving the source alone and letting the client do a
|
|
49
|
+
// multi-offset substring probe against block text is more robust and
|
|
50
|
+
// much less code.
|
|
51
|
+
function normalizeForMatch(s) {
|
|
52
|
+
if (!s) return "";
|
|
53
|
+
return s.replace(/\s+/g, " ").trim();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Stable per-message id. Claude's JSONL usually carries one of these but
|
|
57
|
+
// fall back to the parsed line index so the client always has a handle.
|
|
58
|
+
function messageId(obj, index) {
|
|
59
|
+
if (obj && obj.uuid) return String(obj.uuid);
|
|
60
|
+
if (obj && obj.message && obj.message.id) return String(obj.message.id);
|
|
61
|
+
return "msg-" + index;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Parse a single JSONL line into one assistant-text record, or null
|
|
65
|
+
// when the line isn't one we index (user prompts, tool_use blocks,
|
|
66
|
+
// tool_result records, etc.). Text-only assistant blocks get joined
|
|
67
|
+
// in order so a multi-block response surfaces as a single grabbable
|
|
68
|
+
// message.
|
|
69
|
+
function parseAssistantTextLine(line, index) {
|
|
70
|
+
var obj;
|
|
71
|
+
try { obj = JSON.parse(line); } catch (e) { return null; }
|
|
72
|
+
if (!obj || !obj.message) return null;
|
|
73
|
+
if (obj.message.role !== "assistant") return null;
|
|
74
|
+
if (!Array.isArray(obj.message.content)) return null;
|
|
75
|
+
|
|
76
|
+
var text = "";
|
|
77
|
+
for (var i = 0; i < obj.message.content.length; i++) {
|
|
78
|
+
var block = obj.message.content[i];
|
|
79
|
+
if (block && block.type === "text" && typeof block.text === "string") {
|
|
80
|
+
text += block.text;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
text = text.trim();
|
|
84
|
+
if (!text) return null;
|
|
85
|
+
|
|
86
|
+
var normalized = normalizeForMatch(text);
|
|
87
|
+
if (normalized.length < MIN_MATCH_LEN) return null;
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
id: messageId(obj, index),
|
|
91
|
+
text: text,
|
|
92
|
+
matchKey: normalized,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Read the whole transcript and return the assistant text index. The
|
|
97
|
+
// transcripts are small enough (KB to a few MB) that a sync read on
|
|
98
|
+
// session open or on a watcher-driven update is fine. We also return
|
|
99
|
+
// the mtime/size so callers can short-circuit re-reads when nothing
|
|
100
|
+
// changed.
|
|
101
|
+
function readAssistantIndex(home, cwd, cliSessionId) {
|
|
102
|
+
var file = transcriptFilePath(home, cwd, cliSessionId);
|
|
103
|
+
if (!file) return { messages: [], mtimeMs: 0, byteLength: 0 };
|
|
104
|
+
var raw;
|
|
105
|
+
var stat;
|
|
106
|
+
try {
|
|
107
|
+
raw = fs.readFileSync(file, "utf8");
|
|
108
|
+
stat = fs.statSync(file);
|
|
109
|
+
} catch (e) {
|
|
110
|
+
return { messages: [], mtimeMs: 0, byteLength: 0 };
|
|
111
|
+
}
|
|
112
|
+
var lines = raw.split("\n");
|
|
113
|
+
var messages = [];
|
|
114
|
+
for (var i = 0; i < lines.length; i++) {
|
|
115
|
+
if (!lines[i]) continue;
|
|
116
|
+
var entry = parseAssistantTextLine(lines[i], i);
|
|
117
|
+
if (entry) messages.push(entry);
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
messages: messages,
|
|
121
|
+
mtimeMs: stat.mtimeMs || 0,
|
|
122
|
+
byteLength: stat.size || raw.length,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
module.exports = {
|
|
127
|
+
MIN_MATCH_LEN: MIN_MATCH_LEN,
|
|
128
|
+
transcriptFilePath: transcriptFilePath,
|
|
129
|
+
readAssistantIndex: readAssistantIndex,
|
|
130
|
+
parseAssistantTextLine: parseAssistantTextLine,
|
|
131
|
+
normalizeForMatch: normalizeForMatch,
|
|
132
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
function number() {
|
|
2
|
+
for (var i = 0; i < arguments.length; i++) if (typeof arguments[i] === 'number' && Number.isFinite(arguments[i]) && arguments[i] >= 0) return arguments[i];
|
|
3
|
+
return null;
|
|
4
|
+
}
|
|
5
|
+
function accounting(value) {
|
|
6
|
+
if (!value) return null;
|
|
7
|
+
return Object.assign({}, value, { inputTokens: number(value.inputTokens, value.input_tokens), outputTokens: number(value.outputTokens, value.output_tokens),
|
|
8
|
+
cacheReadInputTokens: number(value.cacheReadInputTokens, value.cache_read_input_tokens), cacheCreationInputTokens: number(value.cacheCreationInputTokens, value.cache_creation_input_tokens) });
|
|
9
|
+
}
|
|
10
|
+
function validateProjection(value) {
|
|
11
|
+
value = value || {};
|
|
12
|
+
var used = number(value.usedTokens), window = number(value.windowTokens);
|
|
13
|
+
var measurement = ['observed', 'estimated', 'unavailable'].indexOf(value.measurement) >= 0 ? value.measurement : 'unavailable';
|
|
14
|
+
var inflated = used !== null && window !== null && used > window;
|
|
15
|
+
if (inflated || used === null || measurement === 'unavailable') { used = null; measurement = 'unavailable'; }
|
|
16
|
+
return { usedTokens: used, windowTokens: window, measurement: measurement, source: inflated || measurement === 'unavailable' && window === null ? 'unavailable' : typeof value.source === 'string' ? value.source : 'unavailable' };
|
|
17
|
+
}
|
|
18
|
+
function context(value, provider) {
|
|
19
|
+
if (!value) return null;
|
|
20
|
+
if (value.context && value.context.measurement) return Object.assign({}, value, { context: validateProjection(value.context) });
|
|
21
|
+
var policy = require('./provider-contract').resolve(provider);
|
|
22
|
+
var projection = typeof policy.normalizeContext === 'function' ? policy.normalizeContext(value) : { usedTokens: null, windowTokens: null, measurement: 'unavailable', source: 'unavailable' };
|
|
23
|
+
return Object.assign({}, value, { context: validateProjection(projection) });
|
|
24
|
+
}
|
|
25
|
+
function sdkContext(value) { return { usedTokens: number(value.totalTokens), windowTokens: number(value.maxTokens), measurement: value.unavailable ? 'unavailable' : value.measurement === 'estimated' ? 'estimated' : 'observed', source: 'claude_sdk_context_usage' }; }
|
|
26
|
+
function tokenContext(value) { return { usedTokens: number(value.input_tokens), windowTokens: number(value.contextWindow), measurement: value.unavailable ? 'unavailable' : value.measurement === 'estimated' ? 'estimated' : 'observed', source: 'adapter_context_usage' }; }
|
|
27
|
+
function turnContext(event) {
|
|
28
|
+
var models = event.modelUsage || {}, entries = Object.keys(models);
|
|
29
|
+
var result = { usedTokens: null, windowTokens: null, measurement: 'unavailable', source: 'unavailable' };
|
|
30
|
+
for (var i = 0; i < entries.length; i++) {
|
|
31
|
+
var value = models[entries[i]], snapshot = value.contextSnapshot;
|
|
32
|
+
if (snapshot) return { usedTokens: snapshot.valid === true ? number(snapshot.inputTokens) : null, windowTokens: number(snapshot.contextWindow, value.contextWindow), measurement: snapshot.valid === true ? 'observed' : 'unavailable', source: 'last_turn' };
|
|
33
|
+
result.windowTokens = number(value.contextWindow, result.windowTokens);
|
|
34
|
+
}
|
|
35
|
+
// Per-query accounting can contain many API calls. Never use its sum as
|
|
36
|
+
// current occupancy. Only an actual last-call measurement is a valid estimate.
|
|
37
|
+
result.usedTokens = number(event.lastStreamInputTokens);
|
|
38
|
+
if (result.usedTokens !== null) { result.measurement = 'estimated'; result.source = 'last_call'; }
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
function clientEvent(event, provider) {
|
|
42
|
+
if (!event) return event;
|
|
43
|
+
var info = require('./provider-contract').resolve(provider);
|
|
44
|
+
if ((event.type === 'rate_limit' || event.type === 'rate_limit_usage') && !event.source && info.requiresQuotaSource) return Object.assign({}, event, { ignored: true });
|
|
45
|
+
if (event.type !== 'result') return event;
|
|
46
|
+
return Object.assign({}, event, { usage: accounting(event.usage), context: validateProjection(event.context || turnContext(event)) });
|
|
47
|
+
}
|
|
48
|
+
module.exports = { number: number, accounting: accounting, context: context, sdkContext: sdkContext, tokenContext: tokenContext, turnContext: turnContext, clientEvent: clientEvent };
|
package/lib/yoke/user-input.js
CHANGED
|
@@ -246,6 +246,7 @@ function capability(adapter) {
|
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
function selectMode(adapter, requestedMode) {
|
|
249
|
+
if (requestedMode !== undefined && ["auto", "native", "fallback"].indexOf(requestedMode) < 0) throw new Error("Unsupported structured input mode.");
|
|
249
250
|
if (requestedMode === "fallback") return "fallback";
|
|
250
251
|
if (requestedMode === "native" && capability(adapter).mode !== "native") {
|
|
251
252
|
throw new Error("This provider does not support native structured user input.");
|
|
@@ -260,7 +261,19 @@ function createFallbackServer(adapter, handler) {
|
|
|
260
261
|
return adapter.createToolServer({ name: "yoke-user-input", version: "1.0.0", tools: fallbackToolDefs(handler, opts) });
|
|
261
262
|
}
|
|
262
263
|
|
|
264
|
+
// AskUserQuestion is also the normalized legacy question-tool identity in
|
|
265
|
+
// stored Clay transcripts. Adapters may translate another native shape.
|
|
266
|
+
function toolQuestions(adapter, name, input) {
|
|
267
|
+
var contract = require("./session-tool-transport").contract(adapter);
|
|
268
|
+
if (typeof contract.questionInput === "function") {
|
|
269
|
+
var nativeInput = contract.questionInput(name, input);
|
|
270
|
+
if (nativeInput) return nativeInput;
|
|
271
|
+
}
|
|
272
|
+
return name === "AskUserQuestion" || name === TOOL_NAME ? input : null;
|
|
273
|
+
}
|
|
274
|
+
|
|
263
275
|
module.exports = {
|
|
276
|
+
toolQuestions: toolQuestions,
|
|
264
277
|
TOOL_NAME: TOOL_NAME,
|
|
265
278
|
normalizeQuestions: normalizeQuestions,
|
|
266
279
|
questionsFromElicitation: questionsFromElicitation,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Static, init-free facts about each vendor YOKE supports. Host code that
|
|
2
2
|
// needs metadata before adapter initialization should read it from here.
|
|
3
|
-
//
|
|
3
|
+
// Only init-free contract data may be imported here; never runtime adapters.
|
|
4
4
|
|
|
5
5
|
// Canonical effort ordering used to clamp a level onto a vendor that does
|
|
6
6
|
// not support it (e.g. codex "minimal" -> claude "low", claude "max" ->
|
|
@@ -10,6 +10,26 @@ var EFFORT_ORDER = ["minimal", "low", "medium", "high", "xhigh", "max"];
|
|
|
10
10
|
// sessionBoundTools gates whether per-session MCP tool mounting reaches a vendor's process.
|
|
11
11
|
var VENDOR_REGISTRY = {
|
|
12
12
|
claude: {
|
|
13
|
+
readSessionHistory: require("./cli-sessions").readCliSessionHistory,
|
|
14
|
+
terminalResumeCommand: "claude --resume",
|
|
15
|
+
planPathSegments: [".claude/plans/"],
|
|
16
|
+
notificationHooks: require("./claude-hook-installer"),
|
|
17
|
+
maintenance: require("./claude-maintenance"),
|
|
18
|
+
credentialDirectories: [".claude"],
|
|
19
|
+
preferredModelFamilies: ["opus", "sonnet", "haiku"],
|
|
20
|
+
provisionUser: require("./providers/claude-provision").attachProvisioning,
|
|
21
|
+
configuration: require("./configuration").claude,
|
|
22
|
+
normalizeContext: require("./usage").sdkContext, authenticationReply: require("./auth-events").authenticationReply,
|
|
23
|
+
rateLimitScheduling: true, acceptsUnstampedQuota: true,
|
|
24
|
+
terminalLoginCommand: "claude auth login", browserLoginCommand: "claude auth login",
|
|
25
|
+
oauthHosts: ["claude.ai", "claude.com", "console.anthropic.com", "platform.claude.com"],
|
|
26
|
+
resolveExecutable: require("./discovery").bundledResolver(function() { return require("./providers/claude-executable").resolve(); }, "claude"),
|
|
27
|
+
processControl: require("./providers/claude-process"),
|
|
28
|
+
prepareIsolation: require("./providers/claude-process").prepareIsolation,
|
|
29
|
+
recoveryFactory: require("./claude-response-recovery").attachResponseRecovery,
|
|
30
|
+
supportsLegacyGuiResume: function(session) { return !!session.cliSessionId; },
|
|
31
|
+
mapQueryOptions: require("./options/claude").map,
|
|
32
|
+
queryContract: require("./adapters/claude-query-contract"),
|
|
13
33
|
displayName: "Claude Code",
|
|
14
34
|
loginCommand: "claude login",
|
|
15
35
|
binaryName: "claude",
|
|
@@ -27,6 +47,16 @@ var VENDOR_REGISTRY = {
|
|
|
27
47
|
rateLimitTracking: true,
|
|
28
48
|
},
|
|
29
49
|
codex: {
|
|
50
|
+
credentialDirectories: [".codex"],
|
|
51
|
+
preferredModelFamilies: ["astra", "sol", "gpt", "o"],
|
|
52
|
+
classifyError: require("./providers/codex-errors").classify,
|
|
53
|
+
settings: require("./options/codex-settings"),
|
|
54
|
+
configuration: require("./configuration").codex,
|
|
55
|
+
normalizeContext: require("./usage").tokenContext, requiresQuotaSource: true,
|
|
56
|
+
browserLoginCommand: "codex login", oauthHosts: ["auth.openai.com"],
|
|
57
|
+
resolveExecutable: require("./discovery").bundledResolver(function() { return require("./codex-app-server").findCodexPath(); }, "codex"),
|
|
58
|
+
mapQueryOptions: require("./options/codex").map,
|
|
59
|
+
queryContract: require("./adapters/codex-query-contract"),
|
|
30
60
|
displayName: "Codex",
|
|
31
61
|
loginCommand: "codex login --device-auth",
|
|
32
62
|
binaryName: "codex",
|
|
@@ -43,7 +73,27 @@ var VENDOR_REGISTRY = {
|
|
|
43
73
|
},
|
|
44
74
|
rateLimitTracking: true,
|
|
45
75
|
},
|
|
76
|
+
muse: {
|
|
77
|
+
displayName: "Muse Code",
|
|
78
|
+
loginCommand: "muse",
|
|
79
|
+
binaryName: "muse",
|
|
80
|
+
avatar: "/muse-avatar.svg",
|
|
81
|
+
sessionModes: ["gui"],
|
|
82
|
+
effortLevels: ["none", "minimal", "low", "medium", "high", "xhigh", "max", "ultra"],
|
|
83
|
+
osUserIsolation: false,
|
|
84
|
+
sessionBoundTools: true,
|
|
85
|
+
usageDashboard: null,
|
|
86
|
+
rateLimitTracking: false,
|
|
87
|
+
forkHistoryBoundary: "completed-turn-inclusive",
|
|
88
|
+
resolveExecutable: require("./providers/muse-executable").resolve,
|
|
89
|
+
mapQueryOptions: require("./options/muse").map,
|
|
90
|
+
queryContract: require("./adapters/muse-query-contract"),
|
|
91
|
+
normalizeContext: require("./usage").tokenContext,
|
|
92
|
+
configuration: { auto: true, permissionModes: [{ value: "default", label: "Ask" }] },
|
|
93
|
+
},
|
|
46
94
|
antigravity: {
|
|
95
|
+
resolveExecutable: require("./providers/antigravity-executable").resolve,
|
|
96
|
+
mapQueryOptions: require("./options/antigravity").map,
|
|
47
97
|
displayName: "Antigravity CLI",
|
|
48
98
|
loginCommand: "agy",
|
|
49
99
|
binaryName: "agy",
|
|
@@ -56,6 +106,8 @@ var VENDOR_REGISTRY = {
|
|
|
56
106
|
rateLimitTracking: false,
|
|
57
107
|
},
|
|
58
108
|
opencode: {
|
|
109
|
+
resolveExecutable: require("./discovery").acpResolver("opencode"),
|
|
110
|
+
mapQueryOptions: require("./options/acp").map,
|
|
59
111
|
displayName: "OpenCode",
|
|
60
112
|
loginCommand: "opencode auth login",
|
|
61
113
|
binaryName: "opencode",
|
|
@@ -68,6 +120,8 @@ var VENDOR_REGISTRY = {
|
|
|
68
120
|
rateLimitTracking: false,
|
|
69
121
|
},
|
|
70
122
|
kimi: {
|
|
123
|
+
resolveExecutable: require("./discovery").acpResolver("kimi"),
|
|
124
|
+
mapQueryOptions: require("./options/acp").map,
|
|
71
125
|
displayName: "Kimi Code",
|
|
72
126
|
loginCommand: "kimi login",
|
|
73
127
|
binaryName: "kimi",
|
|
@@ -80,6 +134,8 @@ var VENDOR_REGISTRY = {
|
|
|
80
134
|
rateLimitTracking: false,
|
|
81
135
|
},
|
|
82
136
|
grok: {
|
|
137
|
+
resolveExecutable: require("./discovery").acpResolver("grok"),
|
|
138
|
+
mapQueryOptions: require("./options/acp").map,
|
|
83
139
|
displayName: "Grok Build",
|
|
84
140
|
loginCommand: "grok login --device-auth",
|
|
85
141
|
binaryName: "grok",
|
|
@@ -92,6 +148,8 @@ var VENDOR_REGISTRY = {
|
|
|
92
148
|
rateLimitTracking: false,
|
|
93
149
|
},
|
|
94
150
|
copilot: {
|
|
151
|
+
resolveExecutable: require("./discovery").acpResolver("copilot"),
|
|
152
|
+
mapQueryOptions: require("./options/acp").map,
|
|
95
153
|
displayName: "GitHub Copilot CLI",
|
|
96
154
|
loginCommand: "copilot login",
|
|
97
155
|
binaryName: "copilot",
|
|
@@ -104,6 +162,8 @@ var VENDOR_REGISTRY = {
|
|
|
104
162
|
rateLimitTracking: false,
|
|
105
163
|
},
|
|
106
164
|
qwen: {
|
|
165
|
+
resolveExecutable: require("./discovery").acpResolver("qwen"),
|
|
166
|
+
mapQueryOptions: require("./options/acp").map,
|
|
107
167
|
displayName: "Qwen Code",
|
|
108
168
|
loginCommand: "qwen",
|
|
109
169
|
binaryName: "qwen",
|
|
@@ -116,6 +176,8 @@ var VENDOR_REGISTRY = {
|
|
|
116
176
|
rateLimitTracking: false,
|
|
117
177
|
},
|
|
118
178
|
junie: {
|
|
179
|
+
resolveExecutable: require("./discovery").acpResolver("junie"),
|
|
180
|
+
mapQueryOptions: require("./options/acp").map,
|
|
119
181
|
displayName: "Junie CLI",
|
|
120
182
|
loginCommand: "junie",
|
|
121
183
|
binaryName: "junie",
|
|
@@ -128,6 +190,9 @@ var VENDOR_REGISTRY = {
|
|
|
128
190
|
rateLimitTracking: false,
|
|
129
191
|
},
|
|
130
192
|
kiro: {
|
|
193
|
+
normalizeContext: require("./usage").tokenContext,
|
|
194
|
+
resolveExecutable: require("./discovery").bundledResolver(function() { return require("./kiro-acp-server").findKiroPath(); }, "kiro-cli"),
|
|
195
|
+
mapQueryOptions: require("./options/kiro").map,
|
|
131
196
|
displayName: "Kiro CLI",
|
|
132
197
|
loginCommand: "kiro-cli login",
|
|
133
198
|
binaryName: "kiro-cli",
|
|
@@ -169,7 +234,22 @@ function clampEffort(vendor, effort) {
|
|
|
169
234
|
return nearest;
|
|
170
235
|
}
|
|
171
236
|
|
|
237
|
+
// Publish only serializable product descriptions, never backend services.
|
|
238
|
+
function publicInfo() {
|
|
239
|
+
var result = {};
|
|
240
|
+
Object.keys(VENDOR_REGISTRY).forEach(function(vendor) {
|
|
241
|
+
var info = VENDOR_REGISTRY[vendor], entry = {};
|
|
242
|
+
["displayName", "terminalResumeCommand", "planPathSegments", "loginCommand", "binaryName", "avatar", "sessionModes", "effortLevels", "osUserIsolation", "sessionBoundTools", "usageDashboard", "rateLimitTracking", "rateLimitScheduling", "acceptsUnstampedQuota", "configuration"].forEach(function(key) {
|
|
243
|
+
if (info[key] !== undefined) entry[key] = info[key];
|
|
244
|
+
});
|
|
245
|
+
entry.browserLoginSupported = typeof info.browserLoginCommand === "string" && Array.isArray(info.oauthHosts) && info.oauthHosts.length > 0;
|
|
246
|
+
result[vendor] = entry;
|
|
247
|
+
});
|
|
248
|
+
return result;
|
|
249
|
+
}
|
|
250
|
+
|
|
172
251
|
module.exports = {
|
|
252
|
+
publicInfo: publicInfo,
|
|
173
253
|
VENDOR_REGISTRY: VENDOR_REGISTRY,
|
|
174
254
|
getVendorInfo: getVendorInfo,
|
|
175
255
|
clampEffort: clampEffort,
|