@cubis/foundry 0.3.23 → 0.3.24
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 +2 -0
- package/bin/cubis.js +106 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -59,6 +59,7 @@ cbx workflows install --platform antigravity --dry-run
|
|
|
59
59
|
cbx workflows install --platform antigravity --terminal-integration --terminal-verifier codex
|
|
60
60
|
cbx workflows install --platform codex --postman
|
|
61
61
|
cbx workflows install --platform codex --postman --postman-workspace-id null
|
|
62
|
+
cbx workflows install --platform codex --postman --postman-workspace-id "<workspace-id>"
|
|
62
63
|
cbx workflows install --platform codex --postman --postman-api-key "<key>"
|
|
63
64
|
cbx workflows install --platform codex --postman --mcp-scope global
|
|
64
65
|
cbx workflows install --platform copilot --postman --mcp-scope project
|
|
@@ -83,6 +84,7 @@ Postman + Antigravity Stitch setup behavior:
|
|
|
83
84
|
- Env-first auth is supported: when `POSTMAN_API_KEY` is set, generated settings keep `apiKey: null` and MCP config uses `Bearer ${POSTMAN_API_KEY}`.
|
|
84
85
|
- Inline auth is supported with `--postman-api-key <key>`.
|
|
85
86
|
- `--postman-workspace-id null` writes JSON `null` for `defaultWorkspaceId`.
|
|
87
|
+
- If `POSTMAN_API_KEY` is available and install is interactive (no `--yes`) without `--postman-workspace-id`, `cbx` fetches your Postman workspaces and prompts you to pick one as default.
|
|
86
88
|
- Antigravity gets an additional managed file at `.cbx/mcp/antigravity/stitch.json` (or `~/.cbx/mcp/antigravity/stitch.json` in global MCP scope).
|
|
87
89
|
- Stitch key source priority for Antigravity: `--stitch-api-key` then `STITCH_API_KEY`; when unset, generated config keeps placeholder `X-Goog-Api-Key: ur stitch key`.
|
|
88
90
|
- In project MCP scope, `cbx_config.json` and `.cbx/mcp/` are auto-added to `.gitignore` (no duplicate entries).
|
package/bin/cubis.js
CHANGED
|
@@ -127,11 +127,13 @@ const TERMINAL_VERIFIER_PROVIDERS = ["codex", "gemini"];
|
|
|
127
127
|
const DEFAULT_TERMINAL_VERIFIER = "codex";
|
|
128
128
|
const POSTMAN_API_KEY_ENV_VAR = "POSTMAN_API_KEY";
|
|
129
129
|
const POSTMAN_MCP_URL = "https://mcp.postman.com/minimal";
|
|
130
|
+
const POSTMAN_API_BASE_URL = "https://api.getpostman.com";
|
|
130
131
|
const POSTMAN_SKILL_ID = "postman";
|
|
131
132
|
const STITCH_MCP_SERVER_ID = "StitchMCP";
|
|
132
133
|
const STITCH_API_KEY_ENV_VAR = "STITCH_API_KEY";
|
|
133
134
|
const STITCH_MCP_URL = "https://stitch.googleapis.com/mcp";
|
|
134
135
|
const STITCH_API_KEY_PLACEHOLDER = "ur stitch key";
|
|
136
|
+
const POSTMAN_WORKSPACE_MANUAL_CHOICE = "__postman_workspace_manual__";
|
|
135
137
|
const CBX_CONFIG_FILENAME = "cbx_config.json";
|
|
136
138
|
const POSTMAN_SETTINGS_FILENAME = "postman_setting.json";
|
|
137
139
|
const POSTMAN_API_KEY_MISSING_WARNING =
|
|
@@ -2428,6 +2430,57 @@ function parseStoredPostmanConfig(raw) {
|
|
|
2428
2430
|
};
|
|
2429
2431
|
}
|
|
2430
2432
|
|
|
2433
|
+
async function fetchPostmanWorkspaces({
|
|
2434
|
+
apiKey,
|
|
2435
|
+
apiBaseUrl = POSTMAN_API_BASE_URL,
|
|
2436
|
+
timeoutMs = 12000
|
|
2437
|
+
}) {
|
|
2438
|
+
if (!apiKey) return [];
|
|
2439
|
+
|
|
2440
|
+
const controller = new AbortController();
|
|
2441
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
2442
|
+
const endpoint = `${apiBaseUrl.replace(/\/$/, "")}/workspaces`;
|
|
2443
|
+
|
|
2444
|
+
try {
|
|
2445
|
+
const response = await fetch(endpoint, {
|
|
2446
|
+
method: "GET",
|
|
2447
|
+
headers: {
|
|
2448
|
+
"X-Api-Key": apiKey,
|
|
2449
|
+
Accept: "application/json"
|
|
2450
|
+
},
|
|
2451
|
+
signal: controller.signal
|
|
2452
|
+
});
|
|
2453
|
+
|
|
2454
|
+
const payload = await response.json().catch(() => null);
|
|
2455
|
+
if (!response.ok) {
|
|
2456
|
+
const message =
|
|
2457
|
+
payload?.error?.message ||
|
|
2458
|
+
payload?.error?.name ||
|
|
2459
|
+
`Postman API request failed (${response.status} ${response.statusText}).`;
|
|
2460
|
+
throw new Error(message);
|
|
2461
|
+
}
|
|
2462
|
+
|
|
2463
|
+
const workspaces = Array.isArray(payload?.workspaces) ? payload.workspaces : [];
|
|
2464
|
+
return workspaces
|
|
2465
|
+
.map((workspace) => {
|
|
2466
|
+
const id = normalizePostmanWorkspaceId(workspace?.id);
|
|
2467
|
+
if (!id) return null;
|
|
2468
|
+
const name = String(workspace?.name || "").trim() || id;
|
|
2469
|
+
const type = String(workspace?.type || "").trim() || null;
|
|
2470
|
+
const visibility = String(workspace?.visibility || "").trim() || null;
|
|
2471
|
+
return { id, name, type, visibility };
|
|
2472
|
+
})
|
|
2473
|
+
.filter(Boolean);
|
|
2474
|
+
} catch (error) {
|
|
2475
|
+
if (error?.name === "AbortError") {
|
|
2476
|
+
throw new Error("Postman workspace lookup timed out.");
|
|
2477
|
+
}
|
|
2478
|
+
throw error;
|
|
2479
|
+
} finally {
|
|
2480
|
+
clearTimeout(timeout);
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
|
|
2431
2484
|
function parseStoredStitchConfig(raw) {
|
|
2432
2485
|
if (!raw || typeof raw !== "object") return null;
|
|
2433
2486
|
const source = raw.stitch && typeof raw.stitch === "object" ? raw.stitch : null;
|
|
@@ -2762,11 +2815,59 @@ async function resolvePostmanInstallSelection({
|
|
|
2762
2815
|
}
|
|
2763
2816
|
|
|
2764
2817
|
if (canPrompt && !hasWorkspaceOption) {
|
|
2765
|
-
const
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2818
|
+
const selectableApiKey = normalizePostmanApiKey(apiKey || envApiKey);
|
|
2819
|
+
let usedWorkspaceSelector = false;
|
|
2820
|
+
let selectedWorkspaceId = defaultWorkspaceId;
|
|
2821
|
+
|
|
2822
|
+
if (selectableApiKey) {
|
|
2823
|
+
try {
|
|
2824
|
+
const fetchedWorkspaces = await fetchPostmanWorkspaces({
|
|
2825
|
+
apiKey: selectableApiKey
|
|
2826
|
+
});
|
|
2827
|
+
if (fetchedWorkspaces.length > 0) {
|
|
2828
|
+
usedWorkspaceSelector = true;
|
|
2829
|
+
const sortedWorkspaces = [...fetchedWorkspaces].sort((a, b) => a.name.localeCompare(b.name));
|
|
2830
|
+
const workspaceChoice = await select({
|
|
2831
|
+
message: "Choose default Postman workspace for this install:",
|
|
2832
|
+
choices: [
|
|
2833
|
+
{ name: "No default workspace (null)", value: null },
|
|
2834
|
+
...sortedWorkspaces.map((workspace) => {
|
|
2835
|
+
const details = [workspace.type, workspace.visibility].filter(Boolean).join(", ");
|
|
2836
|
+
const suffix = details ? ` - ${details}` : "";
|
|
2837
|
+
return {
|
|
2838
|
+
name: `${workspace.name} (${workspace.id})${suffix}`,
|
|
2839
|
+
value: workspace.id
|
|
2840
|
+
};
|
|
2841
|
+
}),
|
|
2842
|
+
{ name: "Enter workspace ID manually", value: POSTMAN_WORKSPACE_MANUAL_CHOICE }
|
|
2843
|
+
],
|
|
2844
|
+
default: null
|
|
2845
|
+
});
|
|
2846
|
+
|
|
2847
|
+
if (workspaceChoice === POSTMAN_WORKSPACE_MANUAL_CHOICE) {
|
|
2848
|
+
const promptedWorkspaceId = await input({
|
|
2849
|
+
message: "Default Postman workspace ID (optional, leave blank for null):",
|
|
2850
|
+
default: ""
|
|
2851
|
+
});
|
|
2852
|
+
selectedWorkspaceId = normalizePostmanWorkspaceId(promptedWorkspaceId);
|
|
2853
|
+
} else {
|
|
2854
|
+
selectedWorkspaceId = normalizePostmanWorkspaceId(workspaceChoice);
|
|
2855
|
+
}
|
|
2856
|
+
}
|
|
2857
|
+
} catch (error) {
|
|
2858
|
+
warnings.push(`Could not load Postman workspaces for selection: ${error.message}`);
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2861
|
+
|
|
2862
|
+
if (!usedWorkspaceSelector) {
|
|
2863
|
+
const promptedWorkspaceId = await input({
|
|
2864
|
+
message: "Default Postman workspace ID (optional, leave blank for null):",
|
|
2865
|
+
default: ""
|
|
2866
|
+
});
|
|
2867
|
+
selectedWorkspaceId = normalizePostmanWorkspaceId(promptedWorkspaceId);
|
|
2868
|
+
}
|
|
2869
|
+
|
|
2870
|
+
defaultWorkspaceId = selectedWorkspaceId;
|
|
2770
2871
|
}
|
|
2771
2872
|
|
|
2772
2873
|
if (canPrompt && stitchEnabled && !hasStitchApiKeyOption && !stitchApiKey && !envStitchApiKey) {
|