clay-server 4.1.0-beta.8 → 4.1.0
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/context-usage.js +47 -0
- package/lib/issues-mcp-server.js +1 -1
- package/lib/issues-service.js +3 -1
- package/lib/loop-registry-occurrence.js +1 -0
- package/lib/notes.js +20 -3
- package/lib/os-users.js +6 -0
- package/lib/project-connection.js +14 -3
- package/lib/project-file-path.js +13 -0
- package/lib/project-file-watch.js +19 -8
- package/lib/project-filesystem.js +10 -16
- package/lib/project-http.js +53 -48
- package/lib/project-logs-mcp-server.js +8 -8
- package/lib/project-logs-schema.js +1 -1
- package/lib/project-logs-service.js +46 -13
- package/lib/project-logs-store.js +17 -15
- package/lib/project-logs.js +70 -0
- package/lib/project-loop.js +1 -0
- package/lib/project-notifications.js +1 -1
- package/lib/project-pending-message-queue.js +71 -7
- package/lib/project-scheduled-messages.js +235 -52
- package/lib/project-scheduled-result-store.js +131 -0
- package/lib/project-scheduled-task-execution.js +35 -2
- package/lib/project-session-notes.js +11 -4
- package/lib/project-sessions.js +7 -0
- package/lib/project-user-message.js +72 -5
- package/lib/project.js +60 -5
- package/lib/public/app.js +27 -12
- package/lib/public/css/avatar-imprints.css +1 -1
- package/lib/public/css/command-palette.css +20 -0
- package/lib/public/css/git-panel.css +13 -12
- package/lib/public/css/git-placard.css +4 -4
- package/lib/public/css/input.css +0 -109
- package/lib/public/css/issues.css +78 -31
- package/lib/public/css/mobile-nav.css +7 -0
- package/lib/public/css/notifications-center.css +3 -3
- package/lib/public/css/pending-message-queue.css +3 -0
- package/lib/public/css/project-logs.css +15 -0
- package/lib/public/css/sidebar.css +7 -0
- package/lib/public/css/sticky-notes.css +29 -0
- package/lib/public/modules/app-connection.js +9 -1
- package/lib/public/modules/app-favicon.js +10 -0
- package/lib/public/modules/app-messages.js +49 -37
- package/lib/public/modules/app-notifications.js +2 -0
- package/lib/public/modules/app-panels.js +77 -23
- package/lib/public/modules/app-projects.js +3 -0
- package/lib/public/modules/app-rate-limit.js +148 -243
- package/lib/public/modules/avatar-imprint.js +25 -70
- package/lib/public/modules/avatar.js +12 -4
- package/lib/public/modules/chat-render-runtime.js +20 -2
- package/lib/public/modules/clay-issue-links.js +23 -2
- package/lib/public/modules/clay-log-links.js +11 -1
- package/lib/public/modules/context-view-preference.js +143 -0
- package/lib/public/modules/default-vendor.js +116 -0
- package/lib/public/modules/filebrowser-tabs.js +1 -0
- package/lib/public/modules/filebrowser.js +45 -18
- package/lib/public/modules/input.js +81 -20
- package/lib/public/modules/issues-render.js +36 -10
- package/lib/public/modules/issues.js +95 -13
- package/lib/public/modules/markdown.js +3 -1
- package/lib/public/modules/pane-bridge.js +14 -8
- package/lib/public/modules/pane-issue-bridge.js +27 -0
- package/lib/public/modules/pending-message-queue.js +43 -1
- package/lib/public/modules/permission-hints.js +13 -0
- package/lib/public/modules/profile.js +9 -9
- package/lib/public/modules/project-activation.js +49 -0
- package/lib/public/modules/project-logs-render.js +13 -3
- package/lib/public/modules/project-logs.js +45 -15
- package/lib/public/modules/right-workbench.js +44 -0
- package/lib/public/modules/scheduled-message-state.js +12 -36
- package/lib/public/modules/scheduled-result-client.js +33 -0
- package/lib/public/modules/scheduled-result-display.js +50 -0
- package/lib/public/modules/scheduled-result-notification.js +31 -0
- package/lib/public/modules/scheduled-task-presentation.js +15 -0
- package/lib/public/modules/scheduled-tasks.js +9 -21
- package/lib/public/modules/sidebar-mobile.js +51 -3
- package/lib/public/modules/sidebar-sessions.js +65 -5
- package/lib/public/modules/split-session-boundary.js +28 -0
- package/lib/public/modules/split-view.js +42 -7
- package/lib/public/modules/sticky-notes-browser.js +130 -18
- package/lib/public/modules/sticky-notes.js +2 -3
- package/lib/public/modules/terminal.js +4 -4
- package/lib/public/modules/thinking-lifecycle.js +4 -1
- package/lib/public/modules/tools.js +5 -1
- package/lib/scheduled-run-state.js +10 -2
- package/lib/scheduler.js +1 -0
- package/lib/sdk-bridge.js +97 -61
- package/lib/sdk-message-processor.js +44 -13
- package/lib/sdk-skill-discovery.js +6 -28
- package/lib/sdk-turn-queue.js +14 -0
- package/lib/server-context-view.js +53 -0
- package/lib/server-default-vendor.js +60 -0
- package/lib/server.js +23 -6
- package/lib/session-notes-mcp-server.js +3 -5
- package/lib/session-pair-factory.js +2 -2
- package/lib/session-pair-mcp-server.js +5 -4
- package/lib/session-title-generator.js +89 -0
- package/lib/session-title-policy.js +8 -2
- package/lib/sessions.js +26 -1
- package/lib/user-presence.js +6 -0
- package/lib/users-context-view-preferences.js +65 -0
- package/lib/users-default-vendor-preferences.js +80 -0
- package/lib/users.js +12 -0
- package/lib/ws-schema.js +11 -0
- package/lib/yoke/acp-agent-profiles.js +15 -2
- package/lib/yoke/adapters/acp.js +3 -2
- package/lib/yoke/adapters/antigravity.js +2 -2
- package/lib/yoke/adapters/claude-worker.js +11 -12
- package/lib/yoke/adapters/claude.js +75 -22
- package/lib/yoke/adapters/codex.js +216 -29
- package/lib/yoke/adapters/kiro.js +6 -5
- package/lib/yoke/claude-context-usage.js +57 -0
- package/lib/yoke/claude-message-correlation.js +31 -0
- package/lib/yoke/claude-model-switch.js +15 -0
- package/lib/yoke/index.js +5 -1
- package/lib/yoke/mcp-bridge-server.js +18 -5
- package/lib/yoke/session-skill-catalog.js +45 -0
- package/lib/yoke/skill-discovery.js +60 -20
- package/lib/yoke/vendor-registry.js +1 -1
- package/package.json +5 -7
|
@@ -58,6 +58,7 @@ var CLAY_MCP_PATH = claySlug
|
|
|
58
58
|
|
|
59
59
|
// --- Auth ---
|
|
60
60
|
var clayAuthToken = process.env.CLAY_AUTH_TOKEN || "";
|
|
61
|
+
var clayBridgeToken = process.env.CLAY_BRIDGE_TOKEN || "";
|
|
61
62
|
|
|
62
63
|
// --- Tool cache ---
|
|
63
64
|
var _tools = []; // [{ server, name, description, inputSchema }]
|
|
@@ -79,6 +80,7 @@ function postJson(urlPath, body) {
|
|
|
79
80
|
if (clayAuthToken) {
|
|
80
81
|
headers["Cookie"] = "relay_auth=" + clayAuthToken;
|
|
81
82
|
}
|
|
83
|
+
if (clayBridgeToken) headers["X-Clay-Bridge-Token"] = clayBridgeToken;
|
|
82
84
|
|
|
83
85
|
var reqOpts = {
|
|
84
86
|
hostname: parsed.hostname,
|
|
@@ -95,6 +97,15 @@ function postJson(urlPath, body) {
|
|
|
95
97
|
res.on("data", function (chunk) { chunks.push(chunk); });
|
|
96
98
|
res.on("end", function () {
|
|
97
99
|
var respBody = Buffer.concat(chunks).toString("utf8");
|
|
100
|
+
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
101
|
+
var statusError = "Clay MCP bridge HTTP " + res.statusCode;
|
|
102
|
+
try {
|
|
103
|
+
var errorBody = JSON.parse(respBody);
|
|
104
|
+
if (errorBody && errorBody.error) statusError += ": " + errorBody.error;
|
|
105
|
+
} catch (e) {}
|
|
106
|
+
reject(new Error(statusError));
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
98
109
|
try {
|
|
99
110
|
resolve(JSON.parse(respBody));
|
|
100
111
|
} catch (e) {
|
|
@@ -122,8 +133,7 @@ function postJson(urlPath, body) {
|
|
|
122
133
|
function fetchTools() {
|
|
123
134
|
return postJson(CLAY_MCP_PATH, { action: "list_tools", sessionId: claySessionId, queryGeneration: clayQueryGeneration, sessionOnly: sessionOnly }).then(function (resp) {
|
|
124
135
|
if (resp.error) {
|
|
125
|
-
|
|
126
|
-
return [];
|
|
136
|
+
throw new Error(resp.error);
|
|
127
137
|
}
|
|
128
138
|
_tools = resp.tools || [];
|
|
129
139
|
_toolsFetched = true;
|
|
@@ -135,7 +145,8 @@ function fetchTools() {
|
|
|
135
145
|
return _tools;
|
|
136
146
|
}).catch(function (err) {
|
|
137
147
|
log("Error fetching tools: " + err.message);
|
|
138
|
-
|
|
148
|
+
_toolsFetched = false;
|
|
149
|
+
throw err;
|
|
139
150
|
});
|
|
140
151
|
}
|
|
141
152
|
|
|
@@ -194,7 +205,7 @@ function handleInitialize(id, params) {
|
|
|
194
205
|
});
|
|
195
206
|
|
|
196
207
|
// Pre-fetch tools after handshake
|
|
197
|
-
fetchTools();
|
|
208
|
+
fetchTools().catch(function () {});
|
|
198
209
|
}
|
|
199
210
|
|
|
200
211
|
function handleToolsList(id, params) {
|
|
@@ -210,7 +221,9 @@ function handleToolsList(id, params) {
|
|
|
210
221
|
}
|
|
211
222
|
|
|
212
223
|
// Always re-fetch: remote MCP servers may connect after initial fetch
|
|
213
|
-
fetchTools().then(respond)
|
|
224
|
+
fetchTools().then(respond).catch(function (err) {
|
|
225
|
+
sendError(id, -32001, "Clay tool discovery failed: " + err.message);
|
|
226
|
+
});
|
|
214
227
|
}
|
|
215
228
|
|
|
216
229
|
function handleToolsCall(id, params) {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Session-owned shared skill catalog.
|
|
2
|
+
// ----------------------------------
|
|
3
|
+
// Keeps personal skill names out of project-wide session-manager state while
|
|
4
|
+
// retaining vendor commands separately for hydration and session switching.
|
|
5
|
+
|
|
6
|
+
var skillDiscovery = require("./skill-discovery");
|
|
7
|
+
|
|
8
|
+
function createSessionSkillCatalog(opts) {
|
|
9
|
+
opts = opts || {};
|
|
10
|
+
var cwd = opts.cwd;
|
|
11
|
+
var osUsers = !!opts.osUsers;
|
|
12
|
+
var getLinuxUser = opts.getLinuxUser || function () { return null; };
|
|
13
|
+
var resolveUser = opts.resolveUser || require("../os-users").resolveOsUserInfo;
|
|
14
|
+
|
|
15
|
+
function optionsFor(session) {
|
|
16
|
+
if (!osUsers) return opts.homeDir ? { homeDir: opts.homeDir, env: opts.env } : {};
|
|
17
|
+
var linuxUser = getLinuxUser(session);
|
|
18
|
+
if (!linuxUser) return { disable: true };
|
|
19
|
+
try {
|
|
20
|
+
return skillDiscovery.optionsForOsUser(resolveUser(linuxUser));
|
|
21
|
+
} catch (e) {
|
|
22
|
+
return { disable: true };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function hydrate(session) {
|
|
27
|
+
if (!session) return [];
|
|
28
|
+
var discovered = skillDiscovery.discoverSkills(cwd, optionsFor(session));
|
|
29
|
+
var names = discovered.map(function (skill) { return skill.name; });
|
|
30
|
+
session.skillNames = names;
|
|
31
|
+
var vendorCommands = Array.isArray(session.vendorSlashCommands) ? session.vendorSlashCommands : [];
|
|
32
|
+
var combined = vendorCommands.slice();
|
|
33
|
+
for (var i = 0; i < names.length; i++) {
|
|
34
|
+
if (combined.indexOf(names[i]) === -1) combined.push(names[i]);
|
|
35
|
+
}
|
|
36
|
+
session.slashCommands = combined;
|
|
37
|
+
session.slashCommandsByVendor = session.slashCommandsByVendor || {};
|
|
38
|
+
session.slashCommandsByVendor[session.vendor || "claude"] = combined;
|
|
39
|
+
return combined;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return { hydrate: hydrate, optionsFor: optionsFor };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = { createSessionSkillCatalog: createSessionSkillCatalog };
|
|
@@ -11,6 +11,18 @@ function defaultHomeDir() {
|
|
|
11
11
|
try { return require("../config").REAL_HOME; } catch (e) { return os.homedir(); }
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
function optionsForOsUser(userInfo, fsAsUser) {
|
|
15
|
+
if (!userInfo || typeof userInfo.home !== "string" || !userInfo.home) return { disable: true };
|
|
16
|
+
fsAsUser = fsAsUser || require("../os-users").fsAsUser;
|
|
17
|
+
return {
|
|
18
|
+
homeDir: userInfo.home,
|
|
19
|
+
scopedHome: true,
|
|
20
|
+
readDir: function (dir) { return fsAsUser("list", { dir: dir }, userInfo).map(function (entry) { return { name: entry.name, isDir: entry.isDir }; }); },
|
|
21
|
+
readFile: function (file) { return fsAsUser("read", { file: file, readContent: true }, userInfo).content; },
|
|
22
|
+
realpath: function (file) { return fsAsUser("realpath", { file: file }, userInfo).path; },
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
14
26
|
function unquote(value) {
|
|
15
27
|
var text = String(value || "").trim();
|
|
16
28
|
if ((text[0] === '"' && text[text.length - 1] === '"') ||
|
|
@@ -20,61 +32,83 @@ function unquote(value) {
|
|
|
20
32
|
return text;
|
|
21
33
|
}
|
|
22
34
|
|
|
23
|
-
function readMetadata(skillPath, fallbackName) {
|
|
35
|
+
function readMetadata(skillPath, fallbackName, opts) {
|
|
24
36
|
var content;
|
|
25
|
-
try { content = fs.readFileSync(skillPath, "utf8"); } catch (e) { return null; }
|
|
37
|
+
try { content = opts && opts.readFile ? opts.readFile(skillPath) : fs.readFileSync(skillPath, "utf8"); } catch (e) { return null; }
|
|
26
38
|
var name = fallbackName;
|
|
27
39
|
var description = "";
|
|
40
|
+
var version = "";
|
|
28
41
|
var frontmatter = content.match(/^---\s*\r?\n([\s\S]*?)\r?\n---(?:\s*\r?\n|$)/);
|
|
29
42
|
if (frontmatter) {
|
|
30
43
|
var nameMatch = frontmatter[1].match(/^name:\s*(.+)$/m);
|
|
31
44
|
var descriptionMatch = frontmatter[1].match(/^description:\s*(.+)$/m);
|
|
32
45
|
if (nameMatch) name = unquote(nameMatch[1]) || fallbackName;
|
|
33
46
|
if (descriptionMatch) description = unquote(descriptionMatch[1]);
|
|
47
|
+
var versionMatch = frontmatter[1].match(/^version:\s*(.+)$/m);
|
|
48
|
+
if (versionMatch) version = unquote(versionMatch[1]);
|
|
34
49
|
}
|
|
35
50
|
if (!description) {
|
|
36
51
|
var heading = content.match(/^#\s+(.+)$/m);
|
|
37
52
|
if (heading) description = heading[1].trim();
|
|
38
53
|
}
|
|
39
|
-
return { name: name, description: description };
|
|
54
|
+
return { name: name, description: description, version: version };
|
|
40
55
|
}
|
|
41
56
|
|
|
42
|
-
function scanRoot(root, source, merged) {
|
|
57
|
+
function scanRoot(root, source, merged, opts) {
|
|
43
58
|
var entries;
|
|
44
|
-
try { entries = fs.readdirSync(root, { withFileTypes: true }); } catch (e) { return; }
|
|
59
|
+
try { entries = opts && opts.readDir ? opts.readDir(root) : fs.readdirSync(root, { withFileTypes: true }); } catch (e) { return; }
|
|
45
60
|
entries.sort(function(a, b) { return a.name.localeCompare(b.name); });
|
|
46
61
|
for (var i = 0; i < entries.length; i++) {
|
|
47
62
|
var entry = entries[i];
|
|
48
|
-
if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
|
|
63
|
+
if ((!opts || !opts.readDir) && (entry.isDir === false || (typeof entry.isDirectory === "function" && !entry.isDirectory() && !entry.isSymbolicLink()))) continue;
|
|
49
64
|
var skillPath = path.join(root, entry.name, "SKILL.md");
|
|
50
|
-
var
|
|
65
|
+
var realSkillPath;
|
|
66
|
+
try { realSkillPath = opts && opts.realpath ? opts.realpath(skillPath) : fs.realpathSync(skillPath); } catch (e) { continue; }
|
|
67
|
+
var metadata = readMetadata(realSkillPath, entry.name, opts);
|
|
51
68
|
if (!metadata) continue;
|
|
52
|
-
|
|
69
|
+
var key = opts && opts.includeDuplicates ? source + "\0" + metadata.name : metadata.name;
|
|
70
|
+
merged[key] = {
|
|
53
71
|
name: metadata.name,
|
|
54
|
-
path:
|
|
72
|
+
path: realSkillPath,
|
|
55
73
|
description: metadata.description,
|
|
74
|
+
version: metadata.version,
|
|
56
75
|
source: source,
|
|
57
76
|
};
|
|
58
77
|
}
|
|
59
78
|
}
|
|
60
79
|
|
|
61
80
|
function getSkillRoots(cwd, opts) {
|
|
62
|
-
|
|
81
|
+
opts = opts || {};
|
|
82
|
+
var env = opts.env || (opts.homeDir ? {} : process.env);
|
|
83
|
+
if (opts.scopedHome) {
|
|
84
|
+
env = Object.assign({}, env);
|
|
85
|
+
delete env.CODEX_HOME;
|
|
86
|
+
delete env.CLAUDE_CONFIG_DIR;
|
|
87
|
+
}
|
|
88
|
+
var homeDir = opts.homeDir || env.HOME || defaultHomeDir();
|
|
89
|
+
var codexHome = env.CODEX_HOME ? path.resolve(homeDir, env.CODEX_HOME) : path.join(homeDir, ".codex");
|
|
90
|
+
var claudeConfigDir = env.CLAUDE_CONFIG_DIR ? path.resolve(homeDir, env.CLAUDE_CONFIG_DIR) : path.join(homeDir, ".claude");
|
|
63
91
|
var roots = [
|
|
64
|
-
{ path: path.join(homeDir, ".
|
|
65
|
-
{ path: path.join(
|
|
92
|
+
{ path: path.join(homeDir, ".agents", "skills"), source: "agents-user" },
|
|
93
|
+
{ path: path.join(codexHome, "skills"), source: "codex-user" },
|
|
94
|
+
{ path: path.join(codexHome, "skills", ".system"), source: "codex-system-user" },
|
|
95
|
+
{ path: path.join(claudeConfigDir, "skills"), source: "claude-user" },
|
|
66
96
|
];
|
|
67
97
|
if (cwd) {
|
|
68
98
|
roots.push({ path: path.join(cwd, "skills"), source: "project" });
|
|
99
|
+
roots.push({ path: path.join(cwd, ".agents", "skills"), source: "agents-project" });
|
|
100
|
+
roots.push({ path: path.join(cwd, ".codex", "skills"), source: "codex-project" });
|
|
101
|
+
roots.push({ path: path.join(cwd, ".codex", "skills", ".system"), source: "codex-system-project" });
|
|
69
102
|
roots.push({ path: path.join(cwd, ".claude", "skills"), source: "claude-project" });
|
|
70
103
|
}
|
|
71
104
|
return roots;
|
|
72
105
|
}
|
|
73
106
|
|
|
74
107
|
function discoverSkills(cwd, opts) {
|
|
108
|
+
if (opts && opts.disable) return [];
|
|
75
109
|
var merged = {};
|
|
76
110
|
var roots = getSkillRoots(cwd, opts);
|
|
77
|
-
for (var i = 0; i < roots.length; i++) scanRoot(roots[i].path, roots[i].source, merged);
|
|
111
|
+
for (var i = 0; i < roots.length; i++) scanRoot(roots[i].path, roots[i].source, merged, opts);
|
|
78
112
|
return Object.keys(merged).sort().map(function(name) { return merged[name]; });
|
|
79
113
|
}
|
|
80
114
|
|
|
@@ -112,13 +146,13 @@ function buildSkillIndex(skills) {
|
|
|
112
146
|
return lines.join("\n");
|
|
113
147
|
}
|
|
114
148
|
|
|
115
|
-
function readReferencedSkills(text, skills, maxChars) {
|
|
149
|
+
function readReferencedSkills(text, skills, maxChars, readOpts) {
|
|
116
150
|
var references = findSkillReferences(text, skills);
|
|
117
151
|
var remaining = maxChars || 32768;
|
|
118
152
|
var blocks = [];
|
|
119
153
|
for (var i = 0; i < references.length && remaining > 0; i++) {
|
|
120
154
|
var content;
|
|
121
|
-
try { content = fs.readFileSync(references[i].path, "utf8"); } catch (e) { continue; }
|
|
155
|
+
try { content = readOpts && readOpts.readFile ? readOpts.readFile(references[i].path) : fs.readFileSync(references[i].path, "utf8"); } catch (e) { continue; }
|
|
122
156
|
var header = "<shared-skill name=\"" + references[i].name + "\" source=\"" + references[i].source + "\">\n";
|
|
123
157
|
var footer = "\n</shared-skill>";
|
|
124
158
|
var available = Math.max(0, remaining - header.length - footer.length);
|
|
@@ -142,18 +176,20 @@ function lstatOrNull(target) {
|
|
|
142
176
|
}
|
|
143
177
|
|
|
144
178
|
function ensureClaudeCodexPlugin(opts) {
|
|
145
|
-
|
|
146
|
-
var
|
|
179
|
+
opts = opts || {};
|
|
180
|
+
var homeDir = opts.homeDir || defaultHomeDir();
|
|
181
|
+
var source = opts.source || path.join(homeDir, ".codex", "skills");
|
|
182
|
+
var bridgeName = opts.name || "codex";
|
|
147
183
|
try {
|
|
148
184
|
if (!fs.statSync(source).isDirectory()) return null;
|
|
149
185
|
} catch (e) { return null; }
|
|
150
186
|
|
|
151
|
-
var pluginDir = path.join(homeDir, ".clay", "skill-bridge",
|
|
187
|
+
var pluginDir = path.join(homeDir, ".clay", "skill-bridge", bridgeName);
|
|
152
188
|
var bridgeRoot = path.dirname(pluginDir);
|
|
153
189
|
var manifestDir = path.join(pluginDir, ".claude-plugin");
|
|
154
190
|
var manifestPath = path.join(manifestDir, "plugin.json");
|
|
155
191
|
var skillsLink = path.join(pluginDir, "skills");
|
|
156
|
-
var manifest = JSON.stringify({ name:
|
|
192
|
+
var manifest = JSON.stringify({ name: bridgeName, version: "1.0.0", description: "Shared skills provided by Clay" }, null, 2) + "\n";
|
|
157
193
|
|
|
158
194
|
try {
|
|
159
195
|
fs.mkdirSync(path.join(homeDir, ".clay"), { recursive: true });
|
|
@@ -168,7 +204,10 @@ function ensureClaudeCodexPlugin(opts) {
|
|
|
168
204
|
if (!manifestDirStat) fs.mkdirSync(manifestDir);
|
|
169
205
|
var manifestStat = lstatOrNull(manifestPath);
|
|
170
206
|
if (manifestStat) {
|
|
171
|
-
if (!manifestStat.isFile()
|
|
207
|
+
if (!manifestStat.isFile()) return null;
|
|
208
|
+
var existingManifest = fs.readFileSync(manifestPath, "utf8");
|
|
209
|
+
var legacyManifest = JSON.stringify({ name: "codex", version: "1.0.0", description: "Codex skills shared by Clay" }, null, 2) + "\n";
|
|
210
|
+
if (existingManifest !== manifest && existingManifest !== legacyManifest) return null;
|
|
172
211
|
} else {
|
|
173
212
|
fs.writeFileSync(manifestPath, manifest, { mode: 0o600, flag: "wx" });
|
|
174
213
|
}
|
|
@@ -192,5 +231,6 @@ module.exports = {
|
|
|
192
231
|
findSkillReferences: findSkillReferences,
|
|
193
232
|
getSkillRoots: getSkillRoots,
|
|
194
233
|
indexSkills: indexSkills,
|
|
234
|
+
optionsForOsUser: optionsForOsUser,
|
|
195
235
|
readReferencedSkills: readReferencedSkills,
|
|
196
236
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clay-server",
|
|
3
|
-
"version": "4.1.0
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "Self-hosted team workspace for Claude Code and Codex. Multi-user, browser-based, with persistent AI mates.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"clay-server": "./bin/cli.js"
|
|
@@ -8,8 +8,6 @@
|
|
|
8
8
|
"scripts": {
|
|
9
9
|
"dev": "node bin/cli.js --dev",
|
|
10
10
|
"test": "node --test --test-force-exit test/*.test.js",
|
|
11
|
-
"prepack": "npm pkg delete bin.clay-dev",
|
|
12
|
-
"postpack": "npm pkg set bin.clay-dev=./bin/cli.js",
|
|
13
11
|
"semantic-release": "semantic-release"
|
|
14
12
|
},
|
|
15
13
|
"files": [
|
|
@@ -49,12 +47,12 @@
|
|
|
49
47
|
"homepage": "https://github.com/chadbyte/clay#readme",
|
|
50
48
|
"author": "Chad",
|
|
51
49
|
"dependencies": {
|
|
52
|
-
"@anthropic-ai/claude-agent-sdk": "^0.3.
|
|
50
|
+
"@anthropic-ai/claude-agent-sdk": "^0.3.272",
|
|
53
51
|
"@lydell/node-pty": "^1.2.0-beta.3",
|
|
54
|
-
"@openai/codex": "^0.
|
|
52
|
+
"@openai/codex": "^0.154.0",
|
|
55
53
|
"@seald-io/nedb": "^4.1.2",
|
|
56
|
-
"imapflow": "^1.
|
|
57
|
-
"nodemailer": "^9.
|
|
54
|
+
"imapflow": "^1.7.8",
|
|
55
|
+
"nodemailer": "^9.1.1",
|
|
58
56
|
"qrcode-terminal": "^0.12.0",
|
|
59
57
|
"web-push": "^3.6.7",
|
|
60
58
|
"ws": "^8.18.0"
|