clay-server 2.34.0-beta.1 → 2.34.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/ask-user-mcp-server.js +120 -0
- package/lib/daemon.js +97 -38
- package/lib/mate-datastore.js +27 -5
- package/lib/mates.js +2 -2
- package/lib/os-users.js +13 -0
- package/lib/project-connection.js +16 -9
- package/lib/project-mate-datastore.js +16 -2
- package/lib/project-sessions.js +110 -7
- package/lib/project-user-message.js +4 -3
- package/lib/project.js +97 -10
- package/lib/public/css/mates.css +94 -52
- package/lib/public/css/mobile-nav.css +0 -14
- package/lib/public/css/notifications-center.css +23 -19
- package/lib/public/css/sidebar.css +326 -101
- package/lib/public/index.html +24 -57
- package/lib/public/modules/app-dm.js +0 -2
- package/lib/public/modules/app-messages.js +3 -5
- package/lib/public/modules/app-rendering.js +0 -2
- package/lib/public/modules/diff.js +21 -7
- package/lib/public/modules/mate-datastore-ui.js +108 -98
- package/lib/public/modules/mate-sidebar.js +0 -9
- package/lib/public/modules/mate-wizard.js +15 -15
- package/lib/public/modules/sidebar-mobile.js +10 -20
- package/lib/public/modules/sidebar-sessions.js +490 -113
- package/lib/public/modules/sidebar.js +8 -6
- package/lib/public/modules/tools.js +58 -13
- package/lib/public/sw.js +1 -1
- package/lib/sdk-bridge.js +36 -28
- package/lib/sdk-message-processor.js +14 -3
- package/lib/server.js +28 -72
- package/lib/sessions.js +157 -20
- package/lib/ws-schema.js +2 -0
- package/lib/yoke/adapters/claude-worker.js +114 -2
- package/lib/yoke/adapters/claude.js +56 -5
- package/lib/yoke/adapters/codex.js +349 -58
- package/lib/yoke/index.js +73 -35
- package/lib/yoke/instructions.js +0 -1
- package/lib/yoke/mcp-bridge-server.js +14 -6
- package/package.json +1 -2
- package/lib/yoke/adapters/gemini.js +0 -709
|
@@ -89,6 +89,56 @@ function generateUuid() {
|
|
|
89
89
|
return "codex-" + ts + "-" + cnt + "-" + rnd;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
function waitMs(ms) {
|
|
93
|
+
return new Promise(function(resolve) {
|
|
94
|
+
setTimeout(resolve, ms);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function waitForProcessExit(proc, timeoutMs) {
|
|
99
|
+
return new Promise(function(resolve) {
|
|
100
|
+
if (!proc) {
|
|
101
|
+
resolve(true);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (proc.exitCode !== null || proc.signalCode !== null) {
|
|
106
|
+
resolve(true);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
var done = false;
|
|
111
|
+
var timer = null;
|
|
112
|
+
|
|
113
|
+
function cleanup() {
|
|
114
|
+
if (done) return;
|
|
115
|
+
done = true;
|
|
116
|
+
if (timer) clearTimeout(timer);
|
|
117
|
+
proc.removeListener("exit", onDone);
|
|
118
|
+
proc.removeListener("close", onDone);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function onDone() {
|
|
122
|
+
cleanup();
|
|
123
|
+
resolve(true);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
proc.once("exit", onDone);
|
|
127
|
+
proc.once("close", onDone);
|
|
128
|
+
|
|
129
|
+
timer = setTimeout(function() {
|
|
130
|
+
cleanup();
|
|
131
|
+
resolve(false);
|
|
132
|
+
}, timeoutMs || 5000);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function createShutdownError() {
|
|
137
|
+
var err = new Error("Codex adapter is shutting down, retry shortly");
|
|
138
|
+
err.code = "CODEX_ADAPTER_SHUTTING_DOWN";
|
|
139
|
+
return err;
|
|
140
|
+
}
|
|
141
|
+
|
|
92
142
|
function normalizePlanStatus(status) {
|
|
93
143
|
if (status === "inProgress") return "in_progress";
|
|
94
144
|
if (status === "completed") return "completed";
|
|
@@ -310,16 +360,33 @@ function flattenEvent(notification, state) {
|
|
|
310
360
|
state.thinkingBlocks[item.id] = "blk_" + state.blockCounter;
|
|
311
361
|
events.push({ yokeType: "thinking_start", blockId: "blk_" + state.blockCounter });
|
|
312
362
|
}
|
|
313
|
-
|
|
363
|
+
// Codex reasoning items may expose plain text via `text`, a short
|
|
364
|
+
// `summary`, or nested `content` parts. Prefer whichever is present;
|
|
365
|
+
// many turns arrive with only encrypted reasoning and no readable
|
|
366
|
+
// text at all, in which case the UI will hide the expand affordance.
|
|
367
|
+
var reasoningText = "";
|
|
368
|
+
if (typeof item.text === "string" && item.text.length > 0) {
|
|
369
|
+
reasoningText = item.text;
|
|
370
|
+
} else if (typeof item.summary === "string" && item.summary.length > 0) {
|
|
371
|
+
reasoningText = item.summary;
|
|
372
|
+
} else if (Array.isArray(item.content)) {
|
|
373
|
+
var parts = [];
|
|
374
|
+
for (var rpi = 0; rpi < item.content.length; rpi++) {
|
|
375
|
+
var rp = item.content[rpi];
|
|
376
|
+
if (rp && typeof rp.text === "string") parts.push(rp.text);
|
|
377
|
+
}
|
|
378
|
+
reasoningText = parts.join("\n");
|
|
379
|
+
}
|
|
380
|
+
if (reasoningText) {
|
|
314
381
|
var thinkBlockId = state.thinkingBlocks[item.id];
|
|
315
382
|
var prevThinkLen = state.thinkingLengths[item.id] || 0;
|
|
316
|
-
if (
|
|
383
|
+
if (reasoningText.length > prevThinkLen) {
|
|
317
384
|
events.push({
|
|
318
385
|
yokeType: "thinking_delta",
|
|
319
386
|
blockId: thinkBlockId,
|
|
320
|
-
text:
|
|
387
|
+
text: reasoningText.substring(prevThinkLen),
|
|
321
388
|
});
|
|
322
|
-
state.thinkingLengths[item.id] =
|
|
389
|
+
state.thinkingLengths[item.id] = reasoningText.length;
|
|
323
390
|
}
|
|
324
391
|
}
|
|
325
392
|
if (evtPhase === "completed") {
|
|
@@ -503,6 +570,7 @@ function createCodexQueryHandle(appServer, queryOpts) {
|
|
|
503
570
|
var systemPrompt = queryOpts.systemPrompt || "";
|
|
504
571
|
var canUseTool = queryOpts.canUseTool || null;
|
|
505
572
|
var onElicitation = queryOpts.onElicitation || null;
|
|
573
|
+
var onFinished = queryOpts.onFinished || null;
|
|
506
574
|
|
|
507
575
|
// Check if the query was cancelled (either via handle.abort() or direct signal abort)
|
|
508
576
|
function isCancelled() {
|
|
@@ -533,6 +601,19 @@ function createCodexQueryHandle(appServer, queryOpts) {
|
|
|
533
601
|
var eventBuffer = [];
|
|
534
602
|
var eventWaiting = null;
|
|
535
603
|
var iteratorDone = false;
|
|
604
|
+
var finishedNotified = false;
|
|
605
|
+
|
|
606
|
+
function notifyFinished() {
|
|
607
|
+
if (finishedNotified) return;
|
|
608
|
+
finishedNotified = true;
|
|
609
|
+
if (typeof onFinished === "function") {
|
|
610
|
+
try {
|
|
611
|
+
onFinished();
|
|
612
|
+
} catch (e) {
|
|
613
|
+
console.error("[yoke/codex] onFinished error:", e.message || e);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
}
|
|
536
617
|
|
|
537
618
|
function pushEvent(evt) {
|
|
538
619
|
if (iteratorDone) return;
|
|
@@ -552,6 +633,7 @@ function createCodexQueryHandle(appServer, queryOpts) {
|
|
|
552
633
|
eventWaiting = null;
|
|
553
634
|
resolve({ value: undefined, done: true });
|
|
554
635
|
}
|
|
636
|
+
notifyFinished();
|
|
555
637
|
}
|
|
556
638
|
|
|
557
639
|
// Message queue for multi-turn
|
|
@@ -711,10 +793,37 @@ function createCodexQueryHandle(appServer, queryOpts) {
|
|
|
711
793
|
|
|
712
794
|
// --- Main query loop ---
|
|
713
795
|
async function runQueryLoop(initialMessage) {
|
|
714
|
-
// Prepend system prompt (project instructions from YOKE layer) to first message
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
796
|
+
// Prepend system prompt (project instructions from YOKE layer) to first message.
|
|
797
|
+
// initialMessage may be a string (text-only) or an array of content items
|
|
798
|
+
// (e.g. [{ type: "text", text: "..." }, ...] when images/attachments are present).
|
|
799
|
+
// Naive string concatenation on an array coerces it via toString(), producing
|
|
800
|
+
// "[object Object]" inside the prompt, so we must branch on the shape.
|
|
801
|
+
var currentMessage;
|
|
802
|
+
if (!systemPrompt) {
|
|
803
|
+
currentMessage = initialMessage;
|
|
804
|
+
} else if (typeof initialMessage === "string") {
|
|
805
|
+
currentMessage = systemPrompt + "\n\n" + initialMessage;
|
|
806
|
+
} else if (Array.isArray(initialMessage)) {
|
|
807
|
+
// Prepend systemPrompt to the first text item; if none exists, insert one.
|
|
808
|
+
var cloned = initialMessage.slice();
|
|
809
|
+
var injected = false;
|
|
810
|
+
for (var i = 0; i < cloned.length; i++) {
|
|
811
|
+
if (cloned[i] && cloned[i].type === "text") {
|
|
812
|
+
cloned[i] = {
|
|
813
|
+
type: "text",
|
|
814
|
+
text: systemPrompt + "\n\n" + (cloned[i].text || ""),
|
|
815
|
+
};
|
|
816
|
+
injected = true;
|
|
817
|
+
break;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
if (!injected) {
|
|
821
|
+
cloned.unshift({ type: "text", text: systemPrompt });
|
|
822
|
+
}
|
|
823
|
+
currentMessage = cloned;
|
|
824
|
+
} else {
|
|
825
|
+
currentMessage = initialMessage;
|
|
826
|
+
}
|
|
718
827
|
|
|
719
828
|
try {
|
|
720
829
|
// Set event handler on app-server
|
|
@@ -936,48 +1045,182 @@ function createCodexQueryHandle(appServer, queryOpts) {
|
|
|
936
1045
|
|
|
937
1046
|
function createCodexAdapter(opts) {
|
|
938
1047
|
var _cwd = (opts && opts.cwd) || process.cwd();
|
|
1048
|
+
var _slug = (opts && opts.slug) || "";
|
|
1049
|
+
var _defaultInitOpts = Object.assign({}, opts || {});
|
|
939
1050
|
var _cachedModels = [];
|
|
940
1051
|
var _appServer = null;
|
|
941
1052
|
var _initPromise = null;
|
|
942
|
-
var
|
|
1053
|
+
var _shutdownPromise = null;
|
|
1054
|
+
var _refCount = 0;
|
|
1055
|
+
var _lastActiveAt = Date.now();
|
|
1056
|
+
var _shuttingDown = false;
|
|
1057
|
+
var _activeQueries = [];
|
|
1058
|
+
|
|
1059
|
+
function updateLastActiveAt() {
|
|
1060
|
+
_lastActiveAt = Date.now();
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
function registerActiveQuery(entry) {
|
|
1064
|
+
_activeQueries.push(entry);
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
function removeActiveQuery(entry) {
|
|
1068
|
+
var next = [];
|
|
1069
|
+
for (var i = 0; i < _activeQueries.length; i++) {
|
|
1070
|
+
if (_activeQueries[i] !== entry) next.push(_activeQueries[i]);
|
|
1071
|
+
}
|
|
1072
|
+
_activeQueries = next;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
function decrementRefCount() {
|
|
1076
|
+
if (_refCount > 0) {
|
|
1077
|
+
_refCount--;
|
|
1078
|
+
} else {
|
|
1079
|
+
console.error("[yoke/codex] refCount negative, bug!");
|
|
1080
|
+
_refCount = 0;
|
|
1081
|
+
}
|
|
1082
|
+
updateLastActiveAt();
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
function buildReadyResponse(skillNames) {
|
|
1086
|
+
return {
|
|
1087
|
+
models: _cachedModels,
|
|
1088
|
+
defaultModel: "gpt-5.4",
|
|
1089
|
+
skills: skillNames || [],
|
|
1090
|
+
slashCommands: skillNames || [],
|
|
1091
|
+
fastModeState: null,
|
|
1092
|
+
capabilities: {
|
|
1093
|
+
thinking: true,
|
|
1094
|
+
betas: false,
|
|
1095
|
+
rewind: false,
|
|
1096
|
+
sessionResume: true,
|
|
1097
|
+
promptSuggestions: true,
|
|
1098
|
+
elicitation: true,
|
|
1099
|
+
fileCheckpointing: false,
|
|
1100
|
+
contextCompacting: false,
|
|
1101
|
+
toolPolicy: ["ask", "allow-all"],
|
|
1102
|
+
},
|
|
1103
|
+
};
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
function clearRuntimeState() {
|
|
1107
|
+
_appServer = null;
|
|
1108
|
+
_initPromise = null;
|
|
1109
|
+
_cachedModels = [];
|
|
1110
|
+
_refCount = 0;
|
|
1111
|
+
_activeQueries = [];
|
|
1112
|
+
updateLastActiveAt();
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
function waitForRefCount(targetCount, timeoutMs) {
|
|
1116
|
+
var deadline = Date.now() + (timeoutMs || 5000);
|
|
1117
|
+
return new Promise(function(resolve) {
|
|
1118
|
+
function tick() {
|
|
1119
|
+
if (_refCount <= targetCount) {
|
|
1120
|
+
resolve(true);
|
|
1121
|
+
return;
|
|
1122
|
+
}
|
|
1123
|
+
if (Date.now() >= deadline) {
|
|
1124
|
+
resolve(false);
|
|
1125
|
+
return;
|
|
1126
|
+
}
|
|
1127
|
+
setTimeout(tick, 50);
|
|
1128
|
+
}
|
|
1129
|
+
tick();
|
|
1130
|
+
});
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
function stopAppServer(deadlineMs) {
|
|
1134
|
+
var proc = _appServer && _appServer.proc ? _appServer.proc : null;
|
|
1135
|
+
if (!_appServer) return Promise.resolve(true);
|
|
1136
|
+
try {
|
|
1137
|
+
_appServer.stop();
|
|
1138
|
+
} catch (e) {
|
|
1139
|
+
console.error("[yoke/codex] App-server stop error:", e.message || e);
|
|
1140
|
+
}
|
|
1141
|
+
if (!proc) return Promise.resolve(true);
|
|
1142
|
+
var remaining = (typeof deadlineMs === "number") ? Math.max(0, deadlineMs - Date.now()) : 5000;
|
|
1143
|
+
return waitForProcessExit(proc, remaining).then(function(exited) {
|
|
1144
|
+
if (!exited) {
|
|
1145
|
+
try {
|
|
1146
|
+
proc.kill("SIGKILL");
|
|
1147
|
+
} catch (e) {}
|
|
1148
|
+
}
|
|
1149
|
+
return exited;
|
|
1150
|
+
});
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
function beginShutdown(force, idleMs) {
|
|
1154
|
+
if (_shutdownPromise) return _shutdownPromise;
|
|
1155
|
+
if (_shuttingDown) return null;
|
|
1156
|
+
|
|
1157
|
+
_shuttingDown = true;
|
|
1158
|
+
|
|
1159
|
+
_shutdownPromise = (async function() {
|
|
1160
|
+
var deadline = Date.now() + 5000;
|
|
1161
|
+
var shouldAbort = !!force;
|
|
1162
|
+
|
|
1163
|
+
if (_initPromise) {
|
|
1164
|
+
try {
|
|
1165
|
+
await Promise.race([
|
|
1166
|
+
_initPromise.catch(function() { return null; }),
|
|
1167
|
+
waitMs(Math.max(0, deadline - Date.now())),
|
|
1168
|
+
]);
|
|
1169
|
+
} catch (e) {}
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
if (shouldAbort && _activeQueries.length > 0) {
|
|
1173
|
+
var active = _activeQueries.slice();
|
|
1174
|
+
for (var i = 0; i < active.length; i++) {
|
|
1175
|
+
try {
|
|
1176
|
+
if (active[i] && active[i].abort) active[i].abort();
|
|
1177
|
+
} catch (e) {}
|
|
1178
|
+
}
|
|
1179
|
+
await waitForRefCount(0, Math.max(0, deadline - Date.now()));
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
if (_appServer) {
|
|
1183
|
+
await stopAppServer(deadline);
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
clearRuntimeState();
|
|
1187
|
+
_shuttingDown = false;
|
|
1188
|
+
_shutdownPromise = null;
|
|
1189
|
+
return true;
|
|
1190
|
+
})().catch(function(err) {
|
|
1191
|
+
clearRuntimeState();
|
|
1192
|
+
_shuttingDown = false;
|
|
1193
|
+
_shutdownPromise = null;
|
|
1194
|
+
throw err;
|
|
1195
|
+
});
|
|
1196
|
+
|
|
1197
|
+
return _shutdownPromise;
|
|
1198
|
+
}
|
|
943
1199
|
|
|
944
1200
|
var adapter = {
|
|
945
1201
|
vendor: "codex",
|
|
946
1202
|
|
|
947
1203
|
init: function(initOpts) {
|
|
1204
|
+
if (_shuttingDown) {
|
|
1205
|
+
return Promise.reject(createShutdownError());
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
var effectiveInitOpts = Object.assign({}, _defaultInitOpts, initOpts || {});
|
|
1209
|
+
|
|
948
1210
|
// Already initialized - return cached result
|
|
949
1211
|
if (_appServer && _appServer.started && _cachedModels.length > 0) {
|
|
950
|
-
return Promise.resolve(
|
|
951
|
-
models: _cachedModels,
|
|
952
|
-
defaultModel: "gpt-5.4",
|
|
953
|
-
skills: [],
|
|
954
|
-
slashCommands: [],
|
|
955
|
-
fastModeState: null,
|
|
956
|
-
capabilities: {
|
|
957
|
-
thinking: true,
|
|
958
|
-
betas: false,
|
|
959
|
-
rewind: false,
|
|
960
|
-
sessionResume: true,
|
|
961
|
-
promptSuggestions: true,
|
|
962
|
-
elicitation: true,
|
|
963
|
-
fileCheckpointing: false,
|
|
964
|
-
contextCompacting: false,
|
|
965
|
-
toolPolicy: ["ask", "allow-all"],
|
|
966
|
-
},
|
|
967
|
-
});
|
|
1212
|
+
return Promise.resolve(buildReadyResponse([]));
|
|
968
1213
|
}
|
|
969
1214
|
|
|
970
1215
|
// Deduplicate concurrent init calls
|
|
971
1216
|
if (_initPromise) return _initPromise;
|
|
972
1217
|
|
|
973
1218
|
_initPromise = (async function() {
|
|
974
|
-
_initOpts = initOpts;
|
|
975
|
-
|
|
976
1219
|
var serverOpts = { cwd: _cwd };
|
|
977
1220
|
|
|
978
1221
|
// Extract adapter options
|
|
979
|
-
if (
|
|
980
|
-
var co =
|
|
1222
|
+
if (effectiveInitOpts && effectiveInitOpts.adapterOptions && effectiveInitOpts.adapterOptions.CODEX) {
|
|
1223
|
+
var co = effectiveInitOpts.adapterOptions.CODEX;
|
|
981
1224
|
if (co.apiKey) serverOpts.env = Object.assign({}, serverOpts.env || {}, { OPENAI_API_KEY: co.apiKey });
|
|
982
1225
|
if (co.baseUrl) serverOpts.env = Object.assign({}, serverOpts.env || {}, { OPENAI_BASE_URL: co.baseUrl });
|
|
983
1226
|
if (co.config) serverOpts.config = co.config;
|
|
@@ -1005,10 +1248,10 @@ function createCodexAdapter(opts) {
|
|
|
1005
1248
|
|
|
1006
1249
|
// Track 2: Add clay-tools bridge server for in-app + remote MCP tools.
|
|
1007
1250
|
var bridgePath = require("path").join(__dirname, "..", "mcp-bridge-server.js");
|
|
1008
|
-
var clayPort =
|
|
1009
|
-
var clayTls =
|
|
1010
|
-
var clayAuthToken =
|
|
1011
|
-
var claySlug =
|
|
1251
|
+
var clayPort = effectiveInitOpts.clayPort || process.env.CLAY_PORT || 2633;
|
|
1252
|
+
var clayTls = effectiveInitOpts.clayTls || false;
|
|
1253
|
+
var clayAuthToken = effectiveInitOpts.clayAuthToken || "";
|
|
1254
|
+
var claySlug = effectiveInitOpts.slug || _slug || "";
|
|
1012
1255
|
try {
|
|
1013
1256
|
if (require("fs").existsSync(bridgePath)) {
|
|
1014
1257
|
var bridgeArgs = [bridgePath, "--port", String(clayPort), "--slug", claySlug];
|
|
@@ -1049,6 +1292,11 @@ function createCodexAdapter(opts) {
|
|
|
1049
1292
|
});
|
|
1050
1293
|
_appServer.notify("initialized", {});
|
|
1051
1294
|
|
|
1295
|
+
if (_shuttingDown) {
|
|
1296
|
+
await stopAppServer(Date.now() + 1000);
|
|
1297
|
+
throw createShutdownError();
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1052
1300
|
console.log("[codex] App-server initialized, models: gpt-5.4, gpt-5.4-mini, gpt-5.3-codex, gpt-5.3-codex-spark, gpt-5.2");
|
|
1053
1301
|
|
|
1054
1302
|
_cachedModels = [
|
|
@@ -1097,26 +1345,15 @@ function createCodexAdapter(opts) {
|
|
|
1097
1345
|
console.error("[codex] Failed to discover skills:", e.message);
|
|
1098
1346
|
}
|
|
1099
1347
|
|
|
1348
|
+
if (_shuttingDown) {
|
|
1349
|
+
await stopAppServer(Date.now() + 1000);
|
|
1350
|
+
throw createShutdownError();
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1100
1353
|
_initPromise = null;
|
|
1354
|
+
updateLastActiveAt();
|
|
1101
1355
|
|
|
1102
|
-
return
|
|
1103
|
-
models: _cachedModels,
|
|
1104
|
-
defaultModel: "gpt-5.4",
|
|
1105
|
-
skills: skillNames,
|
|
1106
|
-
slashCommands: skillNames,
|
|
1107
|
-
fastModeState: null,
|
|
1108
|
-
capabilities: {
|
|
1109
|
-
thinking: true,
|
|
1110
|
-
betas: false,
|
|
1111
|
-
rewind: false,
|
|
1112
|
-
sessionResume: true,
|
|
1113
|
-
promptSuggestions: true,
|
|
1114
|
-
elicitation: true,
|
|
1115
|
-
fileCheckpointing: false,
|
|
1116
|
-
contextCompacting: false,
|
|
1117
|
-
toolPolicy: ["ask", "allow-all"],
|
|
1118
|
-
},
|
|
1119
|
-
};
|
|
1356
|
+
return buildReadyResponse(skillNames);
|
|
1120
1357
|
})();
|
|
1121
1358
|
|
|
1122
1359
|
return _initPromise;
|
|
@@ -1134,12 +1371,31 @@ function createCodexAdapter(opts) {
|
|
|
1134
1371
|
},
|
|
1135
1372
|
|
|
1136
1373
|
createQuery: async function(queryOpts) {
|
|
1374
|
+
if (_shuttingDown) {
|
|
1375
|
+
throw createShutdownError();
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
if (!_appServer || !_appServer.started) {
|
|
1379
|
+
await adapter.init(queryOpts || {});
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
if (_shuttingDown) {
|
|
1383
|
+
throw createShutdownError();
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1137
1386
|
if (!_appServer || !_appServer.started) {
|
|
1138
1387
|
throw new Error("[yoke/codex] Adapter not initialized. Call init() first.");
|
|
1139
1388
|
}
|
|
1140
1389
|
|
|
1141
1390
|
var model = queryOpts.model || "gpt-5.4";
|
|
1142
1391
|
var ac = queryOpts.abortController || new AbortController();
|
|
1392
|
+
var activeEntry = {
|
|
1393
|
+
abort: function() {
|
|
1394
|
+
try {
|
|
1395
|
+
ac.abort();
|
|
1396
|
+
} catch (e) {}
|
|
1397
|
+
},
|
|
1398
|
+
};
|
|
1143
1399
|
|
|
1144
1400
|
// Map YOKE options to Codex thread options
|
|
1145
1401
|
var codexOpts = (queryOpts.adapterOptions && queryOpts.adapterOptions.CODEX) || {};
|
|
@@ -1176,7 +1432,33 @@ function createCodexAdapter(opts) {
|
|
|
1176
1432
|
|
|
1177
1433
|
console.log("[yoke/codex] createQuery: model=" + model + " approval=" + handleOpts.approvalPolicy + " sandbox=" + handleOpts.sandboxMode);
|
|
1178
1434
|
|
|
1179
|
-
|
|
1435
|
+
_refCount++;
|
|
1436
|
+
registerActiveQuery(activeEntry);
|
|
1437
|
+
|
|
1438
|
+
var handle;
|
|
1439
|
+
try {
|
|
1440
|
+
handleOpts.onFinished = function() {
|
|
1441
|
+
removeActiveQuery(activeEntry);
|
|
1442
|
+
decrementRefCount();
|
|
1443
|
+
};
|
|
1444
|
+
handle = createCodexQueryHandle(_appServer, handleOpts);
|
|
1445
|
+
} catch (e) {
|
|
1446
|
+
removeActiveQuery(activeEntry);
|
|
1447
|
+
decrementRefCount();
|
|
1448
|
+
throw e;
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
activeEntry.handle = handle;
|
|
1452
|
+
activeEntry.abort = function() {
|
|
1453
|
+
try {
|
|
1454
|
+
if (handle && typeof handle.abort === "function") {
|
|
1455
|
+
handle.abort();
|
|
1456
|
+
} else {
|
|
1457
|
+
ac.abort();
|
|
1458
|
+
}
|
|
1459
|
+
} catch (e) {}
|
|
1460
|
+
};
|
|
1461
|
+
|
|
1180
1462
|
return handle;
|
|
1181
1463
|
},
|
|
1182
1464
|
|
|
@@ -1243,10 +1525,19 @@ function createCodexAdapter(opts) {
|
|
|
1243
1525
|
|
|
1244
1526
|
// Shutdown the app-server process
|
|
1245
1527
|
shutdown: function() {
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1528
|
+
return beginShutdown(true);
|
|
1529
|
+
},
|
|
1530
|
+
|
|
1531
|
+
shutdownIfIdle: function(idleMs) {
|
|
1532
|
+
if (_shuttingDown || _shutdownPromise) return Promise.resolve(false);
|
|
1533
|
+
if (_initPromise) return Promise.resolve(false);
|
|
1534
|
+
if (!_appServer) return Promise.resolve(false);
|
|
1535
|
+
if (_refCount > 0) return Promise.resolve(false);
|
|
1536
|
+
if (Date.now() - _lastActiveAt < (idleMs || 0)) return Promise.resolve(false);
|
|
1537
|
+
return beginShutdown(false).then(function() {
|
|
1538
|
+
console.log("[yoke/codex] Reclaimed idle adapter for project " + (_slug || _cwd));
|
|
1539
|
+
return true;
|
|
1540
|
+
});
|
|
1250
1541
|
},
|
|
1251
1542
|
};
|
|
1252
1543
|
|