@cubis/foundry 0.3.54 → 0.3.56

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.
@@ -32,6 +32,9 @@ export function buildInitExecutionPlan({ selections, dryRun, target, }) {
32
32
  mcpFallback: "local",
33
33
  mcpBuildLocal: wantsPostman || stitchEnabled ? selections.mcpBuildLocal : false,
34
34
  postmanMode: wantsPostman ? selections.postmanMode : undefined,
35
+ postmanWorkspaceId: wantsPostman
36
+ ? selections.postmanWorkspaceId
37
+ : undefined,
35
38
  initWizardMode: true,
36
39
  };
37
40
  planItems.push({
@@ -45,6 +48,7 @@ export function buildInitExecutionPlan({ selections, dryRun, target, }) {
45
48
  };
46
49
  }
47
50
  export function formatInitSummary(selections) {
51
+ const postmanSelected = selections.selectedMcps.includes("postman");
48
52
  return [
49
53
  "Init plan summary:",
50
54
  `- Bundle: ${selections.bundleId}`,
@@ -54,7 +58,8 @@ export function formatInitSummary(selections) {
54
58
  `- MCP scope: ${selections.mcpScope}`,
55
59
  `- MCP runtime: ${selections.mcpRuntime}${selections.mcpRuntime === "docker" ? selections.mcpBuildLocal ? " (build local image)" : " (pull image)" : ""}`,
56
60
  `- MCP selections: ${selections.selectedMcps.length > 0 ? selections.selectedMcps.join(", ") : "(none)"}`,
57
- `- Postman mode: ${selections.postmanMode}`,
61
+ `- Postman mode: ${postmanSelected ? selections.postmanMode : "(not selected)"}`,
62
+ `- Postman workspace: ${postmanSelected ? selections.postmanWorkspaceId === null ? "null" : selections.postmanWorkspaceId : "(not selected)"}`,
58
63
  ].join("\n");
59
64
  }
60
65
  //# sourceMappingURL=execute.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../src/cli/init/execute.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../src/cli/init/execute.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cubis/foundry",
3
- "version": "0.3.54",
3
+ "version": "0.3.56",
4
4
  "description": "Cubis Foundry CLI for workflow-first AI agent environments",
5
5
  "type": "module",
6
6
  "bin": {
@@ -67,6 +67,10 @@ export function registerCommands(deps: CliRegistrationDeps) {
67
67
  "comma-separated MCP selections: cubis-foundry,postman,stitch",
68
68
  )
69
69
  .option("--postman-mode <mode>", "Postman mode: full|minimal")
70
+ .option(
71
+ "--postman-workspace-id <id|null>",
72
+ "optional: set default Postman workspace ID (use 'null' for no default)",
73
+ )
70
74
  .option("--mcp-runtime <runtime>", "MCP runtime: docker|local")
71
75
  .option(
72
76
  "--mcp-build-local",
package/src/cli/core.ts CHANGED
@@ -2622,6 +2622,44 @@ async function resolveProfilePaths(profileId, scope, cwd = process.cwd()) {
2622
2622
  };
2623
2623
  }
2624
2624
 
2625
+ function expandUniquePaths(pathList, cwd = process.cwd()) {
2626
+ const seen = new Set();
2627
+ const output = [];
2628
+ for (const value of pathList || []) {
2629
+ const normalized = String(value || "").trim();
2630
+ if (!normalized) continue;
2631
+ const expanded = expandPath(normalized, cwd);
2632
+ const key = path.resolve(expanded);
2633
+ if (seen.has(key)) continue;
2634
+ seen.add(key);
2635
+ output.push(expanded);
2636
+ }
2637
+ return output;
2638
+ }
2639
+
2640
+ function resolveProfilePathCandidates(profileId, scope, cwd = process.cwd()) {
2641
+ const profile = WORKFLOW_PROFILES[profileId];
2642
+ if (!profile) throw new Error(`Unknown platform '${profileId}'.`);
2643
+ const cfg = profile[scope];
2644
+ return {
2645
+ workflowsDirs: expandUniquePaths(cfg.workflowDirs, cwd),
2646
+ agentsDirs: expandUniquePaths(cfg.agentDirs, cwd),
2647
+ skillsDirs: expandUniquePaths(cfg.skillDirs, cwd),
2648
+ commandsDirs: expandUniquePaths(cfg.commandDirs, cwd),
2649
+ promptsDirs: expandUniquePaths(cfg.promptDirs, cwd),
2650
+ ruleFilesByPriority: expandUniquePaths(cfg.ruleFilesByPriority, cwd),
2651
+ };
2652
+ }
2653
+
2654
+ function resolveLegacySkillDirsForCleanup(platform, scope, cwd = process.cwd()) {
2655
+ if (platform !== "codex") return [];
2656
+ if (scope === "global") {
2657
+ return [path.join(os.homedir(), ".codex", "skills")];
2658
+ }
2659
+ const workspaceRoot = findWorkspaceRoot(cwd);
2660
+ return [path.join(workspaceRoot, ".codex", "skills")];
2661
+ }
2662
+
2625
2663
  async function resolveArtifactProfilePaths(
2626
2664
  profileId,
2627
2665
  scope,
@@ -4574,6 +4612,81 @@ async function fetchPostmanWorkspaces({
4574
4612
  }
4575
4613
  }
4576
4614
 
4615
+ async function promptPostmanWorkspaceSelection({
4616
+ apiKey,
4617
+ defaultWorkspaceId = null,
4618
+ }) {
4619
+ let selectedWorkspaceId = normalizePostmanWorkspaceId(defaultWorkspaceId);
4620
+ let usedWorkspaceSelector = false;
4621
+ const warnings = [];
4622
+ const selectableApiKey = normalizePostmanApiKey(apiKey);
4623
+
4624
+ if (selectableApiKey) {
4625
+ try {
4626
+ const fetchedWorkspaces = await fetchPostmanWorkspaces({
4627
+ apiKey: selectableApiKey,
4628
+ });
4629
+ if (fetchedWorkspaces.length > 0) {
4630
+ usedWorkspaceSelector = true;
4631
+ const sortedWorkspaces = [...fetchedWorkspaces].sort((a, b) =>
4632
+ a.name.localeCompare(b.name),
4633
+ );
4634
+ const workspaceChoice = await select({
4635
+ message: "Choose default Postman workspace for this install:",
4636
+ choices: [
4637
+ { name: "No default workspace (null)", value: null },
4638
+ ...sortedWorkspaces.map((workspace) => {
4639
+ const details = [workspace.type, workspace.visibility]
4640
+ .filter(Boolean)
4641
+ .join(", ");
4642
+ const suffix = details ? ` - ${details}` : "";
4643
+ return {
4644
+ name: `${workspace.name} (${workspace.id})${suffix}`,
4645
+ value: workspace.id,
4646
+ };
4647
+ }),
4648
+ {
4649
+ name: "Enter workspace ID manually",
4650
+ value: POSTMAN_WORKSPACE_MANUAL_CHOICE,
4651
+ },
4652
+ ],
4653
+ default: selectedWorkspaceId,
4654
+ });
4655
+
4656
+ if (workspaceChoice === POSTMAN_WORKSPACE_MANUAL_CHOICE) {
4657
+ const promptedWorkspaceId = await input({
4658
+ message:
4659
+ "Default Postman workspace ID (optional, leave blank for null):",
4660
+ default: selectedWorkspaceId || "",
4661
+ });
4662
+ selectedWorkspaceId =
4663
+ normalizePostmanWorkspaceId(promptedWorkspaceId);
4664
+ } else {
4665
+ selectedWorkspaceId = normalizePostmanWorkspaceId(workspaceChoice);
4666
+ }
4667
+ }
4668
+ } catch (error) {
4669
+ warnings.push(
4670
+ `Could not load Postman workspaces for selection: ${error.message}`,
4671
+ );
4672
+ }
4673
+ }
4674
+
4675
+ if (!usedWorkspaceSelector) {
4676
+ const promptedWorkspaceId = await input({
4677
+ message:
4678
+ "Default Postman workspace ID (optional, leave blank for null):",
4679
+ default: selectedWorkspaceId || "",
4680
+ });
4681
+ selectedWorkspaceId = normalizePostmanWorkspaceId(promptedWorkspaceId);
4682
+ }
4683
+
4684
+ return {
4685
+ workspaceId: selectedWorkspaceId,
4686
+ warnings,
4687
+ };
4688
+ }
4689
+
4577
4690
  function parseJsonLenient(raw) {
4578
4691
  try {
4579
4692
  return {
@@ -5043,71 +5156,12 @@ async function resolvePostmanInstallSelection({
5043
5156
 
5044
5157
  const canPrompt = !options.yes && process.stdin.isTTY;
5045
5158
  if (postmanRequested && canPrompt && !hasWorkspaceOption) {
5046
- const selectableApiKey = normalizePostmanApiKey(envApiKey);
5047
- let usedWorkspaceSelector = false;
5048
- let selectedWorkspaceId = defaultWorkspaceId;
5049
-
5050
- if (selectableApiKey) {
5051
- try {
5052
- const fetchedWorkspaces = await fetchPostmanWorkspaces({
5053
- apiKey: selectableApiKey,
5054
- });
5055
- if (fetchedWorkspaces.length > 0) {
5056
- usedWorkspaceSelector = true;
5057
- const sortedWorkspaces = [...fetchedWorkspaces].sort((a, b) =>
5058
- a.name.localeCompare(b.name),
5059
- );
5060
- const workspaceChoice = await select({
5061
- message: "Choose default Postman workspace for this install:",
5062
- choices: [
5063
- { name: "No default workspace (null)", value: null },
5064
- ...sortedWorkspaces.map((workspace) => {
5065
- const details = [workspace.type, workspace.visibility]
5066
- .filter(Boolean)
5067
- .join(", ");
5068
- const suffix = details ? ` - ${details}` : "";
5069
- return {
5070
- name: `${workspace.name} (${workspace.id})${suffix}`,
5071
- value: workspace.id,
5072
- };
5073
- }),
5074
- {
5075
- name: "Enter workspace ID manually",
5076
- value: POSTMAN_WORKSPACE_MANUAL_CHOICE,
5077
- },
5078
- ],
5079
- default: null,
5080
- });
5081
-
5082
- if (workspaceChoice === POSTMAN_WORKSPACE_MANUAL_CHOICE) {
5083
- const promptedWorkspaceId = await input({
5084
- message:
5085
- "Default Postman workspace ID (optional, leave blank for null):",
5086
- default: "",
5087
- });
5088
- selectedWorkspaceId =
5089
- normalizePostmanWorkspaceId(promptedWorkspaceId);
5090
- } else {
5091
- selectedWorkspaceId = normalizePostmanWorkspaceId(workspaceChoice);
5092
- }
5093
- }
5094
- } catch (error) {
5095
- warnings.push(
5096
- `Could not load Postman workspaces for selection: ${error.message}`,
5097
- );
5098
- }
5099
- }
5100
-
5101
- if (!usedWorkspaceSelector) {
5102
- const promptedWorkspaceId = await input({
5103
- message:
5104
- "Default Postman workspace ID (optional, leave blank for null):",
5105
- default: "",
5106
- });
5107
- selectedWorkspaceId = normalizePostmanWorkspaceId(promptedWorkspaceId);
5108
- }
5109
-
5110
- defaultWorkspaceId = selectedWorkspaceId;
5159
+ const workspaceSelection = await promptPostmanWorkspaceSelection({
5160
+ apiKey: envApiKey,
5161
+ defaultWorkspaceId,
5162
+ });
5163
+ defaultWorkspaceId = workspaceSelection.workspaceId;
5164
+ warnings.push(...workspaceSelection.warnings);
5111
5165
  workspaceSelectionSource = "interactive";
5112
5166
  }
5113
5167
 
@@ -8088,6 +8142,41 @@ async function removePathRecord({
8088
8142
  }
8089
8143
  }
8090
8144
 
8145
+ async function removeEmptyDirectoryRecord({
8146
+ dirPath,
8147
+ category,
8148
+ dryRun = false,
8149
+ records,
8150
+ }) {
8151
+ if (!dirPath) return;
8152
+ if (!(await pathExists(dirPath))) return;
8153
+
8154
+ let entries = [];
8155
+ try {
8156
+ entries = await readdir(dirPath);
8157
+ } catch {
8158
+ return;
8159
+ }
8160
+
8161
+ if (entries.length > 0) return;
8162
+
8163
+ if (dryRun) {
8164
+ records.push({
8165
+ path: dirPath,
8166
+ category,
8167
+ action: "would-remove",
8168
+ });
8169
+ return;
8170
+ }
8171
+
8172
+ await rm(dirPath, { recursive: true, force: true });
8173
+ records.push({
8174
+ path: dirPath,
8175
+ category,
8176
+ action: "removed",
8177
+ });
8178
+ }
8179
+
8091
8180
  async function removeMcpRuntimeEntriesJson({
8092
8181
  filePath,
8093
8182
  keyName,
@@ -8256,6 +8345,8 @@ async function runWorkflowRemoveAll(options) {
8256
8345
  const scopes = resolveRemoveAllScopes(opts.scope);
8257
8346
  const platforms = resolveRemoveAllPlatforms(opts.platform);
8258
8347
  const bundleIds = await listBundleIds();
8348
+ const knownTopLevelSkillIds =
8349
+ await listTopLevelSkillIdsFromRoot(workflowSkillsRoot());
8259
8350
 
8260
8351
  if (!dryRun && !opts.yes && process.stdin.isTTY) {
8261
8352
  const proceed = await confirm({
@@ -8275,11 +8366,45 @@ async function runWorkflowRemoveAll(options) {
8275
8366
 
8276
8367
  for (const scope of scopes) {
8277
8368
  for (const platform of platforms) {
8278
- const artifactProfilePaths = await resolveArtifactProfilePaths(
8369
+ const artifactProfilePaths = await resolveProfilePaths(
8279
8370
  platform,
8280
8371
  scope,
8281
8372
  cwd,
8282
8373
  );
8374
+ const profileCandidates = resolveProfilePathCandidates(
8375
+ platform,
8376
+ scope,
8377
+ cwd,
8378
+ );
8379
+ const legacySkillDirs = resolveLegacySkillDirsForCleanup(
8380
+ platform,
8381
+ scope,
8382
+ cwd,
8383
+ );
8384
+ const allSkillDirs = expandUniquePaths(
8385
+ [...profileCandidates.skillsDirs, ...legacySkillDirs],
8386
+ cwd,
8387
+ );
8388
+ const isPrimaryDir = (candidateDir, primaryDir) => {
8389
+ if (!candidateDir || !primaryDir) return false;
8390
+ return path.resolve(candidateDir) === path.resolve(primaryDir);
8391
+ };
8392
+ const alternateWorkflowsDirs = profileCandidates.workflowsDirs.filter(
8393
+ (dirPath) => !isPrimaryDir(dirPath, artifactProfilePaths.workflowsDir),
8394
+ );
8395
+ const alternateAgentsDirs = profileCandidates.agentsDirs.filter(
8396
+ (dirPath) => !isPrimaryDir(dirPath, artifactProfilePaths.agentsDir),
8397
+ );
8398
+ const alternateCommandsDirs = profileCandidates.commandsDirs.filter(
8399
+ (dirPath) => !isPrimaryDir(dirPath, artifactProfilePaths.commandsDir),
8400
+ );
8401
+ const alternatePromptsDirs = profileCandidates.promptsDirs.filter(
8402
+ (dirPath) => !isPrimaryDir(dirPath, artifactProfilePaths.promptsDir),
8403
+ );
8404
+ const alternateSkillsDirs = allSkillDirs.filter(
8405
+ (dirPath) => !isPrimaryDir(dirPath, artifactProfilePaths.skillsDir),
8406
+ );
8407
+
8283
8408
  for (const bundleId of bundleIds) {
8284
8409
  const manifest = await readBundleManifest(bundleId);
8285
8410
  const removedBundle = await removeBundleArtifacts({
@@ -8298,20 +8423,103 @@ async function runWorkflowRemoveAll(options) {
8298
8423
  action: dryRun ? "would-remove" : "removed",
8299
8424
  });
8300
8425
  }
8301
- }
8302
8426
 
8303
- const extraSkillPaths = [
8304
- path.join(artifactProfilePaths.skillsDir || "", POSTMAN_SKILL_ID),
8305
- path.join(artifactProfilePaths.skillsDir || "", STITCH_SKILL_ID),
8306
- path.join(artifactProfilePaths.skillsDir || "", "skills_index.json"),
8307
- ];
8308
- for (const extraPath of extraSkillPaths) {
8309
- await removePathRecord({
8310
- targetPath: extraPath,
8311
- category: `${platform}/${scope}/extra-skill`,
8312
- dryRun,
8313
- records: removedRecords,
8427
+ const platformSpec = manifest.platforms?.[platform];
8428
+ if (!platformSpec) continue;
8429
+
8430
+ const workflowFiles = (platformSpec.workflows || []).map((entry) =>
8431
+ path.basename(entry),
8432
+ );
8433
+ const agentFiles = (platformSpec.agents || []).map((entry) =>
8434
+ path.basename(entry),
8435
+ );
8436
+ const commandFiles = (platformSpec.commands || []).map((entry) =>
8437
+ path.basename(entry),
8438
+ );
8439
+ const promptFiles = (platformSpec.prompts || []).map((entry) =>
8440
+ path.basename(entry),
8441
+ );
8442
+ const skillIds = await resolveInstallSkillIds({
8443
+ platformSpec,
8444
+ extraSkillIds: [],
8314
8445
  });
8446
+ const wrapperSkillIds =
8447
+ platform === "codex" ? buildCodexWrapperSkillIds(platformSpec) : [];
8448
+ const bundleSkillIds = [...new Set([...skillIds, ...wrapperSkillIds])];
8449
+
8450
+ for (const workflowsDir of alternateWorkflowsDirs) {
8451
+ for (const workflowFile of workflowFiles) {
8452
+ await removePathRecord({
8453
+ targetPath: path.join(workflowsDir, workflowFile),
8454
+ category: `${platform}/${scope}/bundle-alt`,
8455
+ dryRun,
8456
+ records: removedRecords,
8457
+ });
8458
+ }
8459
+ }
8460
+ for (const agentsDir of alternateAgentsDirs) {
8461
+ for (const agentFile of agentFiles) {
8462
+ await removePathRecord({
8463
+ targetPath: path.join(agentsDir, agentFile),
8464
+ category: `${platform}/${scope}/bundle-alt`,
8465
+ dryRun,
8466
+ records: removedRecords,
8467
+ });
8468
+ }
8469
+ }
8470
+ for (const commandsDir of alternateCommandsDirs) {
8471
+ for (const commandFile of commandFiles) {
8472
+ await removePathRecord({
8473
+ targetPath: path.join(commandsDir, commandFile),
8474
+ category: `${platform}/${scope}/bundle-alt`,
8475
+ dryRun,
8476
+ records: removedRecords,
8477
+ });
8478
+ }
8479
+ }
8480
+ for (const promptsDir of alternatePromptsDirs) {
8481
+ for (const promptFile of promptFiles) {
8482
+ await removePathRecord({
8483
+ targetPath: path.join(promptsDir, promptFile),
8484
+ category: `${platform}/${scope}/bundle-alt`,
8485
+ dryRun,
8486
+ records: removedRecords,
8487
+ });
8488
+ }
8489
+ }
8490
+ for (const skillsDir of alternateSkillsDirs) {
8491
+ for (const skillId of bundleSkillIds) {
8492
+ await removePathRecord({
8493
+ targetPath: path.join(skillsDir, skillId),
8494
+ category: `${platform}/${scope}/bundle-alt`,
8495
+ dryRun,
8496
+ records: removedRecords,
8497
+ });
8498
+ }
8499
+ }
8500
+ }
8501
+
8502
+ for (const skillsDir of allSkillDirs) {
8503
+ for (const entry of [
8504
+ POSTMAN_SKILL_ID,
8505
+ STITCH_SKILL_ID,
8506
+ "skills_index.json",
8507
+ ]) {
8508
+ await removePathRecord({
8509
+ targetPath: path.join(skillsDir, entry),
8510
+ category: `${platform}/${scope}/extra-skill`,
8511
+ dryRun,
8512
+ records: removedRecords,
8513
+ });
8514
+ }
8515
+ for (const skillId of knownTopLevelSkillIds) {
8516
+ await removePathRecord({
8517
+ targetPath: path.join(skillsDir, skillId),
8518
+ category: `${platform}/${scope}/known-skill`,
8519
+ dryRun,
8520
+ records: removedRecords,
8521
+ });
8522
+ }
8315
8523
  }
8316
8524
 
8317
8525
  if (platform === "antigravity") {
@@ -8363,6 +8571,25 @@ async function runWorkflowRemoveAll(options) {
8363
8571
  }
8364
8572
  }
8365
8573
 
8574
+ for (const managedDir of expandUniquePaths(
8575
+ [
8576
+ ...profileCandidates.skillsDirs,
8577
+ ...profileCandidates.agentsDirs,
8578
+ ...profileCandidates.workflowsDirs,
8579
+ ...profileCandidates.commandsDirs,
8580
+ ...profileCandidates.promptsDirs,
8581
+ ...legacySkillDirs,
8582
+ ],
8583
+ cwd,
8584
+ )) {
8585
+ await removeEmptyDirectoryRecord({
8586
+ dirPath: managedDir,
8587
+ category: `${platform}/${scope}/managed-dir-empty`,
8588
+ dryRun,
8589
+ records: removedRecords,
8590
+ });
8591
+ }
8592
+
8366
8593
  const scopedProfilePaths = await resolveProfilePaths(platform, scope, cwd);
8367
8594
  const ruleCandidates = [...scopedProfilePaths.ruleFilesByPriority];
8368
8595
  if (scope === "global") {
@@ -8429,7 +8656,7 @@ async function runWorkflowRemoveAll(options) {
8429
8656
  dryRun,
8430
8657
  records: removedRecords,
8431
8658
  });
8432
- } else if (includeCredentials) {
8659
+ } else if (scope === "global" || includeCredentials) {
8433
8660
  await removePathRecord({
8434
8661
  targetPath: resolveManagedCredentialsEnvPath(),
8435
8662
  category: "global/credentials",
@@ -8437,6 +8664,20 @@ async function runWorkflowRemoveAll(options) {
8437
8664
  records: removedRecords,
8438
8665
  });
8439
8666
  }
8667
+
8668
+ if (scope === "global") {
8669
+ for (const globalRootDir of [
8670
+ path.join(os.homedir(), ".cbx"),
8671
+ path.join(os.homedir(), ".agents"),
8672
+ ]) {
8673
+ await removeEmptyDirectoryRecord({
8674
+ dirPath: globalRootDir,
8675
+ category: "global/root-dir-empty",
8676
+ dryRun,
8677
+ records: removedRecords,
8678
+ });
8679
+ }
8680
+ }
8440
8681
  }
8441
8682
 
8442
8683
  if (await checkDockerAvailable({ cwd })) {
@@ -10987,6 +11228,10 @@ async function runInitWizard(options) {
10987
11228
  normalizeMcpScope(options.mcpScope, defaultSkillsScope) === "global"
10988
11229
  ? "global"
10989
11230
  : "project";
11231
+ const defaultPostmanWorkspaceId =
11232
+ options.postmanWorkspaceId !== undefined
11233
+ ? normalizePostmanWorkspaceId(options.postmanWorkspaceId)
11234
+ : null;
10990
11235
  const defaultMcpSelections = normalizeInitMcpSelections(options.mcps);
10991
11236
  const defaultPlatforms = normalizeInitPlatforms(options.platforms);
10992
11237
  const defaultMcpRuntime = normalizeMcpRuntime(
@@ -11035,9 +11280,11 @@ async function runInitWizard(options) {
11035
11280
  options.postmanMode && normalizePostmanMode(options.postmanMode)
11036
11281
  ? normalizePostmanMode(options.postmanMode)
11037
11282
  : "full",
11283
+ postmanWorkspaceId: defaultPostmanWorkspaceId,
11038
11284
  postmanApiKey: null,
11039
11285
  stitchApiKey: null,
11040
11286
  };
11287
+ const initWarnings = [];
11041
11288
 
11042
11289
  if (selections.platforms.length === 0) {
11043
11290
  throw new Error("No platforms selected.");
@@ -11066,6 +11313,20 @@ async function runInitWizard(options) {
11066
11313
  selections.postmanApiKey = await promptOptionalSecret(
11067
11314
  "Postman API key (optional, leave blank to keep existing env/profile state):",
11068
11315
  );
11316
+ const postmanLookupApiKey =
11317
+ normalizePostmanApiKey(selections.postmanApiKey) ||
11318
+ normalizePostmanApiKey(
11319
+ process.env[
11320
+ profileEnvVarAlias("postman", DEFAULT_CREDENTIAL_PROFILE_NAME)
11321
+ ],
11322
+ ) ||
11323
+ normalizePostmanApiKey(process.env[POSTMAN_API_KEY_ENV_VAR]);
11324
+ const postmanWorkspaceSelection = await promptPostmanWorkspaceSelection({
11325
+ apiKey: postmanLookupApiKey,
11326
+ defaultWorkspaceId: selections.postmanWorkspaceId,
11327
+ });
11328
+ selections.postmanWorkspaceId = postmanWorkspaceSelection.workspaceId;
11329
+ initWarnings.push(...postmanWorkspaceSelection.warnings);
11069
11330
  }
11070
11331
 
11071
11332
  if (selections.selectedMcps.includes("stitch") && isInteractive) {
@@ -11090,6 +11351,12 @@ async function runInitWizard(options) {
11090
11351
  });
11091
11352
 
11092
11353
  const initSummary = formatInitSummary(selections);
11354
+ if (initWarnings.length > 0) {
11355
+ console.log("\nInit warnings:");
11356
+ for (const warning of initWarnings) {
11357
+ console.log(`- ${warning}`);
11358
+ }
11359
+ }
11093
11360
  if (!options.yes && isInteractive) {
11094
11361
  const proceed = await promptInitApplyConfirmation(initSummary);
11095
11362
  if (!proceed) {
@@ -53,6 +53,9 @@ export function buildInitExecutionPlan({
53
53
  mcpBuildLocal:
54
54
  wantsPostman || stitchEnabled ? selections.mcpBuildLocal : false,
55
55
  postmanMode: wantsPostman ? selections.postmanMode : undefined,
56
+ postmanWorkspaceId: wantsPostman
57
+ ? selections.postmanWorkspaceId
58
+ : undefined,
56
59
  initWizardMode: true,
57
60
  };
58
61
 
@@ -69,6 +72,7 @@ export function buildInitExecutionPlan({
69
72
  }
70
73
 
71
74
  export function formatInitSummary(selections: InitWizardSelections) {
75
+ const postmanSelected = selections.selectedMcps.includes("postman");
72
76
  return [
73
77
  "Init plan summary:",
74
78
  `- Bundle: ${selections.bundleId}`,
@@ -78,6 +82,7 @@ export function formatInitSummary(selections: InitWizardSelections) {
78
82
  `- MCP scope: ${selections.mcpScope}`,
79
83
  `- MCP runtime: ${selections.mcpRuntime}${selections.mcpRuntime === "docker" ? selections.mcpBuildLocal ? " (build local image)" : " (pull image)" : ""}`,
80
84
  `- MCP selections: ${selections.selectedMcps.length > 0 ? selections.selectedMcps.join(", ") : "(none)"}`,
81
- `- Postman mode: ${selections.postmanMode}`,
85
+ `- Postman mode: ${postmanSelected ? selections.postmanMode : "(not selected)"}`,
86
+ `- Postman workspace: ${postmanSelected ? selections.postmanWorkspaceId === null ? "null" : selections.postmanWorkspaceId : "(not selected)"}`,
82
87
  ].join("\n");
83
88
  }
@@ -15,6 +15,7 @@ export interface InitWizardSelections {
15
15
  mcpBuildLocal: boolean;
16
16
  selectedMcps: InitMcpId[];
17
17
  postmanMode: InitPostmanMode;
18
+ postmanWorkspaceId: string | null;
18
19
  postmanApiKey: string | null;
19
20
  stitchApiKey: string | null;
20
21
  }