@alpacakit/agents 0.1.0-beta.39 → 0.2.0-beta.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 (134) hide show
  1. package/README.md +142 -1
  2. package/dist/agents/builtin.d.ts +2 -2
  3. package/dist/agents/builtin.d.ts.map +1 -1
  4. package/dist/agents/builtin.js +6 -4
  5. package/dist/agents/claude/cli.d.ts +133 -0
  6. package/dist/agents/claude/cli.d.ts.map +1 -0
  7. package/dist/agents/claude/cli.js +182 -0
  8. package/dist/agents/claude/host.d.ts +14 -0
  9. package/dist/agents/claude/host.d.ts.map +1 -0
  10. package/dist/agents/claude/host.js +319 -0
  11. package/dist/agents/{claude.d.ts → claude/index.d.ts} +11 -11
  12. package/dist/agents/claude/index.d.ts.map +1 -0
  13. package/dist/agents/claude/index.js +134 -0
  14. package/dist/agents/claude/session.d.ts +25 -0
  15. package/dist/agents/claude/session.d.ts.map +1 -0
  16. package/dist/agents/claude/session.js +321 -0
  17. package/dist/agents/codex/cli.d.ts +132 -0
  18. package/dist/agents/codex/cli.d.ts.map +1 -0
  19. package/dist/agents/codex/cli.js +110 -0
  20. package/dist/agents/codex/host.d.ts +14 -0
  21. package/dist/agents/codex/host.d.ts.map +1 -0
  22. package/dist/agents/codex/host.js +221 -0
  23. package/dist/agents/codex/index.d.ts +14 -0
  24. package/dist/agents/codex/index.d.ts.map +1 -0
  25. package/dist/agents/codex/index.js +127 -0
  26. package/dist/agents/codex/session.d.ts +21 -0
  27. package/dist/agents/codex/session.d.ts.map +1 -0
  28. package/dist/agents/codex/session.js +390 -0
  29. package/dist/agents/openai-compatible/fetch-engine.d.ts.map +1 -1
  30. package/dist/agents/openai-compatible/fetch-engine.js +3 -2
  31. package/dist/agents/openai-compatible/pi/engine.js +1 -1
  32. package/dist/agents/openai-compatible/pi/{session.d.ts → run.d.ts} +1 -1
  33. package/dist/agents/openai-compatible/pi/run.d.ts.map +1 -0
  34. package/dist/agents/openai-compatible/pi/sandbox.d.ts.map +1 -1
  35. package/dist/auth/login-probe.d.ts +6 -4
  36. package/dist/auth/login-probe.d.ts.map +1 -1
  37. package/dist/auth/login-probe.js +19 -13
  38. package/dist/auth/material.d.ts +1 -1
  39. package/dist/auth/material.d.ts.map +1 -1
  40. package/dist/codex/app-server.d.ts +50 -1
  41. package/dist/codex/app-server.d.ts.map +1 -1
  42. package/dist/codex/app-server.js +140 -66
  43. package/dist/codex/index.d.ts +3 -2
  44. package/dist/codex/index.d.ts.map +1 -1
  45. package/dist/codex/index.js +2 -1
  46. package/dist/codex/protocol.d.ts +101 -0
  47. package/dist/codex/protocol.d.ts.map +1 -1
  48. package/dist/codex/protocol.js +78 -0
  49. package/dist/config/agent-config-validation.d.ts +1 -1
  50. package/dist/config/agent-config-validation.d.ts.map +1 -1
  51. package/dist/config/agent-configs.d.ts.map +1 -1
  52. package/dist/config/agent-configs.js +3 -3
  53. package/dist/config/compose.d.ts.map +1 -1
  54. package/dist/config/config.d.ts +1 -1
  55. package/dist/config/config.d.ts.map +1 -1
  56. package/dist/config/index.d.ts +2 -2
  57. package/dist/config/index.d.ts.map +1 -1
  58. package/dist/config/index.js +1 -1
  59. package/dist/config/model.d.ts +0 -1
  60. package/dist/config/model.d.ts.map +1 -1
  61. package/dist/config/schema.d.ts.map +1 -1
  62. package/dist/config/schema.js +1 -1
  63. package/dist/config/store.d.ts.map +1 -1
  64. package/dist/config/store.js +6 -24
  65. package/dist/config/support.d.ts +0 -1
  66. package/dist/config/support.d.ts.map +1 -1
  67. package/dist/config/support.js +0 -9
  68. package/dist/core/cli-child.d.ts +56 -0
  69. package/dist/core/cli-child.d.ts.map +1 -0
  70. package/dist/core/cli-child.js +105 -0
  71. package/dist/core/fs.d.ts +1 -1
  72. package/dist/core/fs.d.ts.map +1 -1
  73. package/dist/core/fs.js +10 -2
  74. package/dist/core/node-ports.d.ts.map +1 -1
  75. package/dist/core/node-ports.js +1 -5
  76. package/dist/core/session.d.ts +104 -0
  77. package/dist/core/session.d.ts.map +1 -0
  78. package/dist/core/session.js +29 -0
  79. package/dist/fleet/store.d.ts.map +1 -1
  80. package/dist/fleet/store.js +4 -3
  81. package/dist/host/availability.d.ts +2 -1
  82. package/dist/host/availability.d.ts.map +1 -1
  83. package/dist/host/github-dir.d.ts.map +1 -1
  84. package/dist/host/github-dir.js +2 -1
  85. package/dist/host/mcp-list.d.ts.map +1 -1
  86. package/dist/host/mcp-list.js +5 -6
  87. package/dist/host/run-command.d.ts +2 -1
  88. package/dist/host/run-command.d.ts.map +1 -1
  89. package/dist/host/run-command.js +10 -19
  90. package/dist/host/session-files.d.ts +23 -0
  91. package/dist/host/session-files.d.ts.map +1 -0
  92. package/dist/host/session-files.js +92 -0
  93. package/dist/index.d.ts +9 -4
  94. package/dist/index.d.ts.map +1 -1
  95. package/dist/index.js +5 -2
  96. package/dist/internal/controlled-process/supervisor-runtime.js +27 -1
  97. package/dist/kernel/classify.d.ts +1 -2
  98. package/dist/kernel/classify.d.ts.map +1 -1
  99. package/dist/kernel/classify.js +1 -1
  100. package/dist/kernel/cli-agent.d.ts.map +1 -1
  101. package/dist/kernel/cli-agent.js +26 -85
  102. package/dist/kernel/cli-login.d.ts.map +1 -1
  103. package/dist/kernel/cli-login.js +9 -30
  104. package/dist/kernel/definition.d.ts +11 -2
  105. package/dist/kernel/definition.d.ts.map +1 -1
  106. package/dist/kernel/facets.d.ts +38 -1
  107. package/dist/kernel/facets.d.ts.map +1 -1
  108. package/dist/kernel/facets.js +20 -0
  109. package/dist/kernel/login.d.ts.map +1 -1
  110. package/dist/kernel/login.js +2 -1
  111. package/dist/kernel/options.d.ts +1 -1
  112. package/dist/kernel/options.d.ts.map +1 -1
  113. package/dist/kernel/run.d.ts.map +1 -1
  114. package/dist/kernel/run.js +2 -1
  115. package/dist/kernel/runtime.d.ts +10 -6
  116. package/dist/kernel/runtime.d.ts.map +1 -1
  117. package/dist/kernel/runtime.js +4 -1
  118. package/dist/kernel/session.d.ts +104 -0
  119. package/dist/kernel/session.d.ts.map +1 -0
  120. package/dist/kernel/session.js +314 -0
  121. package/dist/testing/fake-exec.d.ts +10 -5
  122. package/dist/testing/fake-exec.d.ts.map +1 -1
  123. package/dist/testing/fake-exec.js +17 -2
  124. package/dist/testing/index.d.ts +1 -1
  125. package/dist/testing/index.d.ts.map +1 -1
  126. package/dist/testing/index.js +1 -1
  127. package/package.json +2 -2
  128. package/dist/agents/claude.d.ts.map +0 -1
  129. package/dist/agents/claude.js +0 -543
  130. package/dist/agents/codex.d.ts +0 -19
  131. package/dist/agents/codex.d.ts.map +0 -1
  132. package/dist/agents/codex.js +0 -377
  133. package/dist/agents/openai-compatible/pi/session.d.ts.map +0 -1
  134. /package/dist/agents/openai-compatible/pi/{session.js → run.js} +0 -0
@@ -0,0 +1,221 @@
1
+ /**
2
+ * The codex host plane: auth materials and sign-in, skills and plugins
3
+ * through a short-lived app-server client, and MCP registration through
4
+ * the CLI. Outside a run and a session; every path comes from
5
+ * `HostContext.location`, never `os.homedir()`.
6
+ */
7
+ import { LOGIN_METHOD, } from "../../auth/login.js";
8
+ import { cliLoginProbe } from "../../auth/login-probe.js";
9
+ import { AUTH_MATERIAL_KIND, envVarAuthMaterial } from "../../auth/material.js";
10
+ import { requireSecret } from "../../auth/secrets.js";
11
+ import { listAllCodexMcpServerStatuses, withCodexAppServer, } from "../../codex/app-server.js";
12
+ import { CODEX_APP_SERVER_METHOD } from "../../codex/protocol.js";
13
+ import { AGENT_ERROR_CODE, AgentError, AUTH_FAILURE_REASON, } from "../../core/error.js";
14
+ import { INSTALL_STATUS, MCP_SCOPE, MCP_TRANSPORT, SKILL_SOURCE_KIND, } from "../../host/capabilities.js";
15
+ import { runHostCommand } from "../../host/run-command.js";
16
+ import { cliLoginCommand } from "../../kernel/cli-login.js";
17
+ import { CODEX, CODEX_API_KEY_ENV_VAR, CODEX_HOME_ENV_VAR } from "./cli.js";
18
+ const COMPETING_API_KEY_VARS = [CODEX_API_KEY_ENV_VAR, "CODEX_API_KEY"];
19
+ const COMPETING_HOME_VARS = [CODEX_HOME_ENV_VAR, "CODEX_API_KEY"];
20
+ const UNSUPPORTED_CWD_REASON = "unsupported codex stdio mcp cwd";
21
+ const UNSUPPORTED_SCOPE_REASON_PREFIX = "unsupported codex mcp scope";
22
+ const UNSUPPORTED_PLUGIN_OVERWRITE_REASON = "plugin install does not support overwrite";
23
+ const CODEX_PLUGIN_AUTH_REQUIRED_MESSAGE = "Codex plugin installation requires app authorization";
24
+ const CODEX_ALREADY_INSTALLED_STATUS = /already/i;
25
+ const CODEX_MCP_UNUSABLE_STATUS = /failed|error|invalid|missing|required/i;
26
+ function codexAppServerCwd(ctx) {
27
+ return ctx.location.projectDir ?? ctx.location.homeDir;
28
+ }
29
+ function codexAppServerCwds(ctx) {
30
+ return [codexAppServerCwd(ctx)];
31
+ }
32
+ async function listCodexSkills(ctx) {
33
+ return withCodexAppServer(codexAppServerOptions(ctx), async (client) => {
34
+ const result = await client.request(CODEX_APP_SERVER_METHOD.skillsList, {
35
+ cwds: codexAppServerCwds(ctx),
36
+ forceReload: true,
37
+ });
38
+ return skillsFromCodexResult(result);
39
+ });
40
+ }
41
+ async function installCodexPlugin(ctx, source, options) {
42
+ if (options.overwrite === true) {
43
+ // `plugin/install` has no overwrite semantics; refusing is honest,
44
+ // silently ignoring the request is not (same contract as claude).
45
+ throw new AgentError({
46
+ code: AGENT_ERROR_CODE.invalidInput,
47
+ classification: AgentError.agentFailure(AGENT_ERROR_CODE.invalidInput),
48
+ message: "Codex plugin installation cannot overwrite an installed plugin",
49
+ data: { reason: UNSUPPORTED_PLUGIN_OVERWRITE_REASON },
50
+ });
51
+ }
52
+ return withCodexAppServer(codexAppServerOptions(ctx), async (client) => {
53
+ const result = await client.request(CODEX_APP_SERVER_METHOD.pluginInstall, {
54
+ pluginName: source.name,
55
+ marketplacePath: null,
56
+ remoteMarketplaceName: null,
57
+ });
58
+ return installOutcomeFromCodexPlugin(source.name, result);
59
+ });
60
+ }
61
+ async function listCodexMcp(ctx) {
62
+ return withCodexAppServer(codexAppServerOptions(ctx), async (client) => (await listAllCodexMcpServerStatuses(client)).map(codexMcpState));
63
+ }
64
+ async function addCodexStdioMcp(ctx, name, spec, options) {
65
+ assertCodexStdioMcpSupported(spec, options);
66
+ await runHostCommand(ctx, {
67
+ command: CODEX.command,
68
+ args: [
69
+ CODEX.mcp.mcp,
70
+ CODEX.mcp.add,
71
+ name,
72
+ ...Object.entries(spec.env).flatMap(([key, value]) => [
73
+ CODEX.mcp.env,
74
+ `${key}=${value}`,
75
+ ]),
76
+ CODEX.mcp.executableSeparator,
77
+ spec.command,
78
+ ...spec.args,
79
+ ],
80
+ });
81
+ return {
82
+ status: INSTALL_STATUS.installed,
83
+ location: `codex:${options.scope}:${name}`,
84
+ };
85
+ }
86
+ async function removeCodexMcp(ctx, name, options) {
87
+ assertCodexMcpScopeSupported(options.scope);
88
+ await runHostCommand(ctx, {
89
+ command: CODEX.command,
90
+ args: [CODEX.mcp.mcp, CODEX.mcp.remove, name],
91
+ });
92
+ }
93
+ function assertCodexStdioMcpSupported(spec, options) {
94
+ assertCodexMcpScopeSupported(options.scope);
95
+ if (spec.cwd !== null) {
96
+ throw new AgentError({
97
+ code: AGENT_ERROR_CODE.invalidInput,
98
+ classification: AgentError.agentFailure(AGENT_ERROR_CODE.invalidInput),
99
+ message: "Codex stdio MCP registration does not support server cwd",
100
+ data: { reason: UNSUPPORTED_CWD_REASON },
101
+ });
102
+ }
103
+ }
104
+ function assertCodexMcpScopeSupported(scope) {
105
+ if (scope === MCP_SCOPE.user) {
106
+ return;
107
+ }
108
+ const reason = [UNSUPPORTED_SCOPE_REASON_PREFIX, scope].join(": ");
109
+ throw new AgentError({
110
+ code: AGENT_ERROR_CODE.invalidInput,
111
+ classification: AgentError.agentFailure(AGENT_ERROR_CODE.invalidInput),
112
+ message: `Codex MCP registration does not support scope "${scope}"`,
113
+ data: { reason },
114
+ });
115
+ }
116
+ function codexAppServerOptions(ctx) {
117
+ return {
118
+ exec: ctx.exec,
119
+ clock: ctx.clock,
120
+ env: ctx.env,
121
+ cwd: codexAppServerCwd(ctx),
122
+ command: CODEX.command,
123
+ };
124
+ }
125
+ function skillsFromCodexResult(result) {
126
+ return result.data.flatMap((entry) => entry.skills.map((skill) => ({
127
+ id: skill.name,
128
+ name: skill.name,
129
+ description: skill.description,
130
+ location: skill.path,
131
+ source: `codex:${skill.scope}`,
132
+ })));
133
+ }
134
+ function installOutcomeFromCodexPlugin(name, result) {
135
+ if (result.appsNeedingAuth.length > 0) {
136
+ throw new AgentError({
137
+ code: AGENT_ERROR_CODE.auth,
138
+ classification: AgentError.agentFailure(AGENT_ERROR_CODE.auth),
139
+ message: CODEX_PLUGIN_AUTH_REQUIRED_MESSAGE,
140
+ data: {
141
+ reason: AUTH_FAILURE_REASON.notLoggedIn,
142
+ detail: result.authPolicy,
143
+ },
144
+ });
145
+ }
146
+ const location = result.location ?? `codex:plugin:${name}`;
147
+ const alreadyInstalled = result.alreadyInstalled === true ||
148
+ (result.status !== null &&
149
+ CODEX_ALREADY_INSTALLED_STATUS.test(result.status));
150
+ return {
151
+ status: alreadyInstalled
152
+ ? INSTALL_STATUS.alreadyInstalled
153
+ : INSTALL_STATUS.installed,
154
+ location,
155
+ };
156
+ }
157
+ function codexMcpState(status) {
158
+ // tools === null = the app-server did not enumerate tools; McpServerState
159
+ // keeps that distinct from an enumerated-but-empty tool list.
160
+ const tools = status.tools === null
161
+ ? null
162
+ : Object.entries(status.tools).map(([key, tool]) => tool.name ?? key);
163
+ return {
164
+ name: status.name,
165
+ transport: MCP_TRANSPORT.stdio,
166
+ usable: !CODEX_MCP_UNUSABLE_STATUS.test(status.authStatus),
167
+ tools,
168
+ };
169
+ }
170
+ function codexLoginCommand(args) {
171
+ return (request, ctx) => cliLoginCommand({
172
+ command: CODEX.command,
173
+ args,
174
+ envPatch: {
175
+ set: { [CODEX_HOME_ENV_VAR]: request.homeDir },
176
+ unset: COMPETING_API_KEY_VARS,
177
+ },
178
+ request,
179
+ ctx,
180
+ });
181
+ }
182
+ export const codexAuth = {
183
+ [AUTH_MATERIAL_KIND.homeDir]: envVarAuthMaterial({
184
+ set: (material) => ({ [CODEX_HOME_ENV_VAR]: material.path }),
185
+ unset: COMPETING_API_KEY_VARS,
186
+ check: (material, ctx) => cliLoginProbe({
187
+ command: CODEX.command,
188
+ args: CODEX.auth.statusArgs,
189
+ envPatch: {
190
+ set: { [CODEX_HOME_ENV_VAR]: material.path },
191
+ unset: COMPETING_API_KEY_VARS,
192
+ },
193
+ ctx,
194
+ }),
195
+ }),
196
+ [AUTH_MATERIAL_KIND.apiKey]: envVarAuthMaterial({
197
+ set: async (material, secrets) => ({
198
+ [CODEX_API_KEY_ENV_VAR]: await requireSecret(secrets, material.secret),
199
+ }),
200
+ unset: COMPETING_HOME_VARS,
201
+ }),
202
+ };
203
+ export const codexLogin = {
204
+ methods: {
205
+ [LOGIN_METHOD.oauth]: codexLoginCommand(CODEX.auth.oauthLoginArgs),
206
+ [LOGIN_METHOD.device]: codexLoginCommand(CODEX.auth.deviceLoginArgs),
207
+ },
208
+ };
209
+ export const codexSkills = {
210
+ list: listCodexSkills,
211
+ install: {
212
+ [SKILL_SOURCE_KIND.plugin]: installCodexPlugin,
213
+ },
214
+ };
215
+ export const codexMcp = {
216
+ list: listCodexMcp,
217
+ add: {
218
+ [MCP_TRANSPORT.stdio]: addCodexStdioMcp,
219
+ },
220
+ remove: removeCodexMcp,
221
+ };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The built-in codex agent: the one-shot run contract
3
+ * (`codex exec [--model m] [-c model_reasoning_effort="e"] --json
4
+ * --skip-git-repo-check --sandbox <mode> -C <workspace>`, prompt on
5
+ * stdin; sandboxing is filesystem-level, so read-only grants have no argv
6
+ * mapping) composed with the session adapter and the host plane.
7
+ * Vocabulary lives in `cli.ts`.
8
+ */
9
+ import { type FailureMatcher } from "../../kernel/classify.js";
10
+ import type { AgentDefinition } from "../../kernel/definition.js";
11
+ import { type CodexSessionPermissions } from "./cli.js";
12
+ export declare function capacityTextMatcher(): FailureMatcher;
13
+ export declare function codex(): AgentDefinition<"codex", CodexSessionPermissions>;
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agents/codex/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,OAAO,EACL,KAAK,cAAc,EAEpB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAElE,OAAO,EAAS,KAAK,uBAAuB,EAAE,MAAM,UAAU,CAAC;AA2D/D,wBAAgB,mBAAmB,IAAI,cAAc,CAepD;AAED,wBAAgB,KAAK,IAAI,eAAe,CAAC,OAAO,EAAE,uBAAuB,CAAC,CA8CzE"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * The built-in codex agent: the one-shot run contract
3
+ * (`codex exec [--model m] [-c model_reasoning_effort="e"] --json
4
+ * --skip-git-repo-check --sandbox <mode> -C <workspace>`, prompt on
5
+ * stdin; sandboxing is filesystem-level, so read-only grants have no argv
6
+ * mapping) composed with the session adapter and the host plane.
7
+ * Vocabulary lives in `cli.ts`.
8
+ */
9
+ import { CODEX_SANDBOX_MODE } from "../../codex/protocol.js";
10
+ import { AGENT_ERROR_CODE } from "../../core/error.js";
11
+ import { readJsonRecord, readRecord, readString } from "../../core/json.js";
12
+ import { AGENT_EVENT_TYPE } from "../../core/run.js";
13
+ import { cliAvailability } from "../../host/availability.js";
14
+ import { parseCooldownHint, } from "../../kernel/classify.js";
15
+ import { defineCliAgent } from "../../kernel/cli-agent.js";
16
+ import { SANDBOX_MODE } from "../../kernel/options.js";
17
+ import { CODEX } from "./cli.js";
18
+ import { codexAuth, codexLogin, codexMcp, codexSkills } from "./host.js";
19
+ import { codexSessions } from "./session.js";
20
+ function sharedArgs(ctx, sandboxValue) {
21
+ return [
22
+ CODEX.cli.exec,
23
+ ...(ctx.model === null ? [] : [CODEX.cli.model, ctx.model]),
24
+ ...(ctx.effort === null
25
+ ? []
26
+ : [
27
+ CODEX.cli.config,
28
+ `${CODEX.cli.reasoningEffortConfigKey}="${ctx.effort}"`,
29
+ ]),
30
+ CODEX.cli.json,
31
+ CODEX.cli.skipGitRepoCheck,
32
+ CODEX.cli.sandbox,
33
+ sandboxValue,
34
+ CODEX.cli.workspace,
35
+ ctx.workspace,
36
+ ];
37
+ }
38
+ function parseCodexLine(line) {
39
+ const record = readJsonRecord(line);
40
+ if (record === null) {
41
+ return [];
42
+ }
43
+ const type = readString(record, CODEX.json.field.type);
44
+ if (type === CODEX.json.event.turnCompleted) {
45
+ return [{ type: AGENT_EVENT_TYPE.turn }];
46
+ }
47
+ if (type === CODEX.json.event.agentMessage) {
48
+ const text = readString(record, CODEX.json.field.text);
49
+ return text === null ? [] : [{ type: AGENT_EVENT_TYPE.message, text }];
50
+ }
51
+ if (type === CODEX.json.event.itemCompleted) {
52
+ const item = readRecord(record, CODEX.json.field.item);
53
+ if (item !== null &&
54
+ readString(item, CODEX.json.field.type) === CODEX.json.event.agentMessage) {
55
+ const text = readString(item, CODEX.json.field.text);
56
+ return text === null ? [] : [{ type: AGENT_EVENT_TYPE.message, text }];
57
+ }
58
+ }
59
+ return [];
60
+ }
61
+ /**
62
+ * Codex "selected model is at capacity" phrasing, plus the looser
63
+ * "model ... at capacity" combination. Exported for custom agents that
64
+ * surface the same provider text.
65
+ */
66
+ /** Codex capacity phrasing (v1 F5 signals, kept verbatim). */
67
+ const CAPACITY_TEXT = /selected model is at capacity|model is at capacity/i;
68
+ const CAPACITY_COMBINED = /at capacity/i;
69
+ const CAPACITY_MODEL = /model/i;
70
+ export function capacityTextMatcher() {
71
+ return (evidence) => {
72
+ const text = `${evidence.stderr}\n${evidence.stdout}`;
73
+ const matches = CAPACITY_TEXT.test(text) ||
74
+ (CAPACITY_COMBINED.test(text) && CAPACITY_MODEL.test(text));
75
+ if (!matches) {
76
+ return null;
77
+ }
78
+ return {
79
+ code: AGENT_ERROR_CODE.capacity,
80
+ message: "Provider is at capacity",
81
+ data: { cooldownUntil: parseCooldownHint(text, evidence.now) },
82
+ };
83
+ };
84
+ }
85
+ export function codex() {
86
+ const definition = defineCliAgent({
87
+ id: CODEX.id,
88
+ command: CODEX.command,
89
+ args: {
90
+ [SANDBOX_MODE.full]: (_sandbox, ctx) => sharedArgs(ctx, CODEX_SANDBOX_MODE.dangerFullAccess),
91
+ [SANDBOX_MODE.readOnly]: (_sandbox, ctx) => sharedArgs(ctx, CODEX_SANDBOX_MODE.readOnly),
92
+ },
93
+ parseLine: parseCodexLine,
94
+ classify: [capacityTextMatcher()],
95
+ detectCompletion: (line, state) => {
96
+ if (state.messages.length === 0) {
97
+ return false;
98
+ }
99
+ const record = readJsonRecord(line);
100
+ return (record !== null &&
101
+ readString(record, CODEX.json.field.type) ===
102
+ CODEX.json.event.turnCompleted);
103
+ },
104
+ availability: cliAvailability({
105
+ command: CODEX.command,
106
+ commandMissingRemediation: {
107
+ detail: "Install Codex and ensure `codex` is on PATH.",
108
+ command: null,
109
+ },
110
+ authentication: {
111
+ args: CODEX.auth.statusArgs,
112
+ remediation: {
113
+ detail: "Sign in to Codex.",
114
+ command: {
115
+ executable: CODEX.command,
116
+ args: CODEX.auth.oauthLoginArgs,
117
+ },
118
+ },
119
+ },
120
+ }),
121
+ auth: codexAuth,
122
+ login: codexLogin,
123
+ skills: codexSkills,
124
+ mcp: codexMcp,
125
+ });
126
+ return { ...definition, session: codexSessions() };
127
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Codex session adapter: one `codex app-server` process holding one thread.
3
+ *
4
+ * Protocol facts (codex 0.153.4, T53 / T57 / T61 lab runs):
5
+ * - `thread/start {cwd, sandbox, approvalPolicy, approvalsReviewer}` creates
6
+ * the thread and takes its writer lock; with a writable sandbox Codex also
7
+ * appends a `trust_level` entry for `cwd` to `~/.codex/config.toml`;
8
+ * - `thread/resume` must repeat the permissions — without `sandbox` the
9
+ * resumed turns ran as danger-full-access; it answers -32600 "already has
10
+ * an active writer" while another process holds the thread and -32600
11
+ * "… is archived" for an archived one (`thread/unarchive` first, opt-in);
12
+ * - `turn/start` answers the turn id at once; `turn/steer {expectedTurnId}`
13
+ * appends to it; `turn/interrupt` ends it with `turn/completed`
14
+ * status `interrupted` (the command's own `item/completed` may trail by ~36 s);
15
+ * - `item/commandExecution/requestApproval` is a server request answered by
16
+ * `{"decision": "accept" | "decline"}`; closing stdin releases the lock.
17
+ */
18
+ import { type SessionCapability } from "../../kernel/session.js";
19
+ import { type CodexSessionPermissions } from "./cli.js";
20
+ export declare function codexSessions(): SessionCapability<CodexSessionPermissions>;
21
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/agents/codex/session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAyCH,OAAO,EAKL,KAAK,iBAAiB,EAIvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAKL,KAAK,uBAAuB,EAC7B,MAAM,UAAU,CAAC;AAielB,wBAAgB,aAAa,IAAI,iBAAiB,CAAC,uBAAuB,CAAC,CAM1E"}