@cubis/foundry 0.3.59 → 0.3.61
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 +21 -0
- package/dist/cli/core.js +123 -16
- package/dist/cli/core.js.map +1 -1
- package/package.json +4 -2
- package/src/cli/core.ts +161 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cubis/foundry",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.61",
|
|
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
|
@@ -173,7 +173,7 @@ const CODEX_WORKFLOW_SKILL_PREFIX = "workflow-";
|
|
|
173
173
|
const CODEX_AGENT_SKILL_PREFIX = "agent-";
|
|
174
174
|
const TERMINAL_VERIFIER_PROVIDERS = ["codex", "gemini"];
|
|
175
175
|
const DEFAULT_TERMINAL_VERIFIER = "codex";
|
|
176
|
-
const POSTMAN_API_KEY_ENV_VAR = "
|
|
176
|
+
const POSTMAN_API_KEY_ENV_VAR = "POSTMAN_API_KEY_DEFAULT";
|
|
177
177
|
const POSTMAN_MODE_TO_URL = Object.freeze({
|
|
178
178
|
minimal: "https://mcp.postman.com/minimal",
|
|
179
179
|
code: "https://mcp.postman.com/code",
|
|
@@ -190,7 +190,7 @@ const FOUNDRY_MCP_SERVER_ID = "cubis-foundry";
|
|
|
190
190
|
const FOUNDRY_MCP_COMMAND = "cbx";
|
|
191
191
|
const STITCH_SKILL_ID = "stitch";
|
|
192
192
|
const STITCH_MCP_SERVER_ID = "StitchMCP";
|
|
193
|
-
const STITCH_API_KEY_ENV_VAR = "
|
|
193
|
+
const STITCH_API_KEY_ENV_VAR = "STITCH_API_KEY_DEFAULT";
|
|
194
194
|
const STITCH_MCP_URL = "https://stitch.googleapis.com/mcp";
|
|
195
195
|
const POSTMAN_WORKSPACE_MANUAL_CHOICE = "__postman_workspace_manual__";
|
|
196
196
|
const CBX_CONFIG_FILENAME = "cbx_config.json";
|
|
@@ -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;
|
|
@@ -4208,16 +4301,31 @@ function resolveStitchMcpDefinitionPath({ scope, cwd = process.cwd() }) {
|
|
|
4208
4301
|
);
|
|
4209
4302
|
}
|
|
4210
4303
|
|
|
4211
|
-
function buildPostmanAuthHeader({
|
|
4304
|
+
function buildPostmanAuthHeader({
|
|
4305
|
+
apiKeyEnvVar = POSTMAN_API_KEY_ENV_VAR,
|
|
4306
|
+
apiKey = null,
|
|
4307
|
+
}) {
|
|
4308
|
+
const normalizedApiKey = normalizePostmanApiKey(apiKey);
|
|
4309
|
+
if (normalizedApiKey) {
|
|
4310
|
+
return `Bearer ${normalizedApiKey}`;
|
|
4311
|
+
}
|
|
4212
4312
|
return `Bearer \${${apiKeyEnvVar}}`;
|
|
4213
4313
|
}
|
|
4214
4314
|
|
|
4215
|
-
function buildStitchApiHeader({
|
|
4315
|
+
function buildStitchApiHeader({
|
|
4316
|
+
apiKeyEnvVar = STITCH_API_KEY_ENV_VAR,
|
|
4317
|
+
apiKey = null,
|
|
4318
|
+
}) {
|
|
4319
|
+
const normalizedApiKey = normalizePostmanApiKey(apiKey);
|
|
4320
|
+
if (normalizedApiKey) {
|
|
4321
|
+
return `X-Goog-Api-Key: ${normalizedApiKey}`;
|
|
4322
|
+
}
|
|
4216
4323
|
return `X-Goog-Api-Key: \${${apiKeyEnvVar}}`;
|
|
4217
4324
|
}
|
|
4218
4325
|
|
|
4219
4326
|
function buildPostmanMcpDefinition({
|
|
4220
4327
|
apiKeyEnvVar = POSTMAN_API_KEY_ENV_VAR,
|
|
4328
|
+
apiKey = null,
|
|
4221
4329
|
mcpUrl = POSTMAN_MCP_URL,
|
|
4222
4330
|
}) {
|
|
4223
4331
|
return {
|
|
@@ -4226,13 +4334,14 @@ function buildPostmanMcpDefinition({
|
|
|
4226
4334
|
transport: "http",
|
|
4227
4335
|
url: mcpUrl,
|
|
4228
4336
|
headers: {
|
|
4229
|
-
Authorization: buildPostmanAuthHeader({ apiKeyEnvVar }),
|
|
4337
|
+
Authorization: buildPostmanAuthHeader({ apiKeyEnvVar, apiKey }),
|
|
4230
4338
|
},
|
|
4231
4339
|
};
|
|
4232
4340
|
}
|
|
4233
4341
|
|
|
4234
4342
|
function buildStitchMcpDefinition({
|
|
4235
4343
|
apiKeyEnvVar = STITCH_API_KEY_ENV_VAR,
|
|
4344
|
+
apiKey = null,
|
|
4236
4345
|
mcpUrl = STITCH_MCP_URL,
|
|
4237
4346
|
}) {
|
|
4238
4347
|
return {
|
|
@@ -4245,7 +4354,7 @@ function buildStitchMcpDefinition({
|
|
|
4245
4354
|
"mcp-remote",
|
|
4246
4355
|
mcpUrl,
|
|
4247
4356
|
"--header",
|
|
4248
|
-
buildStitchApiHeader({ apiKeyEnvVar }),
|
|
4357
|
+
buildStitchApiHeader({ apiKeyEnvVar, apiKey }),
|
|
4249
4358
|
],
|
|
4250
4359
|
env: {},
|
|
4251
4360
|
};
|
|
@@ -4253,13 +4362,14 @@ function buildStitchMcpDefinition({
|
|
|
4253
4362
|
|
|
4254
4363
|
function buildVsCodePostmanServer({
|
|
4255
4364
|
apiKeyEnvVar = POSTMAN_API_KEY_ENV_VAR,
|
|
4365
|
+
apiKey = null,
|
|
4256
4366
|
mcpUrl = POSTMAN_MCP_URL,
|
|
4257
4367
|
}) {
|
|
4258
4368
|
return {
|
|
4259
4369
|
type: "sse",
|
|
4260
4370
|
url: mcpUrl,
|
|
4261
4371
|
headers: {
|
|
4262
|
-
Authorization: buildPostmanAuthHeader({ apiKeyEnvVar }),
|
|
4372
|
+
Authorization: buildPostmanAuthHeader({ apiKeyEnvVar, apiKey }),
|
|
4263
4373
|
},
|
|
4264
4374
|
};
|
|
4265
4375
|
}
|
|
@@ -4283,13 +4393,14 @@ function buildVsCodeFoundryServer({ scope = "auto" } = {}) {
|
|
|
4283
4393
|
|
|
4284
4394
|
function buildCopilotCliPostmanServer({
|
|
4285
4395
|
apiKeyEnvVar = POSTMAN_API_KEY_ENV_VAR,
|
|
4396
|
+
apiKey = null,
|
|
4286
4397
|
mcpUrl = POSTMAN_MCP_URL,
|
|
4287
4398
|
}) {
|
|
4288
4399
|
return {
|
|
4289
4400
|
type: "http",
|
|
4290
4401
|
url: mcpUrl,
|
|
4291
4402
|
headers: {
|
|
4292
|
-
Authorization: buildPostmanAuthHeader({ apiKeyEnvVar }),
|
|
4403
|
+
Authorization: buildPostmanAuthHeader({ apiKeyEnvVar, apiKey }),
|
|
4293
4404
|
},
|
|
4294
4405
|
tools: ["*"],
|
|
4295
4406
|
};
|
|
@@ -4307,12 +4418,13 @@ function buildCopilotCliFoundryServer({ scope = "auto" } = {}) {
|
|
|
4307
4418
|
|
|
4308
4419
|
function buildGeminiPostmanServer({
|
|
4309
4420
|
apiKeyEnvVar = POSTMAN_API_KEY_ENV_VAR,
|
|
4421
|
+
apiKey = null,
|
|
4310
4422
|
mcpUrl = POSTMAN_MCP_URL,
|
|
4311
4423
|
}) {
|
|
4312
4424
|
return {
|
|
4313
4425
|
httpUrl: mcpUrl,
|
|
4314
4426
|
headers: {
|
|
4315
|
-
Authorization: buildPostmanAuthHeader({ apiKeyEnvVar }),
|
|
4427
|
+
Authorization: buildPostmanAuthHeader({ apiKeyEnvVar, apiKey }),
|
|
4316
4428
|
},
|
|
4317
4429
|
};
|
|
4318
4430
|
}
|
|
@@ -4327,6 +4439,7 @@ function buildGeminiFoundryServer({ scope = "auto" } = {}) {
|
|
|
4327
4439
|
|
|
4328
4440
|
function buildGeminiStitchServer({
|
|
4329
4441
|
apiKeyEnvVar = STITCH_API_KEY_ENV_VAR,
|
|
4442
|
+
apiKey = null,
|
|
4330
4443
|
mcpUrl = STITCH_MCP_URL,
|
|
4331
4444
|
}) {
|
|
4332
4445
|
return {
|
|
@@ -4336,7 +4449,7 @@ function buildGeminiStitchServer({
|
|
|
4336
4449
|
"mcp-remote",
|
|
4337
4450
|
mcpUrl,
|
|
4338
4451
|
"--header",
|
|
4339
|
-
buildStitchApiHeader({ apiKeyEnvVar }),
|
|
4452
|
+
buildStitchApiHeader({ apiKeyEnvVar, apiKey }),
|
|
4340
4453
|
],
|
|
4341
4454
|
env: {},
|
|
4342
4455
|
};
|
|
@@ -4840,6 +4953,12 @@ async function applyPostmanMcpForPlatform({
|
|
|
4840
4953
|
const workspaceRoot = findWorkspaceRoot(cwd);
|
|
4841
4954
|
const warnings = [];
|
|
4842
4955
|
const foundryScope = mcpScope === "global" ? "global" : "project";
|
|
4956
|
+
const resolvedPostmanApiKey = normalizePostmanApiKey(
|
|
4957
|
+
process.env[apiKeyEnvVar || POSTMAN_API_KEY_ENV_VAR],
|
|
4958
|
+
);
|
|
4959
|
+
const resolvedStitchApiKey = normalizePostmanApiKey(
|
|
4960
|
+
process.env[stitchApiKeyEnvVar || STITCH_API_KEY_ENV_VAR],
|
|
4961
|
+
);
|
|
4843
4962
|
|
|
4844
4963
|
if (platform === "antigravity") {
|
|
4845
4964
|
const settingsPath =
|
|
@@ -4859,6 +4978,7 @@ async function applyPostmanMcpForPlatform({
|
|
|
4859
4978
|
if (includePostmanMcp) {
|
|
4860
4979
|
mcpServers[POSTMAN_SKILL_ID] = buildGeminiPostmanServer({
|
|
4861
4980
|
apiKeyEnvVar,
|
|
4981
|
+
apiKey: resolvedPostmanApiKey,
|
|
4862
4982
|
mcpUrl,
|
|
4863
4983
|
});
|
|
4864
4984
|
}
|
|
@@ -4872,6 +4992,7 @@ async function applyPostmanMcpForPlatform({
|
|
|
4872
4992
|
if (includeStitchMcp) {
|
|
4873
4993
|
mcpServers[STITCH_MCP_SERVER_ID] = buildGeminiStitchServer({
|
|
4874
4994
|
apiKeyEnvVar: stitchApiKeyEnvVar,
|
|
4995
|
+
apiKey: resolvedStitchApiKey,
|
|
4875
4996
|
mcpUrl: stitchMcpUrl,
|
|
4876
4997
|
});
|
|
4877
4998
|
}
|
|
@@ -4908,6 +5029,7 @@ async function applyPostmanMcpForPlatform({
|
|
|
4908
5029
|
if (includePostmanMcp) {
|
|
4909
5030
|
mcpServers[POSTMAN_SKILL_ID] = buildCopilotCliPostmanServer({
|
|
4910
5031
|
apiKeyEnvVar,
|
|
5032
|
+
apiKey: resolvedPostmanApiKey,
|
|
4911
5033
|
mcpUrl,
|
|
4912
5034
|
});
|
|
4913
5035
|
}
|
|
@@ -4931,6 +5053,7 @@ async function applyPostmanMcpForPlatform({
|
|
|
4931
5053
|
if (includePostmanMcp) {
|
|
4932
5054
|
servers[POSTMAN_SKILL_ID] = buildVsCodePostmanServer({
|
|
4933
5055
|
apiKeyEnvVar,
|
|
5056
|
+
apiKey: resolvedPostmanApiKey,
|
|
4934
5057
|
mcpUrl,
|
|
4935
5058
|
});
|
|
4936
5059
|
}
|
|
@@ -4971,6 +5094,7 @@ async function applyPostmanMcpForPlatform({
|
|
|
4971
5094
|
if (includePostmanMcp) {
|
|
4972
5095
|
servers[POSTMAN_SKILL_ID] = buildVsCodePostmanServer({
|
|
4973
5096
|
apiKeyEnvVar,
|
|
5097
|
+
apiKey: resolvedPostmanApiKey,
|
|
4974
5098
|
mcpUrl,
|
|
4975
5099
|
});
|
|
4976
5100
|
}
|
|
@@ -5034,6 +5158,23 @@ async function applyPostmanMcpForPlatform({
|
|
|
5034
5158
|
],
|
|
5035
5159
|
{ cwd },
|
|
5036
5160
|
);
|
|
5161
|
+
const postmanToken = normalizePostmanApiKey(
|
|
5162
|
+
process.env[apiKeyEnvVar || POSTMAN_API_KEY_ENV_VAR],
|
|
5163
|
+
);
|
|
5164
|
+
const postmanPatch = await patchCodexPostmanHttpHeaders({
|
|
5165
|
+
configPath: codexConfigPath,
|
|
5166
|
+
mcpUrl,
|
|
5167
|
+
bearerToken: postmanToken,
|
|
5168
|
+
dryRun: false,
|
|
5169
|
+
});
|
|
5170
|
+
if (postmanPatch.action === "patched") {
|
|
5171
|
+
warnings.push(
|
|
5172
|
+
"Codex Postman MCP config patched to static Authorization header for startup reliability.",
|
|
5173
|
+
);
|
|
5174
|
+
}
|
|
5175
|
+
if (postmanPatch.warnings?.length) {
|
|
5176
|
+
warnings.push(...postmanPatch.warnings);
|
|
5177
|
+
}
|
|
5037
5178
|
} catch (error) {
|
|
5038
5179
|
warnings.push(
|
|
5039
5180
|
`Failed to register Postman MCP via Codex CLI. Ensure 'codex' is installed and rerun. (${error.message})`,
|
|
@@ -5562,6 +5703,7 @@ async function configurePostmanInstallArtifacts({
|
|
|
5562
5703
|
const mcpDefinitionContent = `${JSON.stringify(
|
|
5563
5704
|
buildPostmanMcpDefinition({
|
|
5564
5705
|
apiKeyEnvVar: effectiveApiKeyEnvVar,
|
|
5706
|
+
apiKey: envApiKey,
|
|
5565
5707
|
mcpUrl: effectiveMcpUrl,
|
|
5566
5708
|
}),
|
|
5567
5709
|
null,
|
|
@@ -5583,6 +5725,7 @@ async function configurePostmanInstallArtifacts({
|
|
|
5583
5725
|
const stitchMcpDefinitionContent = `${JSON.stringify(
|
|
5584
5726
|
buildStitchMcpDefinition({
|
|
5585
5727
|
apiKeyEnvVar: effectiveStitchApiKeyEnvVar,
|
|
5728
|
+
apiKey: envStitchApiKey,
|
|
5586
5729
|
mcpUrl: effectiveStitchMcpUrl,
|
|
5587
5730
|
}),
|
|
5588
5731
|
null,
|
|
@@ -5721,6 +5864,12 @@ async function applyPostmanConfigArtifacts({
|
|
|
5721
5864
|
const stitchApiKeyEnvVar =
|
|
5722
5865
|
normalizePostmanApiKey(stitchState?.apiKeyEnvVar) || STITCH_API_KEY_ENV_VAR;
|
|
5723
5866
|
const stitchMcpUrl = stitchState?.mcpUrl || STITCH_MCP_URL;
|
|
5867
|
+
const resolvedPostmanApiKey = normalizePostmanApiKey(
|
|
5868
|
+
process.env[postmanApiKeyEnvVar],
|
|
5869
|
+
);
|
|
5870
|
+
const resolvedStitchApiKey = normalizePostmanApiKey(
|
|
5871
|
+
process.env[stitchApiKeyEnvVar],
|
|
5872
|
+
);
|
|
5724
5873
|
|
|
5725
5874
|
const mcpDefinitionPath = resolvePostmanMcpDefinitionPath({
|
|
5726
5875
|
platform,
|
|
@@ -5730,6 +5879,7 @@ async function applyPostmanConfigArtifacts({
|
|
|
5730
5879
|
const mcpDefinitionContent = `${JSON.stringify(
|
|
5731
5880
|
buildPostmanMcpDefinition({
|
|
5732
5881
|
apiKeyEnvVar: postmanApiKeyEnvVar,
|
|
5882
|
+
apiKey: resolvedPostmanApiKey,
|
|
5733
5883
|
mcpUrl: postmanMcpUrl,
|
|
5734
5884
|
}),
|
|
5735
5885
|
null,
|
|
@@ -5751,6 +5901,7 @@ async function applyPostmanConfigArtifacts({
|
|
|
5751
5901
|
const stitchMcpDefinitionContent = `${JSON.stringify(
|
|
5752
5902
|
buildStitchMcpDefinition({
|
|
5753
5903
|
apiKeyEnvVar: stitchApiKeyEnvVar,
|
|
5904
|
+
apiKey: resolvedStitchApiKey,
|
|
5754
5905
|
mcpUrl: stitchMcpUrl,
|
|
5755
5906
|
}),
|
|
5756
5907
|
null,
|