@cubis/foundry 0.3.59 → 0.3.60
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 +9 -0
- package/dist/cli/core.js +86 -0
- package/dist/cli/core.js.map +1 -1
- package/package.json +4 -2
- package/src/cli/core.ts +110 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cubis/foundry",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.60",
|
|
4
4
|
"description": "Cubis Foundry CLI for workflow-first AI agent environments",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -82,8 +82,10 @@
|
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
84
|
"@inquirer/prompts": "^7.8.6",
|
|
85
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
85
86
|
"commander": "^14.0.1",
|
|
86
|
-
"jsonc-parser": "^3.3.1"
|
|
87
|
+
"jsonc-parser": "^3.3.1",
|
|
88
|
+
"zod": "^3.25.76"
|
|
87
89
|
},
|
|
88
90
|
"devDependencies": {
|
|
89
91
|
"@types/node": "^20.14.0",
|
package/src/cli/core.ts
CHANGED
|
@@ -1203,6 +1203,99 @@ function parseTomlSections(content) {
|
|
|
1203
1203
|
return sections;
|
|
1204
1204
|
}
|
|
1205
1205
|
|
|
1206
|
+
function escapeTomlBasicString(value) {
|
|
1207
|
+
return String(value ?? "")
|
|
1208
|
+
.replace(/\\/g, "\\\\")
|
|
1209
|
+
.replace(/"/g, '\\"');
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
async function patchCodexPostmanHttpHeaders({
|
|
1213
|
+
configPath,
|
|
1214
|
+
mcpUrl,
|
|
1215
|
+
bearerToken,
|
|
1216
|
+
dryRun = false,
|
|
1217
|
+
}) {
|
|
1218
|
+
const warnings = [];
|
|
1219
|
+
const normalizedToken = normalizePostmanApiKey(bearerToken);
|
|
1220
|
+
if (!normalizedToken) {
|
|
1221
|
+
return {
|
|
1222
|
+
action: "skipped",
|
|
1223
|
+
warnings: [
|
|
1224
|
+
"Postman API key is unavailable in current environment. Kept bearer_token_env_var wiring in Codex config.",
|
|
1225
|
+
],
|
|
1226
|
+
};
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
const configExists = await pathExists(configPath);
|
|
1230
|
+
const original = configExists ? await readFile(configPath, "utf8") : "";
|
|
1231
|
+
const lines = original.split(/\r?\n/);
|
|
1232
|
+
const nextLines = [];
|
|
1233
|
+
|
|
1234
|
+
const headerLine =
|
|
1235
|
+
`http_headers = { Authorization = "Bearer ${escapeTomlBasicString(normalizedToken)}" }`;
|
|
1236
|
+
const serverHeader = "[mcp_servers.postman]";
|
|
1237
|
+
let inPostmanSection = false;
|
|
1238
|
+
let postmanSectionFound = false;
|
|
1239
|
+
let insertedHeaders = false;
|
|
1240
|
+
|
|
1241
|
+
const flushPostmanHeaderIfNeeded = () => {
|
|
1242
|
+
if (inPostmanSection && !insertedHeaders) {
|
|
1243
|
+
nextLines.push(headerLine);
|
|
1244
|
+
insertedHeaders = true;
|
|
1245
|
+
}
|
|
1246
|
+
};
|
|
1247
|
+
|
|
1248
|
+
for (const line of lines) {
|
|
1249
|
+
const sectionMatch = line.match(/^\s*\[([^\]]+)\]\s*$/);
|
|
1250
|
+
if (sectionMatch) {
|
|
1251
|
+
flushPostmanHeaderIfNeeded();
|
|
1252
|
+
const sectionName = sectionMatch[1].trim();
|
|
1253
|
+
inPostmanSection = sectionName === "mcp_servers.postman";
|
|
1254
|
+
if (inPostmanSection) {
|
|
1255
|
+
postmanSectionFound = true;
|
|
1256
|
+
insertedHeaders = false;
|
|
1257
|
+
}
|
|
1258
|
+
nextLines.push(line);
|
|
1259
|
+
continue;
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
if (inPostmanSection) {
|
|
1263
|
+
if (
|
|
1264
|
+
/^\s*(bearer_token_env_var|http_headers|env_http_headers)\s*=/.test(
|
|
1265
|
+
line,
|
|
1266
|
+
)
|
|
1267
|
+
) {
|
|
1268
|
+
continue;
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
nextLines.push(line);
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
flushPostmanHeaderIfNeeded();
|
|
1275
|
+
|
|
1276
|
+
if (!postmanSectionFound) {
|
|
1277
|
+
if (nextLines.length > 0 && nextLines[nextLines.length - 1].trim() !== "") {
|
|
1278
|
+
nextLines.push("");
|
|
1279
|
+
}
|
|
1280
|
+
nextLines.push(serverHeader);
|
|
1281
|
+
nextLines.push(`url = "${escapeTomlBasicString(mcpUrl || POSTMAN_MCP_URL)}"`);
|
|
1282
|
+
nextLines.push(headerLine);
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
const next = `${nextLines.join("\n").replace(/\n+$/g, "")}\n`;
|
|
1286
|
+
if (next === original) {
|
|
1287
|
+
return { action: "unchanged", warnings };
|
|
1288
|
+
}
|
|
1289
|
+
if (!dryRun) {
|
|
1290
|
+
await mkdir(path.dirname(configPath), { recursive: true });
|
|
1291
|
+
await writeFile(configPath, next, "utf8");
|
|
1292
|
+
}
|
|
1293
|
+
return {
|
|
1294
|
+
action: dryRun ? "would-patch" : "patched",
|
|
1295
|
+
warnings,
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1206
1299
|
function parsePubspecDependencyNames(content) {
|
|
1207
1300
|
const packages = new Set();
|
|
1208
1301
|
let currentSection = null;
|
|
@@ -5034,6 +5127,23 @@ async function applyPostmanMcpForPlatform({
|
|
|
5034
5127
|
],
|
|
5035
5128
|
{ cwd },
|
|
5036
5129
|
);
|
|
5130
|
+
const postmanToken = normalizePostmanApiKey(
|
|
5131
|
+
process.env[apiKeyEnvVar || POSTMAN_API_KEY_ENV_VAR],
|
|
5132
|
+
);
|
|
5133
|
+
const postmanPatch = await patchCodexPostmanHttpHeaders({
|
|
5134
|
+
configPath: codexConfigPath,
|
|
5135
|
+
mcpUrl,
|
|
5136
|
+
bearerToken: postmanToken,
|
|
5137
|
+
dryRun: false,
|
|
5138
|
+
});
|
|
5139
|
+
if (postmanPatch.action === "patched") {
|
|
5140
|
+
warnings.push(
|
|
5141
|
+
"Codex Postman MCP config patched to static Authorization header for startup reliability.",
|
|
5142
|
+
);
|
|
5143
|
+
}
|
|
5144
|
+
if (postmanPatch.warnings?.length) {
|
|
5145
|
+
warnings.push(...postmanPatch.warnings);
|
|
5146
|
+
}
|
|
5037
5147
|
} catch (error) {
|
|
5038
5148
|
warnings.push(
|
|
5039
5149
|
`Failed to register Postman MCP via Codex CLI. Ensure 'codex' is installed and rerun. (${error.message})`,
|