@sulhadin/orchestrator 1.1.0 → 1.2.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.
package/README.md CHANGED
@@ -8,11 +8,11 @@ Building a feature with Claude Code typically looks like this:
8
8
 
9
9
  ```
10
10
  You: "Build user authentication"
11
- You: *opens terminal* "@architect — design the system"
11
+ You: *opens terminal* "#architect — design the system"
12
12
  You: *reads RFC, approves*
13
- You: *opens terminal* "@backend — implement the API"
14
- You: *opens terminal* "@reviewer — review the code"
15
- You: *opens terminal* "@pm — close the feature"
13
+ You: *opens terminal* "#backend — implement the API"
14
+ You: *opens terminal* "#reviewer — review the code"
15
+ You: *opens terminal* "#pm — close the feature"
16
16
  ```
17
17
 
18
18
  You become the orchestrator. You carry context between sessions, sequence work in the right order, and manage the pipeline manually. This is tedious and error-prone.
@@ -22,13 +22,13 @@ You become the orchestrator. You carry context between sessions, sequence work i
22
22
  Orchestra turns Claude Code's PM role into an autonomous orchestrator. You describe what you want, PM handles the rest:
23
23
 
24
24
  ```
25
- You: "@pm"
25
+ You: "#pm"
26
26
  You: "I want user authentication with JWT"
27
27
  PM: creates milestone, grooms phases, dispatches worker agent
28
- @architect writes RFC → you approve
29
- @backend implements phase by phase → each phase = one commit
30
- @frontend builds the UI → each phase = one commit
31
- @reviewer reviews unpushed commits
28
+ #architect writes RFC → you approve
29
+ #backend implements phase by phase → each phase = one commit
30
+ #frontend builds the UI → each phase = one commit
31
+ #reviewer reviews unpushed commits
32
32
  you approve → PM pushes to origin
33
33
  milestone closed.
34
34
  ```
@@ -43,11 +43,11 @@ You ←→ PM (always-on orchestrator)
43
43
  ├── Creates milestone with groomed phases
44
44
  ├── Spawns one worker agent (all roles loaded)
45
45
 
46
- ├── SendMessage("@architect: write RFC") → awaits
47
- ├── SendMessage("@backend: phase-1") → awaits → commit
48
- ├── SendMessage("@backend: phase-2") → awaits → commit
49
- ├── SendMessage("@frontend: phase-3") → awaits → commit
50
- ├── SendMessage("@reviewer: review") → awaits
46
+ ├── SendMessage("#architect: write RFC") → awaits
47
+ ├── SendMessage("#backend: phase-1") → awaits → commit
48
+ ├── SendMessage("#backend: phase-2") → awaits → commit
49
+ ├── SendMessage("#frontend: phase-3") → awaits → commit
50
+ ├── SendMessage("#reviewer: review") → awaits
51
51
 
52
52
  ├── You approve → PM pushes to origin
53
53
  └── Milestone closed
@@ -138,10 +138,10 @@ your-project/
138
138
 
139
139
  ## Usage
140
140
 
141
- Open Claude Code in your project and say `@pm`:
141
+ Open Claude Code in your project and say `#pm`:
142
142
 
143
143
  ```
144
- You: @pm
144
+ You: #pm
145
145
  PM: "No active milestones. Ready for instructions."
146
146
 
147
147
  You: "I want to add a health check endpoint"
@@ -158,12 +158,12 @@ PM: *creates milestone, grooms phases, dispatches worker*
158
158
 
159
159
  | Command | Description |
160
160
  |---------|------------|
161
- | `@pm` | Activate Product Manager |
162
- | `@backend` | Activate Backend Engineer (manual mode) |
163
- | `@frontend` | Activate Frontend Engineer (manual mode) |
164
- | `@reviewer` | Activate Code Reviewer (manual mode) |
165
- | `@architect` | Activate Architect (manual mode) |
166
- | `@owner` | Activate Owner (system maintenance) |
161
+ | `#pm` | Activate Product Manager |
162
+ | `#backend` | Activate Backend Engineer (manual mode) |
163
+ | `#frontend` | Activate Frontend Engineer (manual mode) |
164
+ | `#reviewer` | Activate Code Reviewer (manual mode) |
165
+ | `#architect` | Activate Architect (manual mode) |
166
+ | `#owner` | Activate Owner (system maintenance) |
167
167
  | `status` | Pipeline status report (PM only) |
168
168
  | `orc help` | Show all commands |
169
169
 
@@ -172,7 +172,7 @@ PM: *creates milestone, grooms phases, dispatches worker*
172
172
  You can still use roles directly without PM orchestration:
173
173
 
174
174
  ```
175
- You: @backend
175
+ You: #backend
176
176
  BE: *checks milestones for pending backend phases*
177
177
  *starts working*
178
178
  ```
package/bin/index.js CHANGED
@@ -11,6 +11,66 @@ const ORCHESTRA_SECTION_END = "<!-- /orchestra -->";
11
11
 
12
12
  const USER_DIRS = ["milestones"];
13
13
 
14
+ const ALLOW_PERMISSIONS = [
15
+ "Bash(npm *)",
16
+ "Bash(npx *)",
17
+ "Bash(node *)",
18
+ "Bash(git *)",
19
+ "Bash(yarn *)",
20
+ "Bash(pnpm *)",
21
+ "Bash(tsc *)",
22
+ "Bash(npx tsc *)",
23
+ "Bash(npx vitest *)",
24
+ "Bash(mkdir *)",
25
+ "Bash(cat *)",
26
+ "Bash(ls *)",
27
+ "Read(*)",
28
+ "Write(*)",
29
+ "Edit(*)",
30
+ "Glob(*)",
31
+ "Grep(*)",
32
+ "Agent(*)",
33
+ ];
34
+
35
+ function parseArgs() {
36
+ const args = process.argv.slice(2);
37
+ const flags = {
38
+ skipPermissions: false,
39
+ help: false,
40
+ };
41
+
42
+ for (const arg of args) {
43
+ switch (arg) {
44
+ case "--dangerously-skip-permissions":
45
+ flags.skipPermissions = true;
46
+ break;
47
+ case "--help":
48
+ case "-h":
49
+ flags.help = true;
50
+ break;
51
+ default:
52
+ console.error(" Unknown flag: " + arg);
53
+ process.exit(1);
54
+ }
55
+ }
56
+
57
+ return flags;
58
+ }
59
+
60
+ function showHelp() {
61
+ console.log("");
62
+ console.log(" Usage: npx @sulhadin/orchestrator [options]");
63
+ console.log("");
64
+ console.log(" Options:");
65
+ console.log(" --dangerously-skip-permissions Auto-allow all tool permissions (no y/n prompts)");
66
+ console.log(" --help, -h Show this help");
67
+ console.log("");
68
+ console.log(" Examples:");
69
+ console.log(" npx @sulhadin/orchestrator");
70
+ console.log(" npx @sulhadin/orchestrator --dangerously-skip-permissions");
71
+ console.log("");
72
+ }
73
+
14
74
  function copyDirRecursive(src, dest) {
15
75
  if (!fs.existsSync(dest)) {
16
76
  fs.mkdirSync(dest, { recursive: true });
@@ -58,7 +118,49 @@ function extractOrchestraSection(content) {
58
118
  return content.slice(startIdx, endIdx + ORCHESTRA_SECTION_END.length);
59
119
  }
60
120
 
121
+ function setupPermissions() {
122
+ const claudeDir = path.join(targetDir, ".claude");
123
+ const settingsPath = path.join(claudeDir, "settings.local.json");
124
+
125
+ if (!fs.existsSync(claudeDir)) {
126
+ fs.mkdirSync(claudeDir, { recursive: true });
127
+ }
128
+
129
+ let settings = {};
130
+ if (fs.existsSync(settingsPath)) {
131
+ try {
132
+ settings = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
133
+ } catch {
134
+ settings = {};
135
+ }
136
+ }
137
+
138
+ if (!settings.permissions) {
139
+ settings.permissions = {};
140
+ }
141
+
142
+ const existing = settings.permissions.allow || [];
143
+ const merged = [...new Set([...existing, ...ALLOW_PERMISSIONS])];
144
+ settings.permissions.allow = merged;
145
+
146
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
147
+
148
+ const added = merged.length - existing.length;
149
+ if (added > 0) {
150
+ console.log(" [+] Permissions configured (" + added + " rules added to .claude/settings.local.json)");
151
+ } else {
152
+ console.log(" [~] Permissions already configured");
153
+ }
154
+ }
155
+
61
156
  function run() {
157
+ const flags = parseArgs();
158
+
159
+ if (flags.help) {
160
+ showHelp();
161
+ return;
162
+ }
163
+
62
164
  console.log("");
63
165
  console.log(" Orchestra — AI Team Orchestration");
64
166
  console.log(" Installing into: " + targetDir);
@@ -69,7 +171,6 @@ function run() {
69
171
  const isUpgrade = fs.existsSync(orchestraDest);
70
172
 
71
173
  if (isUpgrade) {
72
- // Backup user data directories
73
174
  const backups = {};
74
175
 
75
176
  for (const dir of USER_DIRS) {
@@ -77,7 +178,6 @@ function run() {
77
178
  const backupPath = path.join(targetDir, ".orchestra-backup-" + dir);
78
179
 
79
180
  if (fs.existsSync(dirPath)) {
80
- // Check if directory has real content (not just .gitkeep)
81
181
  const files = fs.readdirSync(dirPath).filter((f) => f !== ".gitkeep");
82
182
  if (files.length > 0) {
83
183
  copyDirRecursive(dirPath, backupPath);
@@ -87,19 +187,15 @@ function run() {
87
187
  }
88
188
  }
89
189
 
90
- // Remove old .orchestra/
91
190
  rmDirRecursive(orchestraDest);
92
191
  console.log(" [~] Removed old .orchestra/");
93
192
 
94
- // Copy fresh .orchestra/
95
193
  copyDirRecursive(orchestraSrc, orchestraDest);
96
194
  console.log(" [+] .orchestra/ installed (clean)");
97
195
 
98
- // Restore user data
99
196
  for (const [dir, backupPath] of Object.entries(backups)) {
100
197
  const restorePath = path.join(orchestraDest, dir);
101
198
 
102
- // Remove the template's empty dir first
103
199
  if (fs.existsSync(restorePath)) {
104
200
  rmDirRecursive(restorePath);
105
201
  }
@@ -109,7 +205,6 @@ function run() {
109
205
  console.log(" [+] Restored " + dir + "/");
110
206
  }
111
207
  } else {
112
- // Fresh install
113
208
  copyDirRecursive(orchestraSrc, orchestraDest);
114
209
  console.log(" [+] .orchestra/ installed");
115
210
  }
@@ -151,12 +246,17 @@ function run() {
151
246
  console.log(" [+] CLAUDE.md created");
152
247
  }
153
248
 
249
+ // Handle permissions
250
+ if (flags.skipPermissions) {
251
+ setupPermissions();
252
+ }
253
+
154
254
  console.log("");
155
255
  console.log(" Done! Orchestra is ready.");
156
256
  console.log("");
157
257
  console.log(" Next steps:");
158
258
  console.log(" 1. Open Claude Code in your project");
159
- console.log(' 2. Say "@pm" to start orchestrating');
259
+ console.log(' 2. Say "#pm" to start orchestrating');
160
260
  console.log("");
161
261
  }
162
262
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sulhadin/orchestrator",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "AI Team Orchestration System — multi-role coordination for Claude Code",
5
5
  "bin": {
6
6
  "orchestrator": "bin/index.js"
@@ -15,10 +15,10 @@ You (User)
15
15
  → PM discusses features with you, creates milestones
16
16
  → PM creates a worker agent session (all roles loaded)
17
17
  → PM dispatches phases sequentially:
18
- @architect → writes RFC
19
- @backend → implements backend phases (each → commit)
20
- @frontend → implements frontend phases (each → commit)
21
- @reviewer → reviews unpushed commits
18
+ #architect → writes RFC
19
+ #backend → implements backend phases (each → commit)
20
+ #frontend → implements frontend phases (each → commit)
21
+ #reviewer → reviews unpushed commits
22
22
  → PM pushes to origin after approval
23
23
  → PM closes milestone
24
24
  ```
@@ -57,7 +57,7 @@ User talks only to PM. PM dispatches a worker agent to execute all roles:
57
57
  1. PM creates milestone with groomed phases
58
58
  2. PM creates worker agent session (via `Agent` tool — all roles loaded once)
59
59
  3. PM dispatches phases via `SendMessage` → awaits result → dispatches next
60
- 4. Worker switches roles as PM instructs (`@architect`, `@backend`, `@frontend`, `@reviewer`)
60
+ 4. Worker switches roles as PM instructs (`#architect`, `#backend`, `#frontend`, `#reviewer`)
61
61
  5. Each phase → one commit. Milestone done → push to origin.
62
62
 
63
63
  ### Manual Mode
@@ -65,8 +65,8 @@ User talks only to PM. PM dispatches a worker agent to execute all roles:
65
65
  User switches roles directly — same as before:
66
66
 
67
67
  ```
68
- User → @backend (implement)
69
- User → @reviewer (review)
68
+ User → #backend (implement)
69
+ User → #reviewer (review)
70
70
  ```
71
71
 
72
72
  Roles check `.orchestra/milestones/` for phases assigned to them. Manual mode
@@ -170,7 +170,7 @@ All other transitions are automatic.
170
170
  Reviewer no longer needs task files. Review is based on **unpushed commits**.
171
171
 
172
172
  ```
173
- PM dispatches @reviewer via worker agent
173
+ PM dispatches #reviewer via worker agent
174
174
  → Reviewer runs: git log origin/{branch}..HEAD
175
175
  → Reviewer runs: git diff origin/{branch}...HEAD
176
176
  → Reviewer applies full checklist (backend or frontend mode)
@@ -252,7 +252,7 @@ Each role has exclusive write access to specific directories:
252
252
  PM dispatches tasks by specifying the role and the work:
253
253
 
254
254
  ```
255
- "@backend: Implement phase-1 of M1-user-auth.
255
+ "#backend: Implement phase-1 of M1-user-auth.
256
256
  Read: .orchestra/milestones/M1-user-auth/phases/phase-1.md"
257
257
  ```
258
258
 
@@ -289,28 +289,28 @@ sequenceDiagram
289
289
  PM->>PM: Create milestone + groom phases
290
290
  PM->>W: Agent(worker.md) — create session
291
291
 
292
- PM->>W: SendMessage(@architect: write RFC)
292
+ PM->>W: SendMessage(#architect: write RFC)
293
293
  W-->>PM: RFC result
294
294
  PM->>U: RFC ready — approve?
295
295
  U->>PM: Approved
296
296
 
297
297
  loop Each backend phase
298
- PM->>W: SendMessage(@backend: phase-N)
298
+ PM->>W: SendMessage(#backend: phase-N)
299
299
  W-->>PM: Phase result + commit
300
300
  PM->>U: Progress: phase-N done
301
301
  end
302
302
 
303
303
  loop Each frontend phase
304
- PM->>W: SendMessage(@frontend: phase-N)
304
+ PM->>W: SendMessage(#frontend: phase-N)
305
305
  W-->>PM: Phase result + commit
306
306
  PM->>U: Progress: phase-N done
307
307
  end
308
308
 
309
- PM->>W: SendMessage(@reviewer: review)
309
+ PM->>W: SendMessage(#reviewer: review)
310
310
  W-->>PM: Review verdict
311
311
 
312
312
  alt Changes requested
313
- PM->>W: SendMessage(@backend/@frontend: fix)
313
+ PM->>W: SendMessage(#backend/#frontend: fix)
314
314
  W-->>PM: Fix result + commit
315
315
  end
316
316
 
@@ -326,15 +326,15 @@ sequenceDiagram
326
326
  participant PM as Product Manager
327
327
  participant W as Worker Agent
328
328
 
329
- PM->>W: "@backend: implement phase-1"
329
+ PM->>W: "#backend: implement phase-1"
330
330
  Note over W: Read phase file<br/>Activate backend role<br/>Implement + test<br/>Commit
331
331
  W-->>PM: Result: done, committed abc123
332
332
 
333
- PM->>W: "@backend: implement phase-2"
333
+ PM->>W: "#backend: implement phase-2"
334
334
  Note over W: Same session<br/>Full context preserved<br/>Implement + test<br/>Commit
335
335
  W-->>PM: Result: done, committed def456
336
336
 
337
- PM->>W: "@frontend: implement phase-3"
337
+ PM->>W: "#frontend: implement phase-3"
338
338
  Note over W: Role switch<br/>Architect + backend context available<br/>Implement + test<br/>Commit
339
339
  W-->>PM: Result: done, committed ghi789
340
340
  ```
@@ -347,7 +347,7 @@ sequenceDiagram
347
347
  participant W as Worker Agent
348
348
  actor U as User
349
349
 
350
- PM->>W: "@reviewer: review M1-user-auth"
350
+ PM->>W: "#reviewer: review M1-user-auth"
351
351
  Note over W: git log origin/branch..HEAD<br/>git diff origin/branch...HEAD<br/>Apply review checklist
352
352
 
353
353
  alt Approved
@@ -357,7 +357,7 @@ sequenceDiagram
357
357
  PM->>PM: git push + close milestone
358
358
  else Changes Requested
359
359
  W-->>PM: verdict: changes-requested + issues
360
- PM->>W: "@backend: fix issues in phase-2"
360
+ PM->>W: "#backend: fix issues in phase-2"
361
361
  W-->>PM: Fixed + committed
362
362
  PM->>U: Fixes applied. Push?
363
363
  U->>PM: Yes
@@ -28,7 +28,7 @@ After reading, confirm to PM: "Worker ready. All roles loaded."
28
28
 
29
29
  ## Role Switching
30
30
 
31
- When PM says `@architect`, `@backend`, `@frontend`, or `@reviewer`:
31
+ When PM says `#architect`, `#backend`, `#frontend`, or `#reviewer`:
32
32
  - Switch to that role immediately
33
33
  - Follow ONLY that role's ownership scope — do NOT write files outside scope
34
34
  - Apply that role's engineering principles and standards
@@ -40,10 +40,10 @@ You can only write to files owned by the **currently active** role:
40
40
 
41
41
  | Active Role | Can Write |
42
42
  |------------|-----------|
43
- | `@architect` | `.orchestra/milestones/*/rfc.md`, `.orchestra/milestones/*/architecture.md`, `.orchestra/milestones/*/adrs/*`, project configs |
44
- | `@backend` | `src/*`, `tests/*`, `migrations/*`, `package.json`, `tsconfig.json` |
45
- | `@frontend` | `frontend/*`, `.orchestra/milestones/*/design.md` |
46
- | `@reviewer` | Review findings only — never modify source code |
43
+ | `#architect` | `.orchestra/milestones/*/rfc.md`, `.orchestra/milestones/*/architecture.md`, `.orchestra/milestones/*/adrs/*`, project configs |
44
+ | `#backend` | `src/*`, `tests/*`, `migrations/*`, `package.json`, `tsconfig.json` |
45
+ | `#frontend` | `frontend/*`, `.orchestra/milestones/*/design.md` |
46
+ | `#reviewer` | Review findings only — never modify source code |
47
47
 
48
48
  If you need to write outside your active role's scope, **do not do it**. Report
49
49
  the need to PM in your result and PM will dispatch the appropriate role.
@@ -73,7 +73,7 @@ After completing a phase's work:
73
73
 
74
74
  ## Reviewer Mode
75
75
 
76
- When activated as `@reviewer`, you review **unpushed commits** on the current branch:
76
+ When activated as `#reviewer`, you review **unpushed commits** on the current branch:
77
77
 
78
78
  ```bash
79
79
  git log origin/{current-branch}..HEAD --oneline # see commits to review
@@ -87,7 +87,7 @@ git diff origin/{current-branch}...HEAD # see full changeset
87
87
 
88
88
  ## Architect Mode
89
89
 
90
- When activated as `@architect`:
90
+ When activated as `#architect`:
91
91
  - Write RFC to the milestone's `rfc.md` file
92
92
  - Write ADRs to the milestone's `adrs/` directory if needed
93
93
  - Follow the architect role's technical RFC format
@@ -385,7 +385,7 @@ Send a message to the worker agent specifying the role and phase:
385
385
 
386
386
  ```
387
387
  SendMessage to worker:
388
- "@backend: Implement phase-1 of M1-user-auth.
388
+ "#backend: Implement phase-1 of M1-user-auth.
389
389
  Read the phase file: .orchestra/milestones/M1-user-auth/phases/phase-1.md
390
390
  Follow backend-engineer role rules. Commit when done."
391
391
  ```
@@ -422,7 +422,7 @@ Reviewer reviews all unpushed commits on the current branch:
422
422
 
423
423
  ```
424
424
  SendMessage to worker:
425
- "@reviewer: Review milestone M1-user-auth.
425
+ "#reviewer: Review milestone M1-user-auth.
426
426
  Check unpushed commits: git log origin/{branch}..HEAD
427
427
  Apply the full review checklist. Return verdict: approved or changes-requested."
428
428
  ```
@@ -52,14 +52,14 @@ before asking this question. The role selection question IS your greeting.
52
52
 
53
53
  | Selection | Role ID (for file paths) | Short alias |
54
54
  |-----------|--------------------------|-------------|
55
- | Owner | owner | `@owner` |
56
- | Product Manager | product-manager | `@pm` |
57
- | Architect | architect | `@architect` |
58
- | Backend Engineer | backend-engineer | `@backend` |
59
- | Code Reviewer | code-reviewer | `@reviewer` |
60
- | Frontend Engineer | frontend-engineer | `@frontend` |
61
-
62
- When the user types `@{alias}` (e.g. `@backend`, `@reviewer`), treat it exactly
55
+ | Owner | owner | `#owner` |
56
+ | Product Manager | product-manager | `#pm` |
57
+ | Architect | architect | `#architect` |
58
+ | Backend Engineer | backend-engineer | `#backend` |
59
+ | Code Reviewer | code-reviewer | `#reviewer` |
60
+ | Frontend Engineer | frontend-engineer | `#frontend` |
61
+
62
+ When the user types `#{alias}` (e.g. `#backend`, `#reviewer`), treat it exactly
63
63
  the same as "You are the {role}" — read the role file, check milestones, start working.
64
64
 
65
65
  ### Rules
@@ -81,7 +81,7 @@ These commands work in ANY role, in any terminal:
81
81
  | `status` / `orchestrate` / `what's next` | **PM only.** Full pipeline status report. Other roles: "Open a PM terminal." |
82
82
  | `check` / `check your queue` | Check milestones for pending work and start. Works in any role. |
83
83
  | `orc help` / `orchestra help` | Show all available commands and how the orchestra system works. |
84
- | `You are the {role}` / `@{role}` | Switch to a different role in the current session. Aliases: `@owner`, `@pm`, `@architect`, `@backend`, `@reviewer`, `@frontend` |
84
+ | `You are the {role}` / `#{role}` | Switch to a different role in the current session. Aliases: `#owner`, `#pm`, `#architect`, `#backend`, `#reviewer`, `#frontend` |
85
85
  | `commit` / `commit your changes` | Commit your work using conventional commits (only files in your ownership scope). |
86
86
  | `bootstrap` / `new project` | **Architect only.** Start the discovery phase for a new project. Other roles: "Open an architect terminal." |
87
87
 
@@ -97,15 +97,15 @@ COMMANDS:
97
97
  bootstrap / new project Start new project discovery (Architect role only)
98
98
  orc help Show this help
99
99
  You are the {role} Switch role in current session
100
- @{alias} Short switch: @owner @pm @architect @backend @reviewer @frontend
100
+ #{alias} Short switch: #owner #pm #architect #backend #reviewer #frontend
101
101
 
102
102
  ROLES:
103
- owner (@owner) Maintain and evolve Orchestra system (roles, rules, structure)
104
- product-manager (@pm) Write RFCs, define features, orchestrate pipeline
105
- architect (@architect) Design architecture, choose tech, set up project skeleton
106
- backend-engineer (@backend) Implement features, write code + tests
107
- code-reviewer (@reviewer) Review implementations, write findings
108
- frontend-engineer (@frontend) Design + build UI, write frontend tests
103
+ owner (#owner) Maintain and evolve Orchestra system (roles, rules, structure)
104
+ product-manager (#pm) Write RFCs, define features, orchestrate pipeline
105
+ architect (#architect) Design architecture, choose tech, set up project skeleton
106
+ backend-engineer (#backend) Implement features, write code + tests
107
+ code-reviewer (#reviewer) Review implementations, write findings
108
+ frontend-engineer (#frontend) Design + build UI, write frontend tests
109
109
 
110
110
  PIPELINES:
111
111
  New project: PM → Architect → Engineers start building