@cubis/foundry 0.3.12 → 0.3.14
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/Ai Agent Workflow/powers/postman/POWER.md +2 -2
- package/Ai Agent Workflow/powers/postman/SKILL.md +2 -2
- package/Ai Agent Workflow/skills/postman/POWER.md +3 -3
- package/Ai Agent Workflow/skills/postman/SKILL.md +2 -2
- package/Ai Agent Workflow/workflows/agent-environment-setup/manifest.json +0 -273
- package/Ai Agent Workflow/workflows/agent-environment-setup/platforms/antigravity/agents/backend-specialist.md +1 -1
- package/Ai Agent Workflow/workflows/agent-environment-setup/platforms/antigravity/workflows/backend.md +11 -1
- package/Ai Agent Workflow/workflows/agent-environment-setup/platforms/codex/agents/backend-specialist.md +1 -1
- package/Ai Agent Workflow/workflows/agent-environment-setup/platforms/codex/workflows/backend.md +5 -1
- package/Ai Agent Workflow/workflows/agent-environment-setup/platforms/copilot/agents/backend-specialist.md +1 -1
- package/Ai Agent Workflow/workflows/agent-environment-setup/platforms/copilot/workflows/backend.md +5 -1
- package/README.md +8 -0
- package/bin/cubis.js +413 -59
- package/package.json +1 -1
|
@@ -12,7 +12,7 @@ Before proceeding, validate that the user has completed the following steps befo
|
|
|
12
12
|
|
|
13
13
|
## Step 1
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Generate and maintain `postman_setting.json` as the primary Postman configuration. Use env-first authentication by default: keep `apiKey` as `null`, set `apiKeyEnvVar` to `POSTMAN_API_KEY`, and read the key from environment variables. Only store `apiKey` inline when the user explicitly requests file-based key storage. Keep `defaultWorkspaceId` nullable (`null` when unknown) so workflows can run without a preselected workspace.
|
|
16
16
|
|
|
17
17
|
## Step 2
|
|
18
18
|
|
|
@@ -68,7 +68,7 @@ Create a hook that runs anytime the source code or configuration file has been c
|
|
|
68
68
|
|
|
69
69
|
Automate API testing and collection management with Postman. Create workspaces, collections, environments, and run tests programmatically.
|
|
70
70
|
|
|
71
|
-
**Authentication**:
|
|
71
|
+
**Authentication**: Env-first via `postman_setting.json` + `POSTMAN_API_KEY`; inline `apiKey` is optional.
|
|
72
72
|
|
|
73
73
|
## Available MCP Servers
|
|
74
74
|
|
|
@@ -10,7 +10,7 @@ Before proceeding, validate that the user has completed the following steps befo
|
|
|
10
10
|
|
|
11
11
|
## Step 1
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Generate and maintain `postman_setting.json` as the primary Postman configuration. Use env-first authentication by default: keep `apiKey` as `null`, set `apiKeyEnvVar` to `POSTMAN_API_KEY`, and read the key from environment variables. Only store `apiKey` inline when the user explicitly requests file-based key storage. Keep `defaultWorkspaceId` nullable (`null` when unknown) so workflows can run without a preselected workspace.
|
|
14
14
|
|
|
15
15
|
## Step 2
|
|
16
16
|
|
|
@@ -66,7 +66,7 @@ Create a hook that runs anytime the source code or configuration file has been c
|
|
|
66
66
|
|
|
67
67
|
Automate API testing and collection management with Postman. Create workspaces, collections, environments, and run tests programmatically.
|
|
68
68
|
|
|
69
|
-
**Authentication**:
|
|
69
|
+
**Authentication**: Env-first via `postman_setting.json` + `POSTMAN_API_KEY`; inline `apiKey` is optional.
|
|
70
70
|
|
|
71
71
|
## Available MCP Servers
|
|
72
72
|
|
|
@@ -12,7 +12,7 @@ Before proceeding, validate that the user has completed the following steps befo
|
|
|
12
12
|
|
|
13
13
|
## Step 1
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Generate and maintain `postman_setting.json` as the primary Postman configuration. Use env-first authentication by default: keep `apiKey` as `null`, set `apiKeyEnvVar` to `POSTMAN_API_KEY`, and read the key from environment variables. Only store `apiKey` inline when the user explicitly requests file-based key storage. Keep `defaultWorkspaceId` nullable (`null` when unknown) so workflows can run without a preselected workspace.
|
|
16
16
|
|
|
17
17
|
## Step 2
|
|
18
18
|
|
|
@@ -68,7 +68,7 @@ Create a hook that runs anytime the source code or configuration file has been c
|
|
|
68
68
|
|
|
69
69
|
Automate API testing and collection management with Postman. Create workspaces, collections, environments, and run tests programmatically.
|
|
70
70
|
|
|
71
|
-
**Authentication**:
|
|
71
|
+
**Authentication**: Env-first via `postman_setting.json` + `POSTMAN_API_KEY`; inline `apiKey` is optional.
|
|
72
72
|
|
|
73
73
|
## Available MCP Servers
|
|
74
74
|
|
|
@@ -239,4 +239,4 @@ for (const collection of collections) {
|
|
|
239
239
|
|
|
240
240
|
**Full mode (112 tools):** Change URL to `https://mcp.postman.com/full`
|
|
241
241
|
|
|
242
|
-
**API Key Permissions:** Workspace management, collection read/write, environment read/write, collection runs
|
|
242
|
+
**API Key Permissions:** Workspace management, collection read/write, environment read/write, collection runs
|
|
@@ -10,7 +10,7 @@ Before proceeding, validate that the user has completed the following steps befo
|
|
|
10
10
|
|
|
11
11
|
## Step 1
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Generate and maintain `postman_setting.json` as the primary Postman configuration. Use env-first authentication by default: keep `apiKey` as `null`, set `apiKeyEnvVar` to `POSTMAN_API_KEY`, and read the key from environment variables. Only store `apiKey` inline when the user explicitly requests file-based key storage. Keep `defaultWorkspaceId` nullable (`null` when unknown) so workflows can run without a preselected workspace.
|
|
14
14
|
|
|
15
15
|
## Step 2
|
|
16
16
|
|
|
@@ -66,7 +66,7 @@ Create a hook that runs anytime the source code or configuration file has been c
|
|
|
66
66
|
|
|
67
67
|
Automate API testing and collection management with Postman. Create workspaces, collections, environments, and run tests programmatically.
|
|
68
68
|
|
|
69
|
-
**Authentication**:
|
|
69
|
+
**Authentication**: Env-first via `postman_setting.json` + `POSTMAN_API_KEY`; inline `apiKey` is optional.
|
|
70
70
|
|
|
71
71
|
## Available MCP Servers
|
|
72
72
|
|
|
@@ -123,98 +123,7 @@
|
|
|
123
123
|
"testing-patterns",
|
|
124
124
|
"vulnerability-scanner",
|
|
125
125
|
"web-design-guidelines",
|
|
126
|
-
"vercel-automation",
|
|
127
|
-
"vercel-project-configuration",
|
|
128
|
-
"vercel-git-deployments",
|
|
129
|
-
"vercel-environments",
|
|
130
|
-
"vercel-generated-urls",
|
|
131
|
-
"vercel-deployment-promotion",
|
|
132
|
-
"vercel-build-pipeline",
|
|
133
|
-
"vercel-build-image-upgrades",
|
|
134
|
-
"vercel-build-output-api",
|
|
135
|
-
"vercel-monorepos",
|
|
136
|
-
"vercel-remote-caching",
|
|
137
|
-
"vercel-microfrontends",
|
|
138
|
-
"vercel-multi-tenant",
|
|
139
|
-
"vercel-functions-core",
|
|
140
|
-
"vercel-fluid-compute",
|
|
141
|
-
"vercel-functions-nodejs",
|
|
142
|
-
"vercel-functions-python",
|
|
143
|
-
"vercel-functions-edge-runtime",
|
|
144
|
-
"vercel-edge-to-node-migration",
|
|
145
|
-
"vercel-routing-middleware",
|
|
146
|
-
"vercel-function-config",
|
|
147
|
-
"vercel-runtime-cache",
|
|
148
|
-
"vercel-data-cache-nextjs",
|
|
149
|
-
"vercel-cron-jobs",
|
|
150
|
-
"vercel-og-image-generation",
|
|
151
|
-
"vercel-cdn-cache",
|
|
152
|
-
"vercel-cache-control-headers",
|
|
153
|
-
"vercel-isr",
|
|
154
|
-
"vercel-image-optimization",
|
|
155
|
-
"vercel-request-collapsing",
|
|
156
|
-
"vercel-redirects-rewrites",
|
|
157
|
-
"vercel-cdn-purging",
|
|
158
|
-
"vercel-blob",
|
|
159
|
-
"vercel-edge-config",
|
|
160
|
-
"vercel-edge-config-integrations",
|
|
161
|
-
"vercel-marketplace-storage-redis",
|
|
162
|
-
"vercel-storage-migrations",
|
|
163
|
-
"vercel-ai-sdk-core",
|
|
164
|
-
"vercel-ai-sdk-ui",
|
|
165
|
-
"vercel-ai-gateway-core",
|
|
166
|
-
"vercel-ai-gateway-model-routing",
|
|
167
|
-
"vercel-ai-gateway-fallbacks",
|
|
168
|
-
"vercel-ai-gateway-auth-byok",
|
|
169
|
-
"vercel-ai-gateway-observability",
|
|
170
|
-
"vercel-ai-gateway-openai-compatible",
|
|
171
|
-
"vercel-agent-workflows",
|
|
172
|
-
"vercel-mcp-for-agents",
|
|
173
|
-
"vercel-flags-platform",
|
|
174
|
-
"vercel-flags-dashboard",
|
|
175
|
-
"vercel-flags-sdk",
|
|
176
|
-
"vercel-flags-openfeature",
|
|
177
|
-
"vercel-flags-explorer",
|
|
178
|
-
"vercel-flags-cli-workflows",
|
|
179
|
-
"vercel-observability-overview",
|
|
180
|
-
"vercel-runtime-logs",
|
|
181
|
-
"vercel-tracing-otel",
|
|
182
|
-
"vercel-session-tracing",
|
|
183
|
-
"vercel-alerts-monitoring",
|
|
184
|
-
"vercel-drains-setup",
|
|
185
|
-
"vercel-log-drain-reference",
|
|
186
|
-
"vercel-log-trace-correlation",
|
|
187
|
-
"vercel-speed-insights",
|
|
188
|
-
"vercel-web-analytics",
|
|
189
|
-
"vercel-custom-events",
|
|
190
|
-
"vercel-deployment-protection",
|
|
191
|
-
"vercel-protection-bypass-automation",
|
|
192
|
-
"vercel-firewall-core",
|
|
193
|
-
"vercel-waf-custom-rules",
|
|
194
|
-
"vercel-waf-rate-limiting",
|
|
195
|
-
"vercel-bot-management",
|
|
196
|
-
"vercel-botid",
|
|
197
|
-
"vercel-secure-compute",
|
|
198
|
-
"vercel-static-ips",
|
|
199
|
-
"vercel-oidc-federation",
|
|
200
|
-
"vercel-rbac-access-groups",
|
|
201
|
-
"vercel-audit-logs",
|
|
202
|
-
"vercel-2fa-enforcement",
|
|
203
126
|
"vercel-domains",
|
|
204
|
-
"vercel-dns-records",
|
|
205
|
-
"vercel-nameservers",
|
|
206
|
-
"vercel-ssl-certificates",
|
|
207
|
-
"vercel-domain-ownership-claims",
|
|
208
|
-
"vercel-cli-core",
|
|
209
|
-
"vercel-cli-project-domain-env",
|
|
210
|
-
"vercel-cli-flags",
|
|
211
|
-
"vercel-cli-microfrontends",
|
|
212
|
-
"vercel-cli-mcp",
|
|
213
|
-
"vercel-rest-api",
|
|
214
|
-
"vercel-sdk",
|
|
215
|
-
"vercel-integrations-native",
|
|
216
|
-
"vercel-marketplace-partner-api",
|
|
217
|
-
"vercel-webhooks-and-checks",
|
|
218
127
|
"drift-flutter",
|
|
219
128
|
"database-design",
|
|
220
129
|
"database-optimizer"
|
|
@@ -353,98 +262,7 @@
|
|
|
353
262
|
"testing-patterns",
|
|
354
263
|
"vulnerability-scanner",
|
|
355
264
|
"web-design-guidelines",
|
|
356
|
-
"vercel-automation",
|
|
357
|
-
"vercel-project-configuration",
|
|
358
|
-
"vercel-git-deployments",
|
|
359
|
-
"vercel-environments",
|
|
360
|
-
"vercel-generated-urls",
|
|
361
|
-
"vercel-deployment-promotion",
|
|
362
|
-
"vercel-build-pipeline",
|
|
363
|
-
"vercel-build-image-upgrades",
|
|
364
|
-
"vercel-build-output-api",
|
|
365
|
-
"vercel-monorepos",
|
|
366
|
-
"vercel-remote-caching",
|
|
367
|
-
"vercel-microfrontends",
|
|
368
|
-
"vercel-multi-tenant",
|
|
369
|
-
"vercel-functions-core",
|
|
370
|
-
"vercel-fluid-compute",
|
|
371
|
-
"vercel-functions-nodejs",
|
|
372
|
-
"vercel-functions-python",
|
|
373
|
-
"vercel-functions-edge-runtime",
|
|
374
|
-
"vercel-edge-to-node-migration",
|
|
375
|
-
"vercel-routing-middleware",
|
|
376
|
-
"vercel-function-config",
|
|
377
|
-
"vercel-runtime-cache",
|
|
378
|
-
"vercel-data-cache-nextjs",
|
|
379
|
-
"vercel-cron-jobs",
|
|
380
|
-
"vercel-og-image-generation",
|
|
381
|
-
"vercel-cdn-cache",
|
|
382
|
-
"vercel-cache-control-headers",
|
|
383
|
-
"vercel-isr",
|
|
384
|
-
"vercel-image-optimization",
|
|
385
|
-
"vercel-request-collapsing",
|
|
386
|
-
"vercel-redirects-rewrites",
|
|
387
|
-
"vercel-cdn-purging",
|
|
388
|
-
"vercel-blob",
|
|
389
|
-
"vercel-edge-config",
|
|
390
|
-
"vercel-edge-config-integrations",
|
|
391
|
-
"vercel-marketplace-storage-redis",
|
|
392
|
-
"vercel-storage-migrations",
|
|
393
|
-
"vercel-ai-sdk-core",
|
|
394
|
-
"vercel-ai-sdk-ui",
|
|
395
|
-
"vercel-ai-gateway-core",
|
|
396
|
-
"vercel-ai-gateway-model-routing",
|
|
397
|
-
"vercel-ai-gateway-fallbacks",
|
|
398
|
-
"vercel-ai-gateway-auth-byok",
|
|
399
|
-
"vercel-ai-gateway-observability",
|
|
400
|
-
"vercel-ai-gateway-openai-compatible",
|
|
401
|
-
"vercel-agent-workflows",
|
|
402
|
-
"vercel-mcp-for-agents",
|
|
403
|
-
"vercel-flags-platform",
|
|
404
|
-
"vercel-flags-dashboard",
|
|
405
|
-
"vercel-flags-sdk",
|
|
406
|
-
"vercel-flags-openfeature",
|
|
407
|
-
"vercel-flags-explorer",
|
|
408
|
-
"vercel-flags-cli-workflows",
|
|
409
|
-
"vercel-observability-overview",
|
|
410
|
-
"vercel-runtime-logs",
|
|
411
|
-
"vercel-tracing-otel",
|
|
412
|
-
"vercel-session-tracing",
|
|
413
|
-
"vercel-alerts-monitoring",
|
|
414
|
-
"vercel-drains-setup",
|
|
415
|
-
"vercel-log-drain-reference",
|
|
416
|
-
"vercel-log-trace-correlation",
|
|
417
|
-
"vercel-speed-insights",
|
|
418
|
-
"vercel-web-analytics",
|
|
419
|
-
"vercel-custom-events",
|
|
420
|
-
"vercel-deployment-protection",
|
|
421
|
-
"vercel-protection-bypass-automation",
|
|
422
|
-
"vercel-firewall-core",
|
|
423
|
-
"vercel-waf-custom-rules",
|
|
424
|
-
"vercel-waf-rate-limiting",
|
|
425
|
-
"vercel-bot-management",
|
|
426
|
-
"vercel-botid",
|
|
427
|
-
"vercel-secure-compute",
|
|
428
|
-
"vercel-static-ips",
|
|
429
|
-
"vercel-oidc-federation",
|
|
430
|
-
"vercel-rbac-access-groups",
|
|
431
|
-
"vercel-audit-logs",
|
|
432
|
-
"vercel-2fa-enforcement",
|
|
433
265
|
"vercel-domains",
|
|
434
|
-
"vercel-dns-records",
|
|
435
|
-
"vercel-nameservers",
|
|
436
|
-
"vercel-ssl-certificates",
|
|
437
|
-
"vercel-domain-ownership-claims",
|
|
438
|
-
"vercel-cli-core",
|
|
439
|
-
"vercel-cli-project-domain-env",
|
|
440
|
-
"vercel-cli-flags",
|
|
441
|
-
"vercel-cli-microfrontends",
|
|
442
|
-
"vercel-cli-mcp",
|
|
443
|
-
"vercel-rest-api",
|
|
444
|
-
"vercel-sdk",
|
|
445
|
-
"vercel-integrations-native",
|
|
446
|
-
"vercel-marketplace-partner-api",
|
|
447
|
-
"vercel-webhooks-and-checks",
|
|
448
266
|
"drift-flutter",
|
|
449
267
|
"database-design",
|
|
450
268
|
"database-optimizer"
|
|
@@ -583,98 +401,7 @@
|
|
|
583
401
|
"testing-patterns",
|
|
584
402
|
"vulnerability-scanner",
|
|
585
403
|
"web-design-guidelines",
|
|
586
|
-
"vercel-automation",
|
|
587
|
-
"vercel-project-configuration",
|
|
588
|
-
"vercel-git-deployments",
|
|
589
|
-
"vercel-environments",
|
|
590
|
-
"vercel-generated-urls",
|
|
591
|
-
"vercel-deployment-promotion",
|
|
592
|
-
"vercel-build-pipeline",
|
|
593
|
-
"vercel-build-image-upgrades",
|
|
594
|
-
"vercel-build-output-api",
|
|
595
|
-
"vercel-monorepos",
|
|
596
|
-
"vercel-remote-caching",
|
|
597
|
-
"vercel-microfrontends",
|
|
598
|
-
"vercel-multi-tenant",
|
|
599
|
-
"vercel-functions-core",
|
|
600
|
-
"vercel-fluid-compute",
|
|
601
|
-
"vercel-functions-nodejs",
|
|
602
|
-
"vercel-functions-python",
|
|
603
|
-
"vercel-functions-edge-runtime",
|
|
604
|
-
"vercel-edge-to-node-migration",
|
|
605
|
-
"vercel-routing-middleware",
|
|
606
|
-
"vercel-function-config",
|
|
607
|
-
"vercel-runtime-cache",
|
|
608
|
-
"vercel-data-cache-nextjs",
|
|
609
|
-
"vercel-cron-jobs",
|
|
610
|
-
"vercel-og-image-generation",
|
|
611
|
-
"vercel-cdn-cache",
|
|
612
|
-
"vercel-cache-control-headers",
|
|
613
|
-
"vercel-isr",
|
|
614
|
-
"vercel-image-optimization",
|
|
615
|
-
"vercel-request-collapsing",
|
|
616
|
-
"vercel-redirects-rewrites",
|
|
617
|
-
"vercel-cdn-purging",
|
|
618
|
-
"vercel-blob",
|
|
619
|
-
"vercel-edge-config",
|
|
620
|
-
"vercel-edge-config-integrations",
|
|
621
|
-
"vercel-marketplace-storage-redis",
|
|
622
|
-
"vercel-storage-migrations",
|
|
623
|
-
"vercel-ai-sdk-core",
|
|
624
|
-
"vercel-ai-sdk-ui",
|
|
625
|
-
"vercel-ai-gateway-core",
|
|
626
|
-
"vercel-ai-gateway-model-routing",
|
|
627
|
-
"vercel-ai-gateway-fallbacks",
|
|
628
|
-
"vercel-ai-gateway-auth-byok",
|
|
629
|
-
"vercel-ai-gateway-observability",
|
|
630
|
-
"vercel-ai-gateway-openai-compatible",
|
|
631
|
-
"vercel-agent-workflows",
|
|
632
|
-
"vercel-mcp-for-agents",
|
|
633
|
-
"vercel-flags-platform",
|
|
634
|
-
"vercel-flags-dashboard",
|
|
635
|
-
"vercel-flags-sdk",
|
|
636
|
-
"vercel-flags-openfeature",
|
|
637
|
-
"vercel-flags-explorer",
|
|
638
|
-
"vercel-flags-cli-workflows",
|
|
639
|
-
"vercel-observability-overview",
|
|
640
|
-
"vercel-runtime-logs",
|
|
641
|
-
"vercel-tracing-otel",
|
|
642
|
-
"vercel-session-tracing",
|
|
643
|
-
"vercel-alerts-monitoring",
|
|
644
|
-
"vercel-drains-setup",
|
|
645
|
-
"vercel-log-drain-reference",
|
|
646
|
-
"vercel-log-trace-correlation",
|
|
647
|
-
"vercel-speed-insights",
|
|
648
|
-
"vercel-web-analytics",
|
|
649
|
-
"vercel-custom-events",
|
|
650
|
-
"vercel-deployment-protection",
|
|
651
|
-
"vercel-protection-bypass-automation",
|
|
652
|
-
"vercel-firewall-core",
|
|
653
|
-
"vercel-waf-custom-rules",
|
|
654
|
-
"vercel-waf-rate-limiting",
|
|
655
|
-
"vercel-bot-management",
|
|
656
|
-
"vercel-botid",
|
|
657
|
-
"vercel-secure-compute",
|
|
658
|
-
"vercel-static-ips",
|
|
659
|
-
"vercel-oidc-federation",
|
|
660
|
-
"vercel-rbac-access-groups",
|
|
661
|
-
"vercel-audit-logs",
|
|
662
|
-
"vercel-2fa-enforcement",
|
|
663
404
|
"vercel-domains",
|
|
664
|
-
"vercel-dns-records",
|
|
665
|
-
"vercel-nameservers",
|
|
666
|
-
"vercel-ssl-certificates",
|
|
667
|
-
"vercel-domain-ownership-claims",
|
|
668
|
-
"vercel-cli-core",
|
|
669
|
-
"vercel-cli-project-domain-env",
|
|
670
|
-
"vercel-cli-flags",
|
|
671
|
-
"vercel-cli-microfrontends",
|
|
672
|
-
"vercel-cli-mcp",
|
|
673
|
-
"vercel-rest-api",
|
|
674
|
-
"vercel-sdk",
|
|
675
|
-
"vercel-integrations-native",
|
|
676
|
-
"vercel-marketplace-partner-api",
|
|
677
|
-
"vercel-webhooks-and-checks",
|
|
678
405
|
"drift-flutter",
|
|
679
406
|
"database-design",
|
|
680
407
|
"database-optimizer"
|
|
@@ -3,7 +3,7 @@ name: backend-specialist
|
|
|
3
3
|
description: Expert backend architect for Node.js, Python, and modern serverless/edge systems. Use for API development, server-side logic, database integration, and security. Triggers on backend, server, api, endpoint, database, auth.
|
|
4
4
|
tools: Read, Grep, Glob, Bash, Edit, Write
|
|
5
5
|
model: inherit
|
|
6
|
-
skills: clean-code, nodejs-best-practices, python-patterns, api-patterns, database-design, database-optimizer, database-skills, mcp-builder, lint-and-validate, powershell-windows, bash-linux, rust-pro, api-designer, architecture-designer, typescript-pro, nestjs-expert, fastapi-expert, secure-code-guardian, test-master
|
|
6
|
+
skills: clean-code, nodejs-best-practices, python-patterns, api-patterns, openapi-docs, database-design, database-optimizer, database-skills, mcp-builder, lint-and-validate, powershell-windows, bash-linux, rust-pro, api-designer, architecture-designer, typescript-pro, nestjs-expert, fastapi-expert, secure-code-guardian, test-master
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Backend Development Architect
|
|
@@ -14,4 +14,14 @@ Use this workflow when backend architecture or implementation is primary.
|
|
|
14
14
|
1. Ask `@backend-specialist` for solution outline.
|
|
15
15
|
2. Validate API contracts, data model, and failure handling.
|
|
16
16
|
3. Implement backend changes with tests and observability.
|
|
17
|
-
4.
|
|
17
|
+
4. Always update API docs: OpenAPI spec, Swagger UI route, and Stoplight Elements route/component.
|
|
18
|
+
5. Return summary including migration and rollout notes.
|
|
19
|
+
|
|
20
|
+
## Output Contract
|
|
21
|
+
- API/contract changes
|
|
22
|
+
- OpenAPI spec path
|
|
23
|
+
- Swagger UI route
|
|
24
|
+
- Stoplight route/component status
|
|
25
|
+
- Migration impact
|
|
26
|
+
- Reliability/security notes
|
|
27
|
+
- Verification evidence
|
|
@@ -3,7 +3,7 @@ name: backend-specialist
|
|
|
3
3
|
description: Expert backend architect for Node.js, Python, and modern serverless/edge systems. Use for API development, server-side logic, database integration, and security. Triggers on backend, server, api, endpoint, database, auth.
|
|
4
4
|
tools: Read, Grep, Glob, Bash, Edit, Write
|
|
5
5
|
model: inherit
|
|
6
|
-
skills: clean-code, nodejs-best-practices, python-patterns, api-patterns, database-design, database-optimizer, database-skills, mcp-builder, lint-and-validate, powershell-windows, bash-linux, rust-pro, api-designer, architecture-designer, typescript-pro, nestjs-expert, fastapi-expert, secure-code-guardian, test-master
|
|
6
|
+
skills: clean-code, nodejs-best-practices, python-patterns, api-patterns, openapi-docs, database-design, database-optimizer, database-skills, mcp-builder, lint-and-validate, powershell-windows, bash-linux, rust-pro, api-designer, architecture-designer, typescript-pro, nestjs-expert, fastapi-expert, secure-code-guardian, test-master
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Backend Development Architect
|
package/Ai Agent Workflow/workflows/agent-environment-setup/platforms/codex/workflows/backend.md
CHANGED
|
@@ -16,10 +16,14 @@ Use this when backend architecture or service logic is primary.
|
|
|
16
16
|
1. Ask specialist(s) for design and risk assessment.
|
|
17
17
|
2. Validate contracts, data model, and failure handling.
|
|
18
18
|
3. Implement backend changes with observability.
|
|
19
|
-
4.
|
|
19
|
+
4. Always update API docs: OpenAPI spec, Swagger UI route, and Stoplight Elements route/component.
|
|
20
|
+
5. Run targeted tests and summarize rollout notes.
|
|
20
21
|
|
|
21
22
|
## Output Contract
|
|
22
23
|
- API/contract changes
|
|
24
|
+
- OpenAPI spec path
|
|
25
|
+
- Swagger UI route
|
|
26
|
+
- Stoplight route/component status
|
|
23
27
|
- Migration impact
|
|
24
28
|
- Reliability/security notes
|
|
25
29
|
- Verification evidence
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: backend-specialist
|
|
3
3
|
description: Expert backend architect for Node.js, Python, and modern serverless/edge systems. Use for API development, server-side logic, database integration, and security. Triggers on backend, server, api, endpoint, database, auth.
|
|
4
4
|
tools: Read, Grep, Glob, Bash, Edit, Write
|
|
5
|
-
skills: clean-code, nodejs-best-practices, python-patterns, api-patterns, database-design, database-optimizer, database-skills, mcp-builder, lint-and-validate, powershell-windows, bash-linux, rust-pro, api-designer, architecture-designer, typescript-pro, nestjs-expert, fastapi-expert, secure-code-guardian, test-master
|
|
5
|
+
skills: clean-code, nodejs-best-practices, python-patterns, api-patterns, openapi-docs, database-design, database-optimizer, database-skills, mcp-builder, lint-and-validate, powershell-windows, bash-linux, rust-pro, api-designer, architecture-designer, typescript-pro, nestjs-expert, fastapi-expert, secure-code-guardian, test-master
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Backend Development Architect
|
package/Ai Agent Workflow/workflows/agent-environment-setup/platforms/copilot/workflows/backend.md
CHANGED
|
@@ -16,10 +16,14 @@ Use this when backend architecture or service logic is primary.
|
|
|
16
16
|
1. Ask specialist(s) for design and risk assessment.
|
|
17
17
|
2. Validate contracts, data model, and failure handling.
|
|
18
18
|
3. Implement backend changes with observability.
|
|
19
|
-
4.
|
|
19
|
+
4. Always update API docs: OpenAPI spec, Swagger UI route, and Stoplight Elements route/component.
|
|
20
|
+
5. Run targeted tests and summarize rollout notes.
|
|
20
21
|
|
|
21
22
|
## Output Contract
|
|
22
23
|
- API/contract changes
|
|
24
|
+
- OpenAPI spec path
|
|
25
|
+
- Swagger UI route
|
|
26
|
+
- Stoplight route/component status
|
|
23
27
|
- Migration impact
|
|
24
28
|
- Reliability/security notes
|
|
25
29
|
- Verification evidence
|
package/README.md
CHANGED
|
@@ -34,8 +34,15 @@ cbx workflows doctor codex
|
|
|
34
34
|
cbx workflows platforms
|
|
35
35
|
cbx workflows install --platform antigravity --dry-run
|
|
36
36
|
cbx workflows install --platform antigravity --terminal-integration --terminal-verifier codex
|
|
37
|
+
cbx workflows install --platform codex --postman
|
|
38
|
+
cbx workflows install --platform codex --postman --postman-workspace-id null
|
|
37
39
|
```
|
|
38
40
|
|
|
41
|
+
Install bootstrap behavior:
|
|
42
|
+
- `cbx workflows install` now also bootstraps `ENGINEERING_RULES.md` and `TECH.md` (creates when missing; keeps existing files unless explicitly regenerated).
|
|
43
|
+
- Optional `--postman` bootstrap creates `postman_setting.json` and installs/configures the Postman skill.
|
|
44
|
+
- Use `cbx rules init --platform <platform> --overwrite` to force-regenerate both files.
|
|
45
|
+
|
|
39
46
|
`rules` manages strict engineering policy and a generated codebase tech map:
|
|
40
47
|
|
|
41
48
|
```bash
|
|
@@ -108,6 +115,7 @@ Routing behavior:
|
|
|
108
115
|
- Antigravity/Copilot: workflow + agent markdown can be routed by platform conventions.
|
|
109
116
|
- Codex: use generated callable wrapper skills (`$workflow-*`, `$agent-*`).
|
|
110
117
|
- Example for backend intent in Codex: `$workflow-backend` or `$agent-backend-specialist`.
|
|
118
|
+
- Backend workflow policy: always include OpenAPI updates plus Swagger UI and Stoplight Elements status in output.
|
|
111
119
|
|
|
112
120
|
### Codex Runtime Mode
|
|
113
121
|
|
package/bin/cubis.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { confirm, select } from "@inquirer/prompts";
|
|
3
|
+
import { confirm, input, select } from "@inquirer/prompts";
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
6
|
import {
|
|
@@ -122,6 +122,12 @@ const CODEX_WORKFLOW_SKILL_PREFIX = "workflow-";
|
|
|
122
122
|
const CODEX_AGENT_SKILL_PREFIX = "agent-";
|
|
123
123
|
const TERMINAL_VERIFIER_PROVIDERS = ["codex", "gemini"];
|
|
124
124
|
const DEFAULT_TERMINAL_VERIFIER = "codex";
|
|
125
|
+
const POSTMAN_API_KEY_ENV_VAR = "POSTMAN_API_KEY";
|
|
126
|
+
const POSTMAN_MCP_URL = "https://mcp.postman.com/minimal";
|
|
127
|
+
const POSTMAN_SKILL_ID = "postman";
|
|
128
|
+
const POSTMAN_SETTINGS_FILENAME = "postman_setting.json";
|
|
129
|
+
const POSTMAN_API_KEY_MISSING_WARNING =
|
|
130
|
+
`Postman API key is not configured. Set ${POSTMAN_API_KEY_ENV_VAR} or update ${POSTMAN_SETTINGS_FILENAME}.`;
|
|
125
131
|
const TECH_SCAN_MAX_FILES = 5000;
|
|
126
132
|
const TECH_SCAN_IGNORED_DIRS = new Set([
|
|
127
133
|
".git",
|
|
@@ -231,6 +237,13 @@ function normalizeTerminalVerifier(value) {
|
|
|
231
237
|
return TERMINAL_VERIFIER_ALIASES[normalized] || null;
|
|
232
238
|
}
|
|
233
239
|
|
|
240
|
+
function normalizePostmanWorkspaceId(value) {
|
|
241
|
+
if (value === undefined || value === null) return null;
|
|
242
|
+
const normalized = String(value).trim();
|
|
243
|
+
if (!normalized || normalized.toLowerCase() === "null") return null;
|
|
244
|
+
return normalized;
|
|
245
|
+
}
|
|
246
|
+
|
|
234
247
|
function defaultState() {
|
|
235
248
|
return {
|
|
236
249
|
schemaVersion: 1,
|
|
@@ -1872,6 +1885,237 @@ async function writeGeneratedArtifact({ destination, content, dryRun = false })
|
|
|
1872
1885
|
return { action: exists ? "replaced" : "installed", path: destination };
|
|
1873
1886
|
}
|
|
1874
1887
|
|
|
1888
|
+
function resolvePostmanSettingsPath({ scope, cwd = process.cwd() }) {
|
|
1889
|
+
if (scope === "global") {
|
|
1890
|
+
return path.join(os.homedir(), ".cbx", POSTMAN_SETTINGS_FILENAME);
|
|
1891
|
+
}
|
|
1892
|
+
const workspaceRoot = findWorkspaceRoot(cwd);
|
|
1893
|
+
return path.join(workspaceRoot, POSTMAN_SETTINGS_FILENAME);
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
function buildPostmanMcpConfig({ apiKey = null, mcpUrl = POSTMAN_MCP_URL }) {
|
|
1897
|
+
const authHeader = apiKey
|
|
1898
|
+
? `Bearer ${apiKey}`
|
|
1899
|
+
: `Bearer \${${POSTMAN_API_KEY_ENV_VAR}}`;
|
|
1900
|
+
return {
|
|
1901
|
+
mcpServers: {
|
|
1902
|
+
postman: {
|
|
1903
|
+
url: mcpUrl,
|
|
1904
|
+
headers: {
|
|
1905
|
+
Authorization: authHeader
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
},
|
|
1909
|
+
disabled: false
|
|
1910
|
+
};
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
function getPostmanApiKeySource({ apiKey, envApiKey }) {
|
|
1914
|
+
if (apiKey) return "inline";
|
|
1915
|
+
if (envApiKey) return "env";
|
|
1916
|
+
return "unset";
|
|
1917
|
+
}
|
|
1918
|
+
|
|
1919
|
+
function normalizePostmanApiKey(value) {
|
|
1920
|
+
if (value === undefined || value === null) return null;
|
|
1921
|
+
const normalized = String(value).trim();
|
|
1922
|
+
return normalized || null;
|
|
1923
|
+
}
|
|
1924
|
+
|
|
1925
|
+
async function ensureGitIgnoreEntry({
|
|
1926
|
+
filePath,
|
|
1927
|
+
entry,
|
|
1928
|
+
dryRun = false
|
|
1929
|
+
}) {
|
|
1930
|
+
const exists = await pathExists(filePath);
|
|
1931
|
+
const original = exists ? await readFile(filePath, "utf8") : "";
|
|
1932
|
+
const lines = original.split(/\r?\n/).map((line) => line.trim());
|
|
1933
|
+
const alreadyPresent = lines.includes(entry);
|
|
1934
|
+
|
|
1935
|
+
if (alreadyPresent) {
|
|
1936
|
+
return { action: "unchanged", filePath };
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1939
|
+
if (dryRun) {
|
|
1940
|
+
return {
|
|
1941
|
+
action: exists ? "would-patch" : "would-create",
|
|
1942
|
+
filePath
|
|
1943
|
+
};
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
const suffix = original.endsWith("\n") || original.length === 0 ? "" : "\n";
|
|
1947
|
+
const nextContent = `${original}${suffix}${entry}\n`;
|
|
1948
|
+
await mkdir(path.dirname(filePath), { recursive: true });
|
|
1949
|
+
await writeFile(filePath, nextContent, "utf8");
|
|
1950
|
+
return {
|
|
1951
|
+
action: exists ? "patched" : "created",
|
|
1952
|
+
filePath
|
|
1953
|
+
};
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1956
|
+
async function resolvePostmanInstallSelection({
|
|
1957
|
+
scope,
|
|
1958
|
+
options,
|
|
1959
|
+
cwd = process.cwd()
|
|
1960
|
+
}) {
|
|
1961
|
+
const hasApiKeyOption = options.postmanApiKey !== undefined;
|
|
1962
|
+
const hasWorkspaceOption = options.postmanWorkspaceId !== undefined;
|
|
1963
|
+
const enabled = Boolean(options.postman) || hasApiKeyOption || hasWorkspaceOption;
|
|
1964
|
+
if (!enabled) return { enabled: false };
|
|
1965
|
+
|
|
1966
|
+
const explicitApiKey = hasApiKeyOption ? String(options.postmanApiKey || "").trim() : "";
|
|
1967
|
+
let apiKey = explicitApiKey || null;
|
|
1968
|
+
const envApiKey = String(process.env[POSTMAN_API_KEY_ENV_VAR] || "").trim();
|
|
1969
|
+
let defaultWorkspaceId = hasWorkspaceOption
|
|
1970
|
+
? normalizePostmanWorkspaceId(options.postmanWorkspaceId)
|
|
1971
|
+
: null;
|
|
1972
|
+
const warnings = [];
|
|
1973
|
+
|
|
1974
|
+
const canPrompt = !options.yes && process.stdin.isTTY;
|
|
1975
|
+
if (canPrompt && !hasApiKeyOption && !apiKey && !envApiKey) {
|
|
1976
|
+
const promptedApiKey = String(
|
|
1977
|
+
await input({
|
|
1978
|
+
message: `Postman API key (optional, leave blank to keep ${POSTMAN_API_KEY_ENV_VAR} env mode):`,
|
|
1979
|
+
default: ""
|
|
1980
|
+
})
|
|
1981
|
+
).trim();
|
|
1982
|
+
if (promptedApiKey) {
|
|
1983
|
+
apiKey = promptedApiKey;
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
|
|
1987
|
+
if (canPrompt && !hasWorkspaceOption) {
|
|
1988
|
+
const promptedWorkspaceId = await input({
|
|
1989
|
+
message: "Default Postman workspace ID (optional, leave blank for null):",
|
|
1990
|
+
default: ""
|
|
1991
|
+
});
|
|
1992
|
+
defaultWorkspaceId = normalizePostmanWorkspaceId(promptedWorkspaceId);
|
|
1993
|
+
}
|
|
1994
|
+
|
|
1995
|
+
const apiKeySource = getPostmanApiKeySource({ apiKey, envApiKey });
|
|
1996
|
+
if (apiKeySource === "unset") {
|
|
1997
|
+
warnings.push(POSTMAN_API_KEY_MISSING_WARNING);
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
const settingsPath = resolvePostmanSettingsPath({ scope, cwd });
|
|
2001
|
+
const settings = {
|
|
2002
|
+
apiKey: apiKey || null,
|
|
2003
|
+
apiKeyEnvVar: POSTMAN_API_KEY_ENV_VAR,
|
|
2004
|
+
apiKeySource,
|
|
2005
|
+
defaultWorkspaceId: defaultWorkspaceId ?? null,
|
|
2006
|
+
mcpUrl: POSTMAN_MCP_URL,
|
|
2007
|
+
generatedBy: "cbx workflows install --postman",
|
|
2008
|
+
generatedAt: new Date().toISOString()
|
|
2009
|
+
};
|
|
2010
|
+
|
|
2011
|
+
return {
|
|
2012
|
+
enabled: true,
|
|
2013
|
+
apiKey,
|
|
2014
|
+
apiKeySource,
|
|
2015
|
+
defaultWorkspaceId: defaultWorkspaceId ?? null,
|
|
2016
|
+
warnings,
|
|
2017
|
+
settings,
|
|
2018
|
+
settingsPath
|
|
2019
|
+
};
|
|
2020
|
+
}
|
|
2021
|
+
|
|
2022
|
+
async function configurePostmanInstallArtifacts({
|
|
2023
|
+
scope,
|
|
2024
|
+
profilePaths,
|
|
2025
|
+
postmanSelection,
|
|
2026
|
+
overwrite = false,
|
|
2027
|
+
dryRun = false,
|
|
2028
|
+
cwd = process.cwd()
|
|
2029
|
+
}) {
|
|
2030
|
+
if (!postmanSelection?.enabled) return null;
|
|
2031
|
+
|
|
2032
|
+
let warnings = postmanSelection.warnings.filter((warning) => warning !== POSTMAN_API_KEY_MISSING_WARNING);
|
|
2033
|
+
const settingsContent = `${JSON.stringify(postmanSelection.settings, null, 2)}\n`;
|
|
2034
|
+
const settingsResult = await writeTextFile({
|
|
2035
|
+
targetPath: postmanSelection.settingsPath,
|
|
2036
|
+
content: settingsContent,
|
|
2037
|
+
overwrite,
|
|
2038
|
+
dryRun
|
|
2039
|
+
});
|
|
2040
|
+
|
|
2041
|
+
let effectiveApiKey = normalizePostmanApiKey(postmanSelection.settings.apiKey);
|
|
2042
|
+
let effectiveDefaultWorkspaceId = postmanSelection.defaultWorkspaceId ?? null;
|
|
2043
|
+
let effectiveMcpUrl = postmanSelection.settings.mcpUrl || POSTMAN_MCP_URL;
|
|
2044
|
+
|
|
2045
|
+
if (settingsResult.action === "skipped" || settingsResult.action === "would-skip") {
|
|
2046
|
+
try {
|
|
2047
|
+
const existingSettingsRaw = await readFile(postmanSelection.settingsPath, "utf8");
|
|
2048
|
+
const existingSettings = JSON.parse(existingSettingsRaw);
|
|
2049
|
+
effectiveApiKey = normalizePostmanApiKey(existingSettings?.apiKey);
|
|
2050
|
+
effectiveDefaultWorkspaceId = normalizePostmanWorkspaceId(existingSettings?.defaultWorkspaceId);
|
|
2051
|
+
const existingMcpUrl = String(existingSettings?.mcpUrl || "").trim();
|
|
2052
|
+
if (existingMcpUrl) {
|
|
2053
|
+
effectiveMcpUrl = existingMcpUrl;
|
|
2054
|
+
}
|
|
2055
|
+
} catch {
|
|
2056
|
+
warnings.push(
|
|
2057
|
+
`Existing ${POSTMAN_SETTINGS_FILENAME} could not be parsed. Using install-time Postman values for MCP config.`
|
|
2058
|
+
);
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
|
|
2062
|
+
const envApiKey = normalizePostmanApiKey(process.env[POSTMAN_API_KEY_ENV_VAR]);
|
|
2063
|
+
const effectiveApiKeySource = getPostmanApiKeySource({
|
|
2064
|
+
apiKey: effectiveApiKey,
|
|
2065
|
+
envApiKey
|
|
2066
|
+
});
|
|
2067
|
+
if (effectiveApiKeySource === "unset") {
|
|
2068
|
+
warnings.push(POSTMAN_API_KEY_MISSING_WARNING);
|
|
2069
|
+
}
|
|
2070
|
+
|
|
2071
|
+
let gitIgnoreResult = null;
|
|
2072
|
+
if (scope === "project") {
|
|
2073
|
+
const workspaceRoot = findWorkspaceRoot(cwd);
|
|
2074
|
+
const gitIgnorePath = path.join(workspaceRoot, ".gitignore");
|
|
2075
|
+
gitIgnoreResult = await ensureGitIgnoreEntry({
|
|
2076
|
+
filePath: gitIgnorePath,
|
|
2077
|
+
entry: POSTMAN_SETTINGS_FILENAME,
|
|
2078
|
+
dryRun
|
|
2079
|
+
});
|
|
2080
|
+
}
|
|
2081
|
+
|
|
2082
|
+
const postmanSkillDir = path.join(profilePaths.skillsDir, POSTMAN_SKILL_ID);
|
|
2083
|
+
const postmanMcpPath = path.join(postmanSkillDir, "mcp.json");
|
|
2084
|
+
let mcpResult = null;
|
|
2085
|
+
const postmanSkillExists = await pathExists(postmanSkillDir);
|
|
2086
|
+
if (!dryRun && !postmanSkillExists) {
|
|
2087
|
+
mcpResult = {
|
|
2088
|
+
action: "missing-postman-skill",
|
|
2089
|
+
path: postmanMcpPath
|
|
2090
|
+
};
|
|
2091
|
+
} else {
|
|
2092
|
+
const mcpConfigContent = `${JSON.stringify(
|
|
2093
|
+
buildPostmanMcpConfig({
|
|
2094
|
+
apiKey: effectiveApiKey,
|
|
2095
|
+
mcpUrl: effectiveMcpUrl
|
|
2096
|
+
}),
|
|
2097
|
+
null,
|
|
2098
|
+
2
|
|
2099
|
+
)}\n`;
|
|
2100
|
+
mcpResult = await writeGeneratedArtifact({
|
|
2101
|
+
destination: postmanMcpPath,
|
|
2102
|
+
content: mcpConfigContent,
|
|
2103
|
+
dryRun
|
|
2104
|
+
});
|
|
2105
|
+
}
|
|
2106
|
+
|
|
2107
|
+
return {
|
|
2108
|
+
enabled: true,
|
|
2109
|
+
apiKeySource: effectiveApiKeySource,
|
|
2110
|
+
defaultWorkspaceId: effectiveDefaultWorkspaceId,
|
|
2111
|
+
warnings,
|
|
2112
|
+
settingsPath: postmanSelection.settingsPath,
|
|
2113
|
+
settingsResult,
|
|
2114
|
+
gitIgnoreResult,
|
|
2115
|
+
mcpResult
|
|
2116
|
+
};
|
|
2117
|
+
}
|
|
2118
|
+
|
|
1875
2119
|
async function installAntigravityTerminalIntegrationArtifacts({
|
|
1876
2120
|
profilePaths,
|
|
1877
2121
|
provider,
|
|
@@ -2032,6 +2276,7 @@ async function installBundleArtifacts({
|
|
|
2032
2276
|
platform,
|
|
2033
2277
|
scope,
|
|
2034
2278
|
overwrite,
|
|
2279
|
+
extraSkillIds = [],
|
|
2035
2280
|
terminalVerifierSelection = null,
|
|
2036
2281
|
dryRun = false,
|
|
2037
2282
|
cwd = process.cwd()
|
|
@@ -2092,7 +2337,8 @@ async function installBundleArtifacts({
|
|
|
2092
2337
|
else installed.push(destination);
|
|
2093
2338
|
}
|
|
2094
2339
|
|
|
2095
|
-
const
|
|
2340
|
+
const manifestSkillIds = Array.isArray(platformSpec.skills) ? platformSpec.skills : [];
|
|
2341
|
+
const skillIds = unique([...manifestSkillIds, ...extraSkillIds.filter(Boolean)]);
|
|
2096
2342
|
for (const skillId of skillIds) {
|
|
2097
2343
|
const source = path.join(agentAssetsRoot(), "skills", skillId);
|
|
2098
2344
|
const destination = path.join(profilePaths.skillsDir, skillId);
|
|
@@ -2389,6 +2635,32 @@ function printInstallSummary({
|
|
|
2389
2635
|
}
|
|
2390
2636
|
}
|
|
2391
2637
|
|
|
2638
|
+
function printPostmanSetupSummary({ postmanSetup }) {
|
|
2639
|
+
if (!postmanSetup?.enabled) return;
|
|
2640
|
+
|
|
2641
|
+
console.log("\nPostman setup:");
|
|
2642
|
+
console.log(`- Settings file: ${postmanSetup.settingsResult.action} (${postmanSetup.settingsPath})`);
|
|
2643
|
+
console.log(`- API key source: ${postmanSetup.apiKeySource}`);
|
|
2644
|
+
console.log(
|
|
2645
|
+
`- Default workspace ID: ${postmanSetup.defaultWorkspaceId === null ? "null" : postmanSetup.defaultWorkspaceId}`
|
|
2646
|
+
);
|
|
2647
|
+
if (postmanSetup.gitIgnoreResult) {
|
|
2648
|
+
console.log(
|
|
2649
|
+
`- .gitignore (${postmanSetup.gitIgnoreResult.filePath}): ${postmanSetup.gitIgnoreResult.action}`
|
|
2650
|
+
);
|
|
2651
|
+
}
|
|
2652
|
+
if (postmanSetup.mcpResult) {
|
|
2653
|
+
console.log(`- Postman MCP config (${postmanSetup.mcpResult.path}): ${postmanSetup.mcpResult.action}`);
|
|
2654
|
+
}
|
|
2655
|
+
|
|
2656
|
+
if (postmanSetup.warnings.length > 0) {
|
|
2657
|
+
console.log("- Warnings:");
|
|
2658
|
+
for (const warning of postmanSetup.warnings) {
|
|
2659
|
+
console.log(` - ${warning}`);
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
|
|
2392
2664
|
function printRemoveSummary({
|
|
2393
2665
|
platform,
|
|
2394
2666
|
scope,
|
|
@@ -2694,6 +2966,18 @@ function withInstallOptions(command) {
|
|
|
2694
2966
|
return withWorkflowBaseOptions(command)
|
|
2695
2967
|
.option("-b, --bundle <bundle>", "bundle id (default: agent-environment-setup)")
|
|
2696
2968
|
.option("--overwrite", "overwrite existing files")
|
|
2969
|
+
.option(
|
|
2970
|
+
"--postman",
|
|
2971
|
+
"optional: install Postman skill and generate postman_setting.json"
|
|
2972
|
+
)
|
|
2973
|
+
.option(
|
|
2974
|
+
"--postman-api-key <key>",
|
|
2975
|
+
"optional: set Postman API key inline for generated postman_setting.json and installed Postman MCP config"
|
|
2976
|
+
)
|
|
2977
|
+
.option(
|
|
2978
|
+
"--postman-workspace-id <id|null>",
|
|
2979
|
+
"optional: set default Postman workspace ID (use 'null' for no default)"
|
|
2980
|
+
)
|
|
2697
2981
|
.option(
|
|
2698
2982
|
"--terminal-integration",
|
|
2699
2983
|
"Antigravity only: enable terminal verification integration (prompts for verifier when interactive)"
|
|
@@ -2854,6 +3138,11 @@ async function runWorkflowInstall(options) {
|
|
|
2854
3138
|
platform,
|
|
2855
3139
|
options
|
|
2856
3140
|
});
|
|
3141
|
+
const postmanSelection = await resolvePostmanInstallSelection({
|
|
3142
|
+
scope,
|
|
3143
|
+
options,
|
|
3144
|
+
cwd: process.cwd()
|
|
3145
|
+
});
|
|
2857
3146
|
|
|
2858
3147
|
const installResult = await installBundleArtifacts({
|
|
2859
3148
|
bundleId,
|
|
@@ -2861,6 +3150,7 @@ async function runWorkflowInstall(options) {
|
|
|
2861
3150
|
platform,
|
|
2862
3151
|
scope,
|
|
2863
3152
|
overwrite: Boolean(options.overwrite),
|
|
3153
|
+
extraSkillIds: postmanSelection.enabled ? [POSTMAN_SKILL_ID] : [],
|
|
2864
3154
|
terminalVerifierSelection,
|
|
2865
3155
|
dryRun,
|
|
2866
3156
|
cwd: process.cwd()
|
|
@@ -2882,6 +3172,22 @@ async function runWorkflowInstall(options) {
|
|
|
2882
3172
|
dryRun,
|
|
2883
3173
|
cwd: process.cwd()
|
|
2884
3174
|
});
|
|
3175
|
+
const engineeringArtifactsResult = await upsertEngineeringArtifacts({
|
|
3176
|
+
platform,
|
|
3177
|
+
scope,
|
|
3178
|
+
overwrite: false,
|
|
3179
|
+
dryRun,
|
|
3180
|
+
skipTech: false,
|
|
3181
|
+
cwd: process.cwd()
|
|
3182
|
+
});
|
|
3183
|
+
const postmanSetupResult = await configurePostmanInstallArtifacts({
|
|
3184
|
+
scope,
|
|
3185
|
+
profilePaths: installResult.profilePaths,
|
|
3186
|
+
postmanSelection,
|
|
3187
|
+
overwrite: Boolean(options.overwrite),
|
|
3188
|
+
dryRun,
|
|
3189
|
+
cwd: process.cwd()
|
|
3190
|
+
});
|
|
2885
3191
|
|
|
2886
3192
|
const terminalVerificationRuleResult =
|
|
2887
3193
|
platform === "antigravity" && installResult.terminalIntegration
|
|
@@ -2918,6 +3224,13 @@ async function runWorkflowInstall(options) {
|
|
|
2918
3224
|
dryRun
|
|
2919
3225
|
});
|
|
2920
3226
|
printRuleSyncResult(syncResult);
|
|
3227
|
+
printInstallEngineeringSummary({
|
|
3228
|
+
engineeringResults: engineeringArtifactsResult.engineeringResults,
|
|
3229
|
+
techResult: engineeringArtifactsResult.techResult
|
|
3230
|
+
});
|
|
3231
|
+
printPostmanSetupSummary({
|
|
3232
|
+
postmanSetup: postmanSetupResult
|
|
3233
|
+
});
|
|
2921
3234
|
if (dryRun) {
|
|
2922
3235
|
console.log("\nDry-run complete. Re-run without `--dry-run` to apply changes.");
|
|
2923
3236
|
} else {
|
|
@@ -3128,6 +3441,94 @@ function printRulesInitSummary({
|
|
|
3128
3441
|
}
|
|
3129
3442
|
}
|
|
3130
3443
|
|
|
3444
|
+
function printInstallEngineeringSummary({ engineeringResults, techResult }) {
|
|
3445
|
+
console.log("\nEngineering artifacts:");
|
|
3446
|
+
for (const item of engineeringResults) {
|
|
3447
|
+
console.log(`- ENGINEERING_RULES.md: ${item.rulesFileResult.action} (${item.rulesFilePath})`);
|
|
3448
|
+
console.log(`- Managed engineering block (${item.ruleFilePath}): ${item.blockResult.action}`);
|
|
3449
|
+
if (item.blockResult.warnings.length > 0) {
|
|
3450
|
+
for (const warning of item.blockResult.warnings) {
|
|
3451
|
+
console.log(` - warning: ${warning}`);
|
|
3452
|
+
}
|
|
3453
|
+
}
|
|
3454
|
+
}
|
|
3455
|
+
|
|
3456
|
+
if (techResult) {
|
|
3457
|
+
console.log(`- TECH.md: ${techResult.action} (${techResult.filePath})`);
|
|
3458
|
+
console.log(`- TECH scan files: ${techResult.snapshot.scannedFiles}`);
|
|
3459
|
+
}
|
|
3460
|
+
}
|
|
3461
|
+
|
|
3462
|
+
async function upsertEngineeringArtifacts({
|
|
3463
|
+
platform,
|
|
3464
|
+
scope,
|
|
3465
|
+
overwrite = false,
|
|
3466
|
+
skipTech = false,
|
|
3467
|
+
dryRun = false,
|
|
3468
|
+
cwd = process.cwd()
|
|
3469
|
+
}) {
|
|
3470
|
+
const ruleFilePath = await resolveRuleFilePath(platform, scope, cwd);
|
|
3471
|
+
if (!ruleFilePath) throw new Error(`No rule file configured for platform '${platform}'.`);
|
|
3472
|
+
|
|
3473
|
+
const workspaceRoot = findWorkspaceRoot(cwd);
|
|
3474
|
+
const techMdPath = path.join(workspaceRoot, "TECH.md");
|
|
3475
|
+
const targets = [{ ruleFilePath }];
|
|
3476
|
+
|
|
3477
|
+
if (scope === "global") {
|
|
3478
|
+
const workspaceRuleFile = await resolveWorkspaceRuleFileForGlobalScope(platform, cwd);
|
|
3479
|
+
const globalRuleFile = expandPath(WORKFLOW_PROFILES[platform].global.ruleFilesByPriority[0], cwd);
|
|
3480
|
+
if (workspaceRuleFile && path.resolve(workspaceRuleFile) !== path.resolve(globalRuleFile)) {
|
|
3481
|
+
targets.push({ ruleFilePath: workspaceRuleFile });
|
|
3482
|
+
}
|
|
3483
|
+
}
|
|
3484
|
+
|
|
3485
|
+
const template = buildEngineeringRulesTemplate();
|
|
3486
|
+
const engineeringResults = [];
|
|
3487
|
+
for (const target of targets) {
|
|
3488
|
+
const rulesFilePath = path.join(path.dirname(target.ruleFilePath), "ENGINEERING_RULES.md");
|
|
3489
|
+
const rulesFileResult = await writeTextFile({
|
|
3490
|
+
targetPath: rulesFilePath,
|
|
3491
|
+
content: `${template}\n`,
|
|
3492
|
+
overwrite,
|
|
3493
|
+
dryRun
|
|
3494
|
+
});
|
|
3495
|
+
const blockResult = await upsertEngineeringRulesBlock({
|
|
3496
|
+
ruleFilePath: target.ruleFilePath,
|
|
3497
|
+
platform,
|
|
3498
|
+
engineeringRulesFilePath: rulesFilePath,
|
|
3499
|
+
techMdFilePath: techMdPath,
|
|
3500
|
+
dryRun
|
|
3501
|
+
});
|
|
3502
|
+
engineeringResults.push({
|
|
3503
|
+
ruleFilePath: target.ruleFilePath,
|
|
3504
|
+
rulesFilePath,
|
|
3505
|
+
rulesFileResult,
|
|
3506
|
+
blockResult
|
|
3507
|
+
});
|
|
3508
|
+
}
|
|
3509
|
+
|
|
3510
|
+
let techResult = null;
|
|
3511
|
+
if (!skipTech) {
|
|
3512
|
+
const snapshot = await collectTechSnapshot(workspaceRoot);
|
|
3513
|
+
const content = buildTechMd(snapshot);
|
|
3514
|
+
const fileResult = await writeTextFile({
|
|
3515
|
+
targetPath: techMdPath,
|
|
3516
|
+
content: `${content}\n`,
|
|
3517
|
+
overwrite,
|
|
3518
|
+
dryRun
|
|
3519
|
+
});
|
|
3520
|
+
techResult = {
|
|
3521
|
+
...fileResult,
|
|
3522
|
+
snapshot
|
|
3523
|
+
};
|
|
3524
|
+
}
|
|
3525
|
+
|
|
3526
|
+
return {
|
|
3527
|
+
engineeringResults,
|
|
3528
|
+
techResult
|
|
3529
|
+
};
|
|
3530
|
+
}
|
|
3531
|
+
|
|
3131
3532
|
async function runRulesInit(options) {
|
|
3132
3533
|
try {
|
|
3133
3534
|
const scope = normalizeScope(options.scope);
|
|
@@ -3135,68 +3536,21 @@ async function runRulesInit(options) {
|
|
|
3135
3536
|
const overwrite = Boolean(options.overwrite);
|
|
3136
3537
|
const cwd = process.cwd();
|
|
3137
3538
|
const platform = await resolvePlatform(options.platform, scope, cwd);
|
|
3138
|
-
const
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
const workspaceRuleFile = await resolveWorkspaceRuleFileForGlobalScope(platform, cwd);
|
|
3147
|
-
const globalRuleFile = expandPath(WORKFLOW_PROFILES[platform].global.ruleFilesByPriority[0], cwd);
|
|
3148
|
-
if (workspaceRuleFile && path.resolve(workspaceRuleFile) !== path.resolve(globalRuleFile)) {
|
|
3149
|
-
targets.push({ ruleFilePath: workspaceRuleFile });
|
|
3150
|
-
}
|
|
3151
|
-
}
|
|
3152
|
-
|
|
3153
|
-
const template = buildEngineeringRulesTemplate();
|
|
3154
|
-
const engineeringResults = [];
|
|
3155
|
-
for (const target of targets) {
|
|
3156
|
-
const rulesFilePath = path.join(path.dirname(target.ruleFilePath), "ENGINEERING_RULES.md");
|
|
3157
|
-
const rulesFileResult = await writeTextFile({
|
|
3158
|
-
targetPath: rulesFilePath,
|
|
3159
|
-
content: `${template}\n`,
|
|
3160
|
-
overwrite,
|
|
3161
|
-
dryRun
|
|
3162
|
-
});
|
|
3163
|
-
const blockResult = await upsertEngineeringRulesBlock({
|
|
3164
|
-
ruleFilePath: target.ruleFilePath,
|
|
3165
|
-
platform,
|
|
3166
|
-
engineeringRulesFilePath: rulesFilePath,
|
|
3167
|
-
techMdFilePath: techMdPath,
|
|
3168
|
-
dryRun
|
|
3169
|
-
});
|
|
3170
|
-
engineeringResults.push({
|
|
3171
|
-
ruleFilePath: target.ruleFilePath,
|
|
3172
|
-
rulesFilePath,
|
|
3173
|
-
rulesFileResult,
|
|
3174
|
-
blockResult
|
|
3175
|
-
});
|
|
3176
|
-
}
|
|
3177
|
-
|
|
3178
|
-
let techResult = null;
|
|
3179
|
-
if (!options.skipTech) {
|
|
3180
|
-
const snapshot = await collectTechSnapshot(workspaceRoot);
|
|
3181
|
-
const content = buildTechMd(snapshot);
|
|
3182
|
-
const fileResult = await writeTextFile({
|
|
3183
|
-
targetPath: techMdPath,
|
|
3184
|
-
content: `${content}\n`,
|
|
3185
|
-
overwrite,
|
|
3186
|
-
dryRun
|
|
3187
|
-
});
|
|
3188
|
-
techResult = {
|
|
3189
|
-
...fileResult,
|
|
3190
|
-
snapshot
|
|
3191
|
-
};
|
|
3192
|
-
}
|
|
3539
|
+
const initResult = await upsertEngineeringArtifacts({
|
|
3540
|
+
platform,
|
|
3541
|
+
scope,
|
|
3542
|
+
overwrite,
|
|
3543
|
+
skipTech: Boolean(options.skipTech),
|
|
3544
|
+
dryRun,
|
|
3545
|
+
cwd
|
|
3546
|
+
});
|
|
3193
3547
|
|
|
3194
3548
|
printRulesInitSummary({
|
|
3195
3549
|
platform,
|
|
3196
3550
|
scope,
|
|
3197
3551
|
dryRun,
|
|
3198
|
-
engineeringResults,
|
|
3199
|
-
techResult
|
|
3552
|
+
engineeringResults: initResult.engineeringResults,
|
|
3553
|
+
techResult: initResult.techResult
|
|
3200
3554
|
});
|
|
3201
3555
|
|
|
3202
3556
|
if (dryRun) {
|