@cubis/foundry 0.3.20 → 0.3.21

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.
Files changed (3) hide show
  1. package/README.md +8 -9
  2. package/bin/cubis.js +107 -29
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -60,7 +60,9 @@ cbx workflows install --platform copilot --postman
60
60
 
61
61
  Install bootstrap behavior:
62
62
  - `cbx workflows install` now also bootstraps `ENGINEERING_RULES.md` and `TECH.md` (creates when missing; keeps existing files unless explicitly regenerated).
63
- - When install scope is `global`, workflow/skill/agent artifacts install to global paths, but rule sync + engineering artifacts are maintained in workspace (`project`) scope.
63
+ - When install scope is `global` (default), skills/powers install to global paths, while workflows + agents stay in workspace (`project`) paths.
64
+ - Rule sync + engineering artifacts (`AGENTS.md`/`GEMINI.md`/Copilot instructions, `ENGINEERING_RULES.md`, `TECH.md`) are maintained in workspace (`project`) scope.
65
+ - Codex workflow templates are maintained in workspace `.agents/workflows` so workflow-wrapper routing remains discoverable in project rules.
64
66
  - Optional `--postman` bootstrap creates `postman_setting.json` and installs/configures the Postman skill/MCP for Codex, Antigravity, and Copilot.
65
67
  - Use `cbx rules init --platform <platform> --overwrite` to force-regenerate both files.
66
68
 
@@ -177,11 +179,9 @@ Project scope:
177
179
  - Terminal integration (optional): `.agent/terminal-integration`
178
180
 
179
181
  Global scope:
180
- - Workflows: `~/.gemini/antigravity/workflows`
181
- - Agents: `~/.gemini/antigravity/agents`
182
182
  - Skills: `~/.gemini/antigravity/skills`
183
183
  - Rules: `~/.gemini/GEMINI.md`
184
- - Terminal integration (optional): `~/.gemini/antigravity/terminal-integration`
184
+ - Workflows/agents/terminal-integration: default install keeps these in workspace (`.agent/...`) paths.
185
185
 
186
186
  ### Antigravity Terminal Integration (Optional)
187
187
 
@@ -191,7 +191,7 @@ Install-time options:
191
191
 
192
192
  Behavior:
193
193
  - Interactive installs prompt whether to enable terminal verification integration.
194
- - If enabled, cbx writes managed scripts/config under `.agent/terminal-integration` (or global equivalent).
194
+ - If enabled, cbx writes managed scripts/config under `.agent/terminal-integration`.
195
195
  - cbx also writes a managed terminal verification block into Antigravity rule files so post-task verification commands are explicit.
196
196
  - Removing the bundle cleans the managed terminal integration directory and block.
197
197
 
@@ -208,9 +208,9 @@ Project scope:
208
208
  - Example usage: `$workflow-plan`, `$agent-backend-specialist`
209
209
 
210
210
  Global scope:
211
- - Workflow templates (reference docs): `~/.agents/workflows`
212
211
  - Skills: `~/.agents/skills`
213
212
  - Rules: `~/.codex/AGENTS.md`
213
+ - Workflow templates (reference docs): default install keeps these in workspace `.agents/workflows`
214
214
  - Agents: not installed for Codex runtime
215
215
 
216
216
  Legacy compatibility note:
@@ -226,10 +226,9 @@ Project scope:
226
226
  - Skill schema note: `cbx` normalizes Copilot skill frontmatter by removing unsupported top-level keys like `displayName` and `keywords` during install.
227
227
 
228
228
  Global scope:
229
- - Workflows: `~/.copilot/workflows`
230
- - Agents: `~/.copilot/agents`
231
229
  - Skills: `~/.copilot/skills`
232
230
  - Rules: `~/.copilot/copilot-instructions.md`
231
+ - Workflows/agents: default install keeps these in workspace (`.github/...`) paths.
233
232
 
234
233
  ## Rule Auto-Sync
235
234
 
@@ -261,7 +260,7 @@ Default scope:
261
260
  - `cbx install` (legacy alias)
262
261
  - `cbx init` (legacy alias)
263
262
  - Default scope for these commands is `global`.
264
- - Rule files (`AGENTS.md`/`GEMINI.md`/Copilot instructions) and engineering files (`ENGINEERING_RULES.md`, `TECH.md`) are still updated in workspace (`project`) scope during install.
263
+ - In this default global mode, only skills/powers install globally. Workflows/agents and rule/engineering files remain workspace-scoped.
265
264
  - Other workflow/rules commands default to `project`.
266
265
 
267
266
  Optional:
package/bin/cubis.js CHANGED
@@ -1295,6 +1295,19 @@ async function resolveProfilePaths(profileId, scope, cwd = process.cwd()) {
1295
1295
  };
1296
1296
  }
1297
1297
 
1298
+ async function resolveArtifactProfilePaths(profileId, scope, cwd = process.cwd()) {
1299
+ const scopedPaths = await resolveProfilePaths(profileId, scope, cwd);
1300
+ if (scope !== "global") return scopedPaths;
1301
+
1302
+ // Global install mode is skills-only. Keep workflows/agents in workspace scope.
1303
+ const workspacePaths = await resolveProfilePaths(profileId, "project", cwd);
1304
+ return {
1305
+ ...scopedPaths,
1306
+ workflowsDir: workspacePaths.workflowsDir,
1307
+ agentsDir: workspacePaths.agentsDir
1308
+ };
1309
+ }
1310
+
1298
1311
  async function listBundleIds() {
1299
1312
  const root = path.join(agentAssetsRoot(), "workflows");
1300
1313
  if (!(await pathExists(root))) return [];
@@ -2632,12 +2645,13 @@ async function installBundleArtifacts({
2632
2645
  platform,
2633
2646
  scope,
2634
2647
  overwrite,
2648
+ profilePathsOverride = null,
2635
2649
  extraSkillIds = [],
2636
2650
  terminalVerifierSelection = null,
2637
2651
  dryRun = false,
2638
2652
  cwd = process.cwd()
2639
2653
  }) {
2640
- const profilePaths = await resolveProfilePaths(platform, scope, cwd);
2654
+ const profilePaths = profilePathsOverride || (await resolveArtifactProfilePaths(platform, scope, cwd));
2641
2655
  const platformSpec = manifest.platforms?.[platform];
2642
2656
 
2643
2657
  if (!platformSpec) {
@@ -2766,6 +2780,46 @@ async function installBundleArtifacts({
2766
2780
  };
2767
2781
  }
2768
2782
 
2783
+ async function installCodexProjectWorkflowTemplates({
2784
+ bundleId,
2785
+ manifest,
2786
+ overwrite,
2787
+ dryRun = false,
2788
+ cwd = process.cwd()
2789
+ }) {
2790
+ const platform = "codex";
2791
+ const platformSpec = manifest.platforms?.[platform];
2792
+ if (!platformSpec) return { installed: [], skipped: [] };
2793
+
2794
+ const workflowFiles = Array.isArray(platformSpec.workflows) ? platformSpec.workflows : [];
2795
+ if (workflowFiles.length === 0) return { installed: [], skipped: [] };
2796
+
2797
+ const profilePaths = await resolveProfilePaths(platform, "project", cwd);
2798
+ if (!dryRun) {
2799
+ await mkdir(profilePaths.workflowsDir, { recursive: true });
2800
+ }
2801
+
2802
+ const bundleRoot = path.join(agentAssetsRoot(), "workflows", bundleId);
2803
+ const platformRoot = path.join(bundleRoot, "platforms", platform);
2804
+ const installed = [];
2805
+ const skipped = [];
2806
+
2807
+ for (const workflowFile of workflowFiles) {
2808
+ const source = path.join(platformRoot, "workflows", workflowFile);
2809
+ const destination = path.join(profilePaths.workflowsDir, path.basename(workflowFile));
2810
+
2811
+ if (!(await pathExists(source))) {
2812
+ throw new Error(`Missing workflow source file: ${source}`);
2813
+ }
2814
+
2815
+ const result = await copyArtifact({ source, destination, overwrite, dryRun });
2816
+ if (result.action === "skipped" || result.action === "would-skip") skipped.push(destination);
2817
+ else installed.push(destination);
2818
+ }
2819
+
2820
+ return { installed, skipped };
2821
+ }
2822
+
2769
2823
  async function seedRuleFileFromTemplateIfMissing({
2770
2824
  bundleId,
2771
2825
  manifest,
@@ -2833,10 +2887,11 @@ async function removeBundleArtifacts({
2833
2887
  manifest,
2834
2888
  platform,
2835
2889
  scope,
2890
+ profilePathsOverride = null,
2836
2891
  dryRun = false,
2837
2892
  cwd = process.cwd()
2838
2893
  }) {
2839
- const profilePaths = await resolveProfilePaths(platform, scope, cwd);
2894
+ const profilePaths = profilePathsOverride || (await resolveArtifactProfilePaths(platform, scope, cwd));
2840
2895
  const platformSpec = manifest.platforms?.[platform];
2841
2896
  if (!platformSpec) throw new Error(`Bundle '${bundleId}' does not define platform '${platform}'.`);
2842
2897
 
@@ -2886,6 +2941,7 @@ function printPlatforms() {
2886
2941
  );
2887
2942
  console.log(` global skills: ${profile.global.skillDirs[0]}`);
2888
2943
  console.log(` global rules: ${profile.global.ruleFilesByPriority.join(" | ")}`);
2944
+ console.log(" default install: workflows/agents -> project, skills -> global");
2889
2945
  }
2890
2946
  }
2891
2947
 
@@ -3060,21 +3116,22 @@ function printRemoveSummary({
3060
3116
  async function createDoctorReport({ platform, scope, cwd = process.cwd() }) {
3061
3117
  const profile = WORKFLOW_PROFILES[platform];
3062
3118
  const profilePaths = await resolveProfilePaths(platform, scope, cwd);
3119
+ const artifactPaths = await resolveArtifactProfilePaths(platform, scope, cwd);
3063
3120
  const agentsEnabled = platformInstallsCustomAgents(platform);
3064
3121
 
3065
3122
  const pathStatus = {
3066
3123
  workflows: {
3067
- path: profilePaths.workflowsDir,
3068
- exists: await pathExists(profilePaths.workflowsDir)
3124
+ path: artifactPaths.workflowsDir,
3125
+ exists: await pathExists(artifactPaths.workflowsDir)
3069
3126
  },
3070
3127
  agents: {
3071
- path: profilePaths.agentsDir,
3128
+ path: artifactPaths.agentsDir,
3072
3129
  enabled: agentsEnabled,
3073
- exists: agentsEnabled ? await pathExists(profilePaths.agentsDir) : null
3130
+ exists: agentsEnabled ? await pathExists(artifactPaths.agentsDir) : null
3074
3131
  },
3075
3132
  skills: {
3076
- path: profilePaths.skillsDir,
3077
- exists: await pathExists(profilePaths.skillsDir)
3133
+ path: artifactPaths.skillsDir,
3134
+ exists: await pathExists(artifactPaths.skillsDir)
3078
3135
  }
3079
3136
  };
3080
3137
 
@@ -3100,7 +3157,7 @@ async function createDoctorReport({ platform, scope, cwd = process.cwd() }) {
3100
3157
 
3101
3158
  let terminalIntegration = null;
3102
3159
  if (platform === "antigravity") {
3103
- const integrationDir = getAntigravityTerminalIntegrationDir(profilePaths);
3160
+ const integrationDir = getAntigravityTerminalIntegrationDir(artifactPaths);
3104
3161
  const configPath = path.join(integrationDir, "config.json");
3105
3162
  const exists = await pathExists(integrationDir);
3106
3163
  const configExists = await pathExists(configPath);
@@ -3220,7 +3277,7 @@ async function createDoctorReport({ platform, scope, cwd = process.cwd() }) {
3220
3277
  }
3221
3278
 
3222
3279
  if (platform === "copilot" && pathStatus.skills.exists) {
3223
- const findings = await validateCopilotSkillsSchema(profilePaths.skillsDir);
3280
+ const findings = await validateCopilotSkillsSchema(artifactPaths.skillsDir);
3224
3281
  if (findings.length > 0) {
3225
3282
  const preview = findings
3226
3283
  .slice(0, 5)
@@ -3236,7 +3293,7 @@ async function createDoctorReport({ platform, scope, cwd = process.cwd() }) {
3236
3293
  }
3237
3294
 
3238
3295
  if (platform === "copilot" && pathStatus.agents.exists) {
3239
- const findings = await validateCopilotAgentsSchema(profilePaths.agentsDir);
3296
+ const findings = await validateCopilotAgentsSchema(artifactPaths.agentsDir);
3240
3297
  if (findings.length > 0) {
3241
3298
  const preview = findings
3242
3299
  .slice(0, 5)
@@ -3447,7 +3504,7 @@ async function cleanupAntigravityTerminalIntegration({
3447
3504
  cwd,
3448
3505
  dryRun = false
3449
3506
  }) {
3450
- const profilePaths = await resolveProfilePaths("antigravity", scope, cwd);
3507
+ const profilePaths = await resolveArtifactProfilePaths("antigravity", scope, cwd);
3451
3508
  const integrationDir = getAntigravityTerminalIntegrationDir(profilePaths);
3452
3509
  const dirRemoved = await safeRemove(integrationDir, dryRun);
3453
3510
 
@@ -3475,10 +3532,12 @@ async function cleanupAntigravityTerminalIntegration({
3475
3532
 
3476
3533
  async function runWorkflowInstall(options) {
3477
3534
  try {
3535
+ const cwd = process.cwd();
3478
3536
  const scope = normalizeScope(options.scope);
3479
3537
  const ruleScope = scope === "global" ? "project" : scope;
3480
3538
  const dryRun = Boolean(options.dryRun);
3481
- const platform = await resolvePlatform(options.platform, scope, process.cwd());
3539
+ const platform = await resolvePlatform(options.platform, scope, cwd);
3540
+ const artifactProfilePaths = await resolveArtifactProfilePaths(platform, scope, cwd);
3482
3541
  const bundleId = await chooseBundle(options.bundle);
3483
3542
  const manifest = await readBundleManifest(bundleId);
3484
3543
 
@@ -3500,7 +3559,7 @@ async function runWorkflowInstall(options) {
3500
3559
  const postmanSelection = await resolvePostmanInstallSelection({
3501
3560
  scope,
3502
3561
  options,
3503
- cwd: process.cwd()
3562
+ cwd
3504
3563
  });
3505
3564
 
3506
3565
  const installResult = await installBundleArtifacts({
@@ -3509,12 +3568,28 @@ async function runWorkflowInstall(options) {
3509
3568
  platform,
3510
3569
  scope,
3511
3570
  overwrite: Boolean(options.overwrite),
3571
+ profilePathsOverride: artifactProfilePaths,
3512
3572
  extraSkillIds: postmanSelection.enabled ? [POSTMAN_SKILL_ID] : [],
3513
3573
  terminalVerifierSelection,
3514
3574
  dryRun,
3515
- cwd: process.cwd()
3575
+ cwd
3516
3576
  });
3517
3577
 
3578
+ if (platform === "codex" && scope === "global") {
3579
+ const codexProjectPaths = await resolveProfilePaths("codex", "project", cwd);
3580
+ if (path.resolve(artifactProfilePaths.workflowsDir) !== path.resolve(codexProjectPaths.workflowsDir)) {
3581
+ const codexProjectWorkflows = await installCodexProjectWorkflowTemplates({
3582
+ bundleId,
3583
+ manifest,
3584
+ overwrite: Boolean(options.overwrite),
3585
+ dryRun,
3586
+ cwd
3587
+ });
3588
+ installResult.installed.push(...codexProjectWorkflows.installed);
3589
+ installResult.skipped.push(...codexProjectWorkflows.skipped);
3590
+ }
3591
+ }
3592
+
3518
3593
  await seedRuleFileFromTemplateIfMissing({
3519
3594
  bundleId,
3520
3595
  manifest,
@@ -3522,14 +3597,14 @@ async function runWorkflowInstall(options) {
3522
3597
  scope: ruleScope,
3523
3598
  overwrite: Boolean(options.overwrite),
3524
3599
  dryRun,
3525
- cwd: process.cwd()
3600
+ cwd
3526
3601
  });
3527
3602
 
3528
3603
  const syncResult = await syncRulesForPlatform({
3529
3604
  platform,
3530
3605
  scope: ruleScope,
3531
3606
  dryRun,
3532
- cwd: process.cwd()
3607
+ cwd
3533
3608
  });
3534
3609
  const engineeringArtifactsResult = await upsertEngineeringArtifacts({
3535
3610
  platform,
@@ -3537,7 +3612,7 @@ async function runWorkflowInstall(options) {
3537
3612
  overwrite: false,
3538
3613
  dryRun,
3539
3614
  skipTech: false,
3540
- cwd: process.cwd()
3615
+ cwd
3541
3616
  });
3542
3617
  const postmanSetupResult = await configurePostmanInstallArtifacts({
3543
3618
  scope,
@@ -3545,14 +3620,14 @@ async function runWorkflowInstall(options) {
3545
3620
  postmanSelection,
3546
3621
  overwrite: Boolean(options.overwrite),
3547
3622
  dryRun,
3548
- cwd: process.cwd()
3623
+ cwd
3549
3624
  });
3550
3625
 
3551
3626
  const terminalVerificationRuleResult =
3552
3627
  platform === "antigravity" && installResult.terminalIntegration
3553
3628
  ? await upsertTerminalVerificationForInstall({
3554
3629
  scope: ruleScope,
3555
- cwd: process.cwd(),
3630
+ cwd,
3556
3631
  terminalIntegration: installResult.terminalIntegration,
3557
3632
  dryRun
3558
3633
  })
@@ -3565,7 +3640,7 @@ async function runWorkflowInstall(options) {
3565
3640
  bundleId,
3566
3641
  artifacts: installResult.artifacts,
3567
3642
  ruleFilePath: syncResult.filePath,
3568
- cwd: process.cwd()
3643
+ cwd
3569
3644
  });
3570
3645
  }
3571
3646
 
@@ -3611,9 +3686,12 @@ async function runWorkflowRemove(target, options) {
3611
3686
  throw new Error("Missing <bundle-or-workflow>. Usage: cbx workflows remove <bundle-or-workflow>");
3612
3687
  }
3613
3688
 
3689
+ const cwd = process.cwd();
3614
3690
  const scope = normalizeScope(options.scope);
3691
+ const ruleScope = scope === "global" ? "project" : scope;
3615
3692
  const dryRun = Boolean(options.dryRun);
3616
- const platform = await resolvePlatform(options.platform, scope, process.cwd());
3693
+ const platform = await resolvePlatform(options.platform, scope, cwd);
3694
+ const artifactProfilePaths = await resolveArtifactProfilePaths(platform, scope, cwd);
3617
3695
  const bundleIds = await listBundleIds();
3618
3696
 
3619
3697
  let removed = [];
@@ -3640,8 +3718,9 @@ async function runWorkflowRemove(target, options) {
3640
3718
  manifest,
3641
3719
  platform,
3642
3720
  scope,
3721
+ profilePathsOverride: artifactProfilePaths,
3643
3722
  dryRun,
3644
- cwd: process.cwd()
3723
+ cwd
3645
3724
  });
3646
3725
 
3647
3726
  removed = removeResult.removed;
@@ -3649,7 +3728,7 @@ async function runWorkflowRemove(target, options) {
3649
3728
  if (platform === "antigravity") {
3650
3729
  terminalIntegrationCleanup = await cleanupAntigravityTerminalIntegration({
3651
3730
  scope,
3652
- cwd: process.cwd(),
3731
+ cwd,
3653
3732
  dryRun
3654
3733
  });
3655
3734
  if (terminalIntegrationCleanup.dirRemoved) {
@@ -3657,8 +3736,7 @@ async function runWorkflowRemove(target, options) {
3657
3736
  }
3658
3737
  }
3659
3738
  } else {
3660
- const profilePaths = await resolveProfilePaths(platform, scope, process.cwd());
3661
- const workflowFile = await findWorkflowFileByTarget(profilePaths.workflowsDir, target);
3739
+ const workflowFile = await findWorkflowFileByTarget(artifactProfilePaths.workflowsDir, target);
3662
3740
 
3663
3741
  if (!workflowFile) {
3664
3742
  throw new Error(`Could not find workflow or bundle '${target}' in platform '${platform}'.`);
@@ -3682,9 +3760,9 @@ async function runWorkflowRemove(target, options) {
3682
3760
 
3683
3761
  const syncResult = await syncRulesForPlatform({
3684
3762
  platform,
3685
- scope,
3763
+ scope: ruleScope,
3686
3764
  dryRun,
3687
- cwd: process.cwd()
3765
+ cwd
3688
3766
  });
3689
3767
 
3690
3768
  if (!dryRun && removedType === "bundle") {
@@ -3693,7 +3771,7 @@ async function runWorkflowRemove(target, options) {
3693
3771
  platform,
3694
3772
  bundleId: target,
3695
3773
  ruleFilePath: syncResult.filePath,
3696
- cwd: process.cwd()
3774
+ cwd
3697
3775
  });
3698
3776
  }
3699
3777
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cubis/foundry",
3
- "version": "0.3.20",
3
+ "version": "0.3.21",
4
4
  "description": "Cubis Foundry CLI for workflow-first AI agent environments",
5
5
  "type": "module",
6
6
  "bin": {