@nyssance/codex-acp-v2 0.7.5 → 0.7.7

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,31 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.7 — 2026-10-09
4
+
5
+ ### Added
6
+
7
+ - Independent read-only history APIs: `_codex/session_history` for paginated turns and
8
+ `_codex/session_history_items` for paginated items, advertised through the version 2
9
+ `sessionHistory` capability.
10
+ - Browse mode for live history and export mode with optimistic consistency checks,
11
+ bounded response sizes, scoped cursors, cancellation, and structured errors.
12
+ - History projections preserve media references and text annotations, with optional
13
+ native records and explicit omission metadata for archival and export consumers.
14
+
15
+ ### Fixed
16
+
17
+ - Session listing includes custom-provider conversations by clearing the native
18
+ default model-provider filter.
19
+
20
+ ## 0.7.6 — 2026-10-08
21
+
22
+ ### Added
23
+
24
+ - The `_meta` of a `session/prompt` is echoed once on the `user_message` reported under the same receipt id
25
+ (`_meta.alwith.messageId`), merged with the adapter's own `_meta.codex`. A host can therefore attach its own
26
+ per-message metadata (canvas references, attachments, a skill name) and get it back from the live stream and
27
+ from the Runtime's session event log on replay. Codex's own history snapshots (`session/load`) do not carry it.
28
+
3
29
  ## 0.7.5 — 2026-10-08
4
30
 
5
31
  ### Added
package/dist/index.js CHANGED
@@ -22046,7 +22046,7 @@ var package_default = {
22046
22046
  publishConfig: {
22047
22047
  access: "public"
22048
22048
  },
22049
- version: "0.7.5",
22049
+ version: "0.7.7",
22050
22050
  description: "Native ACP v2 agent for the OpenAI Codex app-server",
22051
22051
  packageManager: "bun@1.4.0",
22052
22052
  engines: {
@@ -23896,6 +23896,7 @@ class EventBridge {
23896
23896
  openToolCalls = new Set;
23897
23897
  announcedTools = new Set;
23898
23898
  messagePhases = new Map;
23899
+ promptMeta = new Map;
23899
23900
  reasoningWithDeltas = new Set;
23900
23901
  terminalItems = new Set;
23901
23902
  imageGenerations = new Set;
@@ -23911,6 +23912,9 @@ class EventBridge {
23911
23912
  this.client = client;
23912
23913
  this.session = session;
23913
23914
  }
23915
+ rememberPromptMeta(messageId, meta) {
23916
+ this.promptMeta.set(messageId, meta);
23917
+ }
23914
23918
  beginTurn() {
23915
23919
  this.lastError = null;
23916
23920
  this.completedPlan = null;
@@ -24192,7 +24196,12 @@ ${details}` : summary)];
24192
24196
  return [compactionUpdate(item.id, "in_progress")];
24193
24197
  case "userMessage": {
24194
24198
  const content = item.content.flatMap(fromUserInput);
24195
- return content.length > 0 ? [{ sessionUpdate: "user_message", messageId: item.clientId ?? item.id, content }] : [];
24199
+ if (content.length === 0)
24200
+ return [];
24201
+ const messageId = item.clientId ?? item.id;
24202
+ const meta = this.promptMeta.get(messageId);
24203
+ this.promptMeta.delete(messageId);
24204
+ return [{ sessionUpdate: "user_message", messageId, content, ...meta ? { _meta: meta } : {} }];
24196
24205
  }
24197
24206
  case "hookPrompt":
24198
24207
  case "functionCallOutput":
@@ -26879,6 +26888,255 @@ function firstLine(text2) {
26879
26888
  return line.length > 120 ? `${line.slice(0, 117)}...` : line;
26880
26889
  }
26881
26890
 
26891
+ // src/agent/historyProtocol.ts
26892
+ import { createHash } from "crypto";
26893
+ function historyError(reason, message, retryable, extra = {}, code = -32600) {
26894
+ return new RequestError(code, message, { reason, retryable, ...extra });
26895
+ }
26896
+ function invalid(message) {
26897
+ throw historyError("history_invalid_params", message, false, {}, -32602);
26898
+ }
26899
+ function parse5(raw, items) {
26900
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
26901
+ invalid("History params must be an object");
26902
+ const p = raw;
26903
+ const allowed = new Set(["sessionId", "cursor", "limit", "mode", "sortDirection", "maxBytes", "includeNative", "_meta", ...items ? ["turnId", "anchorItemId"] : ["itemsView"]]);
26904
+ for (const key of Object.keys(p))
26905
+ if (!allowed.has(key))
26906
+ invalid(`Unknown history parameter: ${key}`);
26907
+ if (typeof p["sessionId"] !== "string" || !p["sessionId"].trim())
26908
+ invalid("sessionId must be a non-empty string");
26909
+ if (p["cursor"] != null && (typeof p["cursor"] !== "string" || !p["cursor"] || p["cursor"].length > 65536))
26910
+ invalid("cursor must be a non-empty history cursor or null");
26911
+ for (const [key, min, max] of [["limit", 1, 100], ["maxBytes", 1024, 16 * 1024 * 1024]]) {
26912
+ if (p[key] !== undefined && (typeof p[key] !== "number" || !Number.isInteger(p[key]) || p[key] < min || p[key] > max))
26913
+ invalid(`${key} must be an integer between ${min} and ${max}`);
26914
+ }
26915
+ if (p["mode"] !== undefined && p["mode"] !== "browse" && p["mode"] !== "export")
26916
+ invalid("mode must be browse or export");
26917
+ if (p["sortDirection"] !== undefined && p["sortDirection"] !== "asc" && p["sortDirection"] !== "desc")
26918
+ invalid("sortDirection must be asc or desc");
26919
+ if (p["includeNative"] !== undefined && typeof p["includeNative"] !== "boolean")
26920
+ invalid("includeNative must be a boolean");
26921
+ if (!items && p["itemsView"] !== undefined && p["itemsView"] !== "summary" && p["itemsView"] !== "full")
26922
+ invalid("itemsView must be summary or full");
26923
+ if (!items && p["includeNative"] === true && p["itemsView"] !== "full")
26924
+ invalid("includeNative requires itemsView: full; use the items endpoint for details");
26925
+ for (const key of ["turnId", "anchorItemId"]) {
26926
+ if (p[key] !== undefined && (typeof p[key] !== "string" || !p[key].trim()))
26927
+ invalid(`${key} must be a non-empty string`);
26928
+ }
26929
+ if (p["anchorItemId"] !== undefined && (p["turnId"] === undefined || p["cursor"] != null))
26930
+ invalid("anchorItemId requires turnId and cannot be combined with cursor");
26931
+ return p;
26932
+ }
26933
+ function parseSessionHistoryParams(raw) {
26934
+ return parse5(raw, false);
26935
+ }
26936
+ function parseSessionHistoryItemsParams(raw) {
26937
+ return parse5(raw, true);
26938
+ }
26939
+ function sourceError(error40) {
26940
+ if (error40 instanceof RequestError)
26941
+ return error40;
26942
+ const e = error40 && typeof error40 === "object" ? error40 : {};
26943
+ const message = error40 instanceof Error ? error40.message : String(error40);
26944
+ const native = { code: e["code"] ?? null, data: e["data"] ?? null };
26945
+ const code = typeof e["code"] === "number" ? e["code"] : -32603;
26946
+ if (/thread not found|no rollout found for thread|unknown thread/i.test(message))
26947
+ return historyError("history_not_found", message, false, { native }, code);
26948
+ if (code === -32602 && /cursor/i.test(message))
26949
+ return historyError("history_invalid_cursor", message, false, { native }, code);
26950
+ if (code === -32602)
26951
+ return historyError("history_invalid_params", message, false, { native }, code);
26952
+ if (code === -32601)
26953
+ return historyError("history_unsupported", message, false, { native }, code);
26954
+ if (["ECONNRESET", "EPIPE", "ETIMEDOUT", "ECONNREFUSED"].includes(String(e["code"])))
26955
+ return historyError("history_unavailable", message, true, { native }, code);
26956
+ return historyError("history_source_error", message, null, { native }, code);
26957
+ }
26958
+
26959
+ class HistoryRead {
26960
+ codex;
26961
+ params;
26962
+ signal;
26963
+ direction;
26964
+ mode;
26965
+ after;
26966
+ binding;
26967
+ previous;
26968
+ constructor(codex, params, scope, signal) {
26969
+ this.codex = codex;
26970
+ this.params = params;
26971
+ this.signal = signal;
26972
+ this.direction = params.sortDirection ?? "asc";
26973
+ this.mode = params.mode ?? "browse";
26974
+ this.binding = JSON.stringify({ sessionId: params.sessionId, mode: this.mode, sortDirection: this.direction, includeNative: params.includeNative ?? false, ...scope });
26975
+ this.previous = this.decode(params.cursor);
26976
+ this.after = this.previous?.after ?? null;
26977
+ }
26978
+ decode(raw) {
26979
+ if (raw == null)
26980
+ return null;
26981
+ try {
26982
+ const v = JSON.parse(Buffer.from(raw, "base64url").toString("utf8"));
26983
+ if (!v || v.version !== 2 || v.binding !== this.binding || typeof v.after !== "string" || !v.after || (this.mode === "browse" ? v.revision !== null : typeof v.revision !== "string" || !/^[a-f0-9]{64}$/.test(v.revision)))
26984
+ throw new Error("cursor mismatch");
26985
+ return v;
26986
+ } catch {
26987
+ throw historyError("history_invalid_cursor", "Invalid history cursor or changed query options; restart without a cursor", false, {}, -32602);
26988
+ }
26989
+ }
26990
+ async call(operation) {
26991
+ const check2 = () => {
26992
+ if (this.signal?.aborted)
26993
+ throw historyError("history_cancelled", "History request cancelled", false);
26994
+ };
26995
+ check2();
26996
+ try {
26997
+ const result = this.signal ? await abortable(operation(), this.signal) : await operation();
26998
+ check2();
26999
+ return result;
27000
+ } catch (error40) {
27001
+ check2();
27002
+ throw sourceError(error40);
27003
+ }
27004
+ }
27005
+ async start() {
27006
+ const boundary = await this.boundary();
27007
+ if (this.previous && this.previous.revision !== boundary.revision)
27008
+ this.changed();
27009
+ return boundary;
27010
+ }
27011
+ async boundary() {
27012
+ const { thread } = await this.call(() => this.codex.threadRead({ threadId: this.params.sessionId, includeTurns: false }));
27013
+ if (this.mode === "browse")
27014
+ return { thread, revision: null };
27015
+ if (thread.status.type === "active")
27016
+ this.busy();
27017
+ if (thread.status.type === "systemError")
27018
+ throw historyError("history_unavailable", "Codex reports a session error; retry when it is resolved", true);
27019
+ const tail = await this.call(() => this.codex.threadTurnsList({ threadId: this.params.sessionId, limit: 1, sortDirection: "desc", itemsView: "summary" }));
27020
+ this.checkTurns(tail.data);
27021
+ const revision = createHash("sha256").update(JSON.stringify({ id: thread.id, cwd: thread.cwd, name: thread.name, preview: thread.preview, createdAt: thread.createdAt, updatedAt: thread.updatedAt, forkedFromId: thread.forkedFromId, tail: tail.data[0] ?? null })).digest("hex");
27022
+ return { thread, revision };
27023
+ }
27024
+ checkTurns(turns) {
27025
+ if (this.mode === "export" && turns.some((turn) => turn.status === "inProgress"))
27026
+ this.busy();
27027
+ }
27028
+ busy() {
27029
+ throw historyError("history_busy", "Session history is still running; retry after the turn finishes", true);
27030
+ }
27031
+ changed() {
27032
+ throw historyError("history_changed", "Session history changed; discard collected pages and restart without a cursor", true);
27033
+ }
27034
+ async finish(start, next, count) {
27035
+ if (next !== null && (!next || next === this.after || count === 0))
27036
+ throw historyError("history_invalid_page", "Codex history pagination made no progress; restart the read", false, {}, -32603);
27037
+ if (this.mode === "export" && start.revision !== (await this.boundary()).revision)
27038
+ this.changed();
27039
+ const nextCursor = next === null ? null : Buffer.from(JSON.stringify({ version: 2, binding: this.binding, revision: start.revision, after: next })).toString("base64url");
27040
+ const t = start.thread;
27041
+ return { sessionId: this.params.sessionId, cwd: t.cwd, title: t.name?.trim() || t.preview.trim() || null, createdAt: t.createdAt, updatedAt: t.updatedAt, forkedFromId: t.forkedFromId, running: t.status.type === "active" ? true : t.status.type === "idle" ? false : null, revision: start.revision, consistency: this.mode === "export" ? "optimistic" : "live", nextCursor, complete: nextCursor === null };
27042
+ }
27043
+ bounded(page) {
27044
+ const bytes = Buffer.byteLength(JSON.stringify(page));
27045
+ const maxBytes = this.params.maxBytes ?? 1024 * 1024;
27046
+ if (bytes > maxBytes)
27047
+ throw historyError("history_page_too_large", "History page exceeds maxBytes; retry the same cursor with a smaller limit or larger maxBytes, or start a new summary/item traversal", true, { bytes, maxBytes }, -32600);
27048
+ return page;
27049
+ }
27050
+ }
27051
+
27052
+ // src/agent/historyProjection.ts
27053
+ import { pathToFileURL as pathToFileURL2 } from "url";
27054
+ function inputBlock(input) {
27055
+ switch (input.type) {
27056
+ case "text":
27057
+ return { type: "text", text: input.text, ...input.text_elements.length ? { _meta: { codex: { textElements: input.text_elements } } } : {} };
27058
+ case "image":
27059
+ return { type: "resource_link", name: "Image", uri: "url" in input ? input.url : `codex-file:${encodeURIComponent(input.fileId)}`, _meta: { codex: { inputType: input.type, ...input.detail ? { detail: input.detail } : {}, ..."fileId" in input ? { fileId: input.fileId } : {} } } };
27060
+ case "audio":
27061
+ return { type: "resource_link", name: "Audio", uri: input.url, _meta: { codex: { inputType: input.type } } };
27062
+ case "localImage":
27063
+ case "localAudio":
27064
+ return { type: "resource_link", name: input.type === "localImage" ? "Image" : "Audio", uri: input.path.startsWith("file://") ? input.path : pathToFileURL2(input.path).href, _meta: { codex: { inputType: input.type, ..."detail" in input && input.detail ? { detail: input.detail } : {} } } };
27065
+ case "skill":
27066
+ case "mention":
27067
+ return { type: "resource_link", name: input.name, uri: input.path.startsWith("file://") ? input.path : pathToFileURL2(input.path).href, _meta: { codex: { inputType: input.type } } };
27068
+ }
27069
+ }
27070
+ function projectHistoryItem(item, turnId, startedAt) {
27071
+ const omissions = [];
27072
+ let updates;
27073
+ if (item.type === "userMessage") {
27074
+ updates = [{ sessionUpdate: "user_message", messageId: item.clientId ?? item.id, content: item.content.map(inputBlock) }];
27075
+ } else {
27076
+ updates = itemSnapshot(item);
27077
+ if (!updates.length)
27078
+ omissions.push({ itemId: item.id, field: "*", reason: "no_acp_representation" });
27079
+ if (item.type === "reasoning" && item.summary.length && item.content.length)
27080
+ omissions.push({ itemId: item.id, field: "content", reason: "summary_selected" });
27081
+ if (item.type === "agentMessage") {
27082
+ for (const field of ["memoryCitation", "delivery", "questions"]) {
27083
+ if (item[field] !== null)
27084
+ omissions.push({ itemId: item.id, field, reason: "no_acp_representation" });
27085
+ }
27086
+ }
27087
+ }
27088
+ return { updates: updates.map((update) => withTurnId(update, turnId, startedAt)), omissions };
27089
+ }
27090
+
27091
+ // src/agent/sessionHistory.ts
27092
+ async function readSessionHistory(codex, raw, signal) {
27093
+ const params = parseSessionHistoryParams(raw);
27094
+ const view = params.itemsView ?? "summary";
27095
+ const read = new HistoryRead(codex, params, { endpoint: "turns", itemsView: view }, signal);
27096
+ const start = await read.start();
27097
+ const page = await read.call(() => codex.threadTurnsList({ threadId: params.sessionId, cursor: read.after, limit: params.limit ?? 50, sortDirection: read.direction, itemsView: view }));
27098
+ read.checkTurns(page.data);
27099
+ if (view === "full" && page.data.some((turn) => turn.itemsView !== "full"))
27100
+ throw historyError("history_incomplete", "Codex did not return full history items; update Codex and retry", false, {}, -32603);
27101
+ const result = await read.finish(start, page.nextCursor, page.data.length);
27102
+ return read.bounded({ ...result, running: page.data.some((turn) => turn.status === "inProgress") ? true : result.running, turns: page.data.map((turn) => {
27103
+ const projections = view === "full" ? turn.items.map((item) => projectHistoryItem(item, turn.id, turn.startedAt)) : [];
27104
+ return {
27105
+ turnId: turn.id,
27106
+ status: turn.status,
27107
+ error: turn.error,
27108
+ startedAt: turn.startedAt,
27109
+ completedAt: turn.completedAt,
27110
+ durationMs: turn.durationMs,
27111
+ itemsView: view === "summary" ? "summary" : turn.itemsView,
27112
+ updates: projections.flatMap((p) => p.updates),
27113
+ omissions: projections.flatMap((p) => p.omissions),
27114
+ ...params.includeNative ? { _meta: { codex: { items: turn.items } } } : {}
27115
+ };
27116
+ }) });
27117
+ }
27118
+ async function readSessionHistoryItems(codex, raw, signal) {
27119
+ const params = parseSessionHistoryItemsParams(raw);
27120
+ const read = new HistoryRead(codex, params, { endpoint: "items", turnId: params.turnId ?? null }, signal);
27121
+ const start = await read.start();
27122
+ const page = await read.call(() => codex.threadItemsList({
27123
+ threadId: params.sessionId,
27124
+ turnId: params.turnId ?? null,
27125
+ cursor: read.after ?? (params.anchorItemId ? { type: "item", itemId: params.anchorItemId } : null),
27126
+ limit: params.limit ?? 50,
27127
+ sortDirection: read.direction
27128
+ }));
27129
+ const result = await read.finish(start, page.nextCursor, page.data.length);
27130
+ return read.bounded({ ...result, items: page.data.map((entry) => ({
27131
+ turnId: entry.turnId,
27132
+ itemId: entry.item.id,
27133
+ startedAtMs: entry.startedAtMs,
27134
+ completedAtMs: entry.completedAtMs,
27135
+ ...projectHistoryItem(entry.item, entry.turnId),
27136
+ ...params.includeNative ? { _meta: { codex: { item: entry.item } } } : {}
27137
+ })) });
27138
+ }
27139
+
26882
27140
  // src/agent/forkIndex.ts
26883
27141
  import { createReadStream } from "fs";
26884
27142
  import { readdir, realpath } from "fs/promises";
@@ -27108,7 +27366,7 @@ class CodexAgent {
27108
27366
  additionalDirectories: {}
27109
27367
  },
27110
27368
  providers: {},
27111
- _meta: { alwith: { tools: { version: 1 }, turns: { version: 2 } }, codex: { forkAtTurn: true, sessionLineage: true, archive: true, seedHistory: true, skills: true, plugins: true, providerCatalog: true, rename: true, account: true, fuzzyFileSearch: true } }
27369
+ _meta: { alwith: { tools: { version: 1 }, turns: { version: 2 } }, codex: { forkAtTurn: true, sessionLineage: true, archive: true, sessionHistory: { version: 2, items: true, modes: ["browse", "export"] }, seedHistory: true, skills: true, plugins: true, providerCatalog: true, rename: true, account: true, fuzzyFileSearch: true } }
27112
27370
  },
27113
27371
  authMethods: authMethods(this.capabilities, this.env)
27114
27372
  };
@@ -27660,6 +27918,7 @@ class CodexAgent {
27660
27918
  cursor,
27661
27919
  ...cwd ? { cwd } : {},
27662
27920
  sourceKinds: ["cli", "vscode", "exec", "appServer", "unknown"],
27921
+ modelProviders: [],
27663
27922
  ...archived ? { archived: true } : {}
27664
27923
  }));
27665
27924
  const response = await list(params.cursor ?? null);
@@ -27713,6 +27972,25 @@ class CodexAgent {
27713
27972
  await this.withCodex(() => this.codex.threadDelete({ threadId: params.sessionId }));
27714
27973
  return {};
27715
27974
  }
27975
+ async sessionHistory(params, signal) {
27976
+ this.requireInitialized("_codex/session_history");
27977
+ this.checkHistoryIdle(params);
27978
+ const response = await readSessionHistory(this.codex, params, signal);
27979
+ this.checkHistoryIdle(params);
27980
+ return { ...response, running: this.sessions.get(params.sessionId)?.session.activeTurn ? true : response.running };
27981
+ }
27982
+ async sessionHistoryItems(params, signal) {
27983
+ this.requireInitialized("_codex/session_history_items");
27984
+ this.checkHistoryIdle(params);
27985
+ const response = await readSessionHistoryItems(this.codex, params, signal);
27986
+ this.checkHistoryIdle(params);
27987
+ return { ...response, running: this.sessions.get(params.sessionId)?.session.activeTurn ? true : response.running };
27988
+ }
27989
+ checkHistoryIdle(params) {
27990
+ if (params.mode === "export" && this.sessions.get(params.sessionId)?.session.activeTurn) {
27991
+ throw historyError("history_busy", "Session history is still running; retry after the turn finishes", true);
27992
+ }
27993
+ }
27716
27994
  async archiveSession(params) {
27717
27995
  return await this.admission(() => this.archiveSessionInternal(params), params.sessionId);
27718
27996
  }
@@ -27925,6 +28203,8 @@ class CodexAgent {
27925
28203
  throw RequestError.invalidParams(undefined, "prompt must contain at least one content block");
27926
28204
  }
27927
28205
  const { session } = runtime;
28206
+ if (params._meta && typeof params._meta === "object")
28207
+ runtime.bridge.rememberPromptMeta(messageId, params._meta);
27928
28208
  this.providers.upstreamModel(session.model.model);
27929
28209
  const model = findModel(session.catalog, session.model.model);
27930
28210
  if (!modelSupportsImages(model) && params.prompt.some((block) => block.type === "image")) {
@@ -28515,7 +28795,7 @@ function createAgentApp(options) {
28515
28795
  };
28516
28796
  return agent({ name: options.info.name }).onConnect((connection) => {
28517
28797
  agent2 = new CodexAgent(connection.client, options);
28518
- }).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(methods.agent.session.close, (ctx) => current().closeSession(ctx.params)).onRequest(methods.agent.session.delete, (ctx) => current().deleteSession(ctx.params)).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_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));
28798
+ }).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(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_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));
28519
28799
  }
28520
28800
 
28521
28801
  // src/codex/AppServerClient.ts
@@ -28832,6 +29112,9 @@ class AppServerClient {
28832
29112
  threadTurnsList(params) {
28833
29113
  return this.send({ method: "thread/turns/list", params });
28834
29114
  }
29115
+ threadItemsList(params) {
29116
+ return this.send({ method: "thread/items/list", params });
29117
+ }
28835
29118
  threadArchive(params) {
28836
29119
  return this.send({ method: "thread/archive", params });
28837
29120
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.7.5",
6
+ "version": "0.7.7",
7
7
  "description": "Native ACP v2 agent for the OpenAI Codex app-server",
8
8
  "packageManager": "bun@1.4.0",
9
9
  "engines": {