@desplega.ai/agent-swarm 1.57.5 → 1.59.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 (68) hide show
  1. package/openapi.json +211 -1
  2. package/package.json +1 -1
  3. package/plugin/commands/create-pr.md +7 -5
  4. package/plugin/commands/implement-issue.md +6 -3
  5. package/plugin/commands/review-pr.md +6 -0
  6. package/plugin/commands/user-management.md +119 -0
  7. package/plugin/pi-skills/create-pr/SKILL.md +7 -5
  8. package/plugin/pi-skills/implement-issue/SKILL.md +6 -3
  9. package/plugin/pi-skills/review-pr/SKILL.md +6 -0
  10. package/plugin/pi-skills/user-management/SKILL.md +119 -0
  11. package/src/agentmail/handlers.ts +20 -0
  12. package/src/be/db.ts +284 -7
  13. package/src/be/migrations/031_user_registry.sql +35 -0
  14. package/src/be/migrations/032_repo_guidelines.sql +4 -0
  15. package/src/commands/runner.ts +28 -4
  16. package/src/github/handlers.ts +18 -1
  17. package/src/gitlab/handlers.ts +12 -1
  18. package/src/heartbeat/heartbeat.ts +174 -6
  19. package/src/heartbeat/index.ts +1 -1
  20. package/src/heartbeat/templates.ts +31 -19
  21. package/src/http/poll.ts +9 -0
  22. package/src/http/repos.ts +5 -1
  23. package/src/linear/sync.ts +25 -1
  24. package/src/prompts/base-prompt.ts +41 -0
  25. package/src/prompts/session-templates.ts +34 -2
  26. package/src/server.ts +12 -0
  27. package/src/slack/actions.ts +10 -1
  28. package/src/slack/assistant.ts +7 -0
  29. package/src/slack/handlers.ts +9 -2
  30. package/src/tests/base-prompt.test.ts +72 -0
  31. package/src/tests/build-pi-skills.test.ts +1 -1
  32. package/src/tests/events-http.test.ts +2 -2
  33. package/src/tests/heartbeat-checklist.test.ts +112 -0
  34. package/src/tests/heartbeat.test.ts +231 -0
  35. package/src/tests/http-api-integration.test.ts +3 -3
  36. package/src/tests/linear-outbound-sync.test.ts +7 -7
  37. package/src/tests/preload.ts +14 -0
  38. package/src/tests/prompt-template-session.test.ts +2 -2
  39. package/src/tests/rest-api.test.ts +1 -1
  40. package/src/tests/swarm-repos.test.ts +75 -0
  41. package/src/tests/user-identity.test.ts +306 -0
  42. package/src/tests/workflow-async-v2.test.ts +7 -7
  43. package/src/tests/workflow-engine-v2.test.ts +3 -3
  44. package/src/tests/workflow-hitl-routing.test.ts +7 -7
  45. package/src/tests/workflow-http-v2.test.ts +1 -1
  46. package/src/tests/workflow-retry-v2.test.ts +4 -4
  47. package/src/tests/workflow-retry-validation.test.ts +3 -3
  48. package/src/tests/workflow-validation-port-routing.test.ts +221 -0
  49. package/src/tools/get-task-details.ts +14 -1
  50. package/src/tools/manage-user.ts +172 -0
  51. package/src/tools/repos/get-repos.ts +57 -0
  52. package/src/tools/repos/index.ts +2 -0
  53. package/src/tools/repos/update-repo.ts +64 -0
  54. package/src/tools/resolve-user.ts +55 -0
  55. package/src/tools/tool-config.ts +8 -0
  56. package/src/types.ts +36 -0
  57. package/src/workflows/engine.ts +18 -4
  58. package/src/workflows/validation.ts +6 -3
  59. package/templates/official/coder/CLAUDE.md +3 -2
  60. package/templates/official/lead/CLAUDE.md +13 -3
  61. package/templates/official/lead/HEARTBEAT.md +5 -8
  62. package/templates/official/lead/SOUL.md +4 -0
  63. package/templates/official/ux-principles/CLAUDE.md +192 -0
  64. package/templates/official/ux-principles/IDENTITY.md +43 -0
  65. package/templates/official/ux-principles/SOUL.md +51 -0
  66. package/templates/official/ux-principles/TOOLS.md +56 -0
  67. package/templates/official/ux-principles/config.json +23 -0
  68. package/templates/official/ux-principles/start-up.sh +18 -0
package/openapi.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.1.0",
3
3
  "info": {
4
4
  "title": "Agent Swarm API",
5
- "version": "1.57.5",
5
+ "version": "1.59.0",
6
6
  "description": "Multi-agent orchestration API for Claude Code, Codex, and Gemini CLI. Enables task distribution, agent communication, and service discovery.\n\nMCP tools are documented separately in [MCP.md](./MCP.md)."
7
7
  },
8
8
  "servers": [
@@ -2879,6 +2879,41 @@
2879
2879
  "type": "boolean",
2880
2880
  "default": true
2881
2881
  },
2882
+ "guidelines": {
2883
+ "type": [
2884
+ "object",
2885
+ "null"
2886
+ ],
2887
+ "properties": {
2888
+ "prChecks": {
2889
+ "type": "array",
2890
+ "items": {
2891
+ "type": "string"
2892
+ }
2893
+ },
2894
+ "mergeChecks": {
2895
+ "type": "array",
2896
+ "items": {
2897
+ "type": "string"
2898
+ }
2899
+ },
2900
+ "allowMerge": {
2901
+ "type": "boolean",
2902
+ "default": false
2903
+ },
2904
+ "review": {
2905
+ "type": "array",
2906
+ "items": {
2907
+ "type": "string"
2908
+ }
2909
+ }
2910
+ },
2911
+ "required": [
2912
+ "prChecks",
2913
+ "mergeChecks",
2914
+ "review"
2915
+ ]
2916
+ },
2882
2917
  "createdAt": {
2883
2918
  "type": "string"
2884
2919
  },
@@ -2959,6 +2994,41 @@
2959
2994
  },
2960
2995
  "autoClone": {
2961
2996
  "type": "boolean"
2997
+ },
2998
+ "guidelines": {
2999
+ "type": [
3000
+ "object",
3001
+ "null"
3002
+ ],
3003
+ "properties": {
3004
+ "prChecks": {
3005
+ "type": "array",
3006
+ "items": {
3007
+ "type": "string"
3008
+ }
3009
+ },
3010
+ "mergeChecks": {
3011
+ "type": "array",
3012
+ "items": {
3013
+ "type": "string"
3014
+ }
3015
+ },
3016
+ "allowMerge": {
3017
+ "type": "boolean",
3018
+ "default": false
3019
+ },
3020
+ "review": {
3021
+ "type": "array",
3022
+ "items": {
3023
+ "type": "string"
3024
+ }
3025
+ }
3026
+ },
3027
+ "required": [
3028
+ "prChecks",
3029
+ "mergeChecks",
3030
+ "review"
3031
+ ]
2962
3032
  }
2963
3033
  }
2964
3034
  }
@@ -2998,6 +3068,41 @@
2998
3068
  "type": "boolean",
2999
3069
  "default": true
3000
3070
  },
3071
+ "guidelines": {
3072
+ "type": [
3073
+ "object",
3074
+ "null"
3075
+ ],
3076
+ "properties": {
3077
+ "prChecks": {
3078
+ "type": "array",
3079
+ "items": {
3080
+ "type": "string"
3081
+ }
3082
+ },
3083
+ "mergeChecks": {
3084
+ "type": "array",
3085
+ "items": {
3086
+ "type": "string"
3087
+ }
3088
+ },
3089
+ "allowMerge": {
3090
+ "type": "boolean",
3091
+ "default": false
3092
+ },
3093
+ "review": {
3094
+ "type": "array",
3095
+ "items": {
3096
+ "type": "string"
3097
+ }
3098
+ }
3099
+ },
3100
+ "required": [
3101
+ "prChecks",
3102
+ "mergeChecks",
3103
+ "review"
3104
+ ]
3105
+ },
3001
3106
  "createdAt": {
3002
3107
  "type": "string"
3003
3108
  },
@@ -3187,6 +3292,41 @@
3187
3292
  "type": "boolean",
3188
3293
  "default": true
3189
3294
  },
3295
+ "guidelines": {
3296
+ "type": [
3297
+ "object",
3298
+ "null"
3299
+ ],
3300
+ "properties": {
3301
+ "prChecks": {
3302
+ "type": "array",
3303
+ "items": {
3304
+ "type": "string"
3305
+ }
3306
+ },
3307
+ "mergeChecks": {
3308
+ "type": "array",
3309
+ "items": {
3310
+ "type": "string"
3311
+ }
3312
+ },
3313
+ "allowMerge": {
3314
+ "type": "boolean",
3315
+ "default": false
3316
+ },
3317
+ "review": {
3318
+ "type": "array",
3319
+ "items": {
3320
+ "type": "string"
3321
+ }
3322
+ }
3323
+ },
3324
+ "required": [
3325
+ "prChecks",
3326
+ "mergeChecks",
3327
+ "review"
3328
+ ]
3329
+ },
3190
3330
  "createdAt": {
3191
3331
  "type": "string"
3192
3332
  },
@@ -3246,6 +3386,41 @@
3246
3386
  },
3247
3387
  "autoClone": {
3248
3388
  "type": "boolean"
3389
+ },
3390
+ "guidelines": {
3391
+ "type": [
3392
+ "object",
3393
+ "null"
3394
+ ],
3395
+ "properties": {
3396
+ "prChecks": {
3397
+ "type": "array",
3398
+ "items": {
3399
+ "type": "string"
3400
+ }
3401
+ },
3402
+ "mergeChecks": {
3403
+ "type": "array",
3404
+ "items": {
3405
+ "type": "string"
3406
+ }
3407
+ },
3408
+ "allowMerge": {
3409
+ "type": "boolean",
3410
+ "default": false
3411
+ },
3412
+ "review": {
3413
+ "type": "array",
3414
+ "items": {
3415
+ "type": "string"
3416
+ }
3417
+ }
3418
+ },
3419
+ "required": [
3420
+ "prChecks",
3421
+ "mergeChecks",
3422
+ "review"
3423
+ ]
3249
3424
  }
3250
3425
  },
3251
3426
  "required": [
@@ -3289,6 +3464,41 @@
3289
3464
  "type": "boolean",
3290
3465
  "default": true
3291
3466
  },
3467
+ "guidelines": {
3468
+ "type": [
3469
+ "object",
3470
+ "null"
3471
+ ],
3472
+ "properties": {
3473
+ "prChecks": {
3474
+ "type": "array",
3475
+ "items": {
3476
+ "type": "string"
3477
+ }
3478
+ },
3479
+ "mergeChecks": {
3480
+ "type": "array",
3481
+ "items": {
3482
+ "type": "string"
3483
+ }
3484
+ },
3485
+ "allowMerge": {
3486
+ "type": "boolean",
3487
+ "default": false
3488
+ },
3489
+ "review": {
3490
+ "type": "array",
3491
+ "items": {
3492
+ "type": "string"
3493
+ }
3494
+ }
3495
+ },
3496
+ "required": [
3497
+ "prChecks",
3498
+ "mergeChecks",
3499
+ "review"
3500
+ ]
3501
+ },
3292
3502
  "createdAt": {
3293
3503
  "type": "string"
3294
3504
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@desplega.ai/agent-swarm",
3
- "version": "1.57.5",
3
+ "version": "1.59.0",
4
4
  "description": "Multi-agent orchestration for Claude Code, Codex, Gemini CLI, and other AI coding assistants",
5
5
  "license": "MIT",
6
6
  "author": "desplega.sh <contact@desplega.sh>",
@@ -22,13 +22,15 @@ You should be working in a repository cloned to `/workspace/personal/<repo-name>
22
22
  ## Workflow
23
23
 
24
24
  1. **Verify state** — confirm you're in a git repo, not on main/master, and have commits to push.
25
- 2. **Push the branch** — `git push -u origin HEAD`
26
- 3. **Gather context** — review commit messages and changed files since diverging from base.
27
- 4. **Generate title and description:**
25
+ 2. **Run PR checks (MANDATORY)** — Run ALL checks listed in the "PR Checks" section of your Repository Guidelines. Run each command/task sequentially. If ANY check fails, fix the issue and re-run until all pass. If no guidelines are defined, check the project's CLAUDE.md for a pre-PR checklist and run those. Do NOT proceed until all checks pass.
26
+ 3. **Push the branch** — `git push -u origin HEAD`
27
+ 4. **Gather context** — review commit messages and changed files since diverging from base.
28
+ 5. **Generate title and description:**
28
29
  - **Title**: Concise summary (conventional commit style if the repo uses it)
29
30
  - **Description**: Summary of changes, notable items, testing done, related issues
30
- 5. **Create the PR/MR** using `gh pr create` or `glab mr create`.
31
- 6. **Report** the PR/MR URL.
31
+ 6. **Create the PR/MR** using `gh pr create` or `glab mr create`.
32
+ 7. **Check CI status** — After creating the PR, wait ~30 seconds, then check CI with `gh pr checks <pr-number>` (GitHub) or `glab mr view --json pipelines` (GitLab). If any check is failing, investigate the failure, fix it, push the fix, and re-check. Repeat until CI is green.
33
+ 8. **Report** the PR/MR URL and CI status.
32
34
 
33
35
  ## Tips
34
36
 
@@ -37,14 +37,18 @@ If given a URL, extract owner, repo, and issue number. Fetch issue details (titl
37
37
 
38
38
  Keep changes focused on what the issue requests. Avoid scope creep.
39
39
 
40
- ### 4. Commit and Push
40
+ ### 4. Quality Checks, Commit, and Push
41
41
 
42
- Commit with a message referencing the issue (e.g., `Fix #123: <description>`). Use conventional commit style if the repo uses it. Push with `git push -u origin HEAD`.
42
+ 1. **Run PR checks (MANDATORY)** — Run ALL checks from the "PR Checks" section of your Repository Guidelines. Fix any failures before proceeding. If no guidelines are defined, check the project's CLAUDE.md for a pre-PR checklist.
43
+ 2. **Commit** with a message referencing the issue (e.g., `Fix #123: <description>`). Use conventional commit style if the repo uses it.
44
+ 3. **Push** with `git push -u origin HEAD`.
43
45
 
44
46
  ### 5. Create the PR
45
47
 
46
48
  Create the PR with a descriptive title and body including: summary of changes, key changes list, testing done, and `Fixes #<issue-number>` to auto-close the issue on merge.
47
49
 
50
+ After creating the PR, check CI status with `gh pr checks` (GitHub) or `glab mr view --json pipelines` (GitLab). If CI fails, fix the issues, push, and re-check until green.
51
+
48
52
  ### 6. Report Back
49
53
 
50
54
  Provide the PR URL, summary of changes, and any caveats. Optionally comment on the original issue linking the PR.
@@ -56,4 +60,3 @@ Provide the PR URL, summary of changes, and any caveats. Optionally comment on t
56
60
  - One issue = one PR
57
61
  - If the issue is too large, break it into smaller PRs
58
62
  - If unclear, use `/respond-github` to ask for clarification
59
- - Run linters and tests before creating the PR
@@ -28,6 +28,12 @@ Check CI with `gh pr checks <pr-number>` (or `glab mr view --json pipelines`).
28
28
 
29
29
  **If CI checks are failing, this is an automatic REQUEST_CHANGES.** Do not approve a PR with failing CI. Include the failing check names and error details in your review.
30
30
 
31
+ ### 2b. Review Repository Guidelines
32
+
33
+ Check the "Review Guidance" section of your Repository Guidelines for repo-specific review instructions (e.g., "check README.md", "enforce camelCase in specific directories"). Apply these instructions during your review below.
34
+
35
+ Also note the repo's **Merge Policy** — check `allowMerge` and `mergeChecks` before approving or merging. If `allowMerge` is false, do NOT merge — only review and approve/request changes.
36
+
31
37
  ### 3. Verify Tests Are Included (MANDATORY)
32
38
 
33
39
  Check that the PR includes test changes. **If the PR modifies code but does not add or update tests, this is an automatic REQUEST_CHANGES.** Every code change must include corresponding tests.
@@ -0,0 +1,119 @@
1
+ ---
2
+ description: "How to manage the user registry — creating users for new Slack/GitHub/GitLab identities, managing aliases, resolving users across platforms. Use when a new human interacts with the swarm or when user identity needs updating."
3
+ argument-hint: [action]
4
+ ---
5
+
6
+ # User Management
7
+
8
+ Manage the swarm's user registry — creating, updating, resolving, and listing users. Users link human identities across platforms (Slack, GitHub, GitLab, Linear, email) so the swarm can track who requested work.
9
+
10
+ ## When to Create Users
11
+
12
+ Create a new user when:
13
+ - An **unknown Slack user** sends a message to the swarm (no `resolveUser` match for their `slackUserId`)
14
+ - An **unknown GitHub user** opens an issue or PR that triggers a task
15
+ - An **unknown GitLab user** creates an issue or MR
16
+ - An **unknown Linear user** is assigned to or creates a synced issue
17
+ - A human explicitly asks to be registered
18
+
19
+ **Do NOT** create duplicate users. Always call `resolve-user` first to check if the person already exists under a different platform identity.
20
+
21
+ ## Tools
22
+
23
+ Two MCP tools handle user management:
24
+
25
+ ### `resolve-user` — Find an existing user
26
+
27
+ Looks up a user by any platform identity. Use this BEFORE creating a new user.
28
+
29
+ ```
30
+ resolve-user with:
31
+ slackUserId: "U12345" # Slack member ID
32
+ # OR
33
+ githubUsername: "octocat" # GitHub username
34
+ # OR
35
+ gitlabUsername: "octocat" # GitLab username
36
+ # OR
37
+ linearUserId: "uuid" # Linear user UUID
38
+ # OR
39
+ email: "user@example.com" # Primary email or alias
40
+ # OR
41
+ name: "Jane Doe" # Fuzzy name search (least specific)
42
+ ```
43
+
44
+ Priority order: platform IDs > email > name. Platform IDs are exact matches; email checks aliases (case-insensitive); name is substring match.
45
+
46
+ ### `manage-user` — CRUD operations
47
+
48
+ ```
49
+ # Create a new user
50
+ manage-user with:
51
+ action: "create"
52
+ name: "Jane Doe" # Required
53
+ email: "jane@company.com" # Optional
54
+ role: "engineering lead" # Optional, free-form
55
+ slackUserId: "U12345" # Optional
56
+ githubUsername: "janedoe" # Optional
57
+ gitlabUsername: "janedoe" # Optional
58
+ linearUserId: "uuid-from-linear" # Optional
59
+ emailAliases: ["jane.doe@company.com"] # Optional
60
+ timezone: "America/New_York" # Optional
61
+ notes: "Prefers async communication" # Optional
62
+
63
+ # List all users
64
+ manage-user with:
65
+ action: "list"
66
+
67
+ # Get a specific user
68
+ manage-user with:
69
+ action: "get"
70
+ userId: "<uuid>"
71
+
72
+ # Update a user (only send fields to change)
73
+ manage-user with:
74
+ action: "update"
75
+ userId: "<uuid>"
76
+ githubUsername: "new-username"
77
+
78
+ # Delete a user
79
+ manage-user with:
80
+ action: "delete"
81
+ userId: "<uuid>"
82
+ ```
83
+
84
+ ## Workflow: New Slack User
85
+
86
+ 1. Receive a message from an unknown Slack user (e.g., `slackUserId: "U_NEW123"`)
87
+ 2. Call `resolve-user` with `slackUserId: "U_NEW123"` — returns null
88
+ 3. Get the user's Slack profile (name, email) via `slack-read` or from the message metadata
89
+ 4. Call `resolve-user` with `email: "<their-email>"` — check if they exist under a different platform
90
+ 5. If found: call `manage-user` with `action: "update"` to add their `slackUserId`
91
+ 6. If not found: call `manage-user` with `action: "create"` including name, email, and slackUserId
92
+
93
+ ## Workflow: New GitHub User
94
+
95
+ 1. Receive a webhook from an unknown GitHub user (e.g., `githubUsername: "octocat"`)
96
+ 2. Call `resolve-user` with `githubUsername: "octocat"` — returns null
97
+ 3. Call `manage-user` with `action: "create"` including at minimum `name` and `githubUsername`
98
+ 4. If you know their email (from the webhook payload), include it
99
+
100
+ ## Workflow: Linking Identities
101
+
102
+ When you discover a known user is also active on another platform:
103
+
104
+ 1. Call `resolve-user` to find them by their known identity
105
+ 2. Call `manage-user` with `action: "update"` to add the new platform identity
106
+
107
+ Example: You know "Jane" by Slack ID, and discover her GitHub username:
108
+ ```
109
+ resolve-user slackUserId: "U_JANE" → returns user with id "abc-123"
110
+ manage-user action: "update" userId: "abc-123" githubUsername: "janedoe"
111
+ ```
112
+
113
+ ## Important Notes
114
+
115
+ - `manage-user` is **lead-only** — workers cannot use it for any action (the lead check happens before action dispatch). Workers must use `resolve-user` for lookups.
116
+ - `slackUserId`, `githubUsername`, `gitlabUsername`, and `linearUserId` have **unique constraints** — duplicates will error.
117
+ - Deleting a user clears `requestedByUserId` on all their associated tasks (sets to null).
118
+ - Email aliases are case-insensitive for resolution.
119
+ - The `preferredChannel` field defaults to `"slack"` and can be `"slack"`, `"email"`, `"github"`, or `"gitlab"`.
@@ -22,13 +22,15 @@ You should be working in a repository cloned to `/workspace/personal/<repo-name>
22
22
  ## Workflow
23
23
 
24
24
  1. **Verify state** — confirm you're in a git repo, not on main/master, and have commits to push.
25
- 2. **Push the branch** — `git push -u origin HEAD`
26
- 3. **Gather context** — review commit messages and changed files since diverging from base.
27
- 4. **Generate title and description:**
25
+ 2. **Run PR checks (MANDATORY)** — Run ALL checks listed in the "PR Checks" section of your Repository Guidelines. Run each command/task sequentially. If ANY check fails, fix the issue and re-run until all pass. If no guidelines are defined, check the project's CLAUDE.md for a pre-PR checklist and run those. Do NOT proceed until all checks pass.
26
+ 3. **Push the branch** — `git push -u origin HEAD`
27
+ 4. **Gather context** — review commit messages and changed files since diverging from base.
28
+ 5. **Generate title and description:**
28
29
  - **Title**: Concise summary (conventional commit style if the repo uses it)
29
30
  - **Description**: Summary of changes, notable items, testing done, related issues
30
- 5. **Create the PR/MR** using `gh pr create` or `glab mr create`.
31
- 6. **Report** the PR/MR URL.
31
+ 6. **Create the PR/MR** using `gh pr create` or `glab mr create`.
32
+ 7. **Check CI status** — After creating the PR, wait ~30 seconds, then check CI with `gh pr checks <pr-number>` (GitHub) or `glab mr view --json pipelines` (GitLab). If any check is failing, investigate the failure, fix it, push the fix, and re-check. Repeat until CI is green.
33
+ 8. **Report** the PR/MR URL and CI status.
32
34
 
33
35
  ## Tips
34
36
 
@@ -37,14 +37,18 @@ If given a URL, extract owner, repo, and issue number. Fetch issue details (titl
37
37
 
38
38
  Keep changes focused on what the issue requests. Avoid scope creep.
39
39
 
40
- ### 4. Commit and Push
40
+ ### 4. Quality Checks, Commit, and Push
41
41
 
42
- Commit with a message referencing the issue (e.g., `Fix #123: <description>`). Use conventional commit style if the repo uses it. Push with `git push -u origin HEAD`.
42
+ 1. **Run PR checks (MANDATORY)** — Run ALL checks from the "PR Checks" section of your Repository Guidelines. Fix any failures before proceeding. If no guidelines are defined, check the project's CLAUDE.md for a pre-PR checklist.
43
+ 2. **Commit** with a message referencing the issue (e.g., `Fix #123: <description>`). Use conventional commit style if the repo uses it.
44
+ 3. **Push** with `git push -u origin HEAD`.
43
45
 
44
46
  ### 5. Create the PR
45
47
 
46
48
  Create the PR with a descriptive title and body including: summary of changes, key changes list, testing done, and `Fixes #<issue-number>` to auto-close the issue on merge.
47
49
 
50
+ After creating the PR, check CI status with `gh pr checks` (GitHub) or `glab mr view --json pipelines` (GitLab). If CI fails, fix the issues, push, and re-check until green.
51
+
48
52
  ### 6. Report Back
49
53
 
50
54
  Provide the PR URL, summary of changes, and any caveats. Optionally comment on the original issue linking the PR.
@@ -56,4 +60,3 @@ Provide the PR URL, summary of changes, and any caveats. Optionally comment on t
56
60
  - One issue = one PR
57
61
  - If the issue is too large, break it into smaller PRs
58
62
  - If unclear, use `/skill:respond-github` to ask for clarification
59
- - Run linters and tests before creating the PR
@@ -28,6 +28,12 @@ Check CI with `gh pr checks <pr-number>` (or `glab mr view --json pipelines`).
28
28
 
29
29
  **If CI checks are failing, this is an automatic REQUEST_CHANGES.** Do not approve a PR with failing CI. Include the failing check names and error details in your review.
30
30
 
31
+ ### 2b. Review Repository Guidelines
32
+
33
+ Check the "Review Guidance" section of your Repository Guidelines for repo-specific review instructions (e.g., "check README.md", "enforce camelCase in specific directories"). Apply these instructions during your review below.
34
+
35
+ Also note the repo's **Merge Policy** — check `allowMerge` and `mergeChecks` before approving or merging. If `allowMerge` is false, do NOT merge — only review and approve/request changes.
36
+
31
37
  ### 3. Verify Tests Are Included (MANDATORY)
32
38
 
33
39
  Check that the PR includes test changes. **If the PR modifies code but does not add or update tests, this is an automatic REQUEST_CHANGES.** Every code change must include corresponding tests.
@@ -0,0 +1,119 @@
1
+ ---
2
+ name: user-management
3
+ description: "How to manage the user registry — creating users for new Slack/GitHub/GitLab identities, managing aliases, resolving users across platforms. Use when a new human interacts with the swarm or when user identity needs updating."
4
+ ---
5
+
6
+ # User Management
7
+
8
+ Manage the swarm's user registry — creating, updating, resolving, and listing users. Users link human identities across platforms (Slack, GitHub, GitLab, Linear, email) so the swarm can track who requested work.
9
+
10
+ ## When to Create Users
11
+
12
+ Create a new user when:
13
+ - An **unknown Slack user** sends a message to the swarm (no `resolveUser` match for their `slackUserId`)
14
+ - An **unknown GitHub user** opens an issue or PR that triggers a task
15
+ - An **unknown GitLab user** creates an issue or MR
16
+ - An **unknown Linear user** is assigned to or creates a synced issue
17
+ - A human explicitly asks to be registered
18
+
19
+ **Do NOT** create duplicate users. Always call `resolve-user` first to check if the person already exists under a different platform identity.
20
+
21
+ ## Tools
22
+
23
+ Two MCP tools handle user management:
24
+
25
+ ### `resolve-user` — Find an existing user
26
+
27
+ Looks up a user by any platform identity. Use this BEFORE creating a new user.
28
+
29
+ ```
30
+ resolve-user with:
31
+ slackUserId: "U12345" # Slack member ID
32
+ # OR
33
+ githubUsername: "octocat" # GitHub username
34
+ # OR
35
+ gitlabUsername: "octocat" # GitLab username
36
+ # OR
37
+ linearUserId: "uuid" # Linear user UUID
38
+ # OR
39
+ email: "user@example.com" # Primary email or alias
40
+ # OR
41
+ name: "Jane Doe" # Fuzzy name search (least specific)
42
+ ```
43
+
44
+ Priority order: platform IDs > email > name. Platform IDs are exact matches; email checks aliases (case-insensitive); name is substring match.
45
+
46
+ ### `manage-user` — CRUD operations
47
+
48
+ ```
49
+ # Create a new user
50
+ manage-user with:
51
+ action: "create"
52
+ name: "Jane Doe" # Required
53
+ email: "jane@company.com" # Optional
54
+ role: "engineering lead" # Optional, free-form
55
+ slackUserId: "U12345" # Optional
56
+ githubUsername: "janedoe" # Optional
57
+ gitlabUsername: "janedoe" # Optional
58
+ linearUserId: "uuid-from-linear" # Optional
59
+ emailAliases: ["jane.doe@company.com"] # Optional
60
+ timezone: "America/New_York" # Optional
61
+ notes: "Prefers async communication" # Optional
62
+
63
+ # List all users
64
+ manage-user with:
65
+ action: "list"
66
+
67
+ # Get a specific user
68
+ manage-user with:
69
+ action: "get"
70
+ userId: "<uuid>"
71
+
72
+ # Update a user (only send fields to change)
73
+ manage-user with:
74
+ action: "update"
75
+ userId: "<uuid>"
76
+ githubUsername: "new-username"
77
+
78
+ # Delete a user
79
+ manage-user with:
80
+ action: "delete"
81
+ userId: "<uuid>"
82
+ ```
83
+
84
+ ## Workflow: New Slack User
85
+
86
+ 1. Receive a message from an unknown Slack user (e.g., `slackUserId: "U_NEW123"`)
87
+ 2. Call `resolve-user` with `slackUserId: "U_NEW123"` — returns null
88
+ 3. Get the user's Slack profile (name, email) via `slack-read` or from the message metadata
89
+ 4. Call `resolve-user` with `email: "<their-email>"` — check if they exist under a different platform
90
+ 5. If found: call `manage-user` with `action: "update"` to add their `slackUserId`
91
+ 6. If not found: call `manage-user` with `action: "create"` including name, email, and slackUserId
92
+
93
+ ## Workflow: New GitHub User
94
+
95
+ 1. Receive a webhook from an unknown GitHub user (e.g., `githubUsername: "octocat"`)
96
+ 2. Call `resolve-user` with `githubUsername: "octocat"` — returns null
97
+ 3. Call `manage-user` with `action: "create"` including at minimum `name` and `githubUsername`
98
+ 4. If you know their email (from the webhook payload), include it
99
+
100
+ ## Workflow: Linking Identities
101
+
102
+ When you discover a known user is also active on another platform:
103
+
104
+ 1. Call `resolve-user` to find them by their known identity
105
+ 2. Call `manage-user` with `action: "update"` to add the new platform identity
106
+
107
+ Example: You know "Jane" by Slack ID, and discover her GitHub username:
108
+ ```
109
+ resolve-user slackUserId: "U_JANE" → returns user with id "abc-123"
110
+ manage-user action: "update" userId: "abc-123" githubUsername: "janedoe"
111
+ ```
112
+
113
+ ## Important Notes
114
+
115
+ - `manage-user` is **lead-only** — workers cannot use it for any action (the lead check happens before action dispatch). Workers must use `resolve-user` for lookups.
116
+ - `slackUserId`, `githubUsername`, `gitlabUsername`, and `linearUserId` have **unique constraints** — duplicates will error.
117
+ - Deleting a user clears `requestedByUserId` on all their associated tasks (sets to null).
118
+ - Email aliases are case-insensitive for resolution.
119
+ - The `preferredChannel` field defaults to `"slack"` and can be `"slack"`, `"email"`, `"github"`, or `"gitlab"`.