@alas-ide/codex-acp 2.2.2-alas.1 → 2.2.2-alas.3

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.
Files changed (3) hide show
  1. package/README.md +1 -0
  2. package/dist/index.js +143 -28
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -21,6 +21,7 @@ Use [OpenAI Codex](https://github.com/openai/codex) from [Agent Client Protocol]
21
21
  - Typed warnings and errors through the opt-in [AIR session failure extension](docs/air-extensions.md#session-failure).
22
22
  - All AIR extensions, capabilities, and `_meta` keys: [AIR extensions](docs/air-extensions.md).
23
23
  - A per-turn [agent file-change report](docs/air-extensions.md#agent-file-change-report) after capability negotiation.
24
+ - Client-provided, session-scoped [system prompt append](docs/system-prompt-extension.md), preserving configured developer instructions.
24
25
  - Client-provided MCP servers over command-based stdio config and HTTP transport.
25
26
  - Slash commands: `/status`, `/mcp` (with `/mcp reconnect`), `/skills`, `/goal`, `/review`, `/review-branch`, `/review-commit`, `/compact`, and `/logout`, as well as configured skills.
26
27
 
package/dist/index.js CHANGED
@@ -27893,6 +27893,20 @@ function attachLogs(proc) {
27893
27893
  });
27894
27894
  }
27895
27895
 
27896
+ // src/SessionInstructions.ts
27897
+ var SYSTEM_PROMPT_CAPABILITY = { version: 1, append: true, clear: true, maxBytes: 256 * 1024 };
27898
+ function readSessionInstructionAppend(meta3) {
27899
+ const prompt = meta3?.["systemPrompt"];
27900
+ if (prompt === void 0) return void 0;
27901
+ if (prompt === null || typeof prompt !== "object" || Array.isArray(prompt) || Object.keys(prompt).some((key) => key !== "append") || !("append" in prompt) || typeof prompt.append !== "string") {
27902
+ throw RequestError.invalidParams(void 0, "systemPrompt must contain only an append string");
27903
+ }
27904
+ if (Buffer.byteLength(prompt.append, "utf8") > SYSTEM_PROMPT_CAPABILITY.maxBytes) {
27905
+ throw RequestError.invalidParams(void 0, `systemPrompt.append exceeds ${SYSTEM_PROMPT_CAPABILITY.maxBytes} UTF-8 bytes`);
27906
+ }
27907
+ return prompt.append;
27908
+ }
27909
+
27896
27910
  // src/AcpSessionExtensions.ts
27897
27911
  function asSdkSessionNotification(notification) {
27898
27912
  return notification;
@@ -34378,7 +34392,7 @@ var package_default = {
34378
34392
  publishConfig: {
34379
34393
  access: "public"
34380
34394
  },
34381
- version: "2.2.2-alas.1",
34395
+ version: "2.2.2-alas.3",
34382
34396
  description: "",
34383
34397
  main: "dist/index.js",
34384
34398
  bin: {
@@ -34455,7 +34469,7 @@ var package_default = {
34455
34469
  alasDownstream: {
34456
34470
  upstreamVersion: "2.2.2",
34457
34471
  upstreamCommit: "202e66e63343ec4f5a5e35ab590251d813d129ca",
34458
- sourceCommit: "066895c1361ae7a82d1e0216a87b32f9be657b2c"
34472
+ sourceCommit: "2be0ccf63ad9c18131815207511597bb34d6adc0"
34459
34473
  }
34460
34474
  };
34461
34475
 
@@ -34659,6 +34673,8 @@ var CodexSubagentSubscriptions = class {
34659
34673
  // src/SessionFork.ts
34660
34674
  import { createHash } from "node:crypto";
34661
34675
  async function forkSession(request, additionalDirectories, dependencies) {
34676
+ const append = readSessionInstructionAppend(request._meta);
34677
+ const instructionOverride = await dependencies.sessionInstructionOverride(append, request.cwd);
34662
34678
  await dependencies.refreshSkills(request.cwd, additionalDirectories);
34663
34679
  const lastTurnId = await resolveForkTurnId(request, dependencies.codexClient);
34664
34680
  const sessionConfig = await dependencies.createSessionConfig(
@@ -34667,6 +34683,7 @@ async function forkSession(request, additionalDirectories, dependencies) {
34667
34683
  request.mcpServers ?? []
34668
34684
  );
34669
34685
  const response = await dependencies.codexClient.threadFork({
34686
+ ...instructionOverride,
34670
34687
  excludeTurns: true,
34671
34688
  config: sessionConfig.config,
34672
34689
  cwd: request.cwd,
@@ -34767,6 +34784,13 @@ var CodexAcpClient = class _CodexAcpClient {
34767
34784
  pendingLoginCompleted = null;
34768
34785
  pendingAccountUpdated = null;
34769
34786
  sessionNotificationQueues = /* @__PURE__ */ new Map();
34787
+ /**
34788
+ * The `systemPrompt.append` each thread was opened with in this process. A
34789
+ * client that reconnects to a live adapter sends `session/load` or
34790
+ * `session/resume` again with the same text; Codex already holds those
34791
+ * instructions, so a matching repeat is accepted without an override.
34792
+ */
34793
+ appliedInstructionAppends = /* @__PURE__ */ new Map();
34770
34794
  subagents;
34771
34795
  skillExtraRoots = [];
34772
34796
  configPath = null;
@@ -35232,16 +35256,20 @@ var CodexAcpClient = class _CodexAcpClient {
35232
35256
  }
35233
35257
  }
35234
35258
  async resumeSession(request, onSubscribed) {
35259
+ const append = readSessionInstructionAppend(request._meta);
35260
+ const instructionOverride = await this.sessionInstructionOverride(append, request.cwd, request.sessionId);
35235
35261
  const additionalDirectories = readAdditionalDirectories(request.cwd, request.additionalDirectories, request._meta);
35236
35262
  await this.refreshSkills(request.cwd, additionalDirectories);
35237
35263
  const sessionConfig = await this.createSessionConfig(request.cwd, additionalDirectories, request.mcpServers ?? []);
35238
35264
  const response = await this.resumeThread({
35239
35265
  excludeTurns: true,
35266
+ ...instructionOverride,
35240
35267
  config: sessionConfig.config,
35241
35268
  cwd: request.cwd,
35242
35269
  modelProvider: await this.getResumeModelProvider(),
35243
35270
  threadId: request.sessionId
35244
35271
  });
35272
+ this.recordInstructionAppend(request.sessionId, append);
35245
35273
  onSubscribed?.();
35246
35274
  const codexModels = await this.fetchAvailableModels();
35247
35275
  const currentModelId = this.createModelId(codexModels, response.model, response.reasoningEffort).toString();
@@ -35259,8 +35287,9 @@ var CodexAcpClient = class _CodexAcpClient {
35259
35287
  }
35260
35288
  async forkSession(request, releaseFailedFork = (threadId) => this.closeSession(threadId)) {
35261
35289
  const additionalDirectories = readAdditionalDirectories(request.cwd, request.additionalDirectories, request._meta);
35262
- return await forkSession(request, additionalDirectories, {
35290
+ const metadata = await forkSession(request, additionalDirectories, {
35263
35291
  codexClient: this.codexClient,
35292
+ sessionInstructionOverride: (append, cwd) => this.sessionInstructionOverride(append, cwd),
35264
35293
  refreshSkills: (cwd, directories) => this.refreshSkills(cwd, directories),
35265
35294
  createSessionConfig: (cwd, directories, mcpServers) => this.createSessionConfig(cwd, directories, mcpServers),
35266
35295
  getResumeModelProvider: () => this.getResumeModelProvider(),
@@ -35269,18 +35298,24 @@ var CodexAcpClient = class _CodexAcpClient {
35269
35298
  getCollaborationMode: (sessionId) => this.getCollaborationMode(sessionId),
35270
35299
  releaseFailedFork
35271
35300
  });
35301
+ this.recordInstructionAppend(metadata.sessionId, readSessionInstructionAppend(request._meta));
35302
+ return metadata;
35272
35303
  }
35273
35304
  async loadSession(request, onSubscribed) {
35305
+ const append = readSessionInstructionAppend(request._meta);
35306
+ const instructionOverride = await this.sessionInstructionOverride(append, request.cwd, request.sessionId);
35274
35307
  const additionalDirectories = readAdditionalDirectories(request.cwd, request.additionalDirectories, request._meta);
35275
35308
  await this.refreshSkills(request.cwd, additionalDirectories);
35276
35309
  const sessionConfig = await this.createSessionConfig(request.cwd, additionalDirectories, request.mcpServers ?? []);
35277
35310
  const response = await this.resumeThread({
35278
35311
  excludeTurns: true,
35312
+ ...instructionOverride,
35279
35313
  config: sessionConfig.config,
35280
35314
  cwd: request.cwd,
35281
35315
  modelProvider: await this.getResumeModelProvider(),
35282
35316
  threadId: request.sessionId
35283
35317
  });
35318
+ this.recordInstructionAppend(request.sessionId, append);
35284
35319
  onSubscribed?.();
35285
35320
  let thread = { ...response.thread, turns: [] };
35286
35321
  let history = noItems();
@@ -35335,16 +35370,24 @@ var CodexAcpClient = class _CodexAcpClient {
35335
35370
  return null;
35336
35371
  }
35337
35372
  async newSession(request) {
35373
+ const append = readSessionInstructionAppend(request._meta);
35374
+ const custom2 = airCustomInstructions(request._meta);
35375
+ if (append !== void 0 && custom2 !== void 0) {
35376
+ throw RequestError.invalidParams(void 0, "systemPrompt.append and AIR customInstructions cannot be combined");
35377
+ }
35378
+ const instructionOverride = await this.sessionInstructionOverride(append, request.cwd);
35338
35379
  const additionalDirectories = readAdditionalDirectories(request.cwd, request.additionalDirectories, request._meta);
35339
35380
  const developerInstructions = airCustomInstructions(request._meta);
35340
35381
  await this.refreshSkills(request.cwd, additionalDirectories);
35341
35382
  const sessionConfig = await this.createSessionConfig(request.cwd, additionalDirectories, request.mcpServers);
35342
35383
  const response = await this.codexClient.threadStart({
35384
+ ...instructionOverride,
35343
35385
  config: sessionConfig.config,
35344
35386
  modelProvider: this.getModelProvider(),
35345
35387
  cwd: request.cwd,
35346
35388
  ...developerInstructions !== void 0 && { developerInstructions }
35347
35389
  });
35390
+ this.recordInstructionAppend(response.thread.id, append);
35348
35391
  const codexModels = await this.fetchAvailableModels();
35349
35392
  if (codexModels.length === 0) {
35350
35393
  throw new Error("Codex did not return any models");
@@ -35441,6 +35484,32 @@ var CodexAcpClient = class _CodexAcpClient {
35441
35484
  getMcpServerStartupVersion() {
35442
35485
  return this.codexClient.mcpStartup.version();
35443
35486
  }
35487
+ recordInstructionAppend(sessionId, append) {
35488
+ if (append === void 0) return;
35489
+ this.appliedInstructionAppends.set(sessionId, append);
35490
+ }
35491
+ async sessionInstructionOverride(append, cwd, sessionId) {
35492
+ if (append === void 0) return {};
35493
+ if (sessionId !== void 0) {
35494
+ let cursor;
35495
+ do {
35496
+ const page = await this.codexClient.threadLoadedList({ ...cursor !== void 0 && { cursor } });
35497
+ if (page.data.includes(sessionId)) {
35498
+ if (this.appliedInstructionAppends.get(sessionId) === append) return {};
35499
+ throw RequestError.invalidParams(void 0, "Cannot append instructions to a loaded thread; close it before loading or resuming with instructions");
35500
+ }
35501
+ cursor = page.nextCursor ?? void 0;
35502
+ } while (cursor !== void 0);
35503
+ }
35504
+ const effective = await this.codexClient.configRead({ cwd, includeLayers: false });
35505
+ const configured = this.config["developer_instructions"] !== void 0 ? this.config["developer_instructions"] : effective.config.developer_instructions;
35506
+ if (configured != null && typeof configured !== "string") {
35507
+ throw RequestError.invalidParams(void 0, "Configured developer_instructions must be a string");
35508
+ }
35509
+ return { developerInstructions: configured ? append ? `${configured}
35510
+
35511
+ ${append}` : configured : append };
35512
+ }
35444
35513
  async createSessionConfig(projectPath, additionalDirectories, mcpServers) {
35445
35514
  const sessionRoots = [projectPath, ...additionalDirectories];
35446
35515
  const activeProvider = this.gatewayConfig ? {
@@ -39236,7 +39305,7 @@ var JsonText = class {
39236
39305
  }
39237
39306
  text;
39238
39307
  };
39239
- var MAX_DEPTH = 256;
39308
+ var MAX_DEPTH = 64;
39240
39309
  var apply = Reflect.apply;
39241
39310
  var getPrototypeOf = Object.getPrototypeOf;
39242
39311
  var isRawJson = JSON.isRawJSON ?? (() => false);
@@ -40148,9 +40217,6 @@ function titleSource(text) {
40148
40217
  return text.slice(0, end);
40149
40218
  }
40150
40219
 
40151
- // src/SessionIndexService.ts
40152
- import path13 from "node:path";
40153
-
40154
40220
  // src/SessionIndex.ts
40155
40221
  var AIR_SESSION_INDEX_KEY = "sessionIndex";
40156
40222
  var AIR_SESSION_ARCHIVE_KEY = "sessionArchive";
@@ -40171,6 +40237,32 @@ var AIR_FORKED_FROM_KEY = "forkedFrom";
40171
40237
  var DEFAULT_SESSION_INDEX_LIMIT = 50;
40172
40238
  var MAX_SESSION_INDEX_LIMIT = 100;
40173
40239
  var AIR_ARCHIVED_KEY = "archived";
40240
+ var NEUTRAL_SESSION_INDEX_META_KEY = "sessionIndex";
40241
+ var NEUTRAL_SESSION_INDEX_VERSION = 1;
40242
+ var AIR_SESSION_INDEX_META = {
40243
+ read: (meta3) => asRecord3(asRecord3(asRecord3(meta3)[JETBRAINS_META_KEY])[AIR_META_KEY]),
40244
+ write: withAirMeta
40245
+ };
40246
+ var NEUTRAL_SESSION_INDEX_META = {
40247
+ read: (meta3) => asRecord3(asRecord3(meta3)[NEUTRAL_SESSION_INDEX_META_KEY]),
40248
+ write: (meta3, key, value) => {
40249
+ const root = asRecord3(meta3);
40250
+ return { ...root, [NEUTRAL_SESSION_INDEX_META_KEY]: { ...asRecord3(root[NEUTRAL_SESSION_INDEX_META_KEY]), [key]: value } };
40251
+ }
40252
+ };
40253
+ function sessionIndexMetaOf(capabilities) {
40254
+ if (isAirClient(capabilities)) {
40255
+ return clientSupportsAirCapability(capabilities, AIR_SESSION_INDEX_KEY) ? AIR_SESSION_INDEX_META : null;
40256
+ }
40257
+ const declared = capabilities?._meta?.[NEUTRAL_SESSION_INDEX_META_KEY];
40258
+ if (declared === null || typeof declared !== "object" || Array.isArray(declared)) return null;
40259
+ const version2 = declared["version"];
40260
+ return typeof version2 === "number" && Number.isInteger(version2) && version2 >= 1 ? NEUTRAL_SESSION_INDEX_META : null;
40261
+ }
40262
+ function sessionIndexRowFields(row) {
40263
+ const air = AIR_SESSION_INDEX_META.read(row._meta);
40264
+ return Object.keys(air).length > 0 ? air : NEUTRAL_SESSION_INDEX_META.read(row._meta);
40265
+ }
40174
40266
  var ARCHIVED_FILTERS = ["unarchived", "archived", "all"];
40175
40267
  function archivedSides(filter) {
40176
40268
  switch (filter) {
@@ -40196,9 +40288,8 @@ var sessionListSubscriptionParamsParser = external_exports.preprocess(
40196
40288
  (params) => params ?? {},
40197
40289
  external_exports.record(external_exports.string(), external_exports.unknown())
40198
40290
  );
40199
- function readSessionIndexListOptions(meta3) {
40200
- const jetbrains = asRecord3(asRecord3(meta3)[JETBRAINS_META_KEY]);
40201
- const list = asRecord3(asRecord3(jetbrains[AIR_META_KEY])[AIR_SESSION_LIST_KEY]);
40291
+ function readSessionIndexListOptions(meta3, namespace = AIR_SESSION_INDEX_META) {
40292
+ const list = asRecord3(namespace.read(meta3)[AIR_SESSION_LIST_KEY]);
40202
40293
  return {
40203
40294
  limit: readLimit(list["limit"]),
40204
40295
  archived: readArchivedFilter(list["archived"]),
@@ -40384,7 +40475,7 @@ function decodeAdapterCursor(cursor) {
40384
40475
  function invalidCursorError(cursor) {
40385
40476
  return RequestError.invalidParams({ cursor }, "invalid cursor");
40386
40477
  }
40387
- function sessionIndexSessionInfo(thread, archived, activity) {
40478
+ function sessionIndexSessionInfo(thread, archived, activity, namespace = AIR_SESSION_INDEX_META) {
40388
40479
  const airFields = { [AIR_ARCHIVED_KEY]: archived };
40389
40480
  if (thread.recencyAt !== null) airFields[AIR_LAST_PROMPT_AT_KEY] = isoTime(thread.recencyAt);
40390
40481
  if (thread.model) airFields[AIR_MODEL_KEY] = thread.model;
@@ -40393,7 +40484,7 @@ function sessionIndexSessionInfo(thread, archived, activity) {
40393
40484
  if (activity?.lastTurnEndedAt !== void 0) airFields[AIR_LAST_TURN_ENDED_AT_KEY] = activity.lastTurnEndedAt;
40394
40485
  let meta3;
40395
40486
  for (const [key, value] of Object.entries(airFields)) {
40396
- meta3 = withAirMeta(meta3, key, value);
40487
+ meta3 = namespace.write(meta3, key, value);
40397
40488
  }
40398
40489
  return {
40399
40490
  sessionId: thread.id,
@@ -40481,7 +40572,7 @@ var SessionIndexActivity = class {
40481
40572
  }
40482
40573
  };
40483
40574
  function sessionIndexRowSignature(row) {
40484
- const air = asRecord3(asRecord3(asRecord3(row._meta)[JETBRAINS_META_KEY])[AIR_META_KEY]);
40575
+ const air = sessionIndexRowFields(row);
40485
40576
  return JSON.stringify([
40486
40577
  row.title ?? null,
40487
40578
  air[AIR_LAST_PROMPT_AT_KEY] ?? null,
@@ -40496,6 +40587,9 @@ function asRecord3(value) {
40496
40587
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
40497
40588
  }
40498
40589
 
40590
+ // src/SessionIndexService.ts
40591
+ import path13 from "node:path";
40592
+
40499
40593
  // src/SessionIndexWorktrees.ts
40500
40594
  import fs8 from "node:fs";
40501
40595
  import path9 from "node:path";
@@ -41223,10 +41317,7 @@ var SessionListSubscriptions = class {
41223
41317
  refreshLoadedThreads(threadIds) {
41224
41318
  this.appServerGeneration++;
41225
41319
  if (this.subscriptions.size === 0) return;
41226
- const loaded = [...this.groups.values()].flatMap((group) => [...group.rows].filter(([, { row }]) => {
41227
- const meta3 = row._meta;
41228
- return meta3?.["jetbrains"]?.["air"]?.["state"] !== void 0;
41229
- }).map(([threadId]) => threadId));
41320
+ const loaded = [...this.groups.values()].flatMap((group) => [...group.rows].filter(([, { row }]) => sessionIndexRowFields(row)[AIR_STATE_KEY] !== void 0).map(([threadId]) => threadId));
41230
41321
  for (const threadId of /* @__PURE__ */ new Set([...threadIds, ...loaded])) this.threadChanged(threadId);
41231
41322
  if (this.pendingThreads.size > 0) this.requestThreads(this.timings.ownChangeDelayMs);
41232
41323
  }
@@ -41702,8 +41793,8 @@ var SessionIndexService = class {
41702
41793
  });
41703
41794
  }
41704
41795
  host;
41705
- /** The client declared the AIR `sessionIndex` capability. */
41706
- enabled = false;
41796
+ /** Where this client's session index metadata goes, or `null` when it did not declare `sessionIndex`. */
41797
+ meta = null;
41707
41798
  activity;
41708
41799
  writes = new SessionWriteQueue();
41709
41800
  titles;
@@ -41716,14 +41807,25 @@ var SessionIndexService = class {
41716
41807
  rowsWithState = /* @__PURE__ */ new Set();
41717
41808
  /** Reads the client capabilities of `initialize`. */
41718
41809
  configure(clientCapabilities) {
41719
- this.enabled = clientSupportsAirCapability(clientCapabilities, AIR_SESSION_INDEX_KEY);
41810
+ this.meta = sessionIndexMetaOf(clientCapabilities);
41811
+ }
41812
+ /** The client declared `sessionIndex`, as AIR or as a client-neutral opt-in. */
41813
+ get enabled() {
41814
+ return this.meta !== null;
41720
41815
  }
41721
41816
  /**
41722
- * The AIR capabilities to answer: only a client that declares `sessionIndex` gets them. `sessionArchive` and
41723
- * `sessionRename` name the requests that come with it; the client need not declare them.
41817
+ * The AIR capabilities to answer: only an AIR client that declares `sessionIndex` gets them. `sessionArchive`
41818
+ * and `sessionRename` name the requests that come with it; the client need not declare them.
41724
41819
  */
41725
41820
  agentCapabilities() {
41726
- return this.enabled ? [AIR_SESSION_INDEX_KEY, AIR_SESSION_ARCHIVE_KEY, AIR_SESSION_RENAME_KEY, AIR_SESSION_LIST_SUBSCRIBE_KEY] : [];
41821
+ return this.meta === AIR_SESSION_INDEX_META ? [AIR_SESSION_INDEX_KEY, AIR_SESSION_ARCHIVE_KEY, AIR_SESSION_RENAME_KEY, AIR_SESSION_LIST_SUBSCRIBE_KEY] : [];
41822
+ }
41823
+ /** The `_meta.sessionIndex` answer of `initialize` to a client-neutral opt-in, or `null`. */
41824
+ neutralCapability() {
41825
+ return this.meta === NEUTRAL_SESSION_INDEX_META ? {
41826
+ version: NEUTRAL_SESSION_INDEX_VERSION,
41827
+ capabilities: [AIR_SESSION_ARCHIVE_KEY, AIR_SESSION_RENAME_KEY, AIR_SESSION_LIST_SUBSCRIBE_KEY]
41828
+ } : null;
41727
41829
  }
41728
41830
  /**
41729
41831
  * Feeds the thread notifications of an app-server, for every thread, to the session index. Each client is
@@ -41757,7 +41859,7 @@ var SessionIndexService = class {
41757
41859
  * reads the local state DB and works without one.
41758
41860
  */
41759
41861
  async list(params) {
41760
- const options = readSessionIndexListOptions(params._meta);
41862
+ const options = readSessionIndexListOptions(params._meta, this.requireMeta());
41761
41863
  const cwd = params.cwd?.trim() || null;
41762
41864
  return await this.readRows(cwd, options, params.cursor ?? null);
41763
41865
  }
@@ -41832,13 +41934,13 @@ var SessionIndexService = class {
41832
41934
  if (archived ? open3 : this.host.session(sessionId) !== void 0) {
41833
41935
  await new ACPSessionConnection(this.host.connection(), sessionId).update({
41834
41936
  sessionUpdate: "session_info_update",
41835
- _meta: withAirMeta(void 0, AIR_ARCHIVED_KEY, archived)
41937
+ _meta: this.requireMeta().write(void 0, AIR_ARCHIVED_KEY, archived)
41836
41938
  });
41837
41939
  }
41838
41940
  return {};
41839
41941
  }
41840
41942
  /**
41841
- * Deletes the thread for `session/delete`: AIR then means "delete", not "done", because it has
41943
+ * Deletes the thread for `session/delete`: a `sessionIndex` client then means "delete", not "done", because it has
41842
41944
  * `_session/archive` for that. A thread that this connection had open but Codex never persisted (no
41843
41945
  * prompt yet) is gone with the close, so it counts as deleted.
41844
41946
  */
@@ -41870,6 +41972,10 @@ var SessionIndexService = class {
41870
41972
  throw RequestError.methodNotFound(method);
41871
41973
  }
41872
41974
  }
41975
+ requireMeta() {
41976
+ if (this.meta === null) throw new Error("The client did not declare sessionIndex");
41977
+ return this.meta;
41978
+ }
41873
41979
  async readRows(cwd, options, cursor) {
41874
41980
  const relativeCwd = cwd !== null && !isAbsolutePathLike(cwd) ? cwd : null;
41875
41981
  const cwds = cwd === null || relativeCwd !== null ? null : options.includeWorktrees ? linkedWorktreeCwds(cwd) : canonicalCwds(cwd);
@@ -41895,7 +42001,7 @@ var SessionIndexService = class {
41895
42001
  if (activity?.state !== void 0) this.rowsWithState.add(thread.id);
41896
42002
  else this.rowsWithState.delete(thread.id);
41897
42003
  return this.withActiveAdditionalDirectories(
41898
- sessionIndexSessionInfo(thread, entry.archived, activity)
42004
+ sessionIndexSessionInfo(thread, entry.archived, activity, this.requireMeta())
41899
42005
  );
41900
42006
  });
41901
42007
  }
@@ -42380,7 +42486,7 @@ var CodexAcpServer = class {
42380
42486
  recovery;
42381
42487
  initializeRequest = null;
42382
42488
  providerUpdate = null;
42383
- /** The AIR `sessionIndex` extension, see `SessionIndexService.ts`. */
42489
+ /** The `sessionIndex` extension, for AIR or a client-neutral opt-in, see `SessionIndexService.ts`. */
42384
42490
  sessionIndex = new SessionIndexService({
42385
42491
  connection: () => this.connection,
42386
42492
  client: () => this.codexAcpClient,
@@ -42464,6 +42570,7 @@ var CodexAcpServer = class {
42464
42570
  controlMethod: GOAL_CONTROL_METHOD,
42465
42571
  actions: [...GOAL_CONTROL_ACTIONS]
42466
42572
  };
42573
+ const neutralSessionIndex = this.sessionIndex.neutralCapability();
42467
42574
  const sessionCapabilities = {
42468
42575
  resume: {},
42469
42576
  list: {},
@@ -42504,6 +42611,7 @@ var CodexAcpServer = class {
42504
42611
  },
42505
42612
  authMethods: getCodexAuthMethods(_params.clientCapabilities),
42506
42613
  _meta: {
42614
+ systemPrompt: SYSTEM_PROMPT_CAPABILITY,
42507
42615
  steering: {
42508
42616
  supported: true
42509
42617
  },
@@ -42513,6 +42621,9 @@ var CodexAcpServer = class {
42513
42621
  ...this.capabilities.asyncTasks && !this.capabilities.airClient ? {
42514
42622
  "async-tasks": asyncTaskCapability()
42515
42623
  } : {},
42624
+ ...neutralSessionIndex ? {
42625
+ [NEUTRAL_SESSION_INDEX_META_KEY]: neutralSessionIndex
42626
+ } : {},
42516
42627
  // Only AIR gets the AIR extension, see `docs/air-extensions.md`.
42517
42628
  ...this.capabilities.airClient ? {
42518
42629
  [JETBRAINS_META_KEY]: {
@@ -43087,6 +43198,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
43087
43198
  return null;
43088
43199
  }
43089
43200
  async loadSession(params) {
43201
+ readSessionInstructionAppend(params._meta);
43090
43202
  return this.recovery === null ? await this.loadSessionOnce(params) : await this.recovery.trackOpen(params.sessionId, () => this.loadSessionOnce(params));
43091
43203
  }
43092
43204
  async loadSessionOnce(params) {
@@ -43129,6 +43241,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
43129
43241
  };
43130
43242
  }
43131
43243
  async resumeSession(params) {
43244
+ readSessionInstructionAppend(params._meta);
43132
43245
  return this.recovery === null ? await this.resumeSessionOnce(params) : await this.recovery.trackOpen(params.sessionId, () => this.resumeSessionOnce(params));
43133
43246
  }
43134
43247
  async resumeSessionOnce(params) {
@@ -43151,6 +43264,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
43151
43264
  };
43152
43265
  }
43153
43266
  async forkSession(params) {
43267
+ readSessionInstructionAppend(params._meta);
43154
43268
  if (this.providerUpdate !== null) {
43155
43269
  await this.waitForProviderUpdate();
43156
43270
  }
@@ -43262,6 +43376,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
43262
43376
  return this.sessionOpenGenerations.get(sessionId) === this.getSessionGeneration(sessionId);
43263
43377
  }
43264
43378
  async newSession(params) {
43379
+ readSessionInstructionAppend(params._meta);
43265
43380
  if (this.providerUpdate !== null) {
43266
43381
  await this.waitForProviderUpdate();
43267
43382
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "2.2.2-alas.1",
6
+ "version": "2.2.2-alas.3",
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": "066895c1361ae7a82d1e0216a87b32f9be657b2c"
83
+ "sourceCommit": "2be0ccf63ad9c18131815207511597bb34d6adc0"
84
84
  }
85
85
  }