@nyssance/codex-acp-v2 0.7.15 → 0.7.16

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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.16 — 2026-10-16
4
+
5
+ ### Added
6
+
7
+ - Codex's durable read state: `thread/readState/changed` is forwarded as `session_info_update` with
8
+ `_meta.codex.readState`, and `_codex/session_read_state_update` marks a session read or unread
9
+ (`capabilities._meta.codex.readState: true`).
10
+
3
11
  ## 0.7.15 — 2026-10-16
4
12
 
5
13
  ### Added
package/dist/index.js CHANGED
@@ -14395,7 +14395,7 @@ var package_default = {
14395
14395
  publishConfig: {
14396
14396
  access: "public"
14397
14397
  },
14398
- version: "0.7.15",
14398
+ version: "0.7.16",
14399
14399
  description: "Native ACP v2 agent for the OpenAI Codex app-server",
14400
14400
  packageManager: "bun@1.4.3",
14401
14401
  engines: {
@@ -16880,6 +16880,8 @@ ${stdin}
16880
16880
  this.session.titleIsExplicit = title !== null;
16881
16881
  return [{ sessionUpdate: "session_info_update", title }];
16882
16882
  }
16883
+ case "thread/readState/changed":
16884
+ return [{ sessionUpdate: "session_info_update", _meta: { codex: { readState: notification.params.readState } } }];
16883
16885
  case "account/rateLimits/updated": {
16884
16886
  const snapshot = notification.params.rateLimits;
16885
16887
  this.rateLimits.set(snapshot.limitId ?? snapshot.limitName ?? "default", snapshot);
@@ -16918,7 +16920,6 @@ ${details}` : summary)];
16918
16920
  case "thread/settings/updated":
16919
16921
  case "thread/goal/updated":
16920
16922
  case "thread/goal/cleared":
16921
- case "thread/readState/changed":
16922
16923
  case "thread/prediction/updated":
16923
16924
  case "thread/project/updated":
16924
16925
  case "thread/environment/connected":
@@ -17530,6 +17531,9 @@ class AppServerClient {
17530
17531
  threadFork(params) {
17531
17532
  return this.send({ method: "thread/fork", params });
17532
17533
  }
17534
+ threadReadStateUpdate(params) {
17535
+ return this.send({ method: "thread/readState/update", params });
17536
+ }
17533
17537
  threadRead(params) {
17534
17538
  return this.send({ method: "thread/read", params });
17535
17539
  }
@@ -20786,7 +20790,7 @@ class CodexAgent {
20786
20790
  additionalDirectories: {}
20787
20791
  },
20788
20792
  providers: {},
20789
- _meta: { alwith: { tools: { version: 1 }, turns: { version: 2 } }, codex: { forkAtTurn: true, sessionLineage: true, archive: true, sessionList: { version: 1 }, sessionHistory: { version: 2, items: true, modes: ["browse", "export"] }, seedHistory: true, skills: true, plugins: true, pluginEnable: true, providerCatalog: true, rename: true, account: true, fuzzyFileSearch: true } }
20793
+ _meta: { alwith: { tools: { version: 1 }, turns: { version: 2 } }, codex: { forkAtTurn: true, sessionLineage: true, archive: true, readState: true, sessionList: { version: 1 }, sessionHistory: { version: 2, items: true, modes: ["browse", "export"] }, seedHistory: true, skills: true, plugins: true, pluginEnable: true, providerCatalog: true, rename: true, account: true, fuzzyFileSearch: true } }
20790
20794
  },
20791
20795
  authMethods: authMethods(this.capabilities, this.env)
20792
20796
  };
@@ -21468,6 +21472,10 @@ class CodexAgent {
21468
21472
  await this.withCodex(() => this.codex.threadArchive({ threadId: params.sessionId }));
21469
21473
  return {};
21470
21474
  }
21475
+ async updateSessionReadState(params) {
21476
+ this.requireInitialized("_codex/session_read_state_update");
21477
+ return await this.withCodex(() => this.codex.threadReadStateUpdate({ threadId: params.sessionId, operation: { type: params.operation }, expectedRevision: params.expectedRevision }));
21478
+ }
21471
21479
  async unarchiveSession(params) {
21472
21480
  return await this.admission(() => this.unarchiveSessionInternal(params), params.sessionId);
21473
21481
  }
@@ -22346,6 +22354,13 @@ function objectParams() {
22346
22354
  return raw;
22347
22355
  };
22348
22356
  }
22357
+ function parseSessionReadStateUpdateParams(raw) {
22358
+ const operation = isJsonObject(raw) ? raw["operation"] : undefined;
22359
+ if (!isJsonObject(raw) || typeof raw["sessionId"] !== "string" || typeof raw["expectedRevision"] !== "string" || operation !== "read" && operation !== "unread") {
22360
+ throw RequestError.invalidParams(undefined, 'Expected {sessionId, operation: "read" | "unread", expectedRevision}');
22361
+ }
22362
+ return { sessionId: raw["sessionId"], operation, expectedRevision: raw["expectedRevision"] };
22363
+ }
22349
22364
  function parseSessionIdParams(raw) {
22350
22365
  const sessionId = raw?.sessionId;
22351
22366
  if (typeof sessionId !== "string" || sessionId.length === 0) {
@@ -22473,7 +22488,7 @@ function createAgentApp(options) {
22473
22488
  };
22474
22489
  return agent({ name: options.info.name }).onConnect((connection) => {
22475
22490
  agent2 = new CodexAgent(connection.client, options);
22476
- }).onRequest(methods.agent.initialize, (ctx) => current().initialize(ctx.params)).onRequest(methods.agent.auth.login, (ctx) => current().login(ctx.params, ctx.requestId)).onRequest(methods.agent.auth.logout, (ctx) => current().logout(ctx.params)).onRequest(methods.agent.providers.list, (ctx) => current().listProviders(ctx.params)).onRequest(methods.agent.providers.set, (ctx) => current().setProvider(ctx.params)).onRequest(methods.agent.providers.disable, (ctx) => current().disableProvider(ctx.params)).onRequest(methods.agent.session.new, (ctx) => current().newSession(ctx.params, ctx.signal)).onRequest(methods.agent.session.resume, (ctx) => current().resumeSession(ctx.params, ctx.signal)).onRequest(methods.agent.session.fork, (ctx) => current().forkSession(ctx.params, ctx.signal)).onRequest(methods.agent.session.list, (ctx) => current().listSessions(ctx.params)).onRequest("_codex/session_list", { parse: parseSessionListParams }, (ctx) => current().sessionList(ctx.params)).onRequest(methods.agent.session.close, (ctx) => current().closeSession(ctx.params)).onRequest(methods.agent.session.delete, (ctx) => current().deleteSession(ctx.params)).onRequest("_codex/session_history", { parse: parseSessionHistoryParams }, (ctx) => current().sessionHistory(ctx.params, ctx.signal)).onRequest("_codex/session_history_items", { parse: parseSessionHistoryItemsParams }, (ctx) => current().sessionHistoryItems(ctx.params, ctx.signal)).onRequest("_codex/session_archive", { parse: parseSessionIdParams }, (ctx) => current().archiveSession(ctx.params)).onRequest("_codex/session_unarchive", { parse: parseSessionIdParams }, (ctx) => current().unarchiveSession(ctx.params)).onRequest("_codex/skills_list", { parse: objectParams() }, (ctx) => current().skillsList(ctx.params)).onRequest("_codex/skills_config_write", { parse: objectParams() }, (ctx) => current().skillsConfigWrite(ctx.params)).onRequest("_codex/plugin_list", { parse: objectParams() }, (ctx) => current().pluginList(ctx.params)).onRequest("_codex/plugin_installed", { parse: objectParams() }, (ctx) => current().pluginInstalled(ctx.params)).onRequest("_codex/plugin_install", { parse: objectParams() }, (ctx) => current().pluginInstall(ctx.params)).onRequest("_codex/plugin_uninstall", { parse: objectParams() }, (ctx) => current().pluginUninstall(ctx.params)).onRequest("_codex/plugin_set_enabled", { parse: parsePluginSetEnabledParams }, (ctx) => current().pluginSetEnabled(ctx.params)).onRequest("_codex/plugin_read", { parse: objectParams() }, (ctx) => current().pluginRead(ctx.params)).onRequest("_codex/marketplace_add", { parse: objectParams() }, (ctx) => current().marketplaceAdd(ctx.params)).onRequest("_codex/marketplace_remove", { parse: objectParams() }, (ctx) => current().marketplaceRemove(ctx.params)).onRequest("_codex/marketplace_upgrade", { parse: objectParams() }, (ctx) => current().marketplaceUpgrade(ctx.params)).onRequest("_codex/session_rename", { parse: parseSessionRenameParams }, (ctx) => current().sessionRename(ctx.params)).onRequest("_codex/account_read", { parse: objectParams() }, () => current().accountRead()).onRequest("_codex/rate_limits", { parse: objectParams() }, () => current().rateLimits()).onRequest("_codex/fuzzy_file_search", { parse: parseFuzzyFileSearchParams }, (ctx) => current().fuzzyFileSearch(ctx.params)).onRequest(methods.agent.session.setConfigOption, (ctx) => current().setSessionConfigOption(ctx.params)).onRequest(methods.agent.session.prompt, (ctx) => current().prompt(ctx.params)).onNotification(methods.agent.session.cancel, (ctx) => current().cancel(ctx.params));
22491
+ }).onRequest(methods.agent.initialize, (ctx) => current().initialize(ctx.params)).onRequest(methods.agent.auth.login, (ctx) => current().login(ctx.params, ctx.requestId)).onRequest(methods.agent.auth.logout, (ctx) => current().logout(ctx.params)).onRequest(methods.agent.providers.list, (ctx) => current().listProviders(ctx.params)).onRequest(methods.agent.providers.set, (ctx) => current().setProvider(ctx.params)).onRequest(methods.agent.providers.disable, (ctx) => current().disableProvider(ctx.params)).onRequest(methods.agent.session.new, (ctx) => current().newSession(ctx.params, ctx.signal)).onRequest(methods.agent.session.resume, (ctx) => current().resumeSession(ctx.params, ctx.signal)).onRequest(methods.agent.session.fork, (ctx) => current().forkSession(ctx.params, ctx.signal)).onRequest(methods.agent.session.list, (ctx) => current().listSessions(ctx.params)).onRequest("_codex/session_list", { parse: parseSessionListParams }, (ctx) => current().sessionList(ctx.params)).onRequest(methods.agent.session.close, (ctx) => current().closeSession(ctx.params)).onRequest(methods.agent.session.delete, (ctx) => current().deleteSession(ctx.params)).onRequest("_codex/session_history", { parse: parseSessionHistoryParams }, (ctx) => current().sessionHistory(ctx.params, ctx.signal)).onRequest("_codex/session_history_items", { parse: parseSessionHistoryItemsParams }, (ctx) => current().sessionHistoryItems(ctx.params, ctx.signal)).onRequest("_codex/session_archive", { parse: parseSessionIdParams }, (ctx) => current().archiveSession(ctx.params)).onRequest("_codex/session_unarchive", { parse: parseSessionIdParams }, (ctx) => current().unarchiveSession(ctx.params)).onRequest("_codex/session_read_state_update", { parse: parseSessionReadStateUpdateParams }, (ctx) => current().updateSessionReadState(ctx.params)).onRequest("_codex/skills_list", { parse: objectParams() }, (ctx) => current().skillsList(ctx.params)).onRequest("_codex/skills_config_write", { parse: objectParams() }, (ctx) => current().skillsConfigWrite(ctx.params)).onRequest("_codex/plugin_list", { parse: objectParams() }, (ctx) => current().pluginList(ctx.params)).onRequest("_codex/plugin_installed", { parse: objectParams() }, (ctx) => current().pluginInstalled(ctx.params)).onRequest("_codex/plugin_install", { parse: objectParams() }, (ctx) => current().pluginInstall(ctx.params)).onRequest("_codex/plugin_uninstall", { parse: objectParams() }, (ctx) => current().pluginUninstall(ctx.params)).onRequest("_codex/plugin_set_enabled", { parse: parsePluginSetEnabledParams }, (ctx) => current().pluginSetEnabled(ctx.params)).onRequest("_codex/plugin_read", { parse: objectParams() }, (ctx) => current().pluginRead(ctx.params)).onRequest("_codex/marketplace_add", { parse: objectParams() }, (ctx) => current().marketplaceAdd(ctx.params)).onRequest("_codex/marketplace_remove", { parse: objectParams() }, (ctx) => current().marketplaceRemove(ctx.params)).onRequest("_codex/marketplace_upgrade", { parse: objectParams() }, (ctx) => current().marketplaceUpgrade(ctx.params)).onRequest("_codex/session_rename", { parse: parseSessionRenameParams }, (ctx) => current().sessionRename(ctx.params)).onRequest("_codex/account_read", { parse: objectParams() }, () => current().accountRead()).onRequest("_codex/rate_limits", { parse: objectParams() }, () => current().rateLimits()).onRequest("_codex/fuzzy_file_search", { parse: parseFuzzyFileSearchParams }, (ctx) => current().fuzzyFileSearch(ctx.params)).onRequest(methods.agent.session.setConfigOption, (ctx) => current().setSessionConfigOption(ctx.params)).onRequest(methods.agent.session.prompt, (ctx) => current().prompt(ctx.params)).onNotification(methods.agent.session.cancel, (ctx) => current().cancel(ctx.params));
22477
22492
  }
22478
22493
 
22479
22494
  // src/codex/process.ts
package/docs/protocol.md CHANGED
@@ -110,6 +110,7 @@ clients), and every session's `model` option becomes one group per source: `chat
110
110
  | `_codex/session_history` | Read-only turn metadata or full ACP history without opening or subscribing to the session. See the contract below. Advertised as `capabilities._meta.codex.sessionHistory: {version: 2, items: true, modes: ["browse", "export"]}`. |
111
111
  | `_codex/session_history_items` | Independent item pagination across a thread or within one turn; supports item anchors and optional native data. Part of the version 2 history capability. |
112
112
  | `_codex/session_archive` | `{sessionId}` closes and archives the thread (reversible hiding). Advertised as `capabilities._meta.codex.archive: true`. |
113
+ | `_codex/session_read_state_update` | `{sessionId, operation: "read" \| "unread", expectedRevision}` sets Codex's durable read receipt for the thread and returns `{readState}`. `expectedRevision` is the `revision` the client last saw; a stale one is rejected by Codex. Changes arrive as `session_info_update` with `_meta.codex.readState = {firstUnread, revision}`. Advertised as `capabilities._meta.codex.readState: true`. |
113
114
  | `_codex/session_unarchive` | `{sessionId}` restores an archived thread's visibility. |
114
115
  | `_codex/session_rename` | `{sessionId, name}` → `thread/name/set`. A loaded thread then reports `thread/name/updated`, delivered as `session_info_update` with the new `title`; a thread that is not loaded gets no notification. Advertised as `capabilities._meta.codex.rename: true`. |
115
116
  | `session/set_config_option` | Returns and broadcasts the full option list. |
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.7.15",
6
+ "version": "0.7.16",
7
7
  "description": "Native ACP v2 agent for the OpenAI Codex app-server",
8
8
  "packageManager": "bun@1.4.3",
9
9
  "engines": {