@musashishao/agent-kit 1.8.2 → 1.9.1
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/.agent/agents/ai-architect.md +39 -0
- package/.agent/agents/ai-asset-factory.md +700 -0
- package/.agent/agents/ai-audio-factory.md +503 -0
- package/.agent/agents/cloud-engineer.md +39 -0
- package/.agent/agents/game-developer.md +190 -89
- package/.agent/agents/marketing-specialist.md +41 -0
- package/.agent/agents/orchestrator.md +113 -3
- package/.agent/agents/penetration-tester.md +15 -1
- package/.agent/agents/project-planner.md +67 -0
- package/.agent/agents/unity-mobile-master.md +949 -0
- package/.agent/mcp/config/registry.json +65 -51
- package/.agent/mcp/servers/notebooklm/README.md +114 -0
- package/.agent/mcp/servers/notebooklm/package.json +35 -0
- package/.agent/mcp/servers/notebooklm/src/auth/chrome.ts +225 -0
- package/.agent/mcp/servers/notebooklm/src/auth/index.ts +1 -0
- package/.agent/mcp/servers/notebooklm/src/index.ts +516 -0
- package/.agent/mcp/servers/notebooklm/src/services/index.ts +3 -0
- package/.agent/mcp/servers/notebooklm/src/services/library.ts +217 -0
- package/.agent/mcp/servers/notebooklm/src/services/notebooklm.ts +380 -0
- package/.agent/mcp/servers/notebooklm/tsconfig.json +15 -0
- package/.agent/mcp-gateway/README.md +169 -20
- package/.agent/mcp-gateway/package.json +22 -7
- package/.agent/mcp-gateway/src/auth/index.ts +55 -0
- package/.agent/mcp-gateway/src/auth/middleware.ts +242 -0
- package/.agent/mcp-gateway/src/auth/oauth.ts +462 -0
- package/.agent/mcp-gateway/src/auth/scopes.ts +227 -0
- package/.agent/mcp-gateway/src/index.ts +252 -105
- package/.agent/mcp-gateway/src/observability/index.ts +5 -0
- package/.agent/mcp-gateway/src/observability/otel.ts +405 -0
- package/.agent/mcp-gateway/src/transports/index.ts +5 -0
- package/.agent/mcp-gateway/src/transports/streamableHttp.ts +235 -0
- package/.agent/rules/CODEX.md +115 -2
- package/.agent/rules/CODE_RULES.md +73 -0
- package/.agent/rules/GEMINI.md +26 -1
- package/.agent/rules/MEMORY_STATE.md +110 -0
- package/.agent/rules/REFERENCE.md +40 -58
- package/.agent/rules/REF_SKILLS.md +116 -0
- package/.agent/rules/REF_WORKFLOWS.md +81 -0
- package/.agent/scripts/ak_cli.py +106 -5
- package/.agent/scripts/memory_manager.py +48 -9
- package/.agent/skills/3d-web-experience/SKILL.md +386 -0
- package/.agent/skills/DEPENDENCIES.md +54 -0
- package/.agent/skills/ab-test-setup/SKILL.md +77 -0
- package/.agent/skills/active-directory-attacks/SKILL.md +59 -0
- package/.agent/skills/agent-evaluation/SKILL.md +430 -0
- package/.agent/skills/agent-memory-systems/SKILL.md +426 -0
- package/.agent/skills/agent-tool-builder/SKILL.md +139 -0
- package/.agent/skills/ai-agents-architect/SKILL.md +115 -0
- package/.agent/skills/ai-product/SKILL.md +86 -0
- package/.agent/skills/ai-wrapper-product/SKILL.md +90 -0
- package/.agent/skills/analytics-tracking/SKILL.md +88 -0
- package/.agent/skills/anti-hallucination/SKILL.md +295 -0
- package/.agent/skills/anti-hallucination/scripts/check_hallucination.py +299 -0
- package/.agent/skills/api-fuzzing-bug-bounty/SKILL.md +66 -0
- package/.agent/skills/app-store-optimization/SKILL.md +66 -0
- package/.agent/skills/autonomous-agent-patterns/SKILL.md +414 -0
- package/.agent/skills/aws-penetration-testing/SKILL.md +50 -0
- package/.agent/skills/aws-serverless/SKILL.md +327 -0
- package/.agent/skills/azure-functions/SKILL.md +340 -0
- package/.agent/skills/bifurcation-analysis/SKILL.md +56 -0
- package/.agent/skills/brainstorming/SKILL.md +80 -6
- package/.agent/skills/broken-authentication/SKILL.md +53 -0
- package/.agent/skills/browser-automation/SKILL.md +408 -0
- package/.agent/skills/browser-extension-builder/SKILL.md +422 -0
- package/.agent/skills/bullmq-specialist/SKILL.md +424 -0
- package/.agent/skills/bun-development/SKILL.md +386 -0
- package/.agent/skills/burp-suite-testing/SKILL.md +60 -0
- package/.agent/skills/clerk-auth/SKILL.md +432 -0
- package/.agent/skills/cloud-penetration-testing/SKILL.md +51 -0
- package/.agent/skills/copywriting/SKILL.md +66 -0
- package/.agent/skills/crewai/SKILL.md +470 -0
- package/.agent/skills/decision-memory/SKILL.md +317 -0
- package/.agent/skills/discord-bot-architect/SKILL.md +447 -0
- package/.agent/skills/email-sequence/SKILL.md +73 -0
- package/.agent/skills/emergence-detector/SKILL.md +230 -0
- package/.agent/skills/emergence-detector/scripts/check_emergence.py +265 -0
- package/.agent/skills/ethical-hacking-methodology/SKILL.md +67 -0
- package/.agent/skills/explained-qa/SKILL.md +142 -0
- package/.agent/skills/explained-qa/game-terminology.md +214 -0
- package/.agent/skills/firebase/SKILL.md +377 -0
- package/.agent/skills/game-development/ai-dialogue-engine/SKILL.md +442 -0
- package/.agent/skills/game-development/ai-graphics-generator/SKILL.md +463 -0
- package/.agent/skills/game-development/ai-playtest-framework/SKILL.md +570 -0
- package/.agent/skills/game-development/camera-systems/SKILL.md +607 -0
- package/.agent/skills/game-development/card-battle-engine/SKILL.md +618 -0
- package/.agent/skills/game-development/character-controller-3d/SKILL.md +908 -0
- package/.agent/skills/game-development/cloud-save-sync/SKILL.md +527 -0
- package/.agent/skills/game-development/combat-system/SKILL.md +748 -0
- package/.agent/skills/game-development/compliance-rating/SKILL.md +277 -0
- package/.agent/skills/game-development/crossplatform-build/SKILL.md +386 -0
- package/.agent/skills/game-development/cultivation-progression/SKILL.md +520 -0
- package/.agent/skills/game-development/data-driven-balance/SKILL.md +535 -0
- package/.agent/skills/game-development/game-analytics-integrator/SKILL.md +410 -0
- package/.agent/skills/game-development/game-audio-advanced/SKILL.md +646 -0
- package/.agent/skills/game-development/game-economy-designer/SKILL.md +375 -0
- package/.agent/skills/game-development/game-marketing/SKILL.md +85 -0
- package/.agent/skills/game-development/game-state-manager/SKILL.md +883 -0
- package/.agent/skills/game-development/godot-expert/SKILL.md +462 -0
- package/.agent/skills/game-development/hybrid-game-spec/SKILL.md +220 -0
- package/.agent/skills/game-development/inventory-quest/SKILL.md +747 -0
- package/.agent/skills/game-development/liveops/SKILL.md +308 -0
- package/.agent/skills/game-development/localization/SKILL.md +286 -0
- package/.agent/skills/game-development/mobile-input-patterns/SKILL.md +343 -0
- package/.agent/skills/game-development/monetization-strategy/SKILL.md +94 -0
- package/.agent/skills/game-development/multiplayer-master/SKILL.md +727 -0
- package/.agent/skills/game-development/narrative-branching/SKILL.md +593 -0
- package/.agent/skills/game-development/npc-ai-integration/SKILL.md +110 -0
- package/.agent/skills/game-development/procedural-generation/SKILL.md +168 -0
- package/.agent/skills/game-development/procedural-level-ai/SKILL.md +367 -0
- package/.agent/skills/game-development/prototyping-rapid/SKILL.md +205 -0
- package/.agent/skills/game-development/spec-ecosystem/SKILL.md +155 -0
- package/.agent/skills/game-development/spec-ecosystem/decision-log-format.md +129 -0
- package/.agent/skills/game-development/spec-ecosystem/templates/PLAN-template.md +178 -0
- package/.agent/skills/game-development/spec-ecosystem/templates/SPEC-template.md +110 -0
- package/.agent/skills/game-development/spec-ecosystem/templates/TASKS-template.md +156 -0
- package/.agent/skills/game-development/survival-systems/SKILL.md +493 -0
- package/.agent/skills/game-development/testing-qa/SKILL.md +270 -0
- package/.agent/skills/game-development/unity-integration/SKILL.md +358 -0
- package/.agent/skills/game-development/unity-mobile-optimization/SKILL.md +271 -0
- package/.agent/skills/game-development/webgpu-shading/SKILL.md +209 -0
- package/.agent/skills/gcp-cloud-run/SKILL.md +358 -0
- package/.agent/skills/graphql/SKILL.md +492 -0
- package/.agent/skills/idor-testing/SKILL.md +64 -0
- package/.agent/skills/inngest/SKILL.md +128 -0
- package/.agent/skills/intent-capture/SKILL.md +65 -0
- package/.agent/skills/langfuse/SKILL.md +415 -0
- package/.agent/skills/langgraph/SKILL.md +360 -0
- package/.agent/skills/launch-strategy/SKILL.md +68 -0
- package/.agent/skills/linux-privilege-escalation/SKILL.md +62 -0
- package/.agent/skills/llm-app-patterns/SKILL.md +367 -0
- package/.agent/skills/marketing-ideas/SKILL.md +66 -0
- package/.agent/skills/mcp-composition/SKILL.md +362 -0
- package/.agent/skills/mcp-observability/SKILL.md +323 -0
- package/.agent/skills/mcp-security/SKILL.md +314 -0
- package/.agent/skills/metasploit-framework/SKILL.md +60 -0
- package/.agent/skills/micro-saas-launcher/SKILL.md +93 -0
- package/.agent/skills/neon-postgres/SKILL.md +339 -0
- package/.agent/skills/paid-ads/SKILL.md +64 -0
- package/.agent/skills/supabase-integration/SKILL.md +411 -0
- package/.agent/skills/trust-spectrum/SKILL.md +291 -0
- package/.agent/skills/vibe-coding-guard/SKILL.md +328 -0
- package/.agent/templates/AGENTS.game.md +63 -0
- package/.agent/templates/docs/WORKFLOW_GUIDE.en.md +100 -0
- package/.agent/templates/docs/WORKFLOW_GUIDE.vi.md +100 -0
- package/.agent/workflows/ai-agent.md +38 -0
- package/.agent/workflows/autofix.md +1 -0
- package/.agent/workflows/brainstorm.md +1 -0
- package/.agent/workflows/context.md +1 -0
- package/.agent/workflows/create.md +39 -8
- package/.agent/workflows/dashboard.md +1 -0
- package/.agent/workflows/debug.md +14 -0
- package/.agent/workflows/deploy.md +14 -0
- package/.agent/workflows/enhance.md +44 -0
- package/.agent/workflows/gamekit-init.md +177 -0
- package/.agent/workflows/gamekit-launch.md +338 -0
- package/.agent/workflows/gamekit-plan.md +204 -0
- package/.agent/workflows/gamekit-qa.md +153 -0
- package/.agent/workflows/gamekit-spec.md +243 -0
- package/.agent/workflows/gamekit-tasks.md +208 -0
- package/.agent/workflows/marketing.md +39 -0
- package/.agent/workflows/next.md +1 -0
- package/.agent/workflows/orchestrate.md +12 -0
- package/.agent/workflows/pentest.md +39 -0
- package/.agent/workflows/plan.md +42 -0
- package/.agent/workflows/preview.md +1 -0
- package/.agent/workflows/quality.md +1 -0
- package/.agent/workflows/saas.md +38 -0
- package/.agent/workflows/spec.md +42 -0
- package/.agent/workflows/status.md +1 -0
- package/.agent/workflows/test.md +14 -0
- package/.agent/workflows/ui-ux-pro-max.md +1 -0
- package/README.md +4 -4
- package/bin/cli.js +411 -111
- package/package.json +1 -2
- package/docs/AI_DATA_INFRASTRUCTURE.md +0 -288
- package/docs/CHANGELOG_AI_INFRA.md +0 -111
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: aws-serverless
|
|
3
|
+
description: "Production-ready serverless applications on AWS. Covers Lambda functions, API Gateway, DynamoDB, SQS/SNS event-driven patterns, SAM/CDK deployment, and cold start optimization."
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
source: "antigravity-awesome-skills (adapted)"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# ☁️ AWS Serverless
|
|
9
|
+
|
|
10
|
+
You are an AWS serverless expert who has built production applications handling millions of requests. You understand Lambda's execution model, cold starts, and cost optimization strategies.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## When to Use This Skill
|
|
15
|
+
|
|
16
|
+
- Building serverless APIs with Lambda + API Gateway
|
|
17
|
+
- Event-driven architectures with SQS/SNS/EventBridge
|
|
18
|
+
- DynamoDB data modeling and access patterns
|
|
19
|
+
- SAM or CDK infrastructure as code
|
|
20
|
+
- Cold start optimization for latency-sensitive apps
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Capabilities
|
|
25
|
+
|
|
26
|
+
- `aws-lambda`
|
|
27
|
+
- `api-gateway`
|
|
28
|
+
- `dynamodb`
|
|
29
|
+
- `sqs-sns`
|
|
30
|
+
- `eventbridge`
|
|
31
|
+
- `sam-cdk`
|
|
32
|
+
- `step-functions`
|
|
33
|
+
- `s3-events`
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 1. Lambda Handler Patterns
|
|
38
|
+
|
|
39
|
+
### Node.js Handler
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
// handler.js
|
|
43
|
+
// Initialize OUTSIDE handler (reused across invocations)
|
|
44
|
+
const { DynamoDBClient } = require('@aws-sdk/client-dynamodb');
|
|
45
|
+
const { DynamoDBDocumentClient, GetCommand } = require('@aws-sdk/lib-dynamodb');
|
|
46
|
+
|
|
47
|
+
const client = new DynamoDBClient({});
|
|
48
|
+
const docClient = DynamoDBDocumentClient.from(client);
|
|
49
|
+
|
|
50
|
+
exports.handler = async (event, context) => {
|
|
51
|
+
// Don't wait for event loop to clear
|
|
52
|
+
context.callbackWaitsForEmptyEventLoop = false;
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const body = typeof event.body === 'string'
|
|
56
|
+
? JSON.parse(event.body)
|
|
57
|
+
: event.body;
|
|
58
|
+
|
|
59
|
+
const result = await processRequest(body);
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
statusCode: 200,
|
|
63
|
+
headers: {
|
|
64
|
+
'Content-Type': 'application/json',
|
|
65
|
+
'Access-Control-Allow-Origin': '*'
|
|
66
|
+
},
|
|
67
|
+
body: JSON.stringify(result)
|
|
68
|
+
};
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.error('Error:', JSON.stringify({
|
|
71
|
+
error: error.message,
|
|
72
|
+
stack: error.stack,
|
|
73
|
+
requestId: context.awsRequestId
|
|
74
|
+
}));
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
statusCode: error.statusCode || 500,
|
|
78
|
+
headers: { 'Content-Type': 'application/json' },
|
|
79
|
+
body: JSON.stringify({ error: error.message })
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Python Handler
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
# handler.py
|
|
89
|
+
import json
|
|
90
|
+
import os
|
|
91
|
+
import logging
|
|
92
|
+
import boto3
|
|
93
|
+
|
|
94
|
+
# Initialize OUTSIDE handler (reused across invocations)
|
|
95
|
+
logger = logging.getLogger()
|
|
96
|
+
logger.setLevel(logging.INFO)
|
|
97
|
+
|
|
98
|
+
dynamodb = boto3.resource('dynamodb')
|
|
99
|
+
table = dynamodb.Table(os.environ['TABLE_NAME'])
|
|
100
|
+
|
|
101
|
+
def handler(event, context):
|
|
102
|
+
try:
|
|
103
|
+
body = json.loads(event.get('body', '{}'))
|
|
104
|
+
result = table.get_item(Key={'id': body['id']})
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
'statusCode': 200,
|
|
108
|
+
'headers': {'Content-Type': 'application/json'},
|
|
109
|
+
'body': json.dumps(result.get('Item', {}))
|
|
110
|
+
}
|
|
111
|
+
except Exception as e:
|
|
112
|
+
logger.error(f"Error: {str(e)}")
|
|
113
|
+
return {
|
|
114
|
+
'statusCode': 500,
|
|
115
|
+
'body': json.dumps({'error': str(e)})
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## 2. SAM Template Pattern
|
|
122
|
+
|
|
123
|
+
```yaml
|
|
124
|
+
# template.yaml
|
|
125
|
+
AWSTemplateFormatVersion: '2010-09-09'
|
|
126
|
+
Transform: AWS::Serverless-2016-10-31
|
|
127
|
+
|
|
128
|
+
Globals:
|
|
129
|
+
Function:
|
|
130
|
+
Runtime: nodejs20.x
|
|
131
|
+
Timeout: 30
|
|
132
|
+
MemorySize: 256
|
|
133
|
+
Environment:
|
|
134
|
+
Variables:
|
|
135
|
+
TABLE_NAME: !Ref ItemsTable
|
|
136
|
+
|
|
137
|
+
Resources:
|
|
138
|
+
# HTTP API (recommended)
|
|
139
|
+
HttpApi:
|
|
140
|
+
Type: AWS::Serverless::HttpApi
|
|
141
|
+
Properties:
|
|
142
|
+
StageName: prod
|
|
143
|
+
CorsConfiguration:
|
|
144
|
+
AllowOrigins: ["*"]
|
|
145
|
+
AllowMethods: [GET, POST, DELETE]
|
|
146
|
+
AllowHeaders: ["*"]
|
|
147
|
+
|
|
148
|
+
# Lambda Functions
|
|
149
|
+
GetItemFunction:
|
|
150
|
+
Type: AWS::Serverless::Function
|
|
151
|
+
Properties:
|
|
152
|
+
Handler: src/handlers/get.handler
|
|
153
|
+
Events:
|
|
154
|
+
GetItem:
|
|
155
|
+
Type: HttpApi
|
|
156
|
+
Properties:
|
|
157
|
+
ApiId: !Ref HttpApi
|
|
158
|
+
Path: /items/{id}
|
|
159
|
+
Method: GET
|
|
160
|
+
Policies:
|
|
161
|
+
- DynamoDBReadPolicy:
|
|
162
|
+
TableName: !Ref ItemsTable
|
|
163
|
+
|
|
164
|
+
# DynamoDB Table
|
|
165
|
+
ItemsTable:
|
|
166
|
+
Type: AWS::DynamoDB::Table
|
|
167
|
+
Properties:
|
|
168
|
+
AttributeDefinitions:
|
|
169
|
+
- AttributeName: id
|
|
170
|
+
AttributeType: S
|
|
171
|
+
KeySchema:
|
|
172
|
+
- AttributeName: id
|
|
173
|
+
KeyType: HASH
|
|
174
|
+
BillingMode: PAY_PER_REQUEST
|
|
175
|
+
|
|
176
|
+
Outputs:
|
|
177
|
+
ApiUrl:
|
|
178
|
+
Value: !Sub "https://${HttpApi}.execute-api.${AWS::Region}.amazonaws.com/prod"
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## 3. Event-Driven Patterns
|
|
184
|
+
|
|
185
|
+
### SQS Processing
|
|
186
|
+
|
|
187
|
+
```javascript
|
|
188
|
+
// sqs-handler.js
|
|
189
|
+
exports.handler = async (event) => {
|
|
190
|
+
const failedRecords = [];
|
|
191
|
+
|
|
192
|
+
for (const record of event.Records) {
|
|
193
|
+
try {
|
|
194
|
+
const body = JSON.parse(record.body);
|
|
195
|
+
await processMessage(body);
|
|
196
|
+
} catch (error) {
|
|
197
|
+
console.error(`Failed: ${record.messageId}`, error);
|
|
198
|
+
failedRecords.push({ itemIdentifier: record.messageId });
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Partial batch response
|
|
203
|
+
return {
|
|
204
|
+
batchItemFailures: failedRecords
|
|
205
|
+
};
|
|
206
|
+
};
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### EventBridge Rule
|
|
210
|
+
|
|
211
|
+
```yaml
|
|
212
|
+
# SAM template
|
|
213
|
+
ProcessOrderRule:
|
|
214
|
+
Type: AWS::Events::Rule
|
|
215
|
+
Properties:
|
|
216
|
+
EventPattern:
|
|
217
|
+
source: ["orders"]
|
|
218
|
+
detail-type: ["OrderCreated"]
|
|
219
|
+
Targets:
|
|
220
|
+
- Id: ProcessOrderLambda
|
|
221
|
+
Arn: !GetAtt ProcessOrderFunction.Arn
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## 4. DynamoDB Patterns
|
|
227
|
+
|
|
228
|
+
### Single Table Design
|
|
229
|
+
|
|
230
|
+
```javascript
|
|
231
|
+
// Access patterns in one table
|
|
232
|
+
const patterns = {
|
|
233
|
+
// Get user by ID
|
|
234
|
+
getUser: { PK: 'USER#123', SK: 'PROFILE' },
|
|
235
|
+
|
|
236
|
+
// Get user's orders
|
|
237
|
+
getUserOrders: {
|
|
238
|
+
PK: 'USER#123',
|
|
239
|
+
SK: { begins_with: 'ORDER#' }
|
|
240
|
+
},
|
|
241
|
+
|
|
242
|
+
// Get order by ID (GSI)
|
|
243
|
+
getOrder: {
|
|
244
|
+
GSI1PK: 'ORDER#456',
|
|
245
|
+
GSI1SK: 'ORDER#456'
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Access Pattern Matrix
|
|
251
|
+
|
|
252
|
+
| Access Pattern | PK | SK | Index |
|
|
253
|
+
|----------------|----|----|-------|
|
|
254
|
+
| Get user | USER#{id} | PROFILE | - |
|
|
255
|
+
| User's orders | USER#{id} | ORDER#{date} | - |
|
|
256
|
+
| Order by ID | - | - | GSI1 |
|
|
257
|
+
| Orders by date | - | - | GSI2 |
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## 5. Cold Start Optimization
|
|
262
|
+
|
|
263
|
+
| Strategy | Impact | Implementation |
|
|
264
|
+
|----------|--------|----------------|
|
|
265
|
+
| **Provisioned Concurrency** | Best | Keep instances warm |
|
|
266
|
+
| **Smaller packages** | High | Tree-shake, omit dev deps |
|
|
267
|
+
| **ARM64 (Graviton)** | Medium | Faster boot, lower cost |
|
|
268
|
+
| **Connection pooling** | Medium | Initialize outside handler |
|
|
269
|
+
| **Lambda SnapStart** | High | Java only, snapshot restore |
|
|
270
|
+
|
|
271
|
+
```yaml
|
|
272
|
+
# Provisioned concurrency
|
|
273
|
+
MyFunction:
|
|
274
|
+
Type: AWS::Serverless::Function
|
|
275
|
+
Properties:
|
|
276
|
+
AutoPublishAlias: live
|
|
277
|
+
ProvisionedConcurrencyConfig:
|
|
278
|
+
ProvisionedConcurrentExecutions: 5
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## 6. Anti-Patterns
|
|
284
|
+
|
|
285
|
+
### ❌ Initialize Inside Handler
|
|
286
|
+
|
|
287
|
+
```javascript
|
|
288
|
+
// WRONG
|
|
289
|
+
exports.handler = async (event) => {
|
|
290
|
+
const dynamodb = new DynamoDB(); // Cold on every call!
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
// CORRECT
|
|
294
|
+
const dynamodb = new DynamoDB(); // Reused!
|
|
295
|
+
exports.handler = async (event) => {};
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### ❌ Synchronous Everything
|
|
299
|
+
|
|
300
|
+
```javascript
|
|
301
|
+
// WRONG: Wait for each
|
|
302
|
+
for (const item of items) {
|
|
303
|
+
await processItem(item);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// CORRECT: Parallel
|
|
307
|
+
await Promise.all(items.map(processItem));
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### ❌ No Dead Letter Queue
|
|
311
|
+
|
|
312
|
+
```yaml
|
|
313
|
+
# CORRECT: Always add DLQ
|
|
314
|
+
MyFunction:
|
|
315
|
+
Properties:
|
|
316
|
+
DeadLetterQueue:
|
|
317
|
+
Type: SQS
|
|
318
|
+
TargetArn: !GetAtt DLQ.Arn
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## Related Skills
|
|
324
|
+
|
|
325
|
+
- `database-design` - DynamoDB modeling
|
|
326
|
+
- `api-patterns` - REST/GraphQL design
|
|
327
|
+
- `deployment-procedures` - CI/CD for serverless
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: azure-functions
|
|
3
|
+
description: "Azure Functions serverless patterns. Covers HTTP triggers, queue triggers, timer triggers, Durable Functions orchestration, and deployment with Azure CLI/Bicep."
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ☁️ Azure Functions
|
|
8
|
+
|
|
9
|
+
You are an Azure Functions expert who has built event-driven applications at scale. You understand the Azure serverless ecosystem, consumption vs premium plans, and Durable Functions for complex workflows.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## When to Use This Skill
|
|
14
|
+
|
|
15
|
+
- Building serverless APIs on Azure
|
|
16
|
+
- Event-driven processing with queues and blobs
|
|
17
|
+
- Complex workflows with Durable Functions
|
|
18
|
+
- Timer-based scheduled tasks
|
|
19
|
+
- Integration with Azure services
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Capabilities
|
|
24
|
+
|
|
25
|
+
- `azure-functions`
|
|
26
|
+
- `http-trigger`
|
|
27
|
+
- `queue-trigger`
|
|
28
|
+
- `timer-trigger`
|
|
29
|
+
- `durable-functions`
|
|
30
|
+
- `blob-trigger`
|
|
31
|
+
- `cosmosdb-trigger`
|
|
32
|
+
- `bicep-deployment`
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 1. HTTP Trigger Pattern
|
|
37
|
+
|
|
38
|
+
### TypeScript Function
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
// src/functions/httpTrigger.ts
|
|
42
|
+
import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";
|
|
43
|
+
|
|
44
|
+
export async function httpTrigger(
|
|
45
|
+
request: HttpRequest,
|
|
46
|
+
context: InvocationContext
|
|
47
|
+
): Promise<HttpResponseInit> {
|
|
48
|
+
context.log(`HTTP function processed request for url "${request.url}"`);
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
const body = await request.json() as { name?: string };
|
|
52
|
+
const name = body.name || request.query.get('name') || 'World';
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
status: 200,
|
|
56
|
+
jsonBody: { message: `Hello, ${name}!` }
|
|
57
|
+
};
|
|
58
|
+
} catch (error) {
|
|
59
|
+
context.error('Error processing request:', error);
|
|
60
|
+
return {
|
|
61
|
+
status: 500,
|
|
62
|
+
jsonBody: { error: 'Internal server error' }
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
app.http('httpTrigger', {
|
|
68
|
+
methods: ['GET', 'POST'],
|
|
69
|
+
authLevel: 'function',
|
|
70
|
+
handler: httpTrigger
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### JavaScript Function (v4 Model)
|
|
75
|
+
|
|
76
|
+
```javascript
|
|
77
|
+
// src/functions/getUser.js
|
|
78
|
+
const { app } = require('@azure/functions');
|
|
79
|
+
const { CosmosClient } = require('@azure/cosmos');
|
|
80
|
+
|
|
81
|
+
// Initialize outside handler
|
|
82
|
+
const client = new CosmosClient(process.env.COSMOS_CONNECTION);
|
|
83
|
+
const container = client.database('mydb').container('users');
|
|
84
|
+
|
|
85
|
+
app.http('getUser', {
|
|
86
|
+
methods: ['GET'],
|
|
87
|
+
authLevel: 'anonymous',
|
|
88
|
+
route: 'users/{id}',
|
|
89
|
+
handler: async (request, context) => {
|
|
90
|
+
const id = request.params.id;
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
const { resource } = await container.item(id, id).read();
|
|
94
|
+
|
|
95
|
+
if (!resource) {
|
|
96
|
+
return { status: 404, jsonBody: { error: 'User not found' } };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return { jsonBody: resource };
|
|
100
|
+
} catch (error) {
|
|
101
|
+
context.error('Error:', error);
|
|
102
|
+
return { status: 500, jsonBody: { error: error.message } };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 2. Queue Trigger Pattern
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
// src/functions/queueTrigger.ts
|
|
114
|
+
import { app, InvocationContext } from "@azure/functions";
|
|
115
|
+
|
|
116
|
+
interface QueueMessage {
|
|
117
|
+
orderId: string;
|
|
118
|
+
customerId: string;
|
|
119
|
+
items: Array<{ id: string; quantity: number }>;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export async function processOrder(
|
|
123
|
+
message: QueueMessage,
|
|
124
|
+
context: InvocationContext
|
|
125
|
+
): Promise<void> {
|
|
126
|
+
context.log(`Processing order: ${message.orderId}`);
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
// Process the order
|
|
130
|
+
await processOrderItems(message.items);
|
|
131
|
+
|
|
132
|
+
// Output to another queue
|
|
133
|
+
context.extraOutputs.set('notification', {
|
|
134
|
+
type: 'order_processed',
|
|
135
|
+
orderId: message.orderId
|
|
136
|
+
});
|
|
137
|
+
} catch (error) {
|
|
138
|
+
context.error(`Failed to process order ${message.orderId}:`, error);
|
|
139
|
+
throw error; // Will move to poison queue after retries
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
app.storageQueue('processOrder', {
|
|
144
|
+
queueName: 'orders',
|
|
145
|
+
connection: 'AzureWebJobsStorage',
|
|
146
|
+
handler: processOrder,
|
|
147
|
+
extraOutputs: [
|
|
148
|
+
{ type: 'storageQueue', queueName: 'notifications', connection: 'AzureWebJobsStorage' }
|
|
149
|
+
]
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## 3. Timer Trigger Pattern
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
// src/functions/dailyCleanup.ts
|
|
159
|
+
import { app, InvocationContext, Timer } from "@azure/functions";
|
|
160
|
+
|
|
161
|
+
export async function dailyCleanup(
|
|
162
|
+
timer: Timer,
|
|
163
|
+
context: InvocationContext
|
|
164
|
+
): Promise<void> {
|
|
165
|
+
context.log('Daily cleanup started at:', new Date().toISOString());
|
|
166
|
+
|
|
167
|
+
if (timer.isPastDue) {
|
|
168
|
+
context.log('Timer is running late!');
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Cleanup logic
|
|
172
|
+
await cleanupOldRecords();
|
|
173
|
+
await archiveCompletedOrders();
|
|
174
|
+
|
|
175
|
+
context.log('Daily cleanup completed');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
app.timer('dailyCleanup', {
|
|
179
|
+
// Every day at 2 AM UTC
|
|
180
|
+
schedule: '0 0 2 * * *',
|
|
181
|
+
handler: dailyCleanup
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## 4. Durable Functions Pattern
|
|
188
|
+
|
|
189
|
+
Orchestrate complex workflows with automatic checkpointing.
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
// src/functions/orderOrchestrator.ts
|
|
193
|
+
import * as df from "durable-functions";
|
|
194
|
+
import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";
|
|
195
|
+
|
|
196
|
+
// Orchestrator function
|
|
197
|
+
df.app.orchestration('orderWorkflow', function* (context) {
|
|
198
|
+
const orderId = context.df.getInput<string>();
|
|
199
|
+
|
|
200
|
+
// Step 1: Validate order
|
|
201
|
+
const isValid = yield context.df.callActivity('validateOrder', orderId);
|
|
202
|
+
if (!isValid) {
|
|
203
|
+
return { status: 'rejected', reason: 'Invalid order' };
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Step 2: Reserve inventory (with retry)
|
|
207
|
+
const retryOptions = new df.RetryOptions(5000, 3);
|
|
208
|
+
const reserved = yield context.df.callActivityWithRetry(
|
|
209
|
+
'reserveInventory',
|
|
210
|
+
retryOptions,
|
|
211
|
+
orderId
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
// Step 3: Process payment
|
|
215
|
+
const payment = yield context.df.callActivity('processPayment', orderId);
|
|
216
|
+
|
|
217
|
+
// Step 4: Ship order (async, wait for external event)
|
|
218
|
+
const shippingTask = context.df.waitForExternalEvent('shippingConfirmed');
|
|
219
|
+
const timeoutTask = context.df.createTimer(
|
|
220
|
+
new Date(context.df.currentUtcDateTime.getTime() + 24 * 60 * 60 * 1000)
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
const winner = yield context.df.Task.any([shippingTask, timeoutTask]);
|
|
224
|
+
|
|
225
|
+
if (winner === timeoutTask) {
|
|
226
|
+
return { status: 'failed', reason: 'Shipping timeout' };
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return { status: 'completed', orderId };
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
// Activity functions
|
|
233
|
+
df.app.activity('validateOrder', { handler: async (orderId: string) => true });
|
|
234
|
+
df.app.activity('reserveInventory', { handler: async (orderId: string) => true });
|
|
235
|
+
df.app.activity('processPayment', { handler: async (orderId: string) => ({ success: true }) });
|
|
236
|
+
|
|
237
|
+
// HTTP starter
|
|
238
|
+
app.http('startOrder', {
|
|
239
|
+
methods: ['POST'],
|
|
240
|
+
route: 'orders/start',
|
|
241
|
+
extraInputs: [df.input.durableClient()],
|
|
242
|
+
handler: async (request: HttpRequest, context: InvocationContext) => {
|
|
243
|
+
const client = df.getClient(context);
|
|
244
|
+
const body = await request.json() as { orderId: string };
|
|
245
|
+
|
|
246
|
+
const instanceId = await client.startNew('orderWorkflow', {
|
|
247
|
+
input: body.orderId
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
return client.createCheckStatusResponse(request, instanceId);
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## 5. Deployment Pattern (Bicep)
|
|
258
|
+
|
|
259
|
+
```bicep
|
|
260
|
+
// main.bicep
|
|
261
|
+
param location string = resourceGroup().location
|
|
262
|
+
param functionAppName string
|
|
263
|
+
|
|
264
|
+
resource storageAccount 'Microsoft.Storage/storageAccounts@2021-02-01' = {
|
|
265
|
+
name: '${functionAppName}storage'
|
|
266
|
+
location: location
|
|
267
|
+
sku: { name: 'Standard_LRS' }
|
|
268
|
+
kind: 'StorageV2'
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
resource hostingPlan 'Microsoft.Web/serverfarms@2021-02-01' = {
|
|
272
|
+
name: '${functionAppName}-plan'
|
|
273
|
+
location: location
|
|
274
|
+
sku: {
|
|
275
|
+
name: 'Y1'
|
|
276
|
+
tier: 'Dynamic'
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
resource functionApp 'Microsoft.Web/sites@2021-02-01' = {
|
|
281
|
+
name: functionAppName
|
|
282
|
+
location: location
|
|
283
|
+
kind: 'functionapp'
|
|
284
|
+
properties: {
|
|
285
|
+
serverFarmId: hostingPlan.id
|
|
286
|
+
siteConfig: {
|
|
287
|
+
appSettings: [
|
|
288
|
+
{ name: 'AzureWebJobsStorage', value: storageAccount.properties.primaryEndpoints.blob }
|
|
289
|
+
{ name: 'FUNCTIONS_EXTENSION_VERSION', value: '~4' }
|
|
290
|
+
{ name: 'FUNCTIONS_WORKER_RUNTIME', value: 'node' }
|
|
291
|
+
]
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## 6. Anti-Patterns
|
|
300
|
+
|
|
301
|
+
### ❌ Long-Running HTTP Functions
|
|
302
|
+
|
|
303
|
+
```javascript
|
|
304
|
+
// WRONG: HTTP function running > 230 seconds
|
|
305
|
+
app.http('longProcess', {
|
|
306
|
+
handler: async (req) => {
|
|
307
|
+
await processFor10Minutes(); // Will timeout!
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// CORRECT: Use Durable Functions for long processes
|
|
312
|
+
app.http('startLongProcess', {
|
|
313
|
+
handler: async (req, context) => {
|
|
314
|
+
const client = df.getClient(context);
|
|
315
|
+
const instanceId = await client.startNew('longWorkflow');
|
|
316
|
+
return client.createCheckStatusResponse(req, instanceId);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### ❌ Cold Start Heavy
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
// WRONG: Heavy initialization in handler
|
|
325
|
+
export async function handler(req, context) {
|
|
326
|
+
const client = new HeavyClient(); // Cold every time!
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// CORRECT: Initialize outside
|
|
330
|
+
const client = new HeavyClient();
|
|
331
|
+
export async function handler(req, context) {}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Related Skills
|
|
337
|
+
|
|
338
|
+
- `aws-serverless` - Compare with AWS patterns
|
|
339
|
+
- `database-design` - CosmosDB patterns
|
|
340
|
+
- `api-patterns` - API design
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bifurcation-analysis
|
|
3
|
+
description: "Proactive decision point identification. Identifies technical, architectural, and scope branches BEFORE acting."
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ⚖️ Bifurcation Analysis
|
|
8
|
+
|
|
9
|
+
> **"Navigate the branches of implementation proactively"**
|
|
10
|
+
|
|
11
|
+
Bifurcation Analysis is the "B" in the VIBES framework. It prevents "implement-then-ask" errors by surfacing critical decision points before a single line of code is written.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Categories of Bifurcation
|
|
16
|
+
|
|
17
|
+
| Category | Description | Examples |
|
|
18
|
+
|----------|-------------|----------|
|
|
19
|
+
| **Technical** | Implementation details | "PostgreSQL vs MongoDB", "Standard CSS vs Tailwind" |
|
|
20
|
+
| **Architecture** | System structure | "Monolith vs Microservices", "Server Side vs Client Side" |
|
|
21
|
+
| **Scope** | Feature boundaries | "Auth v1 (Email only) vs v2 (OAuth)", "MVP vs Full Feature" |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 📋 Bifurcation Checklist
|
|
26
|
+
|
|
27
|
+
For any significant task, identify:
|
|
28
|
+
|
|
29
|
+
- [ ] **Irreversible Decisions**: Decisions that are hard to undo later (e.g., DB schema).
|
|
30
|
+
- [ ] **Trade-offs**: Options with clear pros/cons (documented for the user).
|
|
31
|
+
- [ ] **Defaults**: What will you do if the user doesn't specify? (Why?)
|
|
32
|
+
- [ ] **Dependencies**: How does this choice affect other components?
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 🧠 Decision Log Integration
|
|
37
|
+
|
|
38
|
+
Every confirmed bifurcation point MUST be logged using:
|
|
39
|
+
`ak memory log-decision --point "[Point]" --chosen "[Option]" --rationale "[Why]"`
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 🎼 CONDUCTOR Integration
|
|
44
|
+
|
|
45
|
+
As a CONDUCTOR, your role in Bifurcation is:
|
|
46
|
+
|
|
47
|
+
1. **Navigation**: Guide the user through the identified branches.
|
|
48
|
+
2. **Impact Analysis**: Explain the long-term consequences of each branch.
|
|
49
|
+
3. **Decision Memory**: Ensure the "Why" is captured in the system memory.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Related Skills
|
|
54
|
+
- `intent-capture` - The input for bifurcation analysis
|
|
55
|
+
- `decision-memory` - Where outcomes are stored
|
|
56
|
+
- `vibe-coding-guard` - The overall framework
|