planflow-plugin 0.1.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 (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +93 -0
  3. package/bin/cli.js +169 -0
  4. package/bin/postinstall.js +87 -0
  5. package/commands/pfActivity/SKILL.md +725 -0
  6. package/commands/pfAssign/SKILL.md +623 -0
  7. package/commands/pfCloudLink/SKILL.md +192 -0
  8. package/commands/pfCloudList/SKILL.md +222 -0
  9. package/commands/pfCloudNew/SKILL.md +187 -0
  10. package/commands/pfCloudUnlink/SKILL.md +152 -0
  11. package/commands/pfComment/SKILL.md +227 -0
  12. package/commands/pfComments/SKILL.md +159 -0
  13. package/commands/pfConnectionStatus/SKILL.md +433 -0
  14. package/commands/pfDiscord/SKILL.md +740 -0
  15. package/commands/pfGithubBranch/SKILL.md +672 -0
  16. package/commands/pfGithubIssue/SKILL.md +963 -0
  17. package/commands/pfGithubLink/SKILL.md +859 -0
  18. package/commands/pfGithubPr/SKILL.md +1335 -0
  19. package/commands/pfGithubUnlink/SKILL.md +401 -0
  20. package/commands/pfLive/SKILL.md +185 -0
  21. package/commands/pfLogin/SKILL.md +249 -0
  22. package/commands/pfLogout/SKILL.md +155 -0
  23. package/commands/pfMyTasks/SKILL.md +198 -0
  24. package/commands/pfNotificationSettings/SKILL.md +619 -0
  25. package/commands/pfNotifications/SKILL.md +420 -0
  26. package/commands/pfNotificationsClear/SKILL.md +421 -0
  27. package/commands/pfReact/SKILL.md +232 -0
  28. package/commands/pfSlack/SKILL.md +659 -0
  29. package/commands/pfSyncPull/SKILL.md +210 -0
  30. package/commands/pfSyncPush/SKILL.md +299 -0
  31. package/commands/pfSyncStatus/SKILL.md +212 -0
  32. package/commands/pfTeamInvite/SKILL.md +161 -0
  33. package/commands/pfTeamList/SKILL.md +253 -0
  34. package/commands/pfTeamRemove/SKILL.md +115 -0
  35. package/commands/pfTeamRole/SKILL.md +160 -0
  36. package/commands/pfTestWebhooks/SKILL.md +722 -0
  37. package/commands/pfUnassign/SKILL.md +134 -0
  38. package/commands/pfWhoami/SKILL.md +258 -0
  39. package/commands/pfWorkload/SKILL.md +219 -0
  40. package/commands/planExportCsv/SKILL.md +106 -0
  41. package/commands/planExportGithub/SKILL.md +222 -0
  42. package/commands/planExportJson/SKILL.md +159 -0
  43. package/commands/planExportSummary/SKILL.md +158 -0
  44. package/commands/planNew/SKILL.md +641 -0
  45. package/commands/planNext/SKILL.md +1200 -0
  46. package/commands/planSettingsAutoSync/SKILL.md +199 -0
  47. package/commands/planSettingsLanguage/SKILL.md +201 -0
  48. package/commands/planSettingsReset/SKILL.md +237 -0
  49. package/commands/planSettingsShow/SKILL.md +482 -0
  50. package/commands/planSpec/SKILL.md +929 -0
  51. package/commands/planUpdate/SKILL.md +2518 -0
  52. package/commands/team/SKILL.md +740 -0
  53. package/locales/en.json +1499 -0
  54. package/locales/ka.json +1499 -0
  55. package/package.json +48 -0
  56. package/templates/PROJECT_PLAN.template.md +157 -0
  57. package/templates/backend-api.template.md +562 -0
  58. package/templates/frontend-spa.template.md +610 -0
  59. package/templates/fullstack.template.md +397 -0
  60. package/templates/ka/backend-api.template.md +562 -0
  61. package/templates/ka/frontend-spa.template.md +610 -0
  62. package/templates/ka/fullstack.template.md +397 -0
  63. package/templates/sections/architecture.md +21 -0
  64. package/templates/sections/overview.md +15 -0
  65. package/templates/sections/tasks.md +22 -0
  66. package/templates/sections/tech-stack.md +19 -0
@@ -0,0 +1,619 @@
1
+ ---
2
+ name: pfNotificationSettings
3
+ description: Manage notification preferences for the current PlanFlow project
4
+ ---
5
+
6
+ # PlanFlow Notification Settings
7
+
8
+ Manage your notification preferences for task assignments, mentions, comments, and team activity.
9
+
10
+ ## Usage
11
+
12
+ ```bash
13
+ /pfNotificationSettings # Show current notification settings
14
+ /pfNotificationSettings email on # Enable email notifications
15
+ /pfNotificationSettings email off # Disable email notifications
16
+ /pfNotificationSettings email digest # Set email to daily digest mode
17
+ /pfNotificationSettings inapp on # Enable in-app notifications
18
+ /pfNotificationSettings inapp off # Disable in-app notifications
19
+ /pfNotificationSettings event <event> on # Enable specific event type
20
+ /pfNotificationSettings event <event> off # Disable specific event type
21
+ ```
22
+
23
+ **Event Types:**
24
+ - `assigned` - When you're assigned to a task
25
+ - `mention` - When someone @mentions you in a comment
26
+ - `watching` - When tasks you're watching are updated
27
+ - `team` - All team activity (comments, status changes)
28
+
29
+ ## Process
30
+
31
+ ### Step 0: Load Configuration & Translations
32
+
33
+ **CRITICAL: Execute this step FIRST, before any output!**
34
+
35
+ ```javascript
36
+ // Merge global and local configs
37
+ function getMergedConfig() {
38
+ let globalConfig = {}
39
+ let localConfig = {}
40
+
41
+ const globalPath = expandPath("~/.config/claude/plan-plugin-config.json")
42
+ if (fileExists(globalPath)) {
43
+ try { globalConfig = JSON.parse(readFile(globalPath)) } catch (e) {}
44
+ }
45
+
46
+ if (fileExists("./.plan-config.json")) {
47
+ try { localConfig = JSON.parse(readFile("./.plan-config.json")) } catch (e) {}
48
+ }
49
+
50
+ return {
51
+ ...globalConfig,
52
+ ...localConfig,
53
+ cloud: {
54
+ ...(globalConfig.cloud || {}),
55
+ ...(localConfig.cloud || {})
56
+ }
57
+ }
58
+ }
59
+
60
+ const config = getMergedConfig()
61
+ const language = config.language || "en"
62
+ const cloudConfig = config.cloud || {}
63
+ const isAuthenticated = !!cloudConfig.apiToken
64
+ const projectId = cloudConfig.projectId
65
+ const apiUrl = cloudConfig.apiUrl || "https://api.planflow.tools"
66
+ const currentUserEmail = cloudConfig.userEmail
67
+
68
+ // Load translations
69
+ const t = JSON.parse(readFile(`locales/${language}.json`))
70
+ ```
71
+
72
+ ### Step 1: Check Authentication
73
+
74
+ If not authenticated, show error:
75
+
76
+ ```
77
+ ╭──────────────────────────────────────────────────────────────────────────────╮
78
+ │ ❌ ERROR │
79
+ ├──────────────────────────────────────────────────────────────────────────────┤
80
+ │ │
81
+ │ {t.commands.sync.notAuthenticated} │
82
+ │ │
83
+ │ Notification settings require a cloud connection. │
84
+ │ │
85
+ │ 💡 Run /pfLogin to authenticate first. │
86
+ │ │
87
+ ╰──────────────────────────────────────────────────────────────────────────────╯
88
+ ```
89
+
90
+ If no project linked, show error:
91
+
92
+ ```
93
+ ╭──────────────────────────────────────────────────────────────────────────────╮
94
+ │ ❌ ERROR │
95
+ ├──────────────────────────────────────────────────────────────────────────────┤
96
+ │ │
97
+ │ {t.commands.sync.notLinked} │
98
+ │ │
99
+ │ 💡 Run /pfCloudLink to link a project first. │
100
+ │ │
101
+ ╰──────────────────────────────────────────────────────────────────────────────╯
102
+ ```
103
+
104
+ ### Step 2: Parse Arguments
105
+
106
+ ```javascript
107
+ const args = commandArgs.trim().toLowerCase().split(/\s+/)
108
+ const action = args[0] || null // "email", "inapp", "event", or null (show)
109
+ const subAction = args[1] || null // "on", "off", "digest", or event name
110
+ const eventToggle = args[2] || null // "on" or "off" for event types
111
+ ```
112
+
113
+ ### Step 3: Fetch Current Settings from API
114
+
115
+ **API Endpoint:** `GET /users/me/notification-settings`
116
+
117
+ **Bash Implementation:**
118
+
119
+ ```bash
120
+ API_URL="https://api.planflow.tools"
121
+ TOKEN="$API_TOKEN"
122
+ PROJECT_ID="$PROJECT_ID"
123
+
124
+ # Fetch current notification settings
125
+ RESPONSE=$(curl -s -w "\n%{http_code}" \
126
+ --connect-timeout 5 \
127
+ --max-time 10 \
128
+ -X GET \
129
+ -H "Accept: application/json" \
130
+ -H "Authorization: Bearer $TOKEN" \
131
+ "${API_URL}/users/me/notification-settings?projectId=${PROJECT_ID}")
132
+
133
+ HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
134
+ BODY=$(echo "$RESPONSE" | sed '$d')
135
+
136
+ if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
137
+ echo "$BODY"
138
+ else
139
+ echo "Error: HTTP $HTTP_CODE"
140
+ fi
141
+ ```
142
+
143
+ **Expected Response:**
144
+
145
+ ```json
146
+ {
147
+ "success": true,
148
+ "data": {
149
+ "settings": {
150
+ "channels": {
151
+ "email": {
152
+ "enabled": true,
153
+ "mode": "digest"
154
+ },
155
+ "inapp": {
156
+ "enabled": true
157
+ },
158
+ "slack": {
159
+ "enabled": false,
160
+ "webhookConfigured": false
161
+ },
162
+ "discord": {
163
+ "enabled": false,
164
+ "webhookConfigured": false
165
+ }
166
+ },
167
+ "events": {
168
+ "assigned": true,
169
+ "mention": true,
170
+ "watching": true,
171
+ "team": false
172
+ }
173
+ }
174
+ }
175
+ }
176
+ ```
177
+
178
+ ### Step 4: Handle Actions
179
+
180
+ #### If no action (show current settings)
181
+
182
+ Display settings dashboard card:
183
+
184
+ ```
185
+ ╭──────────────────────────────────────────────────────────────────────────────╮
186
+ │ 🔔 {t.commands.notificationSettings.title} │
187
+ ├──────────────────────────────────────────────────────────────────────────────┤
188
+ │ │
189
+ │ 📁 Project: {projectName} │
190
+ │ │
191
+ │ ── {t.commands.notificationSettings.channels} ──────────────────────────── │
192
+ │ │
193
+ │ 📧 Email: {email.enabled ? "✅ Enabled" : "❌ Disabled"} │
194
+ │ Mode: {email.mode === "digest" ? "Daily digest" : "Immediate"} │
195
+ │ │
196
+ │ 🔔 In-app: {inapp.enabled ? "✅ Enabled" : "❌ Disabled"} │
197
+ │ │
198
+ │ 💬 Slack: {slack.enabled ? "✅ Enabled" : "❌ Disabled"} │
199
+ │ {!slack.webhookConfigured ? "(Not configured)" : ""} │
200
+ │ │
201
+ │ 🎮 Discord: {discord.enabled ? "✅ Enabled" : "❌ Disabled"} │
202
+ │ {!discord.webhookConfigured ? "(Not configured)" : ""} │
203
+ │ │
204
+ │ ── {t.commands.notificationSettings.events} ────────────────────────────── │
205
+ │ │
206
+ │ {events.assigned ? "[✓]" : "[ ]"} Task assigned to me │
207
+ │ {events.mention ? "[✓]" : "[ ]"} Mentioned in comment │
208
+ │ {events.watching ? "[✓]" : "[ ]"} Task I'm watching updated │
209
+ │ {events.team ? "[✓]" : "[ ]"} All team activity │
210
+ │ │
211
+ ├──────────────────────────────────────────────────────────────────────────────┤
212
+ │ │
213
+ │ 💡 {t.ui.labels.commands} │
214
+ │ • /pfNotificationSettings email on|off|digest │
215
+ │ • /pfNotificationSettings inapp on|off │
216
+ │ • /pfNotificationSettings event <type> on|off │
217
+ │ │
218
+ │ Event types: assigned, mention, watching, team │
219
+ │ │
220
+ ╰──────────────────────────────────────────────────────────────────────────────╯
221
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
222
+ ```
223
+
224
+ #### If action is "email"
225
+
226
+ Update email notification settings.
227
+
228
+ **Valid subActions:**
229
+ - `on` - Enable email notifications (immediate mode)
230
+ - `off` - Disable email notifications
231
+ - `digest` - Enable email notifications with daily digest
232
+
233
+ **API Request:**
234
+
235
+ ```bash
236
+ API_URL="https://api.planflow.tools"
237
+ TOKEN="$API_TOKEN"
238
+ PROJECT_ID="$PROJECT_ID"
239
+ ENABLED="true" # or "false"
240
+ MODE="immediate" # or "digest"
241
+
242
+ RESPONSE=$(curl -s -w "\n%{http_code}" \
243
+ --connect-timeout 5 \
244
+ --max-time 10 \
245
+ -X PATCH \
246
+ -H "Content-Type: application/json" \
247
+ -H "Accept: application/json" \
248
+ -H "Authorization: Bearer $TOKEN" \
249
+ -d "{\"channel\": \"email\", \"enabled\": ${ENABLED}, \"mode\": \"${MODE}\"}" \
250
+ "${API_URL}/users/me/notification-settings?projectId=${PROJECT_ID}")
251
+
252
+ HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
253
+ BODY=$(echo "$RESPONSE" | sed '$d')
254
+ ```
255
+
256
+ **Success Card (email on):**
257
+
258
+ ```
259
+ ╭──────────────────────────────────────────────────────────────────────────────╮
260
+ │ ✅ SUCCESS │
261
+ ├──────────────────────────────────────────────────────────────────────────────┤
262
+ │ │
263
+ │ {t.commands.notificationSettings.emailEnabled} │
264
+ │ │
265
+ │ ── Email Notifications ─────────────────────────────────────────────────── │
266
+ │ │
267
+ │ ╭─────────────────╮ │
268
+ │ │ ✓ Enabled │ │
269
+ │ ╰─────────────────╯ │
270
+ │ │
271
+ │ Mode: Immediate │
272
+ │ │
273
+ │ You'll receive email notifications for enabled events. │
274
+ │ │
275
+ ├──────────────────────────────────────────────────────────────────────────────┤
276
+ │ │
277
+ │ 💡 For daily digest instead: /pfNotificationSettings email digest │
278
+ │ │
279
+ ╰──────────────────────────────────────────────────────────────────────────────╯
280
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
281
+ ```
282
+
283
+ **Success Card (email digest):**
284
+
285
+ ```
286
+ ╭──────────────────────────────────────────────────────────────────────────────╮
287
+ │ ✅ SUCCESS │
288
+ ├──────────────────────────────────────────────────────────────────────────────┤
289
+ │ │
290
+ │ {t.commands.notificationSettings.emailDigestEnabled} │
291
+ │ │
292
+ │ ── Email Notifications ─────────────────────────────────────────────────── │
293
+ │ │
294
+ │ ╭─────────────────╮ │
295
+ │ │ ✓ Enabled │ │
296
+ │ ╰─────────────────╯ │
297
+ │ │
298
+ │ Mode: Daily Digest │
299
+ │ │
300
+ │ You'll receive a daily summary email with all notifications. │
301
+ │ │
302
+ ├──────────────────────────────────────────────────────────────────────────────┤
303
+ │ │
304
+ │ 💡 For immediate notifications: /pfNotificationSettings email on │
305
+ │ │
306
+ ╰──────────────────────────────────────────────────────────────────────────────╯
307
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
308
+ ```
309
+
310
+ **Success Card (email off):**
311
+
312
+ ```
313
+ ╭──────────────────────────────────────────────────────────────────────────────╮
314
+ │ ✅ SUCCESS │
315
+ ├──────────────────────────────────────────────────────────────────────────────┤
316
+ │ │
317
+ │ {t.commands.notificationSettings.emailDisabled} │
318
+ │ │
319
+ │ ── Email Notifications ─────────────────────────────────────────────────── │
320
+ │ │
321
+ │ ╭──────────────────╮ │
322
+ │ │ ✕ Disabled │ │
323
+ │ ╰──────────────────╯ │
324
+ │ │
325
+ │ You won't receive email notifications for this project. │
326
+ │ │
327
+ ├──────────────────────────────────────────────────────────────────────────────┤
328
+ │ │
329
+ │ 💡 To enable: /pfNotificationSettings email on │
330
+ │ │
331
+ ╰──────────────────────────────────────────────────────────────────────────────╯
332
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
333
+ ```
334
+
335
+ #### If action is "inapp"
336
+
337
+ Update in-app notification settings.
338
+
339
+ **Valid subActions:**
340
+ - `on` - Enable in-app notifications
341
+ - `off` - Disable in-app notifications
342
+
343
+ **API Request:**
344
+
345
+ ```bash
346
+ RESPONSE=$(curl -s -w "\n%{http_code}" \
347
+ --connect-timeout 5 \
348
+ --max-time 10 \
349
+ -X PATCH \
350
+ -H "Content-Type: application/json" \
351
+ -H "Accept: application/json" \
352
+ -H "Authorization: Bearer $TOKEN" \
353
+ -d "{\"channel\": \"inapp\", \"enabled\": ${ENABLED}}" \
354
+ "${API_URL}/users/me/notification-settings?projectId=${PROJECT_ID}")
355
+ ```
356
+
357
+ **Success Card (inapp on):**
358
+
359
+ ```
360
+ ╭──────────────────────────────────────────────────────────────────────────────╮
361
+ │ ✅ SUCCESS │
362
+ ├──────────────────────────────────────────────────────────────────────────────┤
363
+ │ │
364
+ │ {t.commands.notificationSettings.inappEnabled} │
365
+ │ │
366
+ │ ── In-App Notifications ────────────────────────────────────────────────── │
367
+ │ │
368
+ │ ╭─────────────────╮ │
369
+ │ │ ✓ Enabled │ │
370
+ │ ╰─────────────────╯ │
371
+ │ │
372
+ │ Notifications will appear in /pfNotifications. │
373
+ │ │
374
+ ├──────────────────────────────────────────────────────────────────────────────┤
375
+ │ │
376
+ │ 💡 View notifications: /pfNotifications │
377
+ │ │
378
+ ╰──────────────────────────────────────────────────────────────────────────────╯
379
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
380
+ ```
381
+
382
+ **Success Card (inapp off):**
383
+
384
+ ```
385
+ ╭──────────────────────────────────────────────────────────────────────────────╮
386
+ │ ✅ SUCCESS │
387
+ ├──────────────────────────────────────────────────────────────────────────────┤
388
+ │ │
389
+ │ {t.commands.notificationSettings.inappDisabled} │
390
+ │ │
391
+ │ ── In-App Notifications ────────────────────────────────────────────────── │
392
+ │ │
393
+ │ ╭──────────────────╮ │
394
+ │ │ ✕ Disabled │ │
395
+ │ ╰──────────────────╯ │
396
+ │ │
397
+ │ In-app notifications are disabled. │
398
+ │ │
399
+ ├──────────────────────────────────────────────────────────────────────────────┤
400
+ │ │
401
+ │ 💡 To enable: /pfNotificationSettings inapp on │
402
+ │ │
403
+ ╰──────────────────────────────────────────────────────────────────────────────╯
404
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
405
+ ```
406
+
407
+ #### If action is "event"
408
+
409
+ Update specific event type settings.
410
+
411
+ **Valid event types:**
412
+ - `assigned` - Task assigned to me
413
+ - `mention` - Mentioned in comment
414
+ - `watching` - Task I'm watching updated
415
+ - `team` - All team activity
416
+
417
+ **API Request:**
418
+
419
+ ```bash
420
+ EVENT_TYPE="assigned" # assigned, mention, watching, team
421
+ ENABLED="true" # or "false"
422
+
423
+ RESPONSE=$(curl -s -w "\n%{http_code}" \
424
+ --connect-timeout 5 \
425
+ --max-time 10 \
426
+ -X PATCH \
427
+ -H "Content-Type: application/json" \
428
+ -H "Accept: application/json" \
429
+ -H "Authorization: Bearer $TOKEN" \
430
+ -d "{\"event\": \"${EVENT_TYPE}\", \"enabled\": ${ENABLED}}" \
431
+ "${API_URL}/users/me/notification-settings?projectId=${PROJECT_ID}")
432
+ ```
433
+
434
+ **Success Card (event enabled):**
435
+
436
+ ```
437
+ ╭──────────────────────────────────────────────────────────────────────────────╮
438
+ │ ✅ SUCCESS │
439
+ ├──────────────────────────────────────────────────────────────────────────────┤
440
+ │ │
441
+ │ {t.commands.notificationSettings.eventEnabled} │
442
+ │ │
443
+ │ ── Event: {eventDisplayName} ───────────────────────────────────────────── │
444
+ │ │
445
+ │ ╭─────────────────╮ │
446
+ │ │ ✓ Enabled │ │
447
+ │ ╰─────────────────╯ │
448
+ │ │
449
+ │ You'll be notified when: {eventDescription} │
450
+ │ │
451
+ ├──────────────────────────────────────────────────────────────────────────────┤
452
+ │ │
453
+ │ 💡 View all settings: /pfNotificationSettings │
454
+ │ │
455
+ ╰──────────────────────────────────────────────────────────────────────────────╯
456
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
457
+ ```
458
+
459
+ **Success Card (event disabled):**
460
+
461
+ ```
462
+ ╭──────────────────────────────────────────────────────────────────────────────╮
463
+ │ ✅ SUCCESS │
464
+ ├──────────────────────────────────────────────────────────────────────────────┤
465
+ │ │
466
+ │ {t.commands.notificationSettings.eventDisabled} │
467
+ │ │
468
+ │ ── Event: {eventDisplayName} ───────────────────────────────────────────── │
469
+ │ │
470
+ │ ╭──────────────────╮ │
471
+ │ │ ✕ Disabled │ │
472
+ │ ╰──────────────────╯ │
473
+ │ │
474
+ │ You won't be notified for: {eventDescription} │
475
+ │ │
476
+ ├──────────────────────────────────────────────────────────────────────────────┤
477
+ │ │
478
+ │ 💡 To enable: /pfNotificationSettings event {eventType} on │
479
+ │ │
480
+ ╰──────────────────────────────────────────────────────────────────────────────╯
481
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
482
+ ```
483
+
484
+ ### Step 5: Error Handling
485
+
486
+ **Invalid channel error:**
487
+
488
+ ```
489
+ ╭──────────────────────────────────────────────────────────────────────────────╮
490
+ │ ❌ ERROR │
491
+ ├──────────────────────────────────────────────────────────────────────────────┤
492
+ │ │
493
+ │ {t.commands.notificationSettings.invalidChannel} │
494
+ │ │
495
+ │ Invalid channel: "{action}" │
496
+ │ │
497
+ │ Valid channels: email, inapp │
498
+ │ │
499
+ │ 💡 {t.ui.labels.commands} │
500
+ │ • /pfNotificationSettings email on|off|digest │
501
+ │ • /pfNotificationSettings inapp on|off │
502
+ │ │
503
+ ╰──────────────────────────────────────────────────────────────────────────────╯
504
+ ```
505
+
506
+ **Invalid event type error:**
507
+
508
+ ```
509
+ ╭──────────────────────────────────────────────────────────────────────────────╮
510
+ │ ❌ ERROR │
511
+ ├──────────────────────────────────────────────────────────────────────────────┤
512
+ │ │
513
+ │ {t.commands.notificationSettings.invalidEventType} │
514
+ │ │
515
+ │ Invalid event type: "{subAction}" │
516
+ │ │
517
+ │ Valid event types: │
518
+ │ • assigned - Task assigned to me │
519
+ │ • mention - Mentioned in comment │
520
+ │ • watching - Task I'm watching updated │
521
+ │ • team - All team activity │
522
+ │ │
523
+ │ 💡 Example: /pfNotificationSettings event mention on │
524
+ │ │
525
+ ╰──────────────────────────────────────────────────────────────────────────────╯
526
+ ```
527
+
528
+ **Invalid toggle value error:**
529
+
530
+ ```
531
+ ╭──────────────────────────────────────────────────────────────────────────────╮
532
+ │ ❌ ERROR │
533
+ ├──────────────────────────────────────────────────────────────────────────────┤
534
+ │ │
535
+ │ {t.commands.notificationSettings.invalidToggle} │
536
+ │ │
537
+ │ Invalid value: "{subAction}" │
538
+ │ │
539
+ │ Valid values: on, off │
540
+ │ │
541
+ │ 💡 Example: /pfNotificationSettings email on │
542
+ │ │
543
+ ╰──────────────────────────────────────────────────────────────────────────────╯
544
+ ```
545
+
546
+ **Network error:**
547
+
548
+ ```
549
+ ╭──────────────────────────────────────────────────────────────────────────────╮
550
+ │ ❌ ERROR │
551
+ ├──────────────────────────────────────────────────────────────────────────────┤
552
+ │ │
553
+ │ {t.commands.notificationSettings.networkError} │
554
+ │ │
555
+ │ Could not update notification settings. │
556
+ │ │
557
+ │ {t.commands.notificationSettings.tryAgain} │
558
+ │ │
559
+ ╰──────────────────────────────────────────────────────────────────────────────╯
560
+ ```
561
+
562
+ ## Event Type Display Names
563
+
564
+ | Event Type | Display Name (EN) | Description |
565
+ |------------|-------------------|-------------|
566
+ | assigned | Task assigned to me | When you're assigned to a task |
567
+ | mention | Mentioned in comment | When someone @mentions you |
568
+ | watching | Task I'm watching updated | When a watched task status changes |
569
+ | team | All team activity | All team comments and updates |
570
+
571
+ ## Translation Keys Required
572
+
573
+ ```json
574
+ {
575
+ "commands": {
576
+ "notificationSettings": {
577
+ "title": "Notification Settings",
578
+ "channels": "Notification Channels",
579
+ "events": "Event Types",
580
+ "emailEnabled": "Email notifications enabled!",
581
+ "emailDisabled": "Email notifications disabled.",
582
+ "emailDigestEnabled": "Email daily digest enabled!",
583
+ "inappEnabled": "In-app notifications enabled!",
584
+ "inappDisabled": "In-app notifications disabled.",
585
+ "eventEnabled": "Event notifications enabled!",
586
+ "eventDisabled": "Event notifications disabled.",
587
+ "invalidChannel": "Invalid notification channel.",
588
+ "invalidEventType": "Invalid event type.",
589
+ "invalidToggle": "Invalid toggle value.",
590
+ "networkError": "Could not update notification settings.",
591
+ "tryAgain": "Please check your connection and try again.",
592
+ "emailLabel": "Email",
593
+ "inappLabel": "In-app",
594
+ "slackLabel": "Slack",
595
+ "discordLabel": "Discord",
596
+ "modeImmediate": "Immediate",
597
+ "modeDigest": "Daily digest",
598
+ "notConfigured": "Not configured",
599
+ "eventAssigned": "Task assigned to me",
600
+ "eventMention": "Mentioned in comment",
601
+ "eventWatching": "Task I'm watching updated",
602
+ "eventTeam": "All team activity",
603
+ "eventTypes": "Event types",
604
+ "validChannels": "Valid channels",
605
+ "validEvents": "Valid event types",
606
+ "validValues": "Valid values"
607
+ }
608
+ }
609
+ }
610
+ ```
611
+
612
+ ## Notes
613
+
614
+ - Settings are stored per-project on the cloud
615
+ - Email digest is sent once daily (morning)
616
+ - Slack and Discord require webhook configuration (Phase 14)
617
+ - In-app notifications appear in /pfNotifications
618
+ - Disabling a channel doesn't delete existing notifications
619
+ - Event settings apply to all enabled channels