@brunobracaioli/aibrain 0.4.0-beta.7 → 0.4.0-beta.9
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/README.md +6 -1
- package/dist/claude-observation.mjs +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/codex-compatibility.mjs +52 -2
- package/dist/codex-protocol-fingerprint.json +10 -10
- package/dist/extensions-catalog.mjs +13 -2
- package/dist/extensions-cli.mjs +15 -0
- package/dist/launch.mjs +16 -1
- package/dist/mcp-servers.mjs +29 -2
- package/dist/package.json +1 -1
- package/dist/platform.mjs +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,7 +58,7 @@ notes or lock files to work around a reported storage error.
|
|
|
58
58
|
|
|
59
59
|
The reviewed native compatibility set is Claude Code 2.1.294, 2.1.295, 2.1.296,
|
|
60
60
|
2.1.299, 2.1.300, 2.1.301, 2.1.302 or 2.1.303, and Codex CLI 0.161.0,
|
|
61
|
-
0.162.0, 0.162.1, 0.163.0 or 0.
|
|
61
|
+
0.162.0, 0.162.1, 0.163.0, 0.164.0 or 0.166.0 (0.165.0 was never qualified). A newer stable Codex 0.x release may continue only
|
|
62
62
|
after its locally generated experimental protocol schemas and transport flags
|
|
63
63
|
match the bundled adapter contract; prereleases, older releases and new majors
|
|
64
64
|
remain rejected. Starting with beta14, newer stable Claude 2.1 patches can
|
|
@@ -74,6 +74,11 @@ record formats. Native launch/resume qualification is separate from a new
|
|
|
74
74
|
model/JEV compaction qualification. A later native release that changes the
|
|
75
75
|
consumed contract can still require an AI Brain compatibility update.
|
|
76
76
|
|
|
77
|
+
`0.4.0-beta.9` refreshes the bundled contract to Codex 0.166.0. Its delta is
|
|
78
|
+
additive: optional item timing, an image generation id, an attach-to-source fork
|
|
79
|
+
flag and two error codes. See the
|
|
80
|
+
[Codex 0.166 qualification record](../../docs/reference/codex-166-compatibility-2026-11-04.md).
|
|
81
|
+
|
|
77
82
|
The Codex terminal bridge permits the native session picker's separate read-only
|
|
78
83
|
connection while keeping the primary conversation and monitor intact. A picker
|
|
79
84
|
cannot compact, start a turn, inject history or take ownership of the primary
|
|
@@ -16,7 +16,7 @@ export const MAX_LOG_FILES = 3;
|
|
|
16
16
|
const LOCK_WAIT_MS = 250;
|
|
17
17
|
const LOCK_STALE_MS = 30_000;
|
|
18
18
|
const ADMISSION_MS = 60 * 60 * 1000;
|
|
19
|
-
export const ADAPTER_VERSION = '0.4.0-beta.
|
|
19
|
+
export const ADAPTER_VERSION = '0.4.0-beta.9';
|
|
20
20
|
const MAX_DIAGNOSTIC_COUNT = 10_000_000;
|
|
21
21
|
const MAX_DIAGNOSTIC_BYTES = 128 * 1024 * 1024;
|
|
22
22
|
const CHECKPOINT_BACKENDS = new Set(['native_store', 'private_file']);
|
package/dist/cli.mjs
CHANGED
|
@@ -40,7 +40,7 @@ import { extensionsSummary, hooksCommand, mcpCommand } from './extensions-cli.mj
|
|
|
40
40
|
import { sessionServers } from './mcp-servers.mjs';
|
|
41
41
|
import { anyFormatter } from './guardrails/format.mjs';
|
|
42
42
|
|
|
43
|
-
const VERSION = '0.4.0-beta.
|
|
43
|
+
const VERSION = '0.4.0-beta.9';
|
|
44
44
|
// The command is `aisac`; `aibrain` is an alias installed from the same entry.
|
|
45
45
|
const COMMAND = 'aisac';
|
|
46
46
|
const ENDPOINT = 'https://mcp.ai-brain.aisac.cloud/mcp';
|
|
@@ -26,7 +26,14 @@ const PAGINATION_CONTRACT_VALID =
|
|
|
26
26
|
fingerprint.roots[PAGINATION_CONTRACT.response_schema]?.sha256 &&
|
|
27
27
|
typeof PAGINATION_CONTRACT.graph_sha256 === 'string' &&
|
|
28
28
|
PAGINATION_CONTRACT.graph_sha256.length === 64);
|
|
29
|
-
const QUALIFIED_VERSIONS = new Set([
|
|
29
|
+
const QUALIFIED_VERSIONS = new Set([
|
|
30
|
+
'0.161.0',
|
|
31
|
+
'0.162.0',
|
|
32
|
+
'0.162.1',
|
|
33
|
+
'0.163.0',
|
|
34
|
+
'0.164.0',
|
|
35
|
+
'0.166.0',
|
|
36
|
+
]);
|
|
30
37
|
const ANNOTATIONS = new Set([
|
|
31
38
|
'$comment',
|
|
32
39
|
'title',
|
|
@@ -475,7 +482,50 @@ export async function resolveCodexCompatibility(executable, baseEnvironment = pr
|
|
|
475
482
|
}
|
|
476
483
|
}
|
|
477
484
|
|
|
485
|
+
/** @param {string} left @param {string} right */
|
|
486
|
+
function compareStableVersions(left, right) {
|
|
487
|
+
const a = left.split('.').map(Number);
|
|
488
|
+
const b = right.split('.').map(Number);
|
|
489
|
+
for (let index = 0; index < 3; index += 1) {
|
|
490
|
+
const difference = (a[index] ?? 0) - (b[index] ?? 0);
|
|
491
|
+
if (difference !== 0) return difference;
|
|
492
|
+
}
|
|
493
|
+
return 0;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/** The newest Codex release this client was qualified against. */
|
|
497
|
+
export const LATEST_QUALIFIED_CODEX = /** @type {string} */ (
|
|
498
|
+
[...QUALIFIED_VERSIONS].sort(compareStableVersions).at(-1)
|
|
499
|
+
);
|
|
500
|
+
|
|
501
|
+
// Rejections a user fixes by installing a qualified Codex (or a newer aisac):
|
|
502
|
+
// the installed release's contract or transport differs from the bundled one.
|
|
503
|
+
const CONTRACT_REJECTIONS = new Set([
|
|
504
|
+
'protocol_schema_mismatch',
|
|
505
|
+
'protocol_method_missing',
|
|
506
|
+
'schema_root_missing_or_invalid',
|
|
507
|
+
'schema_set_too_large',
|
|
508
|
+
'schema_generation_failed',
|
|
509
|
+
'transport_flags_missing',
|
|
510
|
+
'protocol_probe_failed',
|
|
511
|
+
]);
|
|
512
|
+
|
|
513
|
+
/** @param {{reason:string, version:string|null}} decision @returns {string|null} */
|
|
514
|
+
export function codexCompatibilityRemedy(decision) {
|
|
515
|
+
const detected = decision.version === null ? 'The installed Codex' : `Codex ${decision.version}`;
|
|
516
|
+
const reinstall = `npm install -g @openai/codex@${LATEST_QUALIFIED_CODEX}`;
|
|
517
|
+
if (CONTRACT_REJECTIONS.has(decision.reason))
|
|
518
|
+
return `${detected} is not qualified by this aisac (newest qualified: ${LATEST_QUALIFIED_CODEX}). Install the qualified Codex with \`${reinstall}\`, or check for an aisac release that qualifies it with \`npm install -g @aisac/cli@beta\`.`;
|
|
519
|
+
if (decision.reason === 'version_unqualified')
|
|
520
|
+
return `${detected} is older than this aisac supports. Update it with \`${reinstall}\`.`;
|
|
521
|
+
if (decision.reason === 'version_not_stable_0x')
|
|
522
|
+
return `${detected} is not a stable 0.x release. Install a qualified one with \`${reinstall}\`.`;
|
|
523
|
+
return null;
|
|
524
|
+
}
|
|
525
|
+
|
|
478
526
|
/** @param {{reason:string, version:string|null}} decision @returns {string} */
|
|
479
527
|
export function codexCompatibilityError(decision) {
|
|
480
|
-
|
|
528
|
+
const coded = `codex_protocol_incompatible:${decision.reason}:detected=${decision.version ?? 'unavailable'};run aisac doctor --json`;
|
|
529
|
+
const remedy = codexCompatibilityRemedy(decision);
|
|
530
|
+
return remedy === null ? coded : `${coded}\n${remedy}`;
|
|
481
531
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"native": "0.
|
|
3
|
+
"native": "0.166.0",
|
|
4
4
|
"consumed_pagination": {
|
|
5
5
|
"method": "thread/turns/list",
|
|
6
6
|
"request_schema": "v2/ThreadTurnsListParams.json",
|
|
7
7
|
"response_schema": "v2/ThreadTurnsListResponse.json",
|
|
8
8
|
"request_schema_sha256": "29717980579b77eb4c7cbd1118dd238fcb3e010f3ef5236d74bd4e4f6e02c005",
|
|
9
|
-
"response_schema_sha256": "
|
|
10
|
-
"graph_sha256": "
|
|
9
|
+
"response_schema_sha256": "53d96dae44edcecee02d8dcce5645800a52a62444f288ff48376e99e506561c6",
|
|
10
|
+
"graph_sha256": "a9008170cbf190054a75f4a539db7fe271e30cf85a157ad27e2dc2192785f311",
|
|
11
11
|
"ordering": "asc",
|
|
12
12
|
"items_view": "full"
|
|
13
13
|
},
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"v2/ThreadTurnsListResponse.json": {
|
|
20
20
|
"methods": null,
|
|
21
|
-
"sha256": "
|
|
21
|
+
"sha256": "53d96dae44edcecee02d8dcce5645800a52a62444f288ff48376e99e506561c6"
|
|
22
22
|
},
|
|
23
23
|
"ClientRequest.json": {
|
|
24
24
|
"methods": [
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"config/read",
|
|
40
40
|
"account/read"
|
|
41
41
|
],
|
|
42
|
-
"sha256": "
|
|
42
|
+
"sha256": "950bcefcb938bdf04b84305fdcf6767b05db782a0853ef1356fe05d607b0f5b3"
|
|
43
43
|
},
|
|
44
44
|
"ClientNotification.json": {
|
|
45
45
|
"methods": ["initialized"],
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"thread/compacted",
|
|
79
79
|
"warning"
|
|
80
80
|
],
|
|
81
|
-
"sha256": "
|
|
81
|
+
"sha256": "7f739a3a39a248692147f1a5b2212f440d36350bf2bcca0a5393abd32c188bdf"
|
|
82
82
|
},
|
|
83
83
|
"JSONRPCResponse.json": {
|
|
84
84
|
"methods": null,
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
},
|
|
107
107
|
"v2/ThreadForkResponse.json": {
|
|
108
108
|
"methods": null,
|
|
109
|
-
"sha256": "
|
|
109
|
+
"sha256": "36af2650a2f2fddd081dd6cb92a91632d0fc12e819fb47ceadcaf238990bec1e"
|
|
110
110
|
},
|
|
111
111
|
"v2/ThreadInjectItemsResponse.json": {
|
|
112
112
|
"methods": null,
|
|
@@ -114,15 +114,15 @@
|
|
|
114
114
|
},
|
|
115
115
|
"v2/ThreadReadResponse.json": {
|
|
116
116
|
"methods": null,
|
|
117
|
-
"sha256": "
|
|
117
|
+
"sha256": "136c873857d2ba0e1aa0836d96ec8d81bfc30a9209e058226e910e0179563e6b"
|
|
118
118
|
},
|
|
119
119
|
"v2/ThreadResumeResponse.json": {
|
|
120
120
|
"methods": null,
|
|
121
|
-
"sha256": "
|
|
121
|
+
"sha256": "ea37ce77b7a1b2fff78191dac117013ef817cfe1f0ab04f95d1bdc847ceacbb9"
|
|
122
122
|
},
|
|
123
123
|
"v2/ThreadStartResponse.json": {
|
|
124
124
|
"methods": null,
|
|
125
|
-
"sha256": "
|
|
125
|
+
"sha256": "36af2650a2f2fddd081dd6cb92a91632d0fc12e819fb47ceadcaf238990bec1e"
|
|
126
126
|
}
|
|
127
127
|
},
|
|
128
128
|
"requiredClientFlags": ["app-server", "--listen", "stdio://"],
|
|
@@ -167,6 +167,10 @@ export function hookIds() {
|
|
|
167
167
|
* @property {Readonly<Record<CatalogLocale, string>>} [loginNote] Why and how this login differs.
|
|
168
168
|
* @property {Readonly<Record<CatalogLocale, string>>} description
|
|
169
169
|
* @property {Readonly<Record<CatalogLocale, string>>} reaches What the server can reach (FR7).
|
|
170
|
+
* @property {readonly string[]} [blockedTools] Tools that spend money, removed in both
|
|
171
|
+
* clients whatever the user's permission mode is (FR7.2). Exact names.
|
|
172
|
+
* @property {readonly string[]} [blockedToolPrefixes] Name prefixes removed in Claude Code
|
|
173
|
+
* only, through a glob deny rule; Codex documents exact names only (FR7.2).
|
|
170
174
|
*/
|
|
171
175
|
|
|
172
176
|
/** Session name of a catalog server, so it never collides with the user's own. */
|
|
@@ -215,6 +219,9 @@ export const MCP_CATALOG = Object.freeze([
|
|
|
215
219
|
source: 'https://github.com/supabase-community/supabase-mcp',
|
|
216
220
|
transport: { type: 'http', url: 'https://mcp.supabase.com/mcp?read_only=true' },
|
|
217
221
|
login: 'host-oauth',
|
|
222
|
+
// read_only=true should already leave these out; the vendor does not publish
|
|
223
|
+
// what it removes, so they are blocked as a second layer (FR7.2).
|
|
224
|
+
blockedTools: ['create_project', 'confirm_cost', 'create_branch'],
|
|
218
225
|
description: {
|
|
219
226
|
en: "Supabase's hosted server, read-only: tables, SQL, logs, advisors and docs.",
|
|
220
227
|
'pt-BR':
|
|
@@ -234,15 +241,19 @@ export const MCP_CATALOG = Object.freeze([
|
|
|
234
241
|
source: 'https://vercel.com/docs/agent-resources/vercel-mcp',
|
|
235
242
|
transport: { type: 'http', url: 'https://mcp.vercel.com' },
|
|
236
243
|
login: 'host-oauth',
|
|
244
|
+
// buy_domain charges the team after a quote, and its confirm flag is a model
|
|
245
|
+
// argument; a domain transfer may be charged (FR7.1, FR7.2).
|
|
246
|
+
blockedTools: ['buy_domain', 'create_or_transfer_domain'],
|
|
247
|
+
blockedToolPrefixes: ['buy_'],
|
|
237
248
|
description: {
|
|
238
249
|
en: "Vercel's hosted server: projects, deployments, logs, domains and environment variables.",
|
|
239
250
|
'pt-BR':
|
|
240
251
|
'Servidor hospedado da Vercel: projetos, deploys, logs, domínios e variáveis de ambiente.',
|
|
241
252
|
},
|
|
242
253
|
reaches: {
|
|
243
|
-
en: 'The teams you grant at login, with the access of your Vercel user: projects, deployments, build and runtime logs, domains and DNS, and environment variables, including decrypted values. It also has write tools (
|
|
254
|
+
en: 'The teams you grant at login, with the access of your Vercel user: projects, deployments, build and runtime logs, domains and DNS, and environment variables, including decrypted values. It also has write tools (deployments, environment variables, DNS records, firewall rules, project settings) and no read-only mode, so keep the confirmation of each call on. Buying domains is blocked by AISAC.',
|
|
244
255
|
'pt-BR':
|
|
245
|
-
'Os times que você liberar no login, com o acesso do seu usuário Vercel: projetos, deploys, logs de build e de execução, domínios e DNS, e variáveis de ambiente, inclusive valores decifrados. Também tem ferramentas de escrita (
|
|
256
|
+
'Os times que você liberar no login, com o acesso do seu usuário Vercel: projetos, deploys, logs de build e de execução, domínios e DNS, e variáveis de ambiente, inclusive valores decifrados. Também tem ferramentas de escrita (deploys, variáveis de ambiente, registros DNS, regras de firewall, configurações de projeto) e não tem modo somente leitura, então mantenha a confirmação de cada chamada ligada. A compra de domínios é bloqueada pela AISAC.',
|
|
246
257
|
},
|
|
247
258
|
},
|
|
248
259
|
{
|
package/dist/extensions-cli.mjs
CHANGED
|
@@ -273,6 +273,11 @@ export function serverInfo(entry, locale, item) {
|
|
|
273
273
|
note: 'Hosted by the vendor: its tools can change without a client release, so keep the confirmation of each call on.',
|
|
274
274
|
},
|
|
275
275
|
reaches: entry.reaches[locale],
|
|
276
|
+
// Tools that spend money, removed whatever the permission mode is (FR7.2).
|
|
277
|
+
blockedTools: [...(entry.blockedTools ?? [])],
|
|
278
|
+
...(entry.blockedToolPrefixes === undefined
|
|
279
|
+
? {}
|
|
280
|
+
: { blockedToolPrefixes: [...entry.blockedToolPrefixes] }),
|
|
276
281
|
login,
|
|
277
282
|
...(variable === undefined ? {} : { tokenVariable: variable }),
|
|
278
283
|
...(entry.loginNote === undefined ? {} : { loginNote: entry.loginNote[locale] }),
|
|
@@ -293,6 +298,16 @@ function printInfo(info) {
|
|
|
293
298
|
const where = info.transport.type === 'local' ? info.transport.command : info.transport.url;
|
|
294
299
|
console.log(`Transport: ${info.transport.type}, ${where}. ${info.transport.note}`);
|
|
295
300
|
console.log(`Reaches: ${info.reaches}`);
|
|
301
|
+
if (info.blockedTools.length > 0) {
|
|
302
|
+
const prefixes = info.blockedToolPrefixes ?? [];
|
|
303
|
+
const claudeOnly =
|
|
304
|
+
prefixes.length === 0
|
|
305
|
+
? ''
|
|
306
|
+
: ` In Claude Code, also any tool whose name starts with ${prefixes.join(', ')}.`;
|
|
307
|
+
console.log(
|
|
308
|
+
`Blocked by AISAC, because they spend money: ${info.blockedTools.join(', ')}.${claudeOnly} They stay blocked even if you allow every tool or skip permission prompts.`,
|
|
309
|
+
);
|
|
310
|
+
}
|
|
296
311
|
if (info.loginNote !== undefined) console.log(`Login: ${info.loginNote}`);
|
|
297
312
|
console.log(`Log in from Claude Code: ${info.login.claude}`);
|
|
298
313
|
console.log(`Log in from Codex: ${info.login.codex}`);
|
package/dist/launch.mjs
CHANGED
|
@@ -19,7 +19,13 @@ import {
|
|
|
19
19
|
writeLaunchMarker,
|
|
20
20
|
} from './engineering-pack.mjs';
|
|
21
21
|
import { prepareGuardrails } from './guardrails-plugin.mjs';
|
|
22
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
CODEX_MCP_ENV,
|
|
24
|
+
claudeDenyRules,
|
|
25
|
+
claudeMcpEntries,
|
|
26
|
+
mcpLaunchLines,
|
|
27
|
+
sessionServers,
|
|
28
|
+
} from './mcp-servers.mjs';
|
|
23
29
|
import { enabledServerIds, readPreferences } from './extensions-preferences.mjs';
|
|
24
30
|
import {
|
|
25
31
|
CODEX_ENGINEERING_ENV,
|
|
@@ -561,6 +567,14 @@ export async function launchClaude(config, root, args, dependencies = {}) {
|
|
|
561
567
|
for (const rule of [...userAllow, ...requiredAllow]) {
|
|
562
568
|
if (!mergedAllow.includes(rule)) mergedAllow.push(rule);
|
|
563
569
|
}
|
|
570
|
+
// Catalog tools that spend money stay denied whatever the user allows or the
|
|
571
|
+
// permission mode is (spec aisac-engineering-extensions FR7.2).
|
|
572
|
+
const userDeny = Array.isArray(userPermissions.deny) ? userPermissions.deny : [];
|
|
573
|
+
/** @type {unknown[]} */
|
|
574
|
+
const mergedDeny = [];
|
|
575
|
+
for (const rule of [...userDeny, ...claudeDenyRules()]) {
|
|
576
|
+
if (!mergedDeny.includes(rule)) mergedDeny.push(rule);
|
|
577
|
+
}
|
|
564
578
|
const settings = {
|
|
565
579
|
...(launchArgs.settings?.sandbox === undefined ? {} : { sandbox: launchArgs.settings.sandbox }),
|
|
566
580
|
pluginConfigs: {
|
|
@@ -570,6 +584,7 @@ export async function launchClaude(config, root, args, dependencies = {}) {
|
|
|
570
584
|
permissions: {
|
|
571
585
|
...userPermissions,
|
|
572
586
|
allow: mergedAllow,
|
|
587
|
+
deny: mergedDeny,
|
|
573
588
|
},
|
|
574
589
|
};
|
|
575
590
|
try {
|
package/dist/mcp-servers.mjs
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* third-party credential: logins live in the host's own store, and a token
|
|
9
9
|
* variable is only named, never read here.
|
|
10
10
|
*/
|
|
11
|
-
import { MCP_SERVER_PREFIX, mcpById } from './extensions-catalog.mjs';
|
|
11
|
+
import { MCP_CATALOG, MCP_SERVER_PREFIX, mcpById } from './extensions-catalog.mjs';
|
|
12
12
|
import { tomlBasicString } from './codex-engineering.mjs';
|
|
13
13
|
|
|
14
14
|
/** @typedef {import('./extensions-catalog.mjs').McpEntry} McpEntry */
|
|
@@ -80,7 +80,27 @@ export function claudeMcpEntries(entries) {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
/**
|
|
83
|
-
*
|
|
83
|
+
* Claude Code deny rules for the tools that spend money (FR7.2). They cover every
|
|
84
|
+
* catalog server, loaded or not, so the settings file can be written before the
|
|
85
|
+
* license is confirmed; a rule for a server that is not loaded matches nothing.
|
|
86
|
+
* Claude evaluates deny rules before allow rules, in every permission mode, and a
|
|
87
|
+
* deny rule removes the tool from the model's context (measured M1, Claude 2.1.318).
|
|
88
|
+
* @param {readonly McpEntry[]} [entries]
|
|
89
|
+
* @returns {string[]}
|
|
90
|
+
*/
|
|
91
|
+
export function claudeDenyRules(entries = MCP_CATALOG) {
|
|
92
|
+
return entries.flatMap((entry) => {
|
|
93
|
+
const prefix = `mcp__${serverName(entry.id)}__`;
|
|
94
|
+
return [
|
|
95
|
+
...(entry.blockedTools ?? []).map((tool) => `${prefix}${tool}`),
|
|
96
|
+
...(entry.blockedToolPrefixes ?? []).map((start) => `${prefix}${start}*`),
|
|
97
|
+
];
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Session-only `-c` overrides for the owned Codex app-server. A server with
|
|
103
|
+
* blocked tools gets `disabled_tools` (FR7.2; measured M2, Codex 0.164.0).
|
|
84
104
|
* @param {readonly McpEntry[]} entries
|
|
85
105
|
* @returns {string[]}
|
|
86
106
|
*/
|
|
@@ -88,6 +108,11 @@ export function codexMcpConfigArgs(entries) {
|
|
|
88
108
|
return entries.flatMap((entry) => {
|
|
89
109
|
const key = `mcp_servers.${serverName(entry.id)}`;
|
|
90
110
|
const { transport } = entry;
|
|
111
|
+
const blocked = entry.blockedTools ?? [];
|
|
112
|
+
const disabled =
|
|
113
|
+
blocked.length === 0
|
|
114
|
+
? []
|
|
115
|
+
: ['-c', `${key}.disabled_tools=[${blocked.map(tomlBasicString).join(',')}]`];
|
|
91
116
|
if (transport.type === 'stdio')
|
|
92
117
|
return [
|
|
93
118
|
'-c',
|
|
@@ -96,6 +121,7 @@ export function codexMcpConfigArgs(entries) {
|
|
|
96
121
|
`${key}.args=[${transport.args.map(tomlBasicString).join(',')}]`,
|
|
97
122
|
'-c',
|
|
98
123
|
`${key}.startup_timeout_sec=${STDIO_STARTUP_TIMEOUT_SEC}`,
|
|
124
|
+
...disabled,
|
|
99
125
|
];
|
|
100
126
|
return [
|
|
101
127
|
'-c',
|
|
@@ -103,6 +129,7 @@ export function codexMcpConfigArgs(entries) {
|
|
|
103
129
|
...(transport.bearerEnv === undefined
|
|
104
130
|
? []
|
|
105
131
|
: ['-c', `${key}.bearer_token_env_var=${tomlBasicString(transport.bearerEnv)}`]),
|
|
132
|
+
...disabled,
|
|
106
133
|
];
|
|
107
134
|
});
|
|
108
135
|
}
|
package/dist/package.json
CHANGED
package/dist/platform.mjs
CHANGED
|
@@ -86,7 +86,7 @@ export function isTestedNativeVersion(client, version) {
|
|
|
86
86
|
return /^(?:(?:claude(?:\s+code)?)\s+)?2\.1\.(?:294|295|296|299|300|301|302|303)(?:\s+\(Claude\s+Code\))?$/iu.test(
|
|
87
87
|
value,
|
|
88
88
|
);
|
|
89
|
-
return /^(?:codex(?:-cli)?\s+)?0\.16(?:1\.0|2\.0|2\.1|3\.0|4\.0)$/iu.test(value);
|
|
89
|
+
return /^(?:codex(?:-cli)?\s+)?0\.16(?:1\.0|2\.0|2\.1|3\.0|4\.0|6\.0)$/iu.test(value);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
const TESTED_NATIVE_VERSIONS = Object.freeze({
|
|
@@ -100,7 +100,7 @@ const TESTED_NATIVE_VERSIONS = Object.freeze({
|
|
|
100
100
|
'2.1.302',
|
|
101
101
|
'2.1.303',
|
|
102
102
|
]),
|
|
103
|
-
codex: Object.freeze(['0.161.0', '0.162.0', '0.162.1', '0.163.0', '0.164.0']),
|
|
103
|
+
codex: Object.freeze(['0.161.0', '0.162.0', '0.162.1', '0.163.0', '0.164.0', '0.166.0']),
|
|
104
104
|
});
|
|
105
105
|
|
|
106
106
|
/** @param {'claude'|'codex'} client @param {string} version */
|
package/package.json
CHANGED