@cubis/foundry 0.3.24 → 0.3.25

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 CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  All notable changes to this project are documented in this file.
4
4
 
5
+ ## [0.3.25] - 2026-02-26
6
+
7
+ ### Added
8
+
9
+ - Added `cbx workflows config` command to view and edit `cbx_config.json` from terminal.
10
+ - Added `cbx skills config` alias for compatibility with deprecated `skills` command group.
11
+ - Added docs for showing/updating/clearing Postman `defaultWorkspaceId` after install.
12
+
13
+ ### Changed
14
+
15
+ - Improved Postman install warnings when workspace selection is not persisted because existing `cbx_config.json` was skipped.
16
+ - Included actionable follow-up command in warnings (`cbx workflows config ...`).
17
+
5
18
  ## [0.3.23] - 2026-02-26
6
19
 
7
20
  ### Added
package/README.md CHANGED
@@ -89,6 +89,51 @@ Postman + Antigravity Stitch setup behavior:
89
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`.
90
90
  - In project MCP scope, `cbx_config.json` and `.cbx/mcp/` are auto-added to `.gitignore` (no duplicate entries).
91
91
 
92
+ Codex Postman workspace selection:
93
+
94
+ ```bash
95
+ # Set Postman API key first
96
+ export POSTMAN_API_KEY="<your-postman-api-key>"
97
+
98
+ # Interactive workspace selector (recommended)
99
+ cbx workflows install --platform codex --bundle agent-environment-setup --postman
100
+ ```
101
+
102
+ - Do not use `--yes` here (it skips prompts).
103
+ - You will get a workspace selector and the selected value is saved as `defaultWorkspaceId`.
104
+
105
+ Direct/manual workspace ID:
106
+
107
+ ```bash
108
+ cbx workflows install --platform codex --bundle agent-environment-setup --postman --postman-workspace-id "<workspace-id>" --yes
109
+ ```
110
+
111
+ Clear default workspace:
112
+
113
+ ```bash
114
+ cbx workflows install --platform codex --bundle agent-environment-setup --postman --postman-workspace-id null --yes
115
+ ```
116
+
117
+ Important:
118
+ - If `cbx_config.json` already exists and you want to change the saved workspace, use `--overwrite` (or edit config manually), because existing config is preserved by default.
119
+ - If install output shows `Config file: skipped (...)`, your newly selected workspace is not persisted. Use `--overwrite` or edit with the config command below.
120
+
121
+ View/edit config in terminal:
122
+
123
+ ```bash
124
+ # View config
125
+ cbx workflows config --scope global --show
126
+
127
+ # Interactive edit (workspace ID)
128
+ cbx workflows config --scope global --edit
129
+
130
+ # Direct set workspace ID
131
+ cbx workflows config --scope global --workspace-id "<workspace-id>"
132
+
133
+ # Clear workspace ID
134
+ cbx workflows config --scope global --clear-workspace-id
135
+ ```
136
+
92
137
  Platform runtime MCP placement:
93
138
  - Codex:
94
139
  - Global MCP scope: `~/.codex/config.toml` via `codex mcp add`.
package/bin/cubis.js CHANGED
@@ -2792,6 +2792,7 @@ async function resolvePostmanInstallSelection({
2792
2792
  let defaultWorkspaceId = hasWorkspaceOption
2793
2793
  ? normalizePostmanWorkspaceId(options.postmanWorkspaceId)
2794
2794
  : null;
2795
+ let workspaceSelectionSource = hasWorkspaceOption ? "option" : "none";
2795
2796
  const requestedMcpScope = options.mcpScope
2796
2797
  ? normalizeMcpScope(options.mcpScope, normalizeMcpScope(scope, "project"))
2797
2798
  : null;
@@ -2868,6 +2869,7 @@ async function resolvePostmanInstallSelection({
2868
2869
  }
2869
2870
 
2870
2871
  defaultWorkspaceId = selectedWorkspaceId;
2872
+ workspaceSelectionSource = "interactive";
2871
2873
  }
2872
2874
 
2873
2875
  if (canPrompt && stitchEnabled && !hasStitchApiKeyOption && !stitchApiKey && !envStitchApiKey) {
@@ -2945,6 +2947,7 @@ async function resolvePostmanInstallSelection({
2945
2947
  stitchApiKey,
2946
2948
  stitchApiKeySource,
2947
2949
  defaultWorkspaceId: defaultWorkspaceId ?? null,
2950
+ workspaceSelectionSource,
2948
2951
  mcpScope,
2949
2952
  warnings,
2950
2953
  cbxConfig,
@@ -3013,6 +3016,21 @@ async function configurePostmanInstallArtifacts({
3013
3016
  effectiveStitchApiKey = storedStitchConfig.apiKey;
3014
3017
  effectiveStitchMcpUrl = storedStitchConfig.mcpUrl || STITCH_MCP_URL;
3015
3018
  }
3019
+
3020
+ if (postmanSelection.workspaceSelectionSource && postmanSelection.workspaceSelectionSource !== "none") {
3021
+ const requestedWorkspaceId = postmanSelection.defaultWorkspaceId ?? null;
3022
+ const persistedWorkspaceId = effectiveDefaultWorkspaceId ?? null;
3023
+ if (requestedWorkspaceId !== persistedWorkspaceId) {
3024
+ const configScope = postmanSelection.mcpScope === "global" ? "global" : "project";
3025
+ const configHint =
3026
+ requestedWorkspaceId === null
3027
+ ? `cbx workflows config --scope ${configScope} --clear-workspace-id`
3028
+ : `cbx workflows config --scope ${configScope} --workspace-id \"${requestedWorkspaceId}\"`;
3029
+ warnings.push(
3030
+ `Selected Postman workspace (${requestedWorkspaceId === null ? "null" : requestedWorkspaceId}) was not saved because ${CBX_CONFIG_FILENAME} already exists. Re-run with --overwrite or run '${configHint}'.`
3031
+ );
3032
+ }
3033
+ }
3016
3034
  }
3017
3035
 
3018
3036
  const envApiKey = normalizePostmanApiKey(process.env[POSTMAN_API_KEY_ENV_VAR]);
@@ -4519,6 +4537,105 @@ async function runWorkflowDoctor(platformArg, options) {
4519
4537
  }
4520
4538
  }
4521
4539
 
4540
+ async function runWorkflowConfig(options) {
4541
+ try {
4542
+ const cwd = process.cwd();
4543
+ const scope = normalizeMcpScope(options.scope, "global");
4544
+ const dryRun = Boolean(options.dryRun);
4545
+ const hasWorkspaceIdOption = options.workspaceId !== undefined;
4546
+ const wantsClearWorkspaceId = Boolean(options.clearWorkspaceId);
4547
+ const wantsInteractiveEdit = Boolean(options.edit);
4548
+
4549
+ if (hasWorkspaceIdOption && wantsClearWorkspaceId) {
4550
+ throw new Error("Use either --workspace-id or --clear-workspace-id, not both.");
4551
+ }
4552
+
4553
+ const wantsMutation = hasWorkspaceIdOption || wantsClearWorkspaceId || wantsInteractiveEdit;
4554
+ const showOnly = Boolean(options.show) || !wantsMutation;
4555
+ const configPath = resolveCbxConfigPath({ scope, cwd });
4556
+ const existing = await readJsonFileIfExists(configPath);
4557
+ const existingValue =
4558
+ existing.value && typeof existing.value === "object" && !Array.isArray(existing.value) ? existing.value : null;
4559
+
4560
+ if (showOnly) {
4561
+ console.log(`Config file: ${configPath}`);
4562
+ if (!existing.exists) {
4563
+ console.log("Status: missing");
4564
+ return;
4565
+ }
4566
+ if (!existingValue) {
4567
+ throw new Error(`Existing config at ${configPath} is not valid JSON object.`);
4568
+ }
4569
+ console.log(`Status: ${existing.exists ? "exists" : "missing"}`);
4570
+ console.log(JSON.stringify(existingValue, null, 2));
4571
+ return;
4572
+ }
4573
+
4574
+ if (existing.exists && !existingValue) {
4575
+ throw new Error(`Existing config at ${configPath} is not valid JSON object.`);
4576
+ }
4577
+
4578
+ const next = existingValue ? JSON.parse(JSON.stringify(existingValue)) : {};
4579
+ if (!next.schemaVersion || typeof next.schemaVersion !== "number") next.schemaVersion = 1;
4580
+ next.generatedBy = "cbx workflows config";
4581
+ next.generatedAt = new Date().toISOString();
4582
+
4583
+ if (!next.mcp || typeof next.mcp !== "object" || Array.isArray(next.mcp)) next.mcp = {};
4584
+ next.mcp.scope = scope;
4585
+ if (!next.mcp.server) next.mcp.server = POSTMAN_SKILL_ID;
4586
+
4587
+ if (!next.postman || typeof next.postman !== "object" || Array.isArray(next.postman)) next.postman = {};
4588
+ next.postman.apiKey = normalizePostmanApiKey(next.postman.apiKey);
4589
+ next.postman.apiKeyEnvVar = String(next.postman.apiKeyEnvVar || POSTMAN_API_KEY_ENV_VAR).trim() || POSTMAN_API_KEY_ENV_VAR;
4590
+ next.postman.mcpUrl = String(next.postman.mcpUrl || POSTMAN_MCP_URL).trim() || POSTMAN_MCP_URL;
4591
+
4592
+ let workspaceId = normalizePostmanWorkspaceId(next.postman.defaultWorkspaceId);
4593
+
4594
+ if (wantsInteractiveEdit) {
4595
+ const promptedWorkspaceId = await input({
4596
+ message: "Postman default workspace ID (optional, leave blank or 'null' to clear):",
4597
+ default: workspaceId || ""
4598
+ });
4599
+ workspaceId = normalizePostmanWorkspaceId(promptedWorkspaceId);
4600
+ }
4601
+
4602
+ if (hasWorkspaceIdOption) {
4603
+ workspaceId = normalizePostmanWorkspaceId(options.workspaceId);
4604
+ }
4605
+
4606
+ if (wantsClearWorkspaceId) {
4607
+ workspaceId = null;
4608
+ }
4609
+
4610
+ next.postman.defaultWorkspaceId = workspaceId;
4611
+ const envApiKey = normalizePostmanApiKey(process.env[POSTMAN_API_KEY_ENV_VAR]);
4612
+ next.postman.apiKeySource = getPostmanApiKeySource({
4613
+ apiKey: next.postman.apiKey,
4614
+ envApiKey
4615
+ });
4616
+
4617
+ const content = `${JSON.stringify(next, null, 2)}\n`;
4618
+ if (!dryRun) {
4619
+ await mkdir(path.dirname(configPath), { recursive: true });
4620
+ await writeFile(configPath, content, "utf8");
4621
+ }
4622
+
4623
+ console.log(`Config file: ${configPath}`);
4624
+ console.log(`Action: ${dryRun ? (existing.exists ? "would-update" : "would-create") : existing.exists ? "updated" : "created"}`);
4625
+ console.log(`postman.defaultWorkspaceId: ${workspaceId === null ? "null" : workspaceId}`);
4626
+ if (Boolean(options.showAfter)) {
4627
+ console.log(JSON.stringify(next, null, 2));
4628
+ }
4629
+ } catch (error) {
4630
+ if (error?.name === "ExitPromptError") {
4631
+ console.error("\nCancelled.");
4632
+ process.exit(130);
4633
+ }
4634
+ console.error(`\nError: ${error.message}`);
4635
+ process.exit(1);
4636
+ }
4637
+ }
4638
+
4522
4639
  function printRulesInitSummary({
4523
4640
  platform,
4524
4641
  scope,
@@ -4750,6 +4867,18 @@ withWorkflowBaseOptions(
4750
4867
  .option("--json", "output JSON")
4751
4868
  ).action(runWorkflowDoctor);
4752
4869
 
4870
+ workflowsCommand
4871
+ .command("config")
4872
+ .description("View or edit cbx_config.json from terminal")
4873
+ .option("--scope <scope>", "config scope: project|workspace|global|user", "global")
4874
+ .option("--show", "show current config (default when no edit flags)")
4875
+ .option("--edit", "edit Postman default workspace ID interactively")
4876
+ .option("--workspace-id <id|null>", "set postman.defaultWorkspaceId")
4877
+ .option("--clear-workspace-id", "set postman.defaultWorkspaceId to null")
4878
+ .option("--show-after", "print JSON after update")
4879
+ .option("--dry-run", "preview changes without writing files")
4880
+ .action(runWorkflowConfig);
4881
+
4753
4882
  workflowsCommand.action(() => {
4754
4883
  workflowsCommand.help();
4755
4884
  });
@@ -4809,6 +4938,21 @@ withWorkflowBaseOptions(
4809
4938
  await runWorkflowDoctor(platform, options);
4810
4939
  });
4811
4940
 
4941
+ skillsCommand
4942
+ .command("config")
4943
+ .description("Alias for workflows config")
4944
+ .option("--scope <scope>", "config scope: project|workspace|global|user", "global")
4945
+ .option("--show", "show current config (default when no edit flags)")
4946
+ .option("--edit", "edit Postman default workspace ID interactively")
4947
+ .option("--workspace-id <id|null>", "set postman.defaultWorkspaceId")
4948
+ .option("--clear-workspace-id", "set postman.defaultWorkspaceId to null")
4949
+ .option("--show-after", "print JSON after update")
4950
+ .option("--dry-run", "preview changes without writing files")
4951
+ .action(async (options) => {
4952
+ printSkillsDeprecation();
4953
+ await runWorkflowConfig(options);
4954
+ });
4955
+
4812
4956
  skillsCommand.action(() => {
4813
4957
  printSkillsDeprecation();
4814
4958
  skillsCommand.help();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cubis/foundry",
3
- "version": "0.3.24",
3
+ "version": "0.3.25",
4
4
  "description": "Cubis Foundry CLI for workflow-first AI agent environments",
5
5
  "type": "module",
6
6
  "bin": {