@alas-ide/codex-acp 2.2.2-alas.2 → 2.2.2-alas.4
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/dist/index.js +344 -82
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -34392,7 +34392,7 @@ var package_default = {
|
|
|
34392
34392
|
publishConfig: {
|
|
34393
34393
|
access: "public"
|
|
34394
34394
|
},
|
|
34395
|
-
version: "2.2.2-alas.
|
|
34395
|
+
version: "2.2.2-alas.4",
|
|
34396
34396
|
description: "",
|
|
34397
34397
|
main: "dist/index.js",
|
|
34398
34398
|
bin: {
|
|
@@ -34469,7 +34469,7 @@ var package_default = {
|
|
|
34469
34469
|
alasDownstream: {
|
|
34470
34470
|
upstreamVersion: "2.2.2",
|
|
34471
34471
|
upstreamCommit: "202e66e63343ec4f5a5e35ab590251d813d129ca",
|
|
34472
|
-
sourceCommit: "
|
|
34472
|
+
sourceCommit: "4b517e7e77ece05ef63f34c890bc853b7fb96a43"
|
|
34473
34473
|
}
|
|
34474
34474
|
};
|
|
34475
34475
|
|
|
@@ -35186,6 +35186,19 @@ var CodexAcpClient = class _CodexAcpClient {
|
|
|
35186
35186
|
isClientConfiguredProvider(providerId) {
|
|
35187
35187
|
return providerId === CUSTOM_GATEWAY_PROVIDER_ID && this.gatewayConfigSource === "acpProviders";
|
|
35188
35188
|
}
|
|
35189
|
+
/** Provider inputs that can change the routing of a subsequent open or turn. Never returned over ACP. */
|
|
35190
|
+
async hookReviewProviderInputs() {
|
|
35191
|
+
const persisted = (await this.codexClient.configRead({ includeLayers: false })).config;
|
|
35192
|
+
const modelProvider = this.getModelProvider() ?? persisted.model_provider ?? "openai";
|
|
35193
|
+
const selected = (providers) => {
|
|
35194
|
+
if (providers === null || typeof providers !== "object" || Array.isArray(providers)) return {};
|
|
35195
|
+
const value = providers[modelProvider];
|
|
35196
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
35197
|
+
};
|
|
35198
|
+
const merged = this.gatewayConfig?.modelProvider === modelProvider ? this.gatewayConfig.config : { ...selected(persisted["model_providers"]), ...selected(this.config["model_providers"]) };
|
|
35199
|
+
const { name: _name, env_key_instructions: _instructions, ...config2 } = merged;
|
|
35200
|
+
return { modelProvider, config: config2 };
|
|
35201
|
+
}
|
|
35189
35202
|
/**
|
|
35190
35203
|
* The model provider the agent itself is configured with (launch option or
|
|
35191
35204
|
* Codex config), ignoring any ACP-configured gateway routing. The
|
|
@@ -37141,6 +37154,21 @@ var CodexAppServerClient = class {
|
|
|
37141
37154
|
threadLoadsInFlight() {
|
|
37142
37155
|
return [...this.threadLoads.keys()];
|
|
37143
37156
|
}
|
|
37157
|
+
/** Validates a reviewed process/configuration and returns the final synchronous dispatch fence. */
|
|
37158
|
+
hookExecutionGate;
|
|
37159
|
+
dispatchRequest(request) {
|
|
37160
|
+
const activeGoal = request.method === "thread/goal/set" && request.params.status !== "paused";
|
|
37161
|
+
if (this.hookExecutionGate !== void 0 && (activeGoal || ["thread/start", "thread/resume", "thread/fork", "turn/start", "review/start"].includes(request.method))) {
|
|
37162
|
+
return this.dispatchReviewedRequest(request, this.hookExecutionGate);
|
|
37163
|
+
}
|
|
37164
|
+
return request.params ? this.connection.sendRequest(request.method, request.params) : this.connection.sendRequest(request.method);
|
|
37165
|
+
}
|
|
37166
|
+
async dispatchReviewedRequest(request, gate) {
|
|
37167
|
+
const params = request.params;
|
|
37168
|
+
const fence = await gate(params.cwd ?? void 0, params.modelProvider);
|
|
37169
|
+
fence();
|
|
37170
|
+
return await this.connection.sendRequest(request.method, request.params);
|
|
37171
|
+
}
|
|
37144
37172
|
async sendRequest(request) {
|
|
37145
37173
|
for (const callback of this.codexEventHandlers) {
|
|
37146
37174
|
callback({ eventType: "request", ...request });
|
|
@@ -37148,11 +37176,7 @@ var CodexAppServerClient = class {
|
|
|
37148
37176
|
const loadedThreadId = threadLoadOf(request);
|
|
37149
37177
|
let result;
|
|
37150
37178
|
if (loadedThreadId === null) {
|
|
37151
|
-
|
|
37152
|
-
result = await this.connection.sendRequest(request.method, request.params);
|
|
37153
|
-
} else {
|
|
37154
|
-
result = await this.connection.sendRequest(request.method);
|
|
37155
|
-
}
|
|
37179
|
+
result = await this.dispatchRequest(request);
|
|
37156
37180
|
} else {
|
|
37157
37181
|
result = await this.threadLoadGate(loadedThreadId, () => this.sendThreadLoad(loadedThreadId, request));
|
|
37158
37182
|
}
|
|
@@ -37164,7 +37188,7 @@ var CodexAppServerClient = class {
|
|
|
37164
37188
|
async sendThreadLoad(threadId, request) {
|
|
37165
37189
|
this.threadLoads.set(threadId, (this.threadLoads.get(threadId) ?? 0) + 1);
|
|
37166
37190
|
try {
|
|
37167
|
-
return await this.
|
|
37191
|
+
return await this.dispatchRequest(request);
|
|
37168
37192
|
} finally {
|
|
37169
37193
|
const count = (this.threadLoads.get(threadId) ?? 1) - 1;
|
|
37170
37194
|
if (count > 0) this.threadLoads.set(threadId, count);
|
|
@@ -37268,6 +37292,183 @@ async function withHistoryTimeout(page, method, threadId) {
|
|
|
37268
37292
|
}
|
|
37269
37293
|
}
|
|
37270
37294
|
|
|
37295
|
+
// src/CodexHookReview.ts
|
|
37296
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
37297
|
+
import { createHash as createHash2, randomUUID as randomUUID3 } from "node:crypto";
|
|
37298
|
+
|
|
37299
|
+
// src/CodexHookTrust.ts
|
|
37300
|
+
var CODEX_HOOKS_LIST_METHOD = "_codex/hooks/list";
|
|
37301
|
+
var CODEX_HOOKS_TRUST_METHOD = "_codex/hooks/trust";
|
|
37302
|
+
async function listCodexHooks(client, cwd) {
|
|
37303
|
+
const [entry] = (await client.hooksList({ cwds: [cwd] })).data;
|
|
37304
|
+
if (entry === void 0) throw new Error("Codex could not list hooks for the requested directory");
|
|
37305
|
+
return { ...entry, hooks: entry.hooks.filter((hook) => hook.source === "sessionFlags") };
|
|
37306
|
+
}
|
|
37307
|
+
async function trustCodexHooks(client, cwd, requested, beforeWrite, afterReadback) {
|
|
37308
|
+
const isListed = (hooks, request) => hooks.find((hook) => hook.key === request.key && hook.currentHash === request.currentHash);
|
|
37309
|
+
const entry = await listCodexHooks(client, cwd);
|
|
37310
|
+
beforeWrite?.(entry);
|
|
37311
|
+
const current = entry.hooks;
|
|
37312
|
+
const edits = requested.map((request) => {
|
|
37313
|
+
const hook = isListed(current, request);
|
|
37314
|
+
if (hook === void 0) throw new Error("A Codex hook changed before trust was recorded");
|
|
37315
|
+
return hook;
|
|
37316
|
+
}).filter((hook) => hook.trustStatus !== "trusted").map((hook) => ({
|
|
37317
|
+
keyPath: `hooks.state.${JSON.stringify(hook.key)}.trusted_hash`,
|
|
37318
|
+
value: hook.currentHash,
|
|
37319
|
+
mergeStrategy: "replace"
|
|
37320
|
+
}));
|
|
37321
|
+
if (edits.length > 0) {
|
|
37322
|
+
await client.configBatchWrite({ edits, reloadUserConfig: true });
|
|
37323
|
+
}
|
|
37324
|
+
const verified = (await listCodexHooks(client, cwd)).hooks;
|
|
37325
|
+
afterReadback?.();
|
|
37326
|
+
return requested.every((request) => isListed(verified, request)?.trustStatus === "trusted");
|
|
37327
|
+
}
|
|
37328
|
+
|
|
37329
|
+
// src/CodexHookReview.ts
|
|
37330
|
+
var CODEX_HOOK_REVIEW_ERROR = -32044;
|
|
37331
|
+
var CodexHookReviewError = class extends RequestError {
|
|
37332
|
+
constructor(kind) {
|
|
37333
|
+
super(CODEX_HOOK_REVIEW_ERROR, kind === "codex_hook_changed" ? "A Codex hook changed; review the startup hooks again" : "Review the startup hooks for the current Codex process before continuing", { kind });
|
|
37334
|
+
}
|
|
37335
|
+
};
|
|
37336
|
+
var CodexHookReview = class {
|
|
37337
|
+
constructor(client) {
|
|
37338
|
+
this.client = client;
|
|
37339
|
+
}
|
|
37340
|
+
client;
|
|
37341
|
+
enabled = false;
|
|
37342
|
+
revision = 0;
|
|
37343
|
+
reviews = /* @__PURE__ */ new Map();
|
|
37344
|
+
context = new AsyncLocalStorage();
|
|
37345
|
+
configure(capability, air) {
|
|
37346
|
+
this.enabled = !air && typeof capability === "object" && capability !== null && !Array.isArray(capability) && capability.version === 1;
|
|
37347
|
+
this.invalidate();
|
|
37348
|
+
this.bind(this.client());
|
|
37349
|
+
}
|
|
37350
|
+
invalidate() {
|
|
37351
|
+
this.revision++;
|
|
37352
|
+
this.reviews.clear();
|
|
37353
|
+
}
|
|
37354
|
+
bind(client) {
|
|
37355
|
+
client.appServerClient.hookExecutionGate = this.enabled ? async (cwd, provider) => {
|
|
37356
|
+
const context = this.context.getStore();
|
|
37357
|
+
const fail = (error62) => {
|
|
37358
|
+
if (context?.dispatched && error62 instanceof CodexHookReviewError) {
|
|
37359
|
+
throw RequestError.internalError(
|
|
37360
|
+
void 0,
|
|
37361
|
+
"Codex hook review changed after this operation began executing. Review again before sending new work; do not retry the completed work automatically."
|
|
37362
|
+
);
|
|
37363
|
+
}
|
|
37364
|
+
throw error62;
|
|
37365
|
+
};
|
|
37366
|
+
try {
|
|
37367
|
+
if (context === void 0 || cwd !== void 0 && cwd !== context.cwd) throw new CodexHookReviewError("codex_hook_review_required");
|
|
37368
|
+
const fence = await this.validate(client, context.cwd, context.token, provider);
|
|
37369
|
+
return () => {
|
|
37370
|
+
try {
|
|
37371
|
+
fence();
|
|
37372
|
+
} catch (error62) {
|
|
37373
|
+
fail(error62);
|
|
37374
|
+
}
|
|
37375
|
+
context.dispatched = true;
|
|
37376
|
+
};
|
|
37377
|
+
} catch (error62) {
|
|
37378
|
+
return fail(error62);
|
|
37379
|
+
}
|
|
37380
|
+
} : void 0;
|
|
37381
|
+
}
|
|
37382
|
+
run(cwd, meta3, operation) {
|
|
37383
|
+
if (!this.enabled) return operation();
|
|
37384
|
+
const hooks = meta3?.codexHooks;
|
|
37385
|
+
return this.context.run({ cwd, token: hooks?.reviewToken, dispatched: false }, operation);
|
|
37386
|
+
}
|
|
37387
|
+
continueOperation(cwd, meta3, operation) {
|
|
37388
|
+
return this.context.getStore() === void 0 ? this.run(cwd, meta3, operation) : operation();
|
|
37389
|
+
}
|
|
37390
|
+
async list(cwd) {
|
|
37391
|
+
const client = this.client();
|
|
37392
|
+
const revision = this.revision;
|
|
37393
|
+
if (!this.enabled) return await listCodexHooks(client.appServerClient, cwd);
|
|
37394
|
+
const [entry, provider] = await Promise.all([
|
|
37395
|
+
listCodexHooks(client.appServerClient, cwd),
|
|
37396
|
+
client.hookReviewProviderInputs()
|
|
37397
|
+
]);
|
|
37398
|
+
this.assertCurrent(client.appServerClient, revision);
|
|
37399
|
+
const definitions = definitionFingerprint(entry);
|
|
37400
|
+
const providerFingerprint = fingerprint(provider);
|
|
37401
|
+
const previous = this.reviews.get(cwd);
|
|
37402
|
+
const review = previous?.client === client.appServerClient && previous.revision === revision && previous.fingerprint === definitions && previous.providerFingerprint === providerFingerprint ? previous : { cwd, token: randomUUID3(), fingerprint: definitions, revision, client: client.appServerClient, provider: provider.modelProvider, providerFingerprint };
|
|
37403
|
+
this.reviews.set(cwd, review);
|
|
37404
|
+
const home = client.getHomePath();
|
|
37405
|
+
return { ...entry, reviewToken: review.token, ...home === null ? {} : { codexHome: home } };
|
|
37406
|
+
}
|
|
37407
|
+
async trust(cwd, requested, token) {
|
|
37408
|
+
const client = this.client().appServerClient;
|
|
37409
|
+
if (!this.enabled) return await trustCodexHooks(client, cwd, requested);
|
|
37410
|
+
const review = this.requireReview(client, cwd, token);
|
|
37411
|
+
const fence = await this.validate(this.client(), cwd, token);
|
|
37412
|
+
fence();
|
|
37413
|
+
if (requested.length === 0 || new Set(requested.map((hook) => hook.key)).size !== requested.length || requested.some((hook) => !hook.key || !hook.currentHash)) throw new CodexHookReviewError("codex_hook_changed");
|
|
37414
|
+
return await trustCodexHooks(client, cwd, requested, (entry) => {
|
|
37415
|
+
this.checkDefinition(client, review, entry);
|
|
37416
|
+
for (const request of requested) {
|
|
37417
|
+
const matches = entry.hooks.filter((hook) => hook.key === request.key);
|
|
37418
|
+
if (matches.length !== 1 || matches[0].currentHash !== request.currentHash) {
|
|
37419
|
+
throw new CodexHookReviewError("codex_hook_changed");
|
|
37420
|
+
}
|
|
37421
|
+
}
|
|
37422
|
+
}, () => {
|
|
37423
|
+
this.requireReview(client, cwd, token);
|
|
37424
|
+
});
|
|
37425
|
+
}
|
|
37426
|
+
async validate(client, cwd, token, requestedProvider) {
|
|
37427
|
+
const review = this.requireReview(client.appServerClient, cwd, token);
|
|
37428
|
+
const [entry, provider] = await Promise.all([
|
|
37429
|
+
listCodexHooks(client.appServerClient, cwd),
|
|
37430
|
+
client.hookReviewProviderInputs()
|
|
37431
|
+
]);
|
|
37432
|
+
this.checkDefinition(client.appServerClient, review, entry);
|
|
37433
|
+
if (fingerprint(provider) !== review.providerFingerprint || requestedProvider != null && requestedProvider !== review.provider) {
|
|
37434
|
+
throw new CodexHookReviewError("codex_hook_changed");
|
|
37435
|
+
}
|
|
37436
|
+
return () => {
|
|
37437
|
+
this.requireReview(client.appServerClient, cwd, token);
|
|
37438
|
+
};
|
|
37439
|
+
}
|
|
37440
|
+
requireReview(client, cwd, token) {
|
|
37441
|
+
const review = this.reviews.get(cwd);
|
|
37442
|
+
if (review === void 0 || typeof token !== "string" || token !== review.token || review.client !== client) {
|
|
37443
|
+
throw new CodexHookReviewError("codex_hook_review_required");
|
|
37444
|
+
}
|
|
37445
|
+
this.assertCurrent(client, review.revision);
|
|
37446
|
+
return review;
|
|
37447
|
+
}
|
|
37448
|
+
checkDefinition(client, review, entry) {
|
|
37449
|
+
this.requireReview(client, review.cwd, review.token);
|
|
37450
|
+
if (definitionFingerprint(entry) !== review.fingerprint) throw new CodexHookReviewError("codex_hook_changed");
|
|
37451
|
+
}
|
|
37452
|
+
assertCurrent(client, revision) {
|
|
37453
|
+
if (client !== this.client().appServerClient || revision !== this.revision || client.connectionLoss.lost) {
|
|
37454
|
+
throw new CodexHookReviewError("codex_hook_review_required");
|
|
37455
|
+
}
|
|
37456
|
+
}
|
|
37457
|
+
};
|
|
37458
|
+
function definitionFingerprint(entry) {
|
|
37459
|
+
const value = { ...entry, hooks: entry.hooks.map(({ trustStatus: _trust, ...definition }) => definition) };
|
|
37460
|
+
return fingerprint(value);
|
|
37461
|
+
}
|
|
37462
|
+
function fingerprint(value) {
|
|
37463
|
+
return createHash2("sha256").update(JSON.stringify(value, (_key, value2) => {
|
|
37464
|
+
if (typeof value2 === "bigint") return value2.toString();
|
|
37465
|
+
if (value2 !== null && typeof value2 === "object" && !Array.isArray(value2)) {
|
|
37466
|
+
return Object.fromEntries(Object.entries(value2).sort(([a], [b]) => a.localeCompare(b)));
|
|
37467
|
+
}
|
|
37468
|
+
return value2;
|
|
37469
|
+
})).digest("hex");
|
|
37470
|
+
}
|
|
37471
|
+
|
|
37271
37472
|
// src/app-server-recovery/AppServerRecovery.ts
|
|
37272
37473
|
var import_node3 = __toESM(require_main(), 1);
|
|
37273
37474
|
|
|
@@ -37907,7 +38108,7 @@ var AppServerRecovery = class {
|
|
|
37907
38108
|
});
|
|
37908
38109
|
}
|
|
37909
38110
|
resumeError(sessionId, error62, client) {
|
|
37910
|
-
if (isAppServerUnavailableError(error62)) return error62;
|
|
38111
|
+
if (isAppServerUnavailableError(error62) || error62 instanceof CodexHookReviewError) return error62;
|
|
37911
38112
|
const mapped = this.mapError(error62, client);
|
|
37912
38113
|
if (mapped !== error62) return mapped;
|
|
37913
38114
|
if (isMissingRolloutError(error62)) {
|
|
@@ -40020,35 +40221,8 @@ function clientSupportsSubagents(capabilities) {
|
|
|
40020
40221
|
return clientSupportsAirCapability(capabilities, AIR_NATIVE_SUBAGENT_SESSIONS_KEY);
|
|
40021
40222
|
}
|
|
40022
40223
|
|
|
40023
|
-
// src/CodexHookTrust.ts
|
|
40024
|
-
var CODEX_HOOKS_LIST_METHOD = "_codex/hooks/list";
|
|
40025
|
-
var CODEX_HOOKS_TRUST_METHOD = "_codex/hooks/trust";
|
|
40026
|
-
async function listCodexHooks(client, cwd) {
|
|
40027
|
-
const [entry] = (await client.hooksList({ cwds: [cwd] })).data;
|
|
40028
|
-
if (entry === void 0) throw new Error("Codex could not list hooks for the requested directory");
|
|
40029
|
-
return { ...entry, hooks: entry.hooks.filter((hook) => hook.source === "sessionFlags") };
|
|
40030
|
-
}
|
|
40031
|
-
async function trustCodexHooks(client, cwd, requested) {
|
|
40032
|
-
const isListed = (hooks, request) => hooks.find((hook) => hook.key === request.key && hook.currentHash === request.currentHash);
|
|
40033
|
-
const current = (await listCodexHooks(client, cwd)).hooks;
|
|
40034
|
-
const edits = requested.map((request) => {
|
|
40035
|
-
const hook = isListed(current, request);
|
|
40036
|
-
if (hook === void 0) throw new Error("A Codex hook changed before trust was recorded");
|
|
40037
|
-
return hook;
|
|
40038
|
-
}).filter((hook) => hook.trustStatus !== "trusted").map((hook) => ({
|
|
40039
|
-
keyPath: `hooks.state.${JSON.stringify(hook.key)}.trusted_hash`,
|
|
40040
|
-
value: hook.currentHash,
|
|
40041
|
-
mergeStrategy: "replace"
|
|
40042
|
-
}));
|
|
40043
|
-
if (edits.length > 0) {
|
|
40044
|
-
await client.configBatchWrite({ edits, reloadUserConfig: true });
|
|
40045
|
-
}
|
|
40046
|
-
const verified = (await listCodexHooks(client, cwd)).hooks;
|
|
40047
|
-
return requested.every((request) => isListed(verified, request)?.trustStatus === "trusted");
|
|
40048
|
-
}
|
|
40049
|
-
|
|
40050
40224
|
// src/CodexAcpServer.ts
|
|
40051
|
-
import { randomUUID as
|
|
40225
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
40052
40226
|
|
|
40053
40227
|
// src/TitleGenerator.ts
|
|
40054
40228
|
var TITLE_MODEL = "gpt-5.6-luna";
|
|
@@ -40217,9 +40391,6 @@ function titleSource(text) {
|
|
|
40217
40391
|
return text.slice(0, end);
|
|
40218
40392
|
}
|
|
40219
40393
|
|
|
40220
|
-
// src/SessionIndexService.ts
|
|
40221
|
-
import path13 from "node:path";
|
|
40222
|
-
|
|
40223
40394
|
// src/SessionIndex.ts
|
|
40224
40395
|
var AIR_SESSION_INDEX_KEY = "sessionIndex";
|
|
40225
40396
|
var AIR_SESSION_ARCHIVE_KEY = "sessionArchive";
|
|
@@ -40240,6 +40411,32 @@ var AIR_FORKED_FROM_KEY = "forkedFrom";
|
|
|
40240
40411
|
var DEFAULT_SESSION_INDEX_LIMIT = 50;
|
|
40241
40412
|
var MAX_SESSION_INDEX_LIMIT = 100;
|
|
40242
40413
|
var AIR_ARCHIVED_KEY = "archived";
|
|
40414
|
+
var NEUTRAL_SESSION_INDEX_META_KEY = "sessionIndex";
|
|
40415
|
+
var NEUTRAL_SESSION_INDEX_VERSION = 1;
|
|
40416
|
+
var AIR_SESSION_INDEX_META = {
|
|
40417
|
+
read: (meta3) => asRecord3(asRecord3(asRecord3(meta3)[JETBRAINS_META_KEY])[AIR_META_KEY]),
|
|
40418
|
+
write: withAirMeta
|
|
40419
|
+
};
|
|
40420
|
+
var NEUTRAL_SESSION_INDEX_META = {
|
|
40421
|
+
read: (meta3) => asRecord3(asRecord3(meta3)[NEUTRAL_SESSION_INDEX_META_KEY]),
|
|
40422
|
+
write: (meta3, key, value) => {
|
|
40423
|
+
const root = asRecord3(meta3);
|
|
40424
|
+
return { ...root, [NEUTRAL_SESSION_INDEX_META_KEY]: { ...asRecord3(root[NEUTRAL_SESSION_INDEX_META_KEY]), [key]: value } };
|
|
40425
|
+
}
|
|
40426
|
+
};
|
|
40427
|
+
function sessionIndexMetaOf(capabilities) {
|
|
40428
|
+
if (isAirClient(capabilities)) {
|
|
40429
|
+
return clientSupportsAirCapability(capabilities, AIR_SESSION_INDEX_KEY) ? AIR_SESSION_INDEX_META : null;
|
|
40430
|
+
}
|
|
40431
|
+
const declared = capabilities?._meta?.[NEUTRAL_SESSION_INDEX_META_KEY];
|
|
40432
|
+
if (declared === null || typeof declared !== "object" || Array.isArray(declared)) return null;
|
|
40433
|
+
const version2 = declared["version"];
|
|
40434
|
+
return typeof version2 === "number" && Number.isInteger(version2) && version2 >= 1 ? NEUTRAL_SESSION_INDEX_META : null;
|
|
40435
|
+
}
|
|
40436
|
+
function sessionIndexRowFields(row) {
|
|
40437
|
+
const air = AIR_SESSION_INDEX_META.read(row._meta);
|
|
40438
|
+
return Object.keys(air).length > 0 ? air : NEUTRAL_SESSION_INDEX_META.read(row._meta);
|
|
40439
|
+
}
|
|
40243
40440
|
var ARCHIVED_FILTERS = ["unarchived", "archived", "all"];
|
|
40244
40441
|
function archivedSides(filter) {
|
|
40245
40442
|
switch (filter) {
|
|
@@ -40265,9 +40462,8 @@ var sessionListSubscriptionParamsParser = external_exports.preprocess(
|
|
|
40265
40462
|
(params) => params ?? {},
|
|
40266
40463
|
external_exports.record(external_exports.string(), external_exports.unknown())
|
|
40267
40464
|
);
|
|
40268
|
-
function readSessionIndexListOptions(meta3) {
|
|
40269
|
-
const
|
|
40270
|
-
const list = asRecord3(asRecord3(jetbrains[AIR_META_KEY])[AIR_SESSION_LIST_KEY]);
|
|
40465
|
+
function readSessionIndexListOptions(meta3, namespace = AIR_SESSION_INDEX_META) {
|
|
40466
|
+
const list = asRecord3(namespace.read(meta3)[AIR_SESSION_LIST_KEY]);
|
|
40271
40467
|
return {
|
|
40272
40468
|
limit: readLimit(list["limit"]),
|
|
40273
40469
|
archived: readArchivedFilter(list["archived"]),
|
|
@@ -40453,7 +40649,7 @@ function decodeAdapterCursor(cursor) {
|
|
|
40453
40649
|
function invalidCursorError(cursor) {
|
|
40454
40650
|
return RequestError.invalidParams({ cursor }, "invalid cursor");
|
|
40455
40651
|
}
|
|
40456
|
-
function sessionIndexSessionInfo(thread, archived, activity) {
|
|
40652
|
+
function sessionIndexSessionInfo(thread, archived, activity, namespace = AIR_SESSION_INDEX_META) {
|
|
40457
40653
|
const airFields = { [AIR_ARCHIVED_KEY]: archived };
|
|
40458
40654
|
if (thread.recencyAt !== null) airFields[AIR_LAST_PROMPT_AT_KEY] = isoTime(thread.recencyAt);
|
|
40459
40655
|
if (thread.model) airFields[AIR_MODEL_KEY] = thread.model;
|
|
@@ -40462,7 +40658,7 @@ function sessionIndexSessionInfo(thread, archived, activity) {
|
|
|
40462
40658
|
if (activity?.lastTurnEndedAt !== void 0) airFields[AIR_LAST_TURN_ENDED_AT_KEY] = activity.lastTurnEndedAt;
|
|
40463
40659
|
let meta3;
|
|
40464
40660
|
for (const [key, value] of Object.entries(airFields)) {
|
|
40465
|
-
meta3 =
|
|
40661
|
+
meta3 = namespace.write(meta3, key, value);
|
|
40466
40662
|
}
|
|
40467
40663
|
return {
|
|
40468
40664
|
sessionId: thread.id,
|
|
@@ -40550,7 +40746,7 @@ var SessionIndexActivity = class {
|
|
|
40550
40746
|
}
|
|
40551
40747
|
};
|
|
40552
40748
|
function sessionIndexRowSignature(row) {
|
|
40553
|
-
const air =
|
|
40749
|
+
const air = sessionIndexRowFields(row);
|
|
40554
40750
|
return JSON.stringify([
|
|
40555
40751
|
row.title ?? null,
|
|
40556
40752
|
air[AIR_LAST_PROMPT_AT_KEY] ?? null,
|
|
@@ -40565,6 +40761,9 @@ function asRecord3(value) {
|
|
|
40565
40761
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
40566
40762
|
}
|
|
40567
40763
|
|
|
40764
|
+
// src/SessionIndexService.ts
|
|
40765
|
+
import path13 from "node:path";
|
|
40766
|
+
|
|
40568
40767
|
// src/SessionIndexWorktrees.ts
|
|
40569
40768
|
import fs8 from "node:fs";
|
|
40570
40769
|
import path9 from "node:path";
|
|
@@ -40846,7 +41045,7 @@ function remember(cache, key, value) {
|
|
|
40846
41045
|
}
|
|
40847
41046
|
|
|
40848
41047
|
// src/SessionListSubscriptions.ts
|
|
40849
|
-
import { randomUUID as
|
|
41048
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
40850
41049
|
import path12 from "node:path";
|
|
40851
41050
|
|
|
40852
41051
|
// src/CodexHomeWatcher.ts
|
|
@@ -41202,7 +41401,7 @@ var SessionListSubscriptions = class {
|
|
|
41202
41401
|
this.startWatching();
|
|
41203
41402
|
created.ready = this.makeReady(created);
|
|
41204
41403
|
}
|
|
41205
|
-
const subscription = { id:
|
|
41404
|
+
const subscription = { id: randomUUID4(), group, sent: /* @__PURE__ */ new Map(), ready: false, held: null, readyTimer: null, startedSecond: null, epoch: ++this.epoch };
|
|
41206
41405
|
this.subscriptions.set(subscription.id, subscription);
|
|
41207
41406
|
group.subscriptions.add(subscription);
|
|
41208
41407
|
this.startWatching();
|
|
@@ -41292,10 +41491,7 @@ var SessionListSubscriptions = class {
|
|
|
41292
41491
|
refreshLoadedThreads(threadIds) {
|
|
41293
41492
|
this.appServerGeneration++;
|
|
41294
41493
|
if (this.subscriptions.size === 0) return;
|
|
41295
|
-
const loaded = [...this.groups.values()].flatMap((group) => [...group.rows].filter(([, { row }]) =>
|
|
41296
|
-
const meta3 = row._meta;
|
|
41297
|
-
return meta3?.["jetbrains"]?.["air"]?.["state"] !== void 0;
|
|
41298
|
-
}).map(([threadId]) => threadId));
|
|
41494
|
+
const loaded = [...this.groups.values()].flatMap((group) => [...group.rows].filter(([, { row }]) => sessionIndexRowFields(row)[AIR_STATE_KEY] !== void 0).map(([threadId]) => threadId));
|
|
41299
41495
|
for (const threadId of /* @__PURE__ */ new Set([...threadIds, ...loaded])) this.threadChanged(threadId);
|
|
41300
41496
|
if (this.pendingThreads.size > 0) this.requestThreads(this.timings.ownChangeDelayMs);
|
|
41301
41497
|
}
|
|
@@ -41771,8 +41967,8 @@ var SessionIndexService = class {
|
|
|
41771
41967
|
});
|
|
41772
41968
|
}
|
|
41773
41969
|
host;
|
|
41774
|
-
/**
|
|
41775
|
-
|
|
41970
|
+
/** Where this client's session index metadata goes, or `null` when it did not declare `sessionIndex`. */
|
|
41971
|
+
meta = null;
|
|
41776
41972
|
activity;
|
|
41777
41973
|
writes = new SessionWriteQueue();
|
|
41778
41974
|
titles;
|
|
@@ -41785,14 +41981,25 @@ var SessionIndexService = class {
|
|
|
41785
41981
|
rowsWithState = /* @__PURE__ */ new Set();
|
|
41786
41982
|
/** Reads the client capabilities of `initialize`. */
|
|
41787
41983
|
configure(clientCapabilities) {
|
|
41788
|
-
this.
|
|
41984
|
+
this.meta = sessionIndexMetaOf(clientCapabilities);
|
|
41985
|
+
}
|
|
41986
|
+
/** The client declared `sessionIndex`, as AIR or as a client-neutral opt-in. */
|
|
41987
|
+
get enabled() {
|
|
41988
|
+
return this.meta !== null;
|
|
41789
41989
|
}
|
|
41790
41990
|
/**
|
|
41791
|
-
* The AIR capabilities to answer: only
|
|
41792
|
-
* `sessionRename` name the requests that come with it; the client need not declare them.
|
|
41991
|
+
* The AIR capabilities to answer: only an AIR client that declares `sessionIndex` gets them. `sessionArchive`
|
|
41992
|
+
* and `sessionRename` name the requests that come with it; the client need not declare them.
|
|
41793
41993
|
*/
|
|
41794
41994
|
agentCapabilities() {
|
|
41795
|
-
return this.
|
|
41995
|
+
return this.meta === AIR_SESSION_INDEX_META ? [AIR_SESSION_INDEX_KEY, AIR_SESSION_ARCHIVE_KEY, AIR_SESSION_RENAME_KEY, AIR_SESSION_LIST_SUBSCRIBE_KEY] : [];
|
|
41996
|
+
}
|
|
41997
|
+
/** The `_meta.sessionIndex` answer of `initialize` to a client-neutral opt-in, or `null`. */
|
|
41998
|
+
neutralCapability() {
|
|
41999
|
+
return this.meta === NEUTRAL_SESSION_INDEX_META ? {
|
|
42000
|
+
version: NEUTRAL_SESSION_INDEX_VERSION,
|
|
42001
|
+
capabilities: [AIR_SESSION_ARCHIVE_KEY, AIR_SESSION_RENAME_KEY, AIR_SESSION_LIST_SUBSCRIBE_KEY]
|
|
42002
|
+
} : null;
|
|
41796
42003
|
}
|
|
41797
42004
|
/**
|
|
41798
42005
|
* Feeds the thread notifications of an app-server, for every thread, to the session index. Each client is
|
|
@@ -41826,7 +42033,7 @@ var SessionIndexService = class {
|
|
|
41826
42033
|
* reads the local state DB and works without one.
|
|
41827
42034
|
*/
|
|
41828
42035
|
async list(params) {
|
|
41829
|
-
const options = readSessionIndexListOptions(params._meta);
|
|
42036
|
+
const options = readSessionIndexListOptions(params._meta, this.requireMeta());
|
|
41830
42037
|
const cwd = params.cwd?.trim() || null;
|
|
41831
42038
|
return await this.readRows(cwd, options, params.cursor ?? null);
|
|
41832
42039
|
}
|
|
@@ -41901,13 +42108,13 @@ var SessionIndexService = class {
|
|
|
41901
42108
|
if (archived ? open3 : this.host.session(sessionId) !== void 0) {
|
|
41902
42109
|
await new ACPSessionConnection(this.host.connection(), sessionId).update({
|
|
41903
42110
|
sessionUpdate: "session_info_update",
|
|
41904
|
-
_meta:
|
|
42111
|
+
_meta: this.requireMeta().write(void 0, AIR_ARCHIVED_KEY, archived)
|
|
41905
42112
|
});
|
|
41906
42113
|
}
|
|
41907
42114
|
return {};
|
|
41908
42115
|
}
|
|
41909
42116
|
/**
|
|
41910
|
-
* Deletes the thread for `session/delete`:
|
|
42117
|
+
* Deletes the thread for `session/delete`: a `sessionIndex` client then means "delete", not "done", because it has
|
|
41911
42118
|
* `_session/archive` for that. A thread that this connection had open but Codex never persisted (no
|
|
41912
42119
|
* prompt yet) is gone with the close, so it counts as deleted.
|
|
41913
42120
|
*/
|
|
@@ -41939,6 +42146,10 @@ var SessionIndexService = class {
|
|
|
41939
42146
|
throw RequestError.methodNotFound(method);
|
|
41940
42147
|
}
|
|
41941
42148
|
}
|
|
42149
|
+
requireMeta() {
|
|
42150
|
+
if (this.meta === null) throw new Error("The client did not declare sessionIndex");
|
|
42151
|
+
return this.meta;
|
|
42152
|
+
}
|
|
41942
42153
|
async readRows(cwd, options, cursor) {
|
|
41943
42154
|
const relativeCwd = cwd !== null && !isAbsolutePathLike(cwd) ? cwd : null;
|
|
41944
42155
|
const cwds = cwd === null || relativeCwd !== null ? null : options.includeWorktrees ? linkedWorktreeCwds(cwd) : canonicalCwds(cwd);
|
|
@@ -41964,7 +42175,7 @@ var SessionIndexService = class {
|
|
|
41964
42175
|
if (activity?.state !== void 0) this.rowsWithState.add(thread.id);
|
|
41965
42176
|
else this.rowsWithState.delete(thread.id);
|
|
41966
42177
|
return this.withActiveAdditionalDirectories(
|
|
41967
|
-
sessionIndexSessionInfo(thread, entry.archived, activity)
|
|
42178
|
+
sessionIndexSessionInfo(thread, entry.archived, activity, this.requireMeta())
|
|
41968
42179
|
);
|
|
41969
42180
|
});
|
|
41970
42181
|
}
|
|
@@ -42449,7 +42660,8 @@ var CodexAcpServer = class {
|
|
|
42449
42660
|
recovery;
|
|
42450
42661
|
initializeRequest = null;
|
|
42451
42662
|
providerUpdate = null;
|
|
42452
|
-
|
|
42663
|
+
hookReview = new CodexHookReview(() => this.codexAcpClient);
|
|
42664
|
+
/** The `sessionIndex` extension, for AIR or a client-neutral opt-in, see `SessionIndexService.ts`. */
|
|
42453
42665
|
sessionIndex = new SessionIndexService({
|
|
42454
42666
|
connection: () => this.connection,
|
|
42455
42667
|
client: () => this.codexAcpClient,
|
|
@@ -42496,7 +42708,7 @@ var CodexAcpServer = class {
|
|
|
42496
42708
|
this.captureStderr();
|
|
42497
42709
|
this.getExitCode = getExitCode ?? (() => this.codexProcessState?.connection.process.exitCode ?? null);
|
|
42498
42710
|
this.getRecentStderr = getRecentStderr ?? (() => this.codexProcessState?.stderr ?? "");
|
|
42499
|
-
this.sessionFailureEpoch =
|
|
42711
|
+
this.sessionFailureEpoch = randomUUID5();
|
|
42500
42712
|
this.clientInfo = null;
|
|
42501
42713
|
this.clientCapabilities = null;
|
|
42502
42714
|
this.capabilities = ClientCapabilities.DEFAULT;
|
|
@@ -42525,6 +42737,7 @@ var CodexAcpServer = class {
|
|
|
42525
42737
|
this.reportingConnection.reports.compareMeta = this.capabilities.airClient;
|
|
42526
42738
|
this.booleanConfigOptionsSupported = clientSupportsBooleanConfigOptions(_params.clientCapabilities);
|
|
42527
42739
|
this.sessionIndex.configure(_params.clientCapabilities);
|
|
42740
|
+
this.hookReview.configure(_params.clientCapabilities?._meta?.["codexHooks"], this.capabilities.airClient);
|
|
42528
42741
|
await this.runWithProcessCheck(() => this.codexAcpClient.initialize(_params));
|
|
42529
42742
|
this.sessionIndex.observe(this.codexAcpClient);
|
|
42530
42743
|
this.publishFirstAuthStatusAfterResponse();
|
|
@@ -42533,6 +42746,7 @@ var CodexAcpServer = class {
|
|
|
42533
42746
|
controlMethod: GOAL_CONTROL_METHOD,
|
|
42534
42747
|
actions: [...GOAL_CONTROL_ACTIONS]
|
|
42535
42748
|
};
|
|
42749
|
+
const neutralSessionIndex = this.sessionIndex.neutralCapability();
|
|
42536
42750
|
const sessionCapabilities = {
|
|
42537
42751
|
resume: {},
|
|
42538
42752
|
list: {},
|
|
@@ -42583,6 +42797,10 @@ var CodexAcpServer = class {
|
|
|
42583
42797
|
...this.capabilities.asyncTasks && !this.capabilities.airClient ? {
|
|
42584
42798
|
"async-tasks": asyncTaskCapability()
|
|
42585
42799
|
} : {},
|
|
42800
|
+
...this.hookReview.enabled ? { codexHooks: { version: 1, reviewToken: true } } : {},
|
|
42801
|
+
...neutralSessionIndex ? {
|
|
42802
|
+
[NEUTRAL_SESSION_INDEX_META_KEY]: neutralSessionIndex
|
|
42803
|
+
} : {},
|
|
42586
42804
|
// Only AIR gets the AIR extension, see `docs/air-extensions.md`.
|
|
42587
42805
|
...this.capabilities.airClient ? {
|
|
42588
42806
|
[JETBRAINS_META_KEY]: {
|
|
@@ -42612,15 +42830,22 @@ var CodexAcpServer = class {
|
|
|
42612
42830
|
if (this.providerUpdate !== null) await this.waitForProviderUpdate();
|
|
42613
42831
|
const appServer = this.ensureAppServer();
|
|
42614
42832
|
if (appServer) await appServer;
|
|
42615
|
-
return await this.runWithProcessCheck(() =>
|
|
42833
|
+
return await this.runWithProcessCheck(() => this.hookReview.list(cwd));
|
|
42616
42834
|
}
|
|
42617
|
-
async trustHooks(cwd, hooks) {
|
|
42835
|
+
async trustHooks(cwd, hooks, reviewToken) {
|
|
42618
42836
|
if (this.providerUpdate !== null) await this.waitForProviderUpdate();
|
|
42619
42837
|
const appServer = this.ensureAppServer();
|
|
42620
42838
|
if (appServer) await appServer;
|
|
42621
|
-
return { trusted: await this.runWithProcessCheck(() =>
|
|
42839
|
+
return { trusted: await this.runWithProcessCheck(() => this.hookReview.trust(cwd, hooks, reviewToken)) };
|
|
42622
42840
|
}
|
|
42623
42841
|
async extMethod(method, params) {
|
|
42842
|
+
if ((method === GOAL_CONTROL_METHOD || method === LEGACY_GOAL_CONTROL_METHOD) && (params["action"] === "set" || params["action"] === "resume")) {
|
|
42843
|
+
const session = this.sessions.get(params["sessionId"]);
|
|
42844
|
+
if (session !== void 0) return this.hookReview.run(session.cwd, params["_meta"], () => this.extMethodReviewed(method, params));
|
|
42845
|
+
}
|
|
42846
|
+
return this.extMethodReviewed(method, params);
|
|
42847
|
+
}
|
|
42848
|
+
async extMethodReviewed(method, params) {
|
|
42624
42849
|
const methodRequest = { method, params };
|
|
42625
42850
|
if (!isExtMethodRequest(methodRequest)) {
|
|
42626
42851
|
return {};
|
|
@@ -43157,6 +43382,9 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
43157
43382
|
return null;
|
|
43158
43383
|
}
|
|
43159
43384
|
async loadSession(params) {
|
|
43385
|
+
return this.hookReview.run(params.cwd, params._meta, () => this.loadSessionReviewed(params));
|
|
43386
|
+
}
|
|
43387
|
+
async loadSessionReviewed(params) {
|
|
43160
43388
|
readSessionInstructionAppend(params._meta);
|
|
43161
43389
|
return this.recovery === null ? await this.loadSessionOnce(params) : await this.recovery.trackOpen(params.sessionId, () => this.loadSessionOnce(params));
|
|
43162
43390
|
}
|
|
@@ -43200,6 +43428,9 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
43200
43428
|
};
|
|
43201
43429
|
}
|
|
43202
43430
|
async resumeSession(params) {
|
|
43431
|
+
return this.hookReview.run(params.cwd, params._meta, () => this.resumeSessionReviewed(params));
|
|
43432
|
+
}
|
|
43433
|
+
async resumeSessionReviewed(params) {
|
|
43203
43434
|
readSessionInstructionAppend(params._meta);
|
|
43204
43435
|
return this.recovery === null ? await this.resumeSessionOnce(params) : await this.recovery.trackOpen(params.sessionId, () => this.resumeSessionOnce(params));
|
|
43205
43436
|
}
|
|
@@ -43223,6 +43454,9 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
43223
43454
|
};
|
|
43224
43455
|
}
|
|
43225
43456
|
async forkSession(params) {
|
|
43457
|
+
return this.hookReview.run(params.cwd, params._meta, () => this.forkSessionReviewed(params));
|
|
43458
|
+
}
|
|
43459
|
+
async forkSessionReviewed(params) {
|
|
43226
43460
|
readSessionInstructionAppend(params._meta);
|
|
43227
43461
|
if (this.providerUpdate !== null) {
|
|
43228
43462
|
await this.waitForProviderUpdate();
|
|
@@ -43335,6 +43569,9 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
43335
43569
|
return this.sessionOpenGenerations.get(sessionId) === this.getSessionGeneration(sessionId);
|
|
43336
43570
|
}
|
|
43337
43571
|
async newSession(params) {
|
|
43572
|
+
return this.hookReview.run(params.cwd, params._meta, () => this.newSessionReviewed(params));
|
|
43573
|
+
}
|
|
43574
|
+
async newSessionReviewed(params) {
|
|
43338
43575
|
readSessionInstructionAppend(params._meta);
|
|
43339
43576
|
if (this.providerUpdate !== null) {
|
|
43340
43577
|
await this.waitForProviderUpdate();
|
|
@@ -43360,14 +43597,19 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
43360
43597
|
const appServer = this.ensureAppServer();
|
|
43361
43598
|
if (appServer) await appServer;
|
|
43362
43599
|
const elicitationRequester = this.createUrlElicitationRequester(requestId);
|
|
43363
|
-
|
|
43364
|
-
|
|
43365
|
-
|
|
43366
|
-
|
|
43600
|
+
this.hookReview.invalidate();
|
|
43601
|
+
try {
|
|
43602
|
+
const isAuthenticated = await this.runWithProcessCheck(() => this.codexAcpClient.authenticate(_params, elicitationRequester));
|
|
43603
|
+
if (!isAuthenticated) {
|
|
43604
|
+
logger.log("Authenticate request failed");
|
|
43605
|
+
throw RequestError.authRequired({ methodId: _params.methodId }, "Sign-in did not complete");
|
|
43606
|
+
}
|
|
43607
|
+
await this.refreshAuthState(this.getAuthProviderForAuthenticateRequest(_params));
|
|
43608
|
+
logger.log("Authenticate request completed");
|
|
43609
|
+
return {};
|
|
43610
|
+
} finally {
|
|
43611
|
+
this.hookReview.invalidate();
|
|
43367
43612
|
}
|
|
43368
|
-
await this.refreshAuthState(this.getAuthProviderForAuthenticateRequest(_params));
|
|
43369
|
-
logger.log("Authenticate request completed");
|
|
43370
|
-
return {};
|
|
43371
43613
|
}
|
|
43372
43614
|
createUrlElicitationRequester(requestId) {
|
|
43373
43615
|
if (requestId == null || !clientSupportsUrlElicitation(this.clientCapabilities)) {
|
|
@@ -43406,11 +43648,13 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
43406
43648
|
}
|
|
43407
43649
|
async setProvider(params) {
|
|
43408
43650
|
this.codexAcpClient.setProvider(params);
|
|
43651
|
+
this.hookReview.invalidate();
|
|
43409
43652
|
await this.enqueueProviderUpdate((client) => client.setProvider(params));
|
|
43410
43653
|
return {};
|
|
43411
43654
|
}
|
|
43412
43655
|
async disableProvider(params) {
|
|
43413
43656
|
this.codexAcpClient.disableProvider(params);
|
|
43657
|
+
if (params.providerId === OPENAI_PROVIDER_ID) this.hookReview.invalidate();
|
|
43414
43658
|
if (params.providerId !== OPENAI_PROVIDER_ID) {
|
|
43415
43659
|
return {};
|
|
43416
43660
|
}
|
|
@@ -43439,6 +43683,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
43439
43683
|
throw new Error("Cannot restart Codex app-server before ACP initialization");
|
|
43440
43684
|
}
|
|
43441
43685
|
await replacement.initialize(this.initializeRequest);
|
|
43686
|
+
this.hookReview.bind(replacement);
|
|
43442
43687
|
this.codexAcpClient = replacement;
|
|
43443
43688
|
this.sessionIndex.observe(replacement);
|
|
43444
43689
|
this.availableCommands = this.createAvailableCommands(replacement);
|
|
@@ -43451,6 +43696,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
43451
43696
|
if (replacement.appServerClient.connectionLoss.lost) {
|
|
43452
43697
|
break;
|
|
43453
43698
|
}
|
|
43699
|
+
if (this.hookReview.enabled) continue;
|
|
43454
43700
|
try {
|
|
43455
43701
|
const request = {
|
|
43456
43702
|
sessionId: session.sessionId,
|
|
@@ -43553,7 +43799,9 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
43553
43799
|
currentClient: () => this.codexAcpClient,
|
|
43554
43800
|
createClient: (connection) => {
|
|
43555
43801
|
this.captureStderr();
|
|
43556
|
-
|
|
43802
|
+
const client = this.codexAcpClient.withAppServer(new CodexAppServerClient(connection.connection));
|
|
43803
|
+
this.hookReview.bind(client);
|
|
43804
|
+
return client;
|
|
43557
43805
|
},
|
|
43558
43806
|
handshake: (client) => this.initializeRequest !== null && this.codexAcpClient.initialized ? client.initialize(this.initializeRequest) : null,
|
|
43559
43807
|
install: (client) => this.installCodexClient(client),
|
|
@@ -43585,6 +43833,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
43585
43833
|
installCodexClient(client) {
|
|
43586
43834
|
client.adoptRoutingFrom(this.codexAcpClient);
|
|
43587
43835
|
this.codexAcpClient = client;
|
|
43836
|
+
this.hookReview.bind(client);
|
|
43588
43837
|
this.sessionIndex.observe(client);
|
|
43589
43838
|
this.availableCommands = this.createAvailableCommands(client);
|
|
43590
43839
|
for (const session of this.sessions.values()) {
|
|
@@ -44120,11 +44369,15 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
44120
44369
|
}
|
|
44121
44370
|
return await new Promise((resolve, reject) => {
|
|
44122
44371
|
let turnStarted = false;
|
|
44123
|
-
const promptDone = this.
|
|
44124
|
-
|
|
44125
|
-
|
|
44126
|
-
|
|
44127
|
-
|
|
44372
|
+
const promptDone = this.hookReview.continueOperation(
|
|
44373
|
+
this.getSessionState(params.sessionId).cwd,
|
|
44374
|
+
params._meta,
|
|
44375
|
+
() => this.promptReviewed(params, void 0, () => {
|
|
44376
|
+
turnStarted = true;
|
|
44377
|
+
logger.log(`${source} started a new turn`, { sessionId: params.sessionId });
|
|
44378
|
+
resolve(true);
|
|
44379
|
+
})
|
|
44380
|
+
);
|
|
44128
44381
|
promptDone.then(
|
|
44129
44382
|
(response) => {
|
|
44130
44383
|
if (!turnStarted && response.stopReason === "cancelled") {
|
|
@@ -44179,7 +44432,8 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
44179
44432
|
}
|
|
44180
44433
|
return {
|
|
44181
44434
|
sessionId,
|
|
44182
|
-
prompt
|
|
44435
|
+
prompt,
|
|
44436
|
+
...params["_meta"] === void 0 ? {} : { _meta: params["_meta"] }
|
|
44183
44437
|
};
|
|
44184
44438
|
}
|
|
44185
44439
|
createSessionConfigOptions(sessionState) {
|
|
@@ -44975,6 +45229,13 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
44975
45229
|
return turnId;
|
|
44976
45230
|
}
|
|
44977
45231
|
async prompt(params, signal, onTurnStarted) {
|
|
45232
|
+
return this.hookReview.run(
|
|
45233
|
+
this.getSessionState(params.sessionId).cwd,
|
|
45234
|
+
params._meta,
|
|
45235
|
+
() => this.promptReviewed(params, signal, onTurnStarted)
|
|
45236
|
+
);
|
|
45237
|
+
}
|
|
45238
|
+
async promptReviewed(params, signal, onTurnStarted) {
|
|
44978
45239
|
if (this.providerUpdate !== null) {
|
|
44979
45240
|
await this.waitForProviderUpdate();
|
|
44980
45241
|
}
|
|
@@ -45816,6 +46077,7 @@ var asyncTaskStopParamsParser = external_exports.object({
|
|
|
45816
46077
|
}).passthrough();
|
|
45817
46078
|
var hooksListParamsParser = external_exports.object({ cwd: external_exports.string().trim().min(1) });
|
|
45818
46079
|
var hooksTrustParamsParser = external_exports.object({
|
|
46080
|
+
reviewToken: external_exports.string().min(1).optional(),
|
|
45819
46081
|
cwd: external_exports.string().trim().min(1),
|
|
45820
46082
|
hooks: external_exports.array(external_exports.object({ key: external_exports.string().min(1), currentHash: external_exports.string().min(1) })).min(1)
|
|
45821
46083
|
});
|
|
@@ -45899,5 +46161,5 @@ function startAcpServer() {
|
|
|
45899
46161
|
codexAcpServer = null;
|
|
45900
46162
|
}
|
|
45901
46163
|
});
|
|
45902
|
-
}).onRequest(methods.agent.initialize, (ctx) => getAgent().initialize(ctx.params)).onRequest(methods.agent.session.new, (ctx) => getAgent().newSession(ctx.params)).onRequest(methods.agent.session.load, (ctx) => getAgent().loadSession(ctx.params)).onRequest(methods.agent.session.fork, (ctx) => getAgent().forkSession(ctx.params)).onRequest(methods.agent.session.list, (ctx) => getAgent().listSessions(ctx.params)).onRequest(methods.agent.session.delete, (ctx) => getAgent().deleteSession(ctx.params)).onRequest(methods.agent.session.resume, (ctx) => getAgent().resumeSession(ctx.params)).onRequest(methods.agent.session.close, (ctx) => getAgent().closeSession(ctx.params)).onRequest(methods.agent.session.setMode, (ctx) => getAgent().setSessionMode(ctx.params)).onRequest(methods.agent.session.setConfigOption, (ctx) => getAgent().setSessionConfigOption(ctx.params)).onRequest(methods.agent.authenticate, (ctx) => getAgent().authenticate(ctx.params, ctx.requestId)).onRequest(methods.agent.logout, (ctx) => getAgent().logout(ctx.params)).onRequest(methods.agent.providers.list, (ctx) => getAgent().listProviders(ctx.params)).onRequest(methods.agent.providers.set, (ctx) => getAgent().setProvider(ctx.params)).onRequest(methods.agent.providers.disable, (ctx) => getAgent().disableProvider(ctx.params)).onRequest(methods.agent.session.prompt, (ctx) => getAgent().prompt(ctx.params, ctx.signal)).onNotification(methods.agent.session.cancel, (ctx) => getAgent().cancel(ctx.params)).onRequest("authentication/status", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/status", ctx.params)).onRequest("authentication/logout", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/logout", ctx.params)).onRequest(LEGACY_SET_SESSION_MODEL_METHOD, legacySetSessionModelParamsParser, (ctx) => getAgent().extMethod(LEGACY_SET_SESSION_MODEL_METHOD, ctx.params)).onRequest(SESSION_STEERING_METHOD, sessionSteerParamsParser, (ctx) => getAgent().extMethod(SESSION_STEERING_METHOD, ctx.params)).onRequest(ASYNC_TASK_STOP_METHOD, asyncTaskStopParamsParser, (ctx) => getAgent().extMethod(ASYNC_TASK_STOP_METHOD, ctx.params)).onRequest(CODEX_HOOKS_LIST_METHOD, hooksListParamsParser, (ctx) => getAgent().listHooks(ctx.params.cwd)).onRequest(CODEX_HOOKS_TRUST_METHOD, hooksTrustParamsParser, (ctx) => getAgent().trustHooks(ctx.params.cwd, ctx.params.hooks)).onRequest(GOAL_CONTROL_METHOD, goalControlParamsParser, (ctx) => getAgent().extMethod(GOAL_CONTROL_METHOD, ctx.params)).onRequest(SESSION_RENAME_METHOD, sessionRenameParamsParser, (ctx) => getAgent().sessionIndex.rename(ctx.params)).onRequest(SESSION_ARCHIVE_METHOD, sessionArchiveParamsParser, (ctx) => getAgent().sessionIndex.setArchived(ctx.params, true)).onRequest(SESSION_UNARCHIVE_METHOD, sessionArchiveParamsParser, (ctx) => getAgent().sessionIndex.setArchived(ctx.params, false)).onRequest(SESSION_LIST_SUBSCRIBE_METHOD, sessionListSubscriptionParamsParser, (ctx) => getAgent().sessionIndex.subscribeList(ctx.params)).onRequest(SESSION_LIST_UNSUBSCRIBE_METHOD, sessionListSubscriptionParamsParser, (ctx) => getAgent().sessionIndex.unsubscribeList(ctx.params)).connect(acpJsonStream);
|
|
46164
|
+
}).onRequest(methods.agent.initialize, (ctx) => getAgent().initialize(ctx.params)).onRequest(methods.agent.session.new, (ctx) => getAgent().newSession(ctx.params)).onRequest(methods.agent.session.load, (ctx) => getAgent().loadSession(ctx.params)).onRequest(methods.agent.session.fork, (ctx) => getAgent().forkSession(ctx.params)).onRequest(methods.agent.session.list, (ctx) => getAgent().listSessions(ctx.params)).onRequest(methods.agent.session.delete, (ctx) => getAgent().deleteSession(ctx.params)).onRequest(methods.agent.session.resume, (ctx) => getAgent().resumeSession(ctx.params)).onRequest(methods.agent.session.close, (ctx) => getAgent().closeSession(ctx.params)).onRequest(methods.agent.session.setMode, (ctx) => getAgent().setSessionMode(ctx.params)).onRequest(methods.agent.session.setConfigOption, (ctx) => getAgent().setSessionConfigOption(ctx.params)).onRequest(methods.agent.authenticate, (ctx) => getAgent().authenticate(ctx.params, ctx.requestId)).onRequest(methods.agent.logout, (ctx) => getAgent().logout(ctx.params)).onRequest(methods.agent.providers.list, (ctx) => getAgent().listProviders(ctx.params)).onRequest(methods.agent.providers.set, (ctx) => getAgent().setProvider(ctx.params)).onRequest(methods.agent.providers.disable, (ctx) => getAgent().disableProvider(ctx.params)).onRequest(methods.agent.session.prompt, (ctx) => getAgent().prompt(ctx.params, ctx.signal)).onNotification(methods.agent.session.cancel, (ctx) => getAgent().cancel(ctx.params)).onRequest("authentication/status", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/status", ctx.params)).onRequest("authentication/logout", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/logout", ctx.params)).onRequest(LEGACY_SET_SESSION_MODEL_METHOD, legacySetSessionModelParamsParser, (ctx) => getAgent().extMethod(LEGACY_SET_SESSION_MODEL_METHOD, ctx.params)).onRequest(SESSION_STEERING_METHOD, sessionSteerParamsParser, (ctx) => getAgent().extMethod(SESSION_STEERING_METHOD, ctx.params)).onRequest(ASYNC_TASK_STOP_METHOD, asyncTaskStopParamsParser, (ctx) => getAgent().extMethod(ASYNC_TASK_STOP_METHOD, ctx.params)).onRequest(CODEX_HOOKS_LIST_METHOD, hooksListParamsParser, (ctx) => getAgent().listHooks(ctx.params.cwd)).onRequest(CODEX_HOOKS_TRUST_METHOD, hooksTrustParamsParser, (ctx) => getAgent().trustHooks(ctx.params.cwd, ctx.params.hooks, ctx.params.reviewToken)).onRequest(GOAL_CONTROL_METHOD, goalControlParamsParser, (ctx) => getAgent().extMethod(GOAL_CONTROL_METHOD, ctx.params)).onRequest(SESSION_RENAME_METHOD, sessionRenameParamsParser, (ctx) => getAgent().sessionIndex.rename(ctx.params)).onRequest(SESSION_ARCHIVE_METHOD, sessionArchiveParamsParser, (ctx) => getAgent().sessionIndex.setArchived(ctx.params, true)).onRequest(SESSION_UNARCHIVE_METHOD, sessionArchiveParamsParser, (ctx) => getAgent().sessionIndex.setArchived(ctx.params, false)).onRequest(SESSION_LIST_SUBSCRIBE_METHOD, sessionListSubscriptionParamsParser, (ctx) => getAgent().sessionIndex.subscribeList(ctx.params)).onRequest(SESSION_LIST_UNSUBSCRIBE_METHOD, sessionListSubscriptionParamsParser, (ctx) => getAgent().sessionIndex.unsubscribeList(ctx.params)).connect(acpJsonStream);
|
|
45903
46165
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "2.2.2-alas.
|
|
6
|
+
"version": "2.2.2-alas.4",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"bin": {
|
|
@@ -80,6 +80,6 @@
|
|
|
80
80
|
"alasDownstream": {
|
|
81
81
|
"upstreamVersion": "2.2.2",
|
|
82
82
|
"upstreamCommit": "202e66e63343ec4f5a5e35ab590251d813d129ca",
|
|
83
|
-
"sourceCommit": "
|
|
83
|
+
"sourceCommit": "4b517e7e77ece05ef63f34c890bc853b7fb96a43"
|
|
84
84
|
}
|
|
85
85
|
}
|