@cubis/foundry 0.3.24 → 0.3.26

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,26 @@
2
2
 
3
3
  All notable changes to this project are documented in this file.
4
4
 
5
+ ## [0.3.26] - 2026-02-26
6
+
7
+ ### Fixed
8
+
9
+ - Fixed MCP install merge behavior for existing JSONC config files (comments/trailing commas), so existing MCP entries are preserved instead of being reset.
10
+ - Fixed Postman MCP patching to parse and merge JSONC for platform config targets (for example `.vscode/mcp.json`).
11
+
12
+ ## [0.3.25] - 2026-02-26
13
+
14
+ ### Added
15
+
16
+ - Added `cbx workflows config` command to view and edit `cbx_config.json` from terminal.
17
+ - Added `cbx skills config` alias for compatibility with deprecated `skills` command group.
18
+ - Added docs for showing/updating/clearing Postman `defaultWorkspaceId` after install.
19
+
20
+ ### Changed
21
+
22
+ - Improved Postman install warnings when workspace selection is not persisted because existing `cbx_config.json` was skipped.
23
+ - Included actionable follow-up command in warnings (`cbx workflows config ...`).
24
+
5
25
  ## [0.3.23] - 2026-02-26
6
26
 
7
27
  ### Added
package/README.md CHANGED
@@ -5,6 +5,7 @@ Workflow-first installer for AI agent environments, with Codex callable-skill wr
5
5
  Repository layout note: reusable workflow/skill/power assets are stored under `Ai Agent Workflow/`.
6
6
 
7
7
  Primary support in this release:
8
+
8
9
  - Antigravity
9
10
  - Codex
10
11
  - Copilot (VS Code Chat + Copilot CLI)
@@ -22,6 +23,7 @@ cbx --help
22
23
  ```
23
24
 
24
25
  Compatibility binaries are still shipped for migration:
26
+
25
27
  - `cubiskill`
26
28
  - `cubis`
27
29
 
@@ -36,11 +38,11 @@ export POSTMAN_API_KEY="<your-postman-api-key>"
36
38
  export STITCH_API_KEY="<your-stitch-api-key>" # Antigravity StitchMCP only
37
39
 
38
40
  # 3) Install workflow bundle for your platform
39
- cbx workflows install --platform codex --bundle agent-environment-setup --postman --yes
41
+ cbx workflows install --platform codex --bundle agent-environment-setup --postman
40
42
 
41
43
  # 4) Optional: install for other platforms too
42
- cbx workflows install --platform antigravity --bundle agent-environment-setup --postman --yes
43
- cbx workflows install --platform copilot --bundle agent-environment-setup --postman --yes
44
+ cbx workflows install --platform antigravity --bundle agent-environment-setup --postman
45
+ cbx workflows install --platform copilot --bundle agent-environment-setup --postman
44
46
  ```
45
47
 
46
48
  ## Command Model
@@ -69,6 +71,7 @@ cbx workflows install --platform copilot --postman
69
71
  ```
70
72
 
71
73
  Install bootstrap behavior:
74
+
72
75
  - `cbx workflows install` now also bootstraps `ENGINEERING_RULES.md` and `TECH.md` (creates when missing; keeps existing files unless explicitly regenerated).
73
76
  - When install scope is `global` (default), skills/powers install to global paths, while workflows + agents stay in workspace (`project`) paths.
74
77
  - Rule sync + engineering artifacts (`AGENTS.md`/`GEMINI.md`/Copilot instructions, `ENGINEERING_RULES.md`, `TECH.md`) are maintained in workspace (`project`) scope.
@@ -79,6 +82,7 @@ Install bootstrap behavior:
79
82
  - Use `cbx rules init --platform <platform> --overwrite` to force-regenerate both files.
80
83
 
81
84
  Postman + Antigravity Stitch setup behavior:
85
+
82
86
  - `cbx_config.json` is generated in workspace root (project MCP scope) or `~/.cbx/cbx_config.json` (global MCP scope).
83
87
  - Managed MCP definition files are generated under `.cbx/mcp/<platform>/postman.json` (workspace scope) or `~/.cbx/mcp/<platform>/postman.json` (global scope).
84
88
  - Env-first auth is supported: when `POSTMAN_API_KEY` is set, generated settings keep `apiKey: null` and MCP config uses `Bearer ${POSTMAN_API_KEY}`.
@@ -89,7 +93,54 @@ Postman + Antigravity Stitch setup behavior:
89
93
  - 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
94
  - In project MCP scope, `cbx_config.json` and `.cbx/mcp/` are auto-added to `.gitignore` (no duplicate entries).
91
95
 
96
+ Codex Postman workspace selection:
97
+
98
+ ```bash
99
+ # Set Postman API key first
100
+ export POSTMAN_API_KEY="<your-postman-api-key>"
101
+
102
+ # Interactive workspace selector (recommended)
103
+ cbx workflows install --platform codex --bundle agent-environment-setup --postman
104
+ ```
105
+
106
+ - Do not use `--yes` here (it skips prompts).
107
+ - You will get a workspace selector and the selected value is saved as `defaultWorkspaceId`.
108
+
109
+ Direct/manual workspace ID:
110
+
111
+ ```bash
112
+ cbx workflows install --platform codex --bundle agent-environment-setup --postman --postman-workspace-id "<workspace-id>" --yes
113
+ ```
114
+
115
+ Clear default workspace:
116
+
117
+ ```bash
118
+ cbx workflows install --platform codex --bundle agent-environment-setup --postman --postman-workspace-id null --yes
119
+ ```
120
+
121
+ Important:
122
+
123
+ - 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.
124
+ - If install output shows `Config file: skipped (...)`, your newly selected workspace is not persisted. Use `--overwrite` or edit with the config command below.
125
+
126
+ View/edit config in terminal:
127
+
128
+ ```bash
129
+ # View config
130
+ cbx workflows config --scope global --show
131
+
132
+ # Interactive edit (workspace ID)
133
+ cbx workflows config --scope global --edit
134
+
135
+ # Direct set workspace ID
136
+ cbx workflows config --scope global --workspace-id "<workspace-id>"
137
+
138
+ # Clear workspace ID
139
+ cbx workflows config --scope global --clear-workspace-id
140
+ ```
141
+
92
142
  Platform runtime MCP placement:
143
+
93
144
  - Codex:
94
145
  - Global MCP scope: `~/.codex/config.toml` via `codex mcp add`.
95
146
  - Workspace MCP scope: `.vscode/mcp.json`.
@@ -101,6 +152,7 @@ Platform runtime MCP placement:
101
152
  - Global MCP scope: `~/.copilot/mcp-config.json`.
102
153
 
103
154
  API key docs:
155
+
104
156
  - Google Stitch MCP setup docs: [stitch.withgoogle.com/docs/mcp/setup](https://stitch.withgoogle.com/docs/mcp/setup)
105
157
  - Google Stitch settings (create API key): [stitch.withgoogle.com/settings](https://stitch.withgoogle.com/settings)
106
158
  - Google Cloud API key guidance: [Authenticate to Google and Google Cloud MCP servers](https://docs.cloud.google.com/mcp/authenticate-mcp)
@@ -119,12 +171,14 @@ cbx rules init --platform codex --dry-run
119
171
  ```
120
172
 
121
173
  What `cbx rules init` does:
174
+
122
175
  - Creates `ENGINEERING_RULES.md` next to the active platform rule file.
123
176
  - Appends/patches one managed engineering block in that rule file.
124
177
  - Generates `TECH.md` at workspace root by scanning the current codebase.
125
178
  - Preserves user content outside managed markers.
126
179
 
127
180
  `TECH.md` scanner coverage (deterministic, no AI calls):
181
+
128
182
  - Language/file signals from workspace scan.
129
183
  - JS/TS package signals from `package.json` (including nested/monorepo package files).
130
184
  - Flutter/Dart package signals from `pubspec.yaml`.
@@ -145,6 +199,7 @@ Ai Agent Workflow/workflows/
145
199
  ```
146
200
 
147
201
  First bundled profile:
202
+
148
203
  - `agent-environment-setup`
149
204
 
150
205
  Bundle manifest:
@@ -154,6 +209,7 @@ Ai Agent Workflow/workflows/agent-environment-setup/manifest.json
154
209
  ```
155
210
 
156
211
  Bundle contains platform-specific:
212
+
157
213
  - workflow templates (`workflows/*.md`)
158
214
  - specialist agent templates (`agents/*.md`)
159
215
  - mapped reusable skills copied from `Ai Agent Workflow/skills/<id>/`
@@ -163,13 +219,14 @@ Bundle contains platform-specific:
163
219
  ## Installed Capability Set (v1)
164
220
 
165
221
  Database capability stack:
222
+
166
223
  - `database-skills` (engine hub)
167
224
  - `database-design` (schema/migration design)
168
225
  - `database-optimizer` (query/index/tuning triage)
169
226
  - `drift-flutter` (Flutter local persistence)
170
227
 
171
-
172
228
  Core workflows:
229
+
173
230
  - `/brainstorm`
174
231
  - `/plan`
175
232
  - `/create`
@@ -184,6 +241,7 @@ Core workflows:
184
241
  - `/qa`
185
242
 
186
243
  Routing behavior:
244
+
187
245
  - Antigravity/Copilot: workflow + agent markdown can be routed by platform conventions.
188
246
  - Codex: use generated callable wrapper skills (`$workflow-*`, `$agent-*`).
189
247
  - Example for backend intent in Codex: `$workflow-backend` or `$agent-backend-specialist`.
@@ -195,6 +253,7 @@ Codex does not currently execute custom workflow slash commands or custom `@agen
195
253
  Codex skill invocation syntax is `$skill-name` (not `@agent-name`).
196
254
 
197
255
  `cbx` handles this by generating callable Codex skills:
256
+
198
257
  - Workflow wrappers: `$workflow-<name>` (for example `$workflow-review`, `$workflow-plan`)
199
258
  - Agent wrappers: `$agent-<name>` (for example `$agent-backend-specialist`)
200
259
 
@@ -206,6 +265,7 @@ Do not rely on custom `/workflow` execution or custom `@agent` invocation in Cod
206
265
  ### Antigravity
207
266
 
208
267
  Project scope:
268
+
209
269
  - Workflows: `.agent/workflows`
210
270
  - Agents: `.agent/agents`
211
271
  - Skills: `.agent/skills`
@@ -213,6 +273,7 @@ Project scope:
213
273
  - Terminal integration (optional): `.agent/terminal-integration`
214
274
 
215
275
  Global scope:
276
+
216
277
  - Skills: `~/.gemini/antigravity/skills`
217
278
  - Rules: `~/.gemini/GEMINI.md`
218
279
  - Workflows/agents/terminal-integration: default install keeps these in workspace (`.agent/...`) paths.
@@ -220,10 +281,12 @@ Global scope:
220
281
  ### Antigravity Terminal Integration (Optional)
221
282
 
222
283
  Install-time options:
284
+
223
285
  - `--terminal-integration`
224
286
  - `--terminal-verifier <codex|gemini>`
225
287
 
226
288
  Behavior:
289
+
227
290
  - Interactive installs prompt whether to enable terminal verification integration.
228
291
  - If enabled, cbx writes managed scripts/config under `.agent/terminal-integration`.
229
292
  - cbx also writes a managed terminal verification block into Antigravity rule files so post-task verification commands are explicit.
@@ -232,6 +295,7 @@ Behavior:
232
295
  ### Codex
233
296
 
234
297
  Project scope:
298
+
235
299
  - Workflow templates (reference docs): `.agents/workflows`
236
300
  - Skills: `.agents/skills`
237
301
  - Rules: `AGENTS.md`
@@ -242,17 +306,20 @@ Project scope:
242
306
  - Example usage: `$workflow-plan`, `$agent-backend-specialist`
243
307
 
244
308
  Global scope:
309
+
245
310
  - Skills: `~/.agents/skills`
246
311
  - Rules: `~/.codex/AGENTS.md`
247
312
  - Workflow templates (reference docs): default install keeps these in workspace `.agents/workflows`
248
313
  - Agents: not installed for Codex runtime
249
314
 
250
315
  Legacy compatibility note:
316
+
251
317
  - `.codex/skills` is treated as legacy and flagged by `doctor` with migration guidance.
252
318
 
253
319
  ### Copilot
254
320
 
255
321
  Project scope:
322
+
256
323
  - Workflows: `.github/copilot/workflows`
257
324
  - Agents: `.github/agents`
258
325
  - Skills: `.github/skills`
@@ -260,6 +327,7 @@ Project scope:
260
327
  - Skill schema note: `cbx` normalizes Copilot skill frontmatter by removing unsupported top-level keys like `displayName` and `keywords` during install.
261
328
 
262
329
  Global scope:
330
+
263
331
  - Skills: `~/.copilot/skills`
264
332
  - Rules: `~/.copilot/copilot-instructions.md`
265
333
  - Workflows/agents: default install keeps these in workspace (`.github/...`) paths.
@@ -272,11 +340,14 @@ Markers:
272
340
 
273
341
  ```md
274
342
  <!-- cbx:workflows:auto:start platform=<platform-id> version=1 -->
343
+
275
344
  ...
345
+
276
346
  <!-- cbx:workflows:auto:end -->
277
347
  ```
278
348
 
279
349
  Behavior:
350
+
280
351
  - Preserves user content outside markers.
281
352
  - Replaces first valid managed block in place.
282
353
  - Appends a managed block if missing.
@@ -286,6 +357,7 @@ Behavior:
286
357
  ## Scope and Detection
287
358
 
288
359
  Default scope:
360
+
289
361
  - Install/init commands:
290
362
  - `cbx workflows install`
291
363
  - `cbx workflows init`
@@ -298,15 +370,18 @@ Default scope:
298
370
  - Other workflow/rules commands default to `project`.
299
371
 
300
372
  Optional:
373
+
301
374
  - `--scope global`
302
375
  - `--scope project`
303
376
 
304
377
  Platform auto-detection:
378
+
305
379
  - Uses repo markers for Antigravity/Codex/Copilot.
306
380
  - Prompts when ambiguous.
307
381
  - Remembers last selected platform in local state.
308
382
 
309
383
  State files:
384
+
310
385
  - Project: `.cbx/workflows-state.json`
311
386
  - Global: `~/.cbx/state.json`
312
387
 
@@ -322,6 +397,7 @@ cbx workflows sync-rules --platform codex --dry-run
322
397
  ```
323
398
 
324
399
  Dry-run behavior:
400
+
325
401
  - prints planned file changes
326
402
  - prints planned managed-block action (`would-create`/`would-patch`)
327
403
  - does not write files
@@ -361,6 +437,7 @@ cbx workflows remove agent-environment-setup --platform antigravity --yes
361
437
  ## Doctor Checks
362
438
 
363
439
  `cbx workflows doctor` validates:
440
+
364
441
  - workflow/agent/skill path existence
365
442
  - active rule file status
366
443
  - managed block health
package/bin/cubis.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { confirm, input, select } from "@inquirer/prompts";
4
4
  import { Command } from "commander";
5
+ import { parse as parseJsonc } from "jsonc-parser";
5
6
  import { existsSync } from "node:fs";
6
7
  import {
7
8
  cp,
@@ -2497,11 +2498,44 @@ function parseStoredStitchConfig(raw) {
2497
2498
  };
2498
2499
  }
2499
2500
 
2501
+ function parseJsonLenient(raw) {
2502
+ try {
2503
+ return {
2504
+ ok: true,
2505
+ value: JSON.parse(raw),
2506
+ mode: "json"
2507
+ };
2508
+ } catch (jsonError) {
2509
+ const errors = [];
2510
+ const value = parseJsonc(raw, errors, {
2511
+ allowTrailingComma: true,
2512
+ disallowComments: false,
2513
+ allowEmptyContent: false
2514
+ });
2515
+ if (errors.length === 0) {
2516
+ return {
2517
+ ok: true,
2518
+ value,
2519
+ mode: "jsonc"
2520
+ };
2521
+ }
2522
+ return {
2523
+ ok: false,
2524
+ value: null,
2525
+ error: jsonError
2526
+ };
2527
+ }
2528
+ }
2529
+
2500
2530
  async function readJsonFileIfExists(filePath) {
2501
2531
  if (!(await pathExists(filePath))) return { exists: false, value: null };
2502
2532
  try {
2503
2533
  const raw = await readFile(filePath, "utf8");
2504
- return { exists: true, value: JSON.parse(raw) };
2534
+ const parsed = parseJsonLenient(raw);
2535
+ if (!parsed.ok) {
2536
+ return { exists: true, value: null, error: parsed.error };
2537
+ }
2538
+ return { exists: true, value: parsed.value };
2505
2539
  } catch (error) {
2506
2540
  return { exists: true, value: null, error };
2507
2541
  }
@@ -2515,9 +2549,11 @@ async function upsertJsonObjectFile({ targetPath, updater, dryRun = false }) {
2515
2549
  if (exists) {
2516
2550
  try {
2517
2551
  const raw = await readFile(targetPath, "utf8");
2518
- const decoded = JSON.parse(raw);
2519
- if (decoded && typeof decoded === "object" && !Array.isArray(decoded)) {
2520
- parsed = decoded;
2552
+ const decoded = parseJsonLenient(raw);
2553
+ if (!decoded.ok) {
2554
+ warnings.push(`Existing JSON at ${targetPath} could not be parsed. Resetting structure.`);
2555
+ } else if (decoded.value && typeof decoded.value === "object" && !Array.isArray(decoded.value)) {
2556
+ parsed = decoded.value;
2521
2557
  } else {
2522
2558
  warnings.push(`Existing JSON at ${targetPath} was not an object. Resetting structure.`);
2523
2559
  }
@@ -2792,6 +2828,7 @@ async function resolvePostmanInstallSelection({
2792
2828
  let defaultWorkspaceId = hasWorkspaceOption
2793
2829
  ? normalizePostmanWorkspaceId(options.postmanWorkspaceId)
2794
2830
  : null;
2831
+ let workspaceSelectionSource = hasWorkspaceOption ? "option" : "none";
2795
2832
  const requestedMcpScope = options.mcpScope
2796
2833
  ? normalizeMcpScope(options.mcpScope, normalizeMcpScope(scope, "project"))
2797
2834
  : null;
@@ -2868,6 +2905,7 @@ async function resolvePostmanInstallSelection({
2868
2905
  }
2869
2906
 
2870
2907
  defaultWorkspaceId = selectedWorkspaceId;
2908
+ workspaceSelectionSource = "interactive";
2871
2909
  }
2872
2910
 
2873
2911
  if (canPrompt && stitchEnabled && !hasStitchApiKeyOption && !stitchApiKey && !envStitchApiKey) {
@@ -2945,6 +2983,7 @@ async function resolvePostmanInstallSelection({
2945
2983
  stitchApiKey,
2946
2984
  stitchApiKeySource,
2947
2985
  defaultWorkspaceId: defaultWorkspaceId ?? null,
2986
+ workspaceSelectionSource,
2948
2987
  mcpScope,
2949
2988
  warnings,
2950
2989
  cbxConfig,
@@ -3013,6 +3052,21 @@ async function configurePostmanInstallArtifacts({
3013
3052
  effectiveStitchApiKey = storedStitchConfig.apiKey;
3014
3053
  effectiveStitchMcpUrl = storedStitchConfig.mcpUrl || STITCH_MCP_URL;
3015
3054
  }
3055
+
3056
+ if (postmanSelection.workspaceSelectionSource && postmanSelection.workspaceSelectionSource !== "none") {
3057
+ const requestedWorkspaceId = postmanSelection.defaultWorkspaceId ?? null;
3058
+ const persistedWorkspaceId = effectiveDefaultWorkspaceId ?? null;
3059
+ if (requestedWorkspaceId !== persistedWorkspaceId) {
3060
+ const configScope = postmanSelection.mcpScope === "global" ? "global" : "project";
3061
+ const configHint =
3062
+ requestedWorkspaceId === null
3063
+ ? `cbx workflows config --scope ${configScope} --clear-workspace-id`
3064
+ : `cbx workflows config --scope ${configScope} --workspace-id \"${requestedWorkspaceId}\"`;
3065
+ warnings.push(
3066
+ `Selected Postman workspace (${requestedWorkspaceId === null ? "null" : requestedWorkspaceId}) was not saved because ${CBX_CONFIG_FILENAME} already exists. Re-run with --overwrite or run '${configHint}'.`
3067
+ );
3068
+ }
3069
+ }
3016
3070
  }
3017
3071
 
3018
3072
  const envApiKey = normalizePostmanApiKey(process.env[POSTMAN_API_KEY_ENV_VAR]);
@@ -4519,6 +4573,105 @@ async function runWorkflowDoctor(platformArg, options) {
4519
4573
  }
4520
4574
  }
4521
4575
 
4576
+ async function runWorkflowConfig(options) {
4577
+ try {
4578
+ const cwd = process.cwd();
4579
+ const scope = normalizeMcpScope(options.scope, "global");
4580
+ const dryRun = Boolean(options.dryRun);
4581
+ const hasWorkspaceIdOption = options.workspaceId !== undefined;
4582
+ const wantsClearWorkspaceId = Boolean(options.clearWorkspaceId);
4583
+ const wantsInteractiveEdit = Boolean(options.edit);
4584
+
4585
+ if (hasWorkspaceIdOption && wantsClearWorkspaceId) {
4586
+ throw new Error("Use either --workspace-id or --clear-workspace-id, not both.");
4587
+ }
4588
+
4589
+ const wantsMutation = hasWorkspaceIdOption || wantsClearWorkspaceId || wantsInteractiveEdit;
4590
+ const showOnly = Boolean(options.show) || !wantsMutation;
4591
+ const configPath = resolveCbxConfigPath({ scope, cwd });
4592
+ const existing = await readJsonFileIfExists(configPath);
4593
+ const existingValue =
4594
+ existing.value && typeof existing.value === "object" && !Array.isArray(existing.value) ? existing.value : null;
4595
+
4596
+ if (showOnly) {
4597
+ console.log(`Config file: ${configPath}`);
4598
+ if (!existing.exists) {
4599
+ console.log("Status: missing");
4600
+ return;
4601
+ }
4602
+ if (!existingValue) {
4603
+ throw new Error(`Existing config at ${configPath} is not valid JSON object.`);
4604
+ }
4605
+ console.log(`Status: ${existing.exists ? "exists" : "missing"}`);
4606
+ console.log(JSON.stringify(existingValue, null, 2));
4607
+ return;
4608
+ }
4609
+
4610
+ if (existing.exists && !existingValue) {
4611
+ throw new Error(`Existing config at ${configPath} is not valid JSON object.`);
4612
+ }
4613
+
4614
+ const next = existingValue ? JSON.parse(JSON.stringify(existingValue)) : {};
4615
+ if (!next.schemaVersion || typeof next.schemaVersion !== "number") next.schemaVersion = 1;
4616
+ next.generatedBy = "cbx workflows config";
4617
+ next.generatedAt = new Date().toISOString();
4618
+
4619
+ if (!next.mcp || typeof next.mcp !== "object" || Array.isArray(next.mcp)) next.mcp = {};
4620
+ next.mcp.scope = scope;
4621
+ if (!next.mcp.server) next.mcp.server = POSTMAN_SKILL_ID;
4622
+
4623
+ if (!next.postman || typeof next.postman !== "object" || Array.isArray(next.postman)) next.postman = {};
4624
+ next.postman.apiKey = normalizePostmanApiKey(next.postman.apiKey);
4625
+ next.postman.apiKeyEnvVar = String(next.postman.apiKeyEnvVar || POSTMAN_API_KEY_ENV_VAR).trim() || POSTMAN_API_KEY_ENV_VAR;
4626
+ next.postman.mcpUrl = String(next.postman.mcpUrl || POSTMAN_MCP_URL).trim() || POSTMAN_MCP_URL;
4627
+
4628
+ let workspaceId = normalizePostmanWorkspaceId(next.postman.defaultWorkspaceId);
4629
+
4630
+ if (wantsInteractiveEdit) {
4631
+ const promptedWorkspaceId = await input({
4632
+ message: "Postman default workspace ID (optional, leave blank or 'null' to clear):",
4633
+ default: workspaceId || ""
4634
+ });
4635
+ workspaceId = normalizePostmanWorkspaceId(promptedWorkspaceId);
4636
+ }
4637
+
4638
+ if (hasWorkspaceIdOption) {
4639
+ workspaceId = normalizePostmanWorkspaceId(options.workspaceId);
4640
+ }
4641
+
4642
+ if (wantsClearWorkspaceId) {
4643
+ workspaceId = null;
4644
+ }
4645
+
4646
+ next.postman.defaultWorkspaceId = workspaceId;
4647
+ const envApiKey = normalizePostmanApiKey(process.env[POSTMAN_API_KEY_ENV_VAR]);
4648
+ next.postman.apiKeySource = getPostmanApiKeySource({
4649
+ apiKey: next.postman.apiKey,
4650
+ envApiKey
4651
+ });
4652
+
4653
+ const content = `${JSON.stringify(next, null, 2)}\n`;
4654
+ if (!dryRun) {
4655
+ await mkdir(path.dirname(configPath), { recursive: true });
4656
+ await writeFile(configPath, content, "utf8");
4657
+ }
4658
+
4659
+ console.log(`Config file: ${configPath}`);
4660
+ console.log(`Action: ${dryRun ? (existing.exists ? "would-update" : "would-create") : existing.exists ? "updated" : "created"}`);
4661
+ console.log(`postman.defaultWorkspaceId: ${workspaceId === null ? "null" : workspaceId}`);
4662
+ if (Boolean(options.showAfter)) {
4663
+ console.log(JSON.stringify(next, null, 2));
4664
+ }
4665
+ } catch (error) {
4666
+ if (error?.name === "ExitPromptError") {
4667
+ console.error("\nCancelled.");
4668
+ process.exit(130);
4669
+ }
4670
+ console.error(`\nError: ${error.message}`);
4671
+ process.exit(1);
4672
+ }
4673
+ }
4674
+
4522
4675
  function printRulesInitSummary({
4523
4676
  platform,
4524
4677
  scope,
@@ -4750,6 +4903,18 @@ withWorkflowBaseOptions(
4750
4903
  .option("--json", "output JSON")
4751
4904
  ).action(runWorkflowDoctor);
4752
4905
 
4906
+ workflowsCommand
4907
+ .command("config")
4908
+ .description("View or edit cbx_config.json from terminal")
4909
+ .option("--scope <scope>", "config scope: project|workspace|global|user", "global")
4910
+ .option("--show", "show current config (default when no edit flags)")
4911
+ .option("--edit", "edit Postman default workspace ID interactively")
4912
+ .option("--workspace-id <id|null>", "set postman.defaultWorkspaceId")
4913
+ .option("--clear-workspace-id", "set postman.defaultWorkspaceId to null")
4914
+ .option("--show-after", "print JSON after update")
4915
+ .option("--dry-run", "preview changes without writing files")
4916
+ .action(runWorkflowConfig);
4917
+
4753
4918
  workflowsCommand.action(() => {
4754
4919
  workflowsCommand.help();
4755
4920
  });
@@ -4809,6 +4974,21 @@ withWorkflowBaseOptions(
4809
4974
  await runWorkflowDoctor(platform, options);
4810
4975
  });
4811
4976
 
4977
+ skillsCommand
4978
+ .command("config")
4979
+ .description("Alias for workflows config")
4980
+ .option("--scope <scope>", "config scope: project|workspace|global|user", "global")
4981
+ .option("--show", "show current config (default when no edit flags)")
4982
+ .option("--edit", "edit Postman default workspace ID interactively")
4983
+ .option("--workspace-id <id|null>", "set postman.defaultWorkspaceId")
4984
+ .option("--clear-workspace-id", "set postman.defaultWorkspaceId to null")
4985
+ .option("--show-after", "print JSON after update")
4986
+ .option("--dry-run", "preview changes without writing files")
4987
+ .action(async (options) => {
4988
+ printSkillsDeprecation();
4989
+ await runWorkflowConfig(options);
4990
+ });
4991
+
4812
4992
  skillsCommand.action(() => {
4813
4993
  printSkillsDeprecation();
4814
4994
  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.26",
4
4
  "description": "Cubis Foundry CLI for workflow-first AI agent environments",
5
5
  "type": "module",
6
6
  "bin": {
@@ -46,6 +46,7 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "@inquirer/prompts": "^7.8.6",
49
- "commander": "^14.0.1"
49
+ "commander": "^14.0.1",
50
+ "jsonc-parser": "^3.3.1"
50
51
  }
51
52
  }