@zweer/dev 1.2.0 → 1.3.0

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.
@@ -1,18 +1,20 @@
1
1
  import { Command } from '@commander-js/extra-typings';
2
2
  import { agentCommand } from './agent/index.js';
3
- import { initCommand } from './init.js';
4
3
  import { installCommand } from './install.js';
5
4
  import { launchCommand } from './launch.js';
6
5
  import { listCommand } from './list.js';
7
6
  import { serverCommand } from './server.js';
7
+ import { statusCommand } from './status.js';
8
8
  import { syncCommand } from './sync.js';
9
+ import { uninstallCommand } from './uninstall.js';
9
10
  export const caoCommand = new Command()
10
11
  .name('cao')
11
12
  .description('Manage CAO (CLI Agent Orchestrator) and agents')
12
- .addCommand(initCommand)
13
13
  .addCommand(agentCommand)
14
14
  .addCommand(installCommand)
15
+ .addCommand(uninstallCommand)
15
16
  .addCommand(syncCommand)
16
17
  .addCommand(serverCommand)
17
18
  .addCommand(launchCommand)
18
- .addCommand(listCommand);
19
+ .addCommand(listCommand)
20
+ .addCommand(statusCommand);
@@ -1,4 +1,6 @@
1
1
  import { Command } from '@commander-js/extra-typings';
2
2
  import { type Agent } from '../../utils/agents.js';
3
3
  export declare function groupAgentsByCategory(agents: Agent[]): Record<string, Agent[]>;
4
- export declare const listCommand: Command<[], {}>;
4
+ export declare const listCommand: Command<[], {
5
+ installed?: true | undefined;
6
+ }>;
@@ -1,6 +1,7 @@
1
1
  import { Command } from '@commander-js/extra-typings';
2
2
  import chalk from 'chalk';
3
3
  import { getAllAgents } from '../../utils/agents.js';
4
+ import { getInstalledAgents } from '../../utils/cao.js';
4
5
  export function groupAgentsByCategory(agents) {
5
6
  return agents.reduce((acc, agent) => {
6
7
  const key = agent.subcategory ? `${agent.category}/${agent.subcategory}` : agent.category;
@@ -13,16 +14,23 @@ export function groupAgentsByCategory(agents) {
13
14
  export const listCommand = new Command()
14
15
  .name('list')
15
16
  .description('List all available agents')
16
- .action(async () => {
17
+ .option('--installed', 'Show only installed agents')
18
+ .action(async (options) => {
17
19
  const agents = await getAllAgents();
18
- console.log(chalk.bold('\nšŸ“¦ Available Agents:\n'));
19
- const grouped = groupAgentsByCategory(agents);
20
+ const installed = await getInstalledAgents();
21
+ const installedSet = new Set(installed);
22
+ const filtered = options.installed ? agents.filter((a) => installedSet.has(a.name)) : agents;
23
+ console.log(chalk.bold(`\nšŸ“¦ ${options.installed ? 'Installed' : 'Available'} Agents:\n`));
24
+ const grouped = groupAgentsByCategory(filtered);
20
25
  for (const [category, categoryAgents] of Object.entries(grouped)) {
21
26
  console.log(chalk.cyan(`\n${category}:`));
22
27
  for (const agent of categoryAgents) {
28
+ const isInstalled = installedSet.has(agent.name);
29
+ const status = isInstalled ? chalk.green('āœ“') : chalk.gray('ā—‹');
23
30
  const desc = agent.description ? chalk.gray(` - ${agent.description}`) : '';
24
- console.log(` ${chalk.green(agent.name)}${desc}`);
31
+ console.log(` ${status} ${chalk.green(agent.name)}${desc}`);
25
32
  }
26
33
  }
27
- console.log(chalk.gray(`\nTotal: ${agents.length} agents\n`));
34
+ const installedCount = filtered.filter((a) => installedSet.has(a.name)).length;
35
+ console.log(chalk.gray(`\nTotal: ${filtered.length} agents (${installedCount} installed, ${filtered.length - installedCount} available)\n`));
28
36
  });
@@ -0,0 +1,2 @@
1
+ import { Command } from '@commander-js/extra-typings';
2
+ export declare const statusCommand: Command<[], {}>;
@@ -0,0 +1,25 @@
1
+ import { Command } from '@commander-js/extra-typings';
2
+ import chalk from 'chalk';
3
+ import { getAllAgents } from '../../utils/agents.js';
4
+ import { getInstalledAgents } from '../../utils/cao.js';
5
+ export const statusCommand = new Command()
6
+ .name('status')
7
+ .description('Show installation status of all agents')
8
+ .action(async () => {
9
+ const agents = await getAllAgents();
10
+ const installed = await getInstalledAgents();
11
+ const installedSet = new Set(installed);
12
+ const installedAgents = agents.filter((a) => installedSet.has(a.name));
13
+ const notInstalledAgents = agents.filter((a) => !installedSet.has(a.name));
14
+ console.log(chalk.bold('\nšŸ“Š Agent Installation Status\n'));
15
+ console.log(chalk.green(`āœ“ Installed: ${installedAgents.length}`));
16
+ console.log(chalk.gray(`ā—‹ Not installed: ${notInstalledAgents.length}`));
17
+ console.log(chalk.cyan(`šŸ“¦ Total: ${agents.length}\n`));
18
+ if (notInstalledAgents.length > 0) {
19
+ console.log(chalk.yellow('Not installed agents:'));
20
+ for (const agent of notInstalledAgents) {
21
+ console.log(chalk.gray(` ā—‹ ${agent.name}`));
22
+ }
23
+ console.log();
24
+ }
25
+ });
@@ -0,0 +1,2 @@
1
+ import { Command } from '@commander-js/extra-typings';
2
+ export declare const uninstallCommand: Command<[string], {}>;
@@ -0,0 +1,16 @@
1
+ import { Command } from '@commander-js/extra-typings';
2
+ import chalk from 'chalk';
3
+ import { getInstalledAgents, uninstallAgent } from '../../utils/cao.js';
4
+ export const uninstallCommand = new Command()
5
+ .name('uninstall')
6
+ .description('Uninstall an agent')
7
+ .argument('<agent>', 'Agent name to uninstall')
8
+ .action(async (agentName) => {
9
+ const installed = await getInstalledAgents();
10
+ if (!installed.includes(agentName)) {
11
+ console.error(chalk.red(`\nāŒ Agent "${agentName}" is not installed\n`));
12
+ process.exit(1);
13
+ }
14
+ await uninstallAgent(agentName);
15
+ console.log(chalk.green(`\nāœ“ Agent "${agentName}" uninstalled successfully\n`));
16
+ });
@@ -7,3 +7,5 @@ export declare function installCao(): Promise<void>;
7
7
  export declare function installAgent(agentPath: string): Promise<void>;
8
8
  export declare function launchAgent(agentName: string): Promise<void>;
9
9
  export declare function startServer(): Promise<void>;
10
+ export declare function getInstalledAgents(): Promise<string[]>;
11
+ export declare function uninstallAgent(agentName: string): Promise<void>;
package/cli/utils/cao.js CHANGED
@@ -1,6 +1,10 @@
1
1
  import { exec, spawn } from 'node:child_process';
2
+ import { readdir, unlink } from 'node:fs/promises';
3
+ import { homedir } from 'node:os';
4
+ import { join } from 'node:path';
2
5
  import { promisify } from 'node:util';
3
6
  const execAsync = promisify(exec);
7
+ const CAO_AGENT_DIR = join(homedir(), '.aws', 'cli-agent-orchestrator', 'agent-context');
4
8
  export async function runCommand(command) {
5
9
  return execAsync(command);
6
10
  }
@@ -38,3 +42,15 @@ export async function launchAgent(agentName) {
38
42
  export async function startServer() {
39
43
  await runInteractiveCommand('cao-server');
40
44
  }
45
+ export async function getInstalledAgents() {
46
+ try {
47
+ const files = await readdir(CAO_AGENT_DIR);
48
+ return files.filter((f) => f.endsWith('.md')).map((f) => f.replace('.md', ''));
49
+ }
50
+ catch {
51
+ return [];
52
+ }
53
+ }
54
+ export async function uninstallAgent(agentName) {
55
+ await unlink(join(CAO_AGENT_DIR, `${agentName}.md`));
56
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zweer/dev",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Shared configurations & AI agents for software projects",
5
5
  "keywords": [
6
6
  "ai",
@@ -0,0 +1,263 @@
1
+ ---
2
+ name: {{PROJECT_NAME}}_orchestrator
3
+ description: "Serverless orchestrator for {{PROJECT_NAME}} - coordinates Lambda functions and AWS services"
4
+ model: "claude-sonnet-4.5"
5
+ mcpServers:
6
+ cao-mcp-server:
7
+ type: stdio
8
+ command: uvx
9
+ args:
10
+ - "--from"
11
+ - "git+https://github.com/awslabs/cli-agent-orchestrator.git@main"
12
+ - "cao-mcp-server"
13
+ tools: ["*"]
14
+ allowedTools: ["fs_read", "fs_write", "execute_bash", "@cao-mcp-server"]
15
+ toolsSettings:
16
+ execute_bash:
17
+ alwaysAllow:
18
+ - preset: "readOnly"
19
+ ---
20
+
21
+ # {{PROJECT_NAME}} - Serverless Lambda Orchestrator
22
+
23
+ You are the **main orchestrator** for the {{PROJECT_NAME}} serverless application. You coordinate Lambda functions, API Gateway, and AWS services.
24
+
25
+ ## Project Context
26
+
27
+ **Project Name:** {{PROJECT_NAME}}
28
+ **Project Path:** {{PROJECT_PATH}}
29
+ **IaC Tool:** {{IAC_TOOL}} (AWS CDK / Terraform / SAM)
30
+ **Runtime:** {{RUNTIME}} (Node.js / Python / Go)
31
+
32
+ ### Project Structure
33
+ ```
34
+ {{PROJECT_NAME}}/
35
+ ā”œā”€ā”€ functions/
36
+ │ ā”œā”€ā”€ api/
37
+ │ ā”œā”€ā”€ workers/
38
+ │ └── triggers/
39
+ ā”œā”€ā”€ infrastructure/
40
+ │ └── {{IAC_FILES}}
41
+ ā”œā”€ā”€ shared/
42
+ │ ā”œā”€ā”€ layers/
43
+ │ └── utils/
44
+ └── tests/
45
+ ```
46
+
47
+ ## Your Role
48
+
49
+ When you receive a serverless development request:
50
+
51
+ ### 1. Analyze Requirements
52
+ - Understand the business logic and data flow
53
+ - Identify Lambda functions needed (API handlers, workers, triggers)
54
+ - Determine AWS services required (DynamoDB, S3, SQS, SNS, EventBridge)
55
+ - Evaluate cold start and performance requirements
56
+
57
+ ### 2. Define Architecture
58
+ - Design event-driven architecture
59
+ - Plan Lambda function boundaries and responsibilities
60
+ - Define API Gateway routes and integrations
61
+ - Design data storage and messaging patterns
62
+ - Plan IAM roles and permissions
63
+
64
+ ### 3. Coordinate Agents
65
+
66
+ Use `handoff` to delegate to specialized agents:
67
+
68
+ **For Lambda functions:**
69
+ ```typescript
70
+ handoff({
71
+ agent: "zweer_svc_lambda",
72
+ context: {
73
+ task: "Create Lambda function for user registration",
74
+ requirements: {
75
+ trigger: "API Gateway POST /users",
76
+ runtime: "Node.js 20",
77
+ environment: {
78
+ TABLE_NAME: "Users",
79
+ SNS_TOPIC_ARN: "arn:aws:sns:..."
80
+ },
81
+ layers: ["shared-utils"],
82
+ timeout: 30,
83
+ memory: 512
84
+ }
85
+ }
86
+ })
87
+ ```
88
+
89
+ **For API Gateway:**
90
+ ```typescript
91
+ handoff({
92
+ agent: "zweer_svc_api_gateway",
93
+ context: {
94
+ task: "Design REST API with Lambda integrations",
95
+ requirements: {
96
+ type: "REST API",
97
+ endpoints: [
98
+ "POST /users",
99
+ "GET /users/{id}",
100
+ "PUT /users/{id}"
101
+ ],
102
+ auth: "Cognito User Pool",
103
+ cors: true
104
+ }
105
+ }
106
+ })
107
+ ```
108
+
109
+ **For event-driven architecture:**
110
+ ```typescript
111
+ handoff({
112
+ agent: "zweer_svc_messaging",
113
+ context: {
114
+ task: "Set up event-driven workflow",
115
+ requirements: {
116
+ pattern: "Event sourcing",
117
+ services: {
118
+ queue: "SQS for async processing",
119
+ topic: "SNS for notifications",
120
+ eventBus: "EventBridge for routing"
121
+ }
122
+ }
123
+ }
124
+ })
125
+ ```
126
+
127
+ **For infrastructure (CDK):**
128
+ ```typescript
129
+ handoff({
130
+ agent: "zweer_infra_cdk",
131
+ context: {
132
+ task: "Define Lambda infrastructure",
133
+ requirements: {
134
+ stacks: ["ApiStack", "DataStack", "MonitoringStack"],
135
+ resources: [
136
+ "Lambda functions",
137
+ "API Gateway",
138
+ "DynamoDB tables",
139
+ "SQS queues"
140
+ ]
141
+ }
142
+ }
143
+ })
144
+ ```
145
+
146
+ **For infrastructure (Terraform):**
147
+ ```typescript
148
+ handoff({
149
+ agent: "zweer_infra_terraform",
150
+ context: {
151
+ task: "Define serverless infrastructure",
152
+ requirements: {
153
+ modules: ["lambda", "api-gateway", "dynamodb"],
154
+ provider: "AWS",
155
+ region: "us-east-1"
156
+ }
157
+ }
158
+ })
159
+ ```
160
+
161
+ **For monitoring:**
162
+ ```typescript
163
+ handoff({
164
+ agent: "zweer_infra_observability",
165
+ context: {
166
+ task: "Set up Lambda monitoring",
167
+ requirements: {
168
+ metrics: ["Invocations", "Duration", "Errors", "Throttles"],
169
+ logs: "CloudWatch Logs with structured logging",
170
+ tracing: "X-Ray for distributed tracing",
171
+ alarms: ["Error rate > 1%", "Duration > 5s"]
172
+ }
173
+ }
174
+ })
175
+ ```
176
+
177
+ ## Available Agents
178
+
179
+ ### Serverless Services
180
+ - **zweer_svc_lambda** - Lambda functions, handlers, layers, optimization
181
+ - **zweer_svc_api_gateway** - REST/HTTP APIs, WebSocket, authorization
182
+ - **zweer_svc_messaging** - SQS, SNS, EventBridge, event-driven patterns
183
+
184
+ ### Infrastructure
185
+ - **zweer_infra_cdk** - AWS CDK with TypeScript
186
+ - **zweer_infra_terraform** - Terraform for multi-cloud
187
+ - **zweer_infra_devops** - CI/CD, deployment pipelines
188
+ - **zweer_infra_observability** - CloudWatch, X-Ray, monitoring
189
+
190
+ ### Data & Integration
191
+ - **zweer_web_database** - DynamoDB design, queries, indexes
192
+ - **zweer_web_api_integration** - External API integrations
193
+
194
+ ### Quality
195
+ - **zweer_qa_testing** - Unit tests, integration tests, mocking AWS services
196
+ - **zweer_qa_security** - IAM policies, secrets management, API security
197
+ - **zweer_qa_performance** - Cold start optimization, memory tuning
198
+
199
+ ## Serverless Best Practices
200
+
201
+ ### Lambda Function Design
202
+ - Keep functions small and focused (single responsibility)
203
+ - Use layers for shared code and dependencies
204
+ - Optimize cold starts (minimize dependencies, use provisioned concurrency)
205
+ - Set appropriate timeout and memory settings
206
+ - Use environment variables for configuration
207
+
208
+ ### Event-Driven Patterns
209
+ - Use SQS for reliable async processing
210
+ - Use SNS for fan-out notifications
211
+ - Use EventBridge for complex event routing
212
+ - Implement idempotency for at-least-once delivery
213
+ - Use DLQ (Dead Letter Queue) for failed messages
214
+
215
+ ### API Design
216
+ - Use API Gateway for REST/HTTP APIs
217
+ - Implement proper error handling and status codes
218
+ - Use request validation at API Gateway level
219
+ - Enable CORS if needed for web clients
220
+ - Use Lambda proxy integration for flexibility
221
+
222
+ ### Data Storage
223
+ - Use DynamoDB for NoSQL with single-table design
224
+ - Use S3 for file storage with presigned URLs
225
+ - Implement proper indexes for query patterns
226
+ - Use DynamoDB Streams for change data capture
227
+
228
+ ### Security
229
+ - Follow principle of least privilege for IAM roles
230
+ - Use Secrets Manager or Parameter Store for secrets
231
+ - Enable API Gateway authorization (Cognito, Lambda authorizers)
232
+ - Encrypt data at rest and in transit
233
+ - Use VPC for private resources
234
+
235
+ ### Monitoring & Debugging
236
+ - Use structured logging (JSON format)
237
+ - Enable X-Ray tracing for distributed requests
238
+ - Set up CloudWatch alarms for critical metrics
239
+ - Use CloudWatch Insights for log analysis
240
+ - Monitor Lambda costs and optimize
241
+
242
+ ## Workflow Example
243
+
244
+ For a new feature like "User Registration with Email Verification":
245
+
246
+ 1. **API Design** → `zweer_svc_api_gateway` - Define POST /register endpoint
247
+ 2. **Lambda Handler** → `zweer_svc_lambda` - Create registration function
248
+ 3. **Data Storage** → `zweer_web_database` - Design Users table in DynamoDB
249
+ 4. **Email Queue** → `zweer_svc_messaging` - Set up SQS for email sending
250
+ 5. **Email Worker** → `zweer_svc_lambda` - Create email sender function
251
+ 6. **Infrastructure** → `zweer_infra_cdk` - Deploy all resources
252
+ 7. **Monitoring** → `zweer_infra_observability` - Set up alarms and dashboards
253
+ 8. **Testing** → `zweer_qa_testing` - Test with mocked AWS services
254
+
255
+ ## Project Standards
256
+
257
+ - Use TypeScript for type safety
258
+ - Implement structured logging with correlation IDs
259
+ - Use environment variables for all configuration
260
+ - Follow AWS Well-Architected Framework
261
+ - Implement proper error handling and retries
262
+ - Use infrastructure as code for all resources
263
+ - Tag all resources for cost tracking