@chris1807/claude-kit 2.0.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.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +821 -0
  3. package/bin/cli.js +521 -0
  4. package/package.json +50 -0
  5. package/templates/agents/global/api-tester.md +75 -0
  6. package/templates/agents/global/azure-ops.md +59 -0
  7. package/templates/agents/global/backend.md +245 -0
  8. package/templates/agents/global/build-validator.md +50 -0
  9. package/templates/agents/global/frontend.md +254 -0
  10. package/templates/agents/global/legacy.md +218 -0
  11. package/templates/agents/global/lint-checker.md +86 -0
  12. package/templates/agents/global/manager.md +138 -0
  13. package/templates/agents/global/mockup.md +95 -0
  14. package/templates/agents/global/reviewer.md +149 -0
  15. package/templates/agents/global/security-auditor.md +74 -0
  16. package/templates/agents/global/test-runner.md +98 -0
  17. package/templates/agents/global/uat-generator.md +107 -0
  18. package/templates/agents/project/db-admin.md +106 -0
  19. package/templates/agents/project/deployer.md +113 -0
  20. package/templates/agents/project/devops-tracker.md +101 -0
  21. package/templates/commands/add-to-release.md +55 -0
  22. package/templates/commands/cherry-pick.md +96 -0
  23. package/templates/commands/cleanup-branches.md +73 -0
  24. package/templates/commands/create-release.md +65 -0
  25. package/templates/commands/deploy-release.md +147 -0
  26. package/templates/commands/deploy.md +65 -0
  27. package/templates/commands/explain.md +49 -0
  28. package/templates/commands/implement.md +170 -0
  29. package/templates/commands/promote.md +71 -0
  30. package/templates/commands/quote.md +39 -0
  31. package/templates/commands/review.md +32 -0
  32. package/templates/commands/rework.md +158 -0
  33. package/templates/commands/rollback.md +106 -0
  34. package/templates/commands/status.md +111 -0
  35. package/templates/hooks/auto-format.sh +46 -0
  36. package/templates/hooks/protected-files.sh +52 -0
  37. package/templates/hooks/secret-blocker.sh +68 -0
  38. package/templates/hooks/self-improve.sh +7 -0
  39. package/templates/hooks/sensitive-data-blocker.sh +43 -0
  40. package/templates/hooks/sensitive-data-mcp-blocker.sh +40 -0
  41. package/templates/hooks/sensitive-data-output-blocker.sh +63 -0
  42. package/templates/hooks/test-on-change.sh +46 -0
  43. package/templates/hooks/uat-reminder.sh +9 -0
  44. package/templates/infrastructure/CLAUDE-WORKFLOW.md +274 -0
  45. package/templates/infrastructure/azure-pipelines-template.yml +199 -0
  46. package/templates/infrastructure/mcp.json +35 -0
  47. package/templates/infrastructure/settings.json +94 -0
@@ -0,0 +1,43 @@
1
+ #!/bin/bash
2
+ # Sensitive Data Blocker Hook (PreToolUse - Bash)
3
+ # Blocks database queries that reference sensitive PII fields like TIN, SSN, etc.
4
+ # Even encrypted values must never be exposed.
5
+ # Exit code 2 = BLOCK the action.
6
+
7
+ # Read the tool input from stdin
8
+ INPUT=$(cat)
9
+
10
+ # Extract the command being run
11
+ COMMAND=$(echo "$INPUT" | python3 -c "
12
+ import sys, json
13
+ try:
14
+ data = json.load(sys.stdin)
15
+ tool = data.get('tool_name', '')
16
+ inp = data.get('tool_input', {})
17
+ if tool == 'Bash':
18
+ print(inp.get('command', ''))
19
+ except:
20
+ pass
21
+ " 2>/dev/null)
22
+
23
+ if [ -z "$COMMAND" ]; then
24
+ exit 0
25
+ fi
26
+
27
+ # Only check commands that interact with MongoDB
28
+ if ! echo "$COMMAND" | grep -qE 'mongosh|mongo '; then
29
+ exit 0
30
+ fi
31
+
32
+ # Case-insensitive check for sensitive field names in the query
33
+ SENSITIVE_PATTERN='\b(TIN|Tin|TaxId|TaxIdentificationNumber|EIN|SSN|SocialSecurityNumber|Social|EncryptedTin|EncryptedSSN|EncryptedTaxId|BankAccountNumber|AccountNumber|RoutingNumber)\b'
34
+
35
+ if echo "$COMMAND" | grep -qE "$SENSITIVE_PATTERN"; then
36
+ echo "BLOCKED: Database query references a sensitive PII field (TIN, SSN, bank account, etc.)"
37
+ echo "These fields contain encrypted sensitive data that must never be queried or displayed."
38
+ echo "Use explicit inclusion projections with only non-sensitive fields."
39
+ echo "If you need to work with this data, use the application UI instead."
40
+ exit 2
41
+ fi
42
+
43
+ exit 0
@@ -0,0 +1,40 @@
1
+ #!/bin/bash
2
+ # Sensitive Data MCP Blocker Hook (PreToolUse - MCP MongoDB/MSSQL/Postgres tools)
3
+ # Blocks MCP database tool calls that reference sensitive PII fields.
4
+ # Even encrypted values must never be exposed.
5
+ # Exit code 2 = BLOCK the action.
6
+
7
+ # Read the tool input from stdin
8
+ INPUT=$(cat)
9
+
10
+ # Extract tool name and full input JSON
11
+ TOOL_INFO=$(echo "$INPUT" | python3 -c "
12
+ import sys, json
13
+ try:
14
+ data = json.load(sys.stdin)
15
+ tool = data.get('tool_name', '')
16
+ inp = json.dumps(data.get('tool_input', {}))
17
+ print(f'{tool}\n{inp}')
18
+ except:
19
+ pass
20
+ " 2>/dev/null)
21
+
22
+ TOOL_NAME=$(echo "$TOOL_INFO" | head -1)
23
+ TOOL_INPUT=$(echo "$TOOL_INFO" | tail -1)
24
+
25
+ if [ -z "$TOOL_NAME" ]; then
26
+ exit 0
27
+ fi
28
+
29
+ # Case-insensitive check for sensitive field names anywhere in the tool input
30
+ SENSITIVE_PATTERN='\b(TIN|Tin|TaxId|TaxIdentificationNumber|EIN|SSN|SocialSecurityNumber|Social|EncryptedTin|EncryptedSSN|EncryptedTaxId|BankAccountNumber|AccountNumber|RoutingNumber)\b'
31
+
32
+ if echo "$TOOL_INPUT" | grep -qE "$SENSITIVE_PATTERN"; then
33
+ echo "BLOCKED: MCP database query references a sensitive PII field (TIN, SSN, bank account, etc.)"
34
+ echo "These fields contain encrypted sensitive data that must never be queried or displayed."
35
+ echo "Use explicit inclusion projections with only non-sensitive fields."
36
+ echo "If you need to work with this data, use the application UI instead."
37
+ exit 2
38
+ fi
39
+
40
+ exit 0
@@ -0,0 +1,63 @@
1
+ #!/bin/bash
2
+ # Sensitive Data Output Blocker Hook (PostToolUse - Bash, Read, Grep, MCP DB tools)
3
+ # Scans tool output for sensitive PII field names that may have been returned
4
+ # by broad database queries, file reads of seed/dump data, or grep results.
5
+ # Exit code 2 = BLOCK (prevents the output from being used).
6
+
7
+ # Read the tool result from stdin
8
+ INPUT=$(cat)
9
+
10
+ # Extract output from any tool type (Bash stdout, Read content, Grep results, MCP results)
11
+ OUTPUT=$(echo "$INPUT" | python3 -c "
12
+ import sys, json
13
+ try:
14
+ data = json.load(sys.stdin)
15
+ tool = data.get('tool_name', '')
16
+ result = data.get('tool_result', '')
17
+
18
+ # Handle different result shapes
19
+ if isinstance(result, dict):
20
+ # Bash tool: check stdout
21
+ text = result.get('stdout', '')
22
+ # MCP/other tools: check content or stringify the whole result
23
+ if not text:
24
+ text = result.get('content', '')
25
+ if not text:
26
+ text = json.dumps(result)
27
+ elif isinstance(result, str):
28
+ text = result
29
+ else:
30
+ text = str(result)
31
+
32
+ print(text)
33
+ except:
34
+ pass
35
+ " 2>/dev/null)
36
+
37
+ if [ -z "$OUTPUT" ]; then
38
+ exit 0
39
+ fi
40
+
41
+ # Check if output contains sensitive field names as keys (indicating PII was returned)
42
+ # These patterns match field names in JSON documents, MongoDB output, C# properties, etc.
43
+ SENSITIVE_PATTERNS=(
44
+ # JSON/MongoDB style: "TIN": or 'TIN':
45
+ '"(TIN|Tin|TaxId|TaxIdentificationNumber|EIN|SSN|SocialSecurityNumber|EncryptedTin|EncryptedSSN|EncryptedTaxId|BankAccountNumber|AccountNumber|RoutingNumber)"\s*:'
46
+ # C# property style: .TIN = or .TaxId =
47
+ '\.(TIN|TaxId|TaxIdentificationNumber|EIN|SSN|SocialSecurityNumber|EncryptedTin|EncryptedSSN|EncryptedTaxId|BankAccountNumber|AccountNumber|RoutingNumber)\s*='
48
+ # YAML/config style: TIN: (start of line or after whitespace)
49
+ '(^|\s)(TIN|TaxId|TaxIdentificationNumber|EIN|SSN|SocialSecurityNumber|EncryptedTin|EncryptedSSN|EncryptedTaxId|BankAccountNumber|AccountNumber|RoutingNumber):\s'
50
+ )
51
+
52
+ for PATTERN in "${SENSITIVE_PATTERNS[@]}"; do
53
+ if echo "$OUTPUT" | grep -qE "$PATTERN"; then
54
+ echo "BLOCKED: Output contains sensitive PII fields (TIN, SSN, bank account, etc.)"
55
+ echo "The output includes documents or data with sensitive fields."
56
+ echo "For database queries: use an explicit inclusion projection listing only non-sensitive fields."
57
+ echo "For code searches: avoid reading seed data, test fixtures, or dump files containing PII."
58
+ echo "If you need to work with this data, use the application UI instead."
59
+ exit 2
60
+ fi
61
+ done
62
+
63
+ exit 0
@@ -0,0 +1,46 @@
1
+ #!/bin/bash
2
+ # Test Runner Hook (PostToolUse - Edit/Write)
3
+ # Suggests running related tests when source files are modified.
4
+ # Does NOT auto-run tests (too slow) — just reminds which tests to run.
5
+
6
+ INPUT=$(cat)
7
+
8
+ FILE_PATH=$(echo "$INPUT" | python3 -c "
9
+ import sys, json
10
+ try:
11
+ data = json.load(sys.stdin)
12
+ inp = data.get('tool_input', {})
13
+ print(inp.get('file_path', ''))
14
+ except:
15
+ pass
16
+ " 2>/dev/null)
17
+
18
+ if [ -z "$FILE_PATH" ]; then
19
+ exit 0
20
+ fi
21
+
22
+ EXT="${FILE_PATH##*.}"
23
+
24
+ # Only suggest for source files, not tests or configs
25
+ if echo "$FILE_PATH" | grep -qE '(Test|test|spec|__tests__)'; then
26
+ exit 0
27
+ fi
28
+
29
+ case "$EXT" in
30
+ cs)
31
+ if echo "$FILE_PATH" | grep -q "Glasswing"; then
32
+ echo "Run: dotnet test src/Glasswing.Tests/ --filter \"$(basename ${FILE_PATH%.cs})\""
33
+ elif echo "$FILE_PATH" | grep -q "Monarch"; then
34
+ echo "Run: dotnet test src/Monarch.Tests/ --filter \"$(basename ${FILE_PATH%.cs})\""
35
+ fi
36
+ ;;
37
+ ts|tsx)
38
+ if echo "$FILE_PATH" | grep -q "glasswing-client"; then
39
+ echo "Run: cd src/glasswing-client && npx vitest run --reporter=verbose"
40
+ elif echo "$FILE_PATH" | grep -q "monarch-client"; then
41
+ echo "Run: cd src/monarch-client && npx vitest run --reporter=verbose"
42
+ fi
43
+ ;;
44
+ esac
45
+
46
+ exit 0
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+ # UAT Reminder Hook for Glasswing-and-Monarch
3
+ # Fires on the Stop event to remind about UAT after feature implementation
4
+ #
5
+ # This checks if recent conversation context suggests a feature was being
6
+ # implemented and reminds the user to run UAT before marking it complete.
7
+
8
+ echo "Reminder: If you just completed a feature implementation, run UAT before marking it done."
9
+ echo "Use: 'Use gm-uat-generator to create UAT checklist for [Feature ID]'"
@@ -0,0 +1,274 @@
1
+
2
+ ## Claude Kit Workflow
3
+
4
+ This project uses [Claude Kit](https://github.com/Christopher-Waters/claude-kit) — a standardized set of agents, hooks, MCP servers, and workflows installed via `npx @chris1807/claude-kit init`.
5
+
6
+ ### Agent Pipeline
7
+
8
+ When given a task, Claude Code can delegate through specialized agents:
9
+
10
+ ```
11
+ You (give task)
12
+ ├── manager → orchestrates workflow, delegates to agents below
13
+ ├── Explore → finds relevant files
14
+ ├── Plan → designs the approach
15
+ ├── mockup → creates HTML screen mockups before implementation
16
+ ├── backend / frontend / legacy → implements code
17
+ ├── deployer → commits, pushes, triggers CD pipeline
18
+ ├── db-admin → queries/fixes MongoDB data
19
+ ├── devops-tracker → creates/updates Azure DevOps work items
20
+ ├── test-runner → runs xUnit, Vitest, Playwright tests
21
+ ├── build-validator → confirms builds pass
22
+ ├── lint-checker → runs ESLint and dotnet format
23
+ ├── uat-generator → generates UAT checklists from requirements
24
+ ├── security-auditor → scans for secrets, vulnerabilities
25
+ ├── api-tester → tests API endpoints with curl
26
+ ├── azure-ops → manages Azure infrastructure
27
+ └── reviewer → reviews code quality
28
+ ```
29
+
30
+ ### Sensitive Data Policy
31
+
32
+ **NEVER query, display, or expose sensitive PII fields from the database — even if the values are encrypted.** This includes TIN, SSN, EIN, TaxId, BankAccountNumber, RoutingNumber, and any `Encrypted*` variants. Even encrypted/hashed values must not appear in output, logs, or summaries. When querying collections that may contain sensitive fields, always use explicit inclusion projections listing only the non-sensitive fields needed. If a user requests access to sensitive data, direct them to use the application UI.
33
+
34
+ ### Automated Hooks
35
+
36
+ These run automatically — no action needed:
37
+
38
+ | When | What Happens |
39
+ |------|-------------|
40
+ | **Before any Bash command** | Sensitive data blocker prevents database queries that reference TIN, SSN, or other PII fields |
41
+ | **Before any MCP database tool** | Sensitive data MCP blocker prevents MCP database queries that reference PII fields |
42
+ | **After any Bash/MCP/Read/Grep command** | Sensitive data output blocker scans results for PII field names and blocks exposure |
43
+ | **Before any file write** | Secret blocker scans for hardcoded credentials and blocks them |
44
+ | **Before any file edit** | Protected files guard warns/blocks edits to production configs |
45
+ | **After any file edit** | Auto-formatter runs (dotnet format for .cs, eslint --fix for .ts) |
46
+ | **After any file edit** | Test suggestions appear for related test files |
47
+ | **When Claude stops** | UAT reminder if a feature was implemented |
48
+ | **When Claude stops** | Self-improvement prompt to save learnings to memory |
49
+
50
+ ### MCP Servers Available
51
+
52
+ | Server | What It Does |
53
+ |--------|-------------|
54
+ | **Azure DevOps** | Work items, pipelines, repos, wiki |
55
+ | **Playwright** | Browser testing (navigate, click, fill, screenshot) |
56
+ | **MongoDB** | Direct database queries and updates |
57
+ | **Microsoft Teams** | Send/read team messages and notifications |
58
+ | **Stripe** | Payment management (when configured) |
59
+ | **Azure** | 40+ Azure services via CLI |
60
+
61
+ ### Memory System
62
+
63
+ Claude maintains persistent memory across sessions in `~/.claude/projects/.../memory/`. This includes:
64
+ - **User preferences** — how you like to work
65
+ - **Feedback patterns** — what to do and what to avoid (self-improving)
66
+ - **Project context** — decisions, priorities, blockers
67
+ - **References** — URLs, test accounts, external resources
68
+
69
+ ### Development Workflow
70
+
71
+ 1. **Pick a work item** from Azure DevOps (or describe what you need)
72
+ 2. **Claude implements** using `/implement AB#<id>` (auto-creates branch)
73
+ 3. **Hooks guard** against secrets and bad patterns automatically
74
+ 4. **PR merges** into `develop` → deploys to Dev environment
75
+ 5. **Create a release** using `/create-release <N>` to group work items
76
+ 6. **Deploy the release** using `/deploy-release 23 staging` then `/deploy-release 23 production`
77
+ 7. **Test** using Playwright MCP for browser testing
78
+ 8. **Track** work items using the devops-tracker agent
79
+ 9. **Learn** — Claude saves what worked for next time
80
+
81
+ ### Branching Strategy
82
+
83
+ #### Target Branch-to-Environment Mapping
84
+
85
+ All projects should converge to this standard. Each long-lived branch maps to an Azure subscription and environment:
86
+
87
+ | Branch | Azure Subscription | Environment | CD Pipeline Trigger |
88
+ |---|---|---|---|
89
+ | `develop` | Dev | Development | Auto on merge |
90
+ | `staging` | Staging | Staging | Auto on merge |
91
+ | `main` | Production | Production | Auto on merge (with approval gate) |
92
+
93
+ > **Note:** Some projects are not yet in sync — they may use `master` instead of `main`, or lack a `staging` branch. Until a project is migrated, the deployer and `/implement` use the **current branch** dynamically and do not assume branch names.
94
+
95
+ #### Promotion Flow
96
+
97
+ Code flows through environments via PRs — never by direct push:
98
+
99
+ ```
100
+ feature/AB#1234-... ──PR──▸ develop ──PR──▸ staging ──PR──▸ main
101
+ (work branch) (Dev) (Staging) (Production)
102
+ ```
103
+
104
+ - **develop → staging**: PR to promote all work ready for QA/stakeholder review
105
+ - **staging → main**: PR to promote to production. May cherry-pick individual commits if only some stories are ready (see Cherry-Pick Deployments below)
106
+
107
+ #### Release Management
108
+
109
+ Releases group work items together for coordinated deployment across environments. Releases are tracked in Azure DevOps as iterations (`Release #N`) and work items are tagged with `release-{N}`.
110
+
111
+ **Creating a release:**
112
+ ```
113
+ /create-release 23
114
+ ```
115
+ This creates a `Release #23` iteration, assigns the selected work items to it, and tags them with `release-23`.
116
+
117
+ **Deploying a release to an environment:**
118
+ ```
119
+ /deploy-release 23 staging
120
+ /deploy-release 23 production
121
+ ```
122
+ This finds all work items in Release #23, cherry-picks their commits into a release branch (`release/23-to-staging`), creates a PR targeting the environment branch, and links all work items.
123
+
124
+ **Selective deployment:** Since releases are deployed via cherry-pick, you can deploy a full release or a subset. If staging has 5 user stories but only 3 should go to production, create a release with just those 3 and deploy it.
125
+
126
+ **Release flow:**
127
+ ```
128
+ /create-release 23 → Groups work items into Release #23
129
+ /deploy-release 23 staging → Cherry-picks Release #23 to staging
130
+ (QA/testing on staging)
131
+ /deploy-release 23 → Auto-detects next env (production), deploys
132
+ ```
133
+
134
+ #### Cherry-Pick Deployments
135
+
136
+ Cherry-pick specific work items to an environment without a formal release:
137
+ ```
138
+ /cherry-pick AB#1234 AB#1235 production
139
+ ```
140
+ This finds commits for the specified work items, cherry-picks them into a branch (`cherry-pick/<date>-to-<environment>`), and creates a PR.
141
+
142
+ #### Promoting Environments
143
+
144
+ Promote all code from one environment to the next:
145
+ ```
146
+ /promote staging production
147
+ /promote ← auto-detects source and target from current branch
148
+ ```
149
+ This creates a PR from the source branch to the target branch with a summary of all included commits.
150
+
151
+ #### Rollbacks
152
+
153
+ Roll back a deployment on any environment:
154
+ ```
155
+ /rollback AB#1234 production ← revert specific work items
156
+ /rollback last staging ← revert the most recent deployment
157
+ ```
158
+ This creates a revert branch, reverts the specified commits, runs pre-flight checks, and creates a PR.
159
+
160
+ For emergency production rollbacks, the `/rollback` command already runs pre-flight checks and skips UAT. Treat the resulting PR as urgent and flag the user accordingly.
161
+
162
+ #### Deploying Changes
163
+
164
+ Commit, push, and deploy the current changes:
165
+ ```
166
+ /deploy "Add payment export feature"
167
+ /deploy ← auto-generates commit message
168
+ ```
169
+ This runs pre-flight checks, commits, pushes the current branch, and triggers the CD pipeline if on an environment branch.
170
+
171
+ #### Branch Naming Convention
172
+
173
+ When `/implement AB#<id>` is run, a branch is created off the current branch based on the Azure DevOps work item type:
174
+
175
+ | Work Item Type | Branch Prefix | Example |
176
+ |---|---|---|
177
+ | Feature | `feature/` | `feature/AB#1234-add-payment-export` |
178
+ | User Story | `story/` | `story/AB#1235-user-can-view-history` |
179
+ | Bug | `bugfix/` | `bugfix/AB#1236-fix-login-redirect` |
180
+ | Hot Fix | `hotfix/` | `hotfix/AB#1237-fix-crash-on-submit` |
181
+ | (other) | `work/` | `work/AB#1238-update-dependencies` |
182
+
183
+ Format: `{prefix}AB#{id}-{sanitized-title}` (title lowercased, special chars replaced with hyphens, max 50 chars)
184
+
185
+ > **Note:** The Azure DevOps work item type is "Hot Fix" (two words), but the branch prefix and PR label use `hotfix` (one word, lowercase).
186
+
187
+ #### PR Targeting
188
+
189
+ PRs always target the branch you were on when `/implement` was invoked. The base branch is captured dynamically at the start — no assumptions about branch names.
190
+
191
+ #### Hot Fix Workflow
192
+
193
+ Hot Fix work items follow the same automated checks (build, lint, tests, review) but skip manual UAT. An abbreviated confirmation is shown instead. Hot Fix PRs get a `hotfix` label. Hot Fixes target the current branch (which should be the project's production branch for production hot fixes).
194
+
195
+ #### Slash Commands Reference
196
+
197
+ All deployment and release operations are available as slash commands:
198
+
199
+ | Command | Usage | What It Does |
200
+ |---|---|---|
201
+ | `/implement` | `/implement AB#1234` | Summarize work item → approve plan → implement → PR |
202
+ | `/review` | `/review 142` | Automated code review on a PR |
203
+ | `/deploy` | `/deploy "commit message"` | Commit, push, trigger pipeline |
204
+ | `/create-release` | `/create-release 23` | Group work items into Release #23 |
205
+ | `/deploy-release` | `/deploy-release 23 staging` | Cherry-pick release to environment |
206
+ | `/add-to-release` | `/add-to-release 24 AB#4599` | Add work items to existing release |
207
+ | `/cherry-pick` | `/cherry-pick AB#1234 AB#1235 production` | Cherry-pick specific work items |
208
+ | `/promote` | `/promote staging production` | Promote all code between environments |
209
+ | `/rollback` | `/rollback AB#1234 production` | Revert commits on an environment |
210
+ | `/status` | `/status release 24` | Check release, pipeline, or work item status |
211
+ | `/cleanup-branches` | `/cleanup-branches` | Delete merged branches |
212
+
213
+ The CD pipeline is only triggered manually when pushing directly to an environment branch. For feature/work branches, the pipeline triggers on PR merge.
214
+
215
+ ### Pipeline Configuration
216
+
217
+ Each project must define its environment chain and pipeline IDs so the slash commands (`/deploy`, `/promote`, `/deploy-release`) know which pipelines to trigger and what the promotion order is.
218
+
219
+ Add this section to your project's `CLAUDE.md`:
220
+
221
+ ```markdown
222
+ ## Pipeline Configuration
223
+
224
+ | Branch | Environment | Pipeline(s) |
225
+ |--------|------------|-------------|
226
+ | develop | Dev | My API (ID), My Client (ID) |
227
+ | staging | Staging | My API (ID), My Client (ID) |
228
+ | main | Production | My API (ID), My Client (ID) |
229
+ ```
230
+
231
+ **Rules for slash commands:**
232
+ - `/deploy` triggers the pipeline(s) listed for the current branch. If the current branch is not in this table, no pipeline is triggered.
233
+ - `/promote` uses this table to determine the next environment (e.g., `develop` → `staging` → `main`).
234
+ - `/deploy-release` and `/cherry-pick` create PRs targeting environment branches listed here.
235
+ - The **order of rows** defines the promotion flow (top to bottom).
236
+
237
+ **Examples from actual projects:**
238
+
239
+ CSIPay (4 environments):
240
+ ```markdown
241
+ | Branch | Environment | Pipeline(s) |
242
+ |--------|------------|-------------|
243
+ | Dev | Dev | CSIPay API (12), CSIPay Client (13) |
244
+ | QA | QA | CSIPay API (12), CSIPay Client (13) |
245
+ | Staging | Staging | CSIPay API (12), CSIPay Client (13) |
246
+ | master | Production | CSIPay API (12), CSIPay Client (13) |
247
+ ```
248
+
249
+ Glasswing and Monarch (1 environment currently):
250
+ ```markdown
251
+ | Branch | Environment | Pipeline(s) |
252
+ |--------|------------|-------------|
253
+ | develop | Dev | CD - Development (28) |
254
+ ```
255
+
256
+ ### Environment Setup
257
+
258
+ Each team member needs to set their own environment variables (never commit these):
259
+
260
+ ```bash
261
+ # MongoDB (required for db-admin agent)
262
+ export MONGODB_CONNECTION_STRING="mongodb+srv://..."
263
+
264
+ # Microsoft Teams (required for team notifications)
265
+ export TEAMS_TENANT_ID="..."
266
+ export TEAMS_CLIENT_ID="..."
267
+ export TEAMS_CLIENT_SECRET="..."
268
+
269
+ # Stripe (required when payment integration is active)
270
+ export STRIPE_SECRET_KEY="sk_test_..."
271
+
272
+ # Azure (use az login instead of env vars)
273
+ az login
274
+ ```
@@ -0,0 +1,199 @@
1
+ # Standard Azure DevOps Pipeline Template (example)
2
+ #
3
+ # Multi-stage YAML pipeline that builds once and deploys to the correct
4
+ # environment based on the source branch.
5
+ #
6
+ # Usage:
7
+ # 1. Copy this file to your project root as azure-pipelines.yml
8
+ # 2. Replace all {{PLACEHOLDER}} values with your project-specific values
9
+ # 3. Remove stages you don't need (e.g., QA if your project doesn't have it)
10
+ # 4. Create a new pipeline in Azure DevOps pointing to this file
11
+ #
12
+ # Branch-to-environment mapping:
13
+ # develop → Dev
14
+ # staging → Staging
15
+ # main → Production
16
+
17
+ trigger:
18
+ branches:
19
+ include:
20
+ - develop
21
+ - staging
22
+ - main
23
+ paths:
24
+ include:
25
+ - "{{PROJECT_PATH}}/**" # e.g., Api/**, Client/**, src/**
26
+
27
+ pool:
28
+ vmImage: "windows-latest" # Use "ubuntu-latest" for Linux-based builds
29
+
30
+ variables:
31
+ buildConfiguration: "Release"
32
+ projectName: "{{PROJECT_NAME}}" # e.g., CompassAPI, CSIPayAPI
33
+ solutionFile: "{{SOLUTION_FILE}}" # e.g., CompassPOC.sln, CSIPay.sln
34
+ WebsitePhysicalPath: "{{PHYSICAL_PATH}}" # e.g., F:\Compass\Api
35
+
36
+ # Dev environment
37
+ devWebsiteName: "{{DEV_WEBSITE_NAME}}" # e.g., dev.api.compass.caresolutions.com
38
+ devAppPoolName: "{{DEV_APP_POOL}}" # e.g., dev.api.compass.com
39
+
40
+ # Staging environment
41
+ stagingWebsiteName: "{{STAGING_WEBSITE_NAME}}" # e.g., staging.api.compass.caresolutions.com
42
+ stagingAppPoolName: "{{STAGING_APP_POOL}}" # e.g., staging.api.compass.com
43
+
44
+ # Production environment
45
+ prodWebsiteName: "{{PROD_WEBSITE_NAME}}" # e.g., api.compass.caresolutions.com
46
+ prodAppPoolName: "{{PROD_APP_POOL}}" # e.g., api.compass.com
47
+
48
+ stages:
49
+ # ── Build ──────────────────────────────────────────────
50
+ - stage: Build
51
+ displayName: "Build"
52
+ jobs:
53
+ - job: BuildJob
54
+ displayName: "Build and Publish"
55
+ steps:
56
+ - script: |
57
+ dotnet build $(solutionFile) --configuration $(buildConfiguration)
58
+ dotnet publish $(solutionFile) --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)
59
+ displayName: "dotnet build and publish"
60
+
61
+ - task: ArchiveFiles@2
62
+ displayName: "Zip Published Files"
63
+ inputs:
64
+ rootFolderOrFile: "$(Build.ArtifactStagingDirectory)"
65
+ includeRootFolder: false
66
+ archiveType: "zip"
67
+ archiveFile: "$(Build.ArtifactStagingDirectory)/$(projectName).zip"
68
+
69
+ - publish: $(Build.ArtifactStagingDirectory)/$(projectName).zip
70
+ artifact: drop
71
+
72
+ # ── Dev ────────────────────────────────────────────────
73
+ - stage: Dev
74
+ displayName: "Deploy to Dev"
75
+ dependsOn: "Build"
76
+ condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/develop'))
77
+ jobs:
78
+ - deployment: DeployDev
79
+ displayName: "Deploy to Dev"
80
+ environment:
81
+ name: "{{DEV_ENVIRONMENT_NAME}}" # e.g., Dev
82
+ resourceType: VirtualMachine
83
+ strategy:
84
+ runOnce:
85
+ deploy:
86
+ steps:
87
+ - task: DownloadPipelineArtifact@2
88
+ inputs:
89
+ artifact: "drop"
90
+ path: "$(Build.ArtifactStagingDirectory)"
91
+
92
+ - task: IISWebAppManagementOnMachineGroup@0
93
+ displayName: "Configure IIS"
94
+ inputs:
95
+ IISDeploymentType: "IISWebsite"
96
+ ActionIISWebsite: "CreateOrUpdateWebsite"
97
+ WebsiteName: "$(devWebsiteName)"
98
+ WebsitePhysicalPath: "$(WebsitePhysicalPath)"
99
+ WebsitePhysicalPathAuth: "WebsiteUserPassThrough"
100
+ AddBinding: false
101
+ CreateOrUpdateAppPoolForWebsite: true
102
+ AppPoolNameForWebsite: "$(devAppPoolName)"
103
+ DotNetVersionForWebsite: "No Managed Code"
104
+ PipeLineModeForWebsite: "Integrated"
105
+ AppPoolIdentityForWebsite: "ApplicationPoolIdentity"
106
+
107
+ - task: IISWebAppDeploymentOnMachineGroup@0
108
+ displayName: "Deploy to IIS"
109
+ inputs:
110
+ WebsiteName: "$(devWebsiteName)"
111
+ Package: "$(Build.ArtifactStagingDirectory)/$(projectName).zip"
112
+ TakeAppOfflineFlag: true
113
+ XmlVariableSubstitution: true
114
+
115
+ # ── Staging ────────────────────────────────────────────
116
+ - stage: Staging
117
+ displayName: "Deploy to Staging"
118
+ dependsOn: "Build"
119
+ condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/staging'))
120
+ jobs:
121
+ - deployment: DeployStaging
122
+ displayName: "Deploy to Staging"
123
+ environment:
124
+ name: "{{STAGING_ENVIRONMENT_NAME}}" # e.g., Staging
125
+ resourceType: VirtualMachine
126
+ strategy:
127
+ runOnce:
128
+ deploy:
129
+ steps:
130
+ - task: DownloadPipelineArtifact@2
131
+ inputs:
132
+ artifact: "drop"
133
+ path: "$(Build.ArtifactStagingDirectory)"
134
+
135
+ - task: IISWebAppManagementOnMachineGroup@0
136
+ displayName: "Configure IIS"
137
+ inputs:
138
+ IISDeploymentType: "IISWebsite"
139
+ ActionIISWebsite: "CreateOrUpdateWebsite"
140
+ WebsiteName: "$(stagingWebsiteName)"
141
+ WebsitePhysicalPath: "$(WebsitePhysicalPath)"
142
+ WebsitePhysicalPathAuth: "WebsiteUserPassThrough"
143
+ AddBinding: false
144
+ CreateOrUpdateAppPoolForWebsite: true
145
+ AppPoolNameForWebsite: "$(stagingAppPoolName)"
146
+ DotNetVersionForWebsite: "No Managed Code"
147
+ PipeLineModeForWebsite: "Integrated"
148
+ AppPoolIdentityForWebsite: "ApplicationPoolIdentity"
149
+
150
+ - task: IISWebAppDeploymentOnMachineGroup@0
151
+ displayName: "Deploy to IIS"
152
+ inputs:
153
+ WebsiteName: "$(stagingWebsiteName)"
154
+ Package: "$(Build.ArtifactStagingDirectory)/$(projectName).zip"
155
+ TakeAppOfflineFlag: true
156
+ XmlVariableSubstitution: true
157
+
158
+ # ── Production ─────────────────────────────────────────
159
+ - stage: Production
160
+ displayName: "Deploy to Production"
161
+ dependsOn: "Build"
162
+ condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
163
+ jobs:
164
+ - deployment: DeployProd
165
+ displayName: "Deploy to Production"
166
+ environment:
167
+ name: "{{PROD_ENVIRONMENT_NAME}}" # e.g., Production
168
+ resourceType: VirtualMachine
169
+ strategy:
170
+ runOnce:
171
+ deploy:
172
+ steps:
173
+ - task: DownloadPipelineArtifact@2
174
+ inputs:
175
+ artifact: "drop"
176
+ path: "$(Build.ArtifactStagingDirectory)"
177
+
178
+ - task: IISWebAppManagementOnMachineGroup@0
179
+ displayName: "Configure IIS"
180
+ inputs:
181
+ IISDeploymentType: "IISWebsite"
182
+ ActionIISWebsite: "CreateOrUpdateWebsite"
183
+ WebsiteName: "$(prodWebsiteName)"
184
+ WebsitePhysicalPath: "$(WebsitePhysicalPath)"
185
+ WebsitePhysicalPathAuth: "WebsiteUserPassThrough"
186
+ AddBinding: false
187
+ CreateOrUpdateAppPoolForWebsite: true
188
+ AppPoolNameForWebsite: "$(prodAppPoolName)"
189
+ DotNetVersionForWebsite: "No Managed Code"
190
+ PipeLineModeForWebsite: "Integrated"
191
+ AppPoolIdentityForWebsite: "ApplicationPoolIdentity"
192
+
193
+ - task: IISWebAppDeploymentOnMachineGroup@0
194
+ displayName: "Deploy to IIS"
195
+ inputs:
196
+ WebsiteName: "$(prodWebsiteName)"
197
+ Package: "$(Build.ArtifactStagingDirectory)/$(projectName).zip"
198
+ TakeAppOfflineFlag: true
199
+ XmlVariableSubstitution: true