@dv.nghiem/flowdeck 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 (331) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +136 -0
  3. package/bin/flowdeck.js +108 -0
  4. package/dist/agents/architect.d.ts +3 -0
  5. package/dist/agents/architect.d.ts.map +1 -0
  6. package/dist/agents/code-explorer.d.ts +3 -0
  7. package/dist/agents/code-explorer.d.ts.map +1 -0
  8. package/dist/agents/coder.d.ts +3 -0
  9. package/dist/agents/coder.d.ts.map +1 -0
  10. package/dist/agents/debug.d.ts +4 -0
  11. package/dist/agents/debug.d.ts.map +1 -0
  12. package/dist/agents/doc-updater.d.ts +3 -0
  13. package/dist/agents/doc-updater.d.ts.map +1 -0
  14. package/dist/agents/flowdeck.d.ts +5 -0
  15. package/dist/agents/flowdeck.d.ts.map +1 -0
  16. package/dist/agents/index.d.ts +38 -0
  17. package/dist/agents/index.d.ts.map +1 -0
  18. package/dist/agents/mapper.d.ts +3 -0
  19. package/dist/agents/mapper.d.ts.map +1 -0
  20. package/dist/agents/orchestrator.d.ts +10 -0
  21. package/dist/agents/orchestrator.d.ts.map +1 -0
  22. package/dist/agents/performance.d.ts +4 -0
  23. package/dist/agents/performance.d.ts.map +1 -0
  24. package/dist/agents/planner.d.ts +3 -0
  25. package/dist/agents/planner.d.ts.map +1 -0
  26. package/dist/agents/policy-enforcer.d.ts +3 -0
  27. package/dist/agents/policy-enforcer.d.ts.map +1 -0
  28. package/dist/agents/researcher.d.ts +3 -0
  29. package/dist/agents/researcher.d.ts.map +1 -0
  30. package/dist/agents/reviewer.d.ts +3 -0
  31. package/dist/agents/reviewer.d.ts.map +1 -0
  32. package/dist/agents/risk-analyst.d.ts +3 -0
  33. package/dist/agents/risk-analyst.d.ts.map +1 -0
  34. package/dist/agents/security-auditor.d.ts +3 -0
  35. package/dist/agents/security-auditor.d.ts.map +1 -0
  36. package/dist/agents/specialist.d.ts +5 -0
  37. package/dist/agents/specialist.d.ts.map +1 -0
  38. package/dist/agents/tester.d.ts +3 -0
  39. package/dist/agents/tester.d.ts.map +1 -0
  40. package/dist/agents/types.d.ts +20 -0
  41. package/dist/agents/types.d.ts.map +1 -0
  42. package/dist/agents/writer.d.ts +3 -0
  43. package/dist/agents/writer.d.ts.map +1 -0
  44. package/dist/commands/analysis/analysis.test.d.ts +2 -0
  45. package/dist/commands/analysis/analysis.test.d.ts.map +1 -0
  46. package/dist/commands/analysis/analyze-change.d.ts +148 -0
  47. package/dist/commands/analysis/analyze-change.d.ts.map +1 -0
  48. package/dist/commands/analysis/evaluate-risk.d.ts +77 -0
  49. package/dist/commands/analysis/evaluate-risk.d.ts.map +1 -0
  50. package/dist/commands/analysis/guarded-edit.d.ts +72 -0
  51. package/dist/commands/analysis/guarded-edit.d.ts.map +1 -0
  52. package/dist/commands/execution/deploy-check.d.ts +91 -0
  53. package/dist/commands/execution/deploy-check.d.ts.map +1 -0
  54. package/dist/commands/execution/fix-bug.d.ts +187 -0
  55. package/dist/commands/execution/fix-bug.d.ts.map +1 -0
  56. package/dist/commands/execution/new-feature.d.ts +171 -0
  57. package/dist/commands/execution/new-feature.d.ts.map +1 -0
  58. package/dist/commands/execution/review-code.d.ts +130 -0
  59. package/dist/commands/execution/review-code.d.ts.map +1 -0
  60. package/dist/commands/execution/write-docs.d.ts +94 -0
  61. package/dist/commands/execution/write-docs.d.ts.map +1 -0
  62. package/dist/commands/governance/approve.d.ts +80 -0
  63. package/dist/commands/governance/approve.d.ts.map +1 -0
  64. package/dist/commands/intelligence/blast-radius.d.ts +67 -0
  65. package/dist/commands/intelligence/blast-radius.d.ts.map +1 -0
  66. package/dist/commands/intelligence/impact-radar.d.ts +71 -0
  67. package/dist/commands/intelligence/impact-radar.d.ts.map +1 -0
  68. package/dist/commands/intelligence/intelligence.test.d.ts +2 -0
  69. package/dist/commands/intelligence/intelligence.test.d.ts.map +1 -0
  70. package/dist/commands/intelligence/regression-predict.d.ts +75 -0
  71. package/dist/commands/intelligence/regression-predict.d.ts.map +1 -0
  72. package/dist/commands/intelligence/review-route.d.ts +65 -0
  73. package/dist/commands/intelligence/review-route.d.ts.map +1 -0
  74. package/dist/commands/intelligence/test-gap.d.ts +73 -0
  75. package/dist/commands/intelligence/test-gap.d.ts.map +1 -0
  76. package/dist/commands/intelligence/translate-intent.d.ts +87 -0
  77. package/dist/commands/intelligence/translate-intent.d.ts.map +1 -0
  78. package/dist/commands/intelligence/volatility-map-cmd.d.ts +68 -0
  79. package/dist/commands/intelligence/volatility-map-cmd.d.ts.map +1 -0
  80. package/dist/commands/planning/ask.d.ts +62 -0
  81. package/dist/commands/planning/ask.d.ts.map +1 -0
  82. package/dist/commands/planning/ask.test.d.ts +2 -0
  83. package/dist/commands/planning/ask.test.d.ts.map +1 -0
  84. package/dist/commands/planning/dashboard.d.ts +30 -0
  85. package/dist/commands/planning/dashboard.d.ts.map +1 -0
  86. package/dist/commands/planning/discuss.d.ts +39 -0
  87. package/dist/commands/planning/discuss.d.ts.map +1 -0
  88. package/dist/commands/planning/plan.d.ts +67 -0
  89. package/dist/commands/planning/plan.d.ts.map +1 -0
  90. package/dist/commands/planning/roadmap.d.ts +105 -0
  91. package/dist/commands/planning/roadmap.d.ts.map +1 -0
  92. package/dist/commands/setup/doctor.d.ts +10 -0
  93. package/dist/commands/setup/doctor.d.ts.map +1 -0
  94. package/dist/commands/setup/map-codebase.d.ts +62 -0
  95. package/dist/commands/setup/map-codebase.d.ts.map +1 -0
  96. package/dist/commands/setup/new-project.d.ts +19 -0
  97. package/dist/commands/setup/new-project.d.ts.map +1 -0
  98. package/dist/commands/setup/settings.d.ts +57 -0
  99. package/dist/commands/setup/settings.d.ts.map +1 -0
  100. package/dist/commands/state/checkpoint.d.ts +27 -0
  101. package/dist/commands/state/checkpoint.d.ts.map +1 -0
  102. package/dist/commands/state/multi-repo.d.ts +63 -0
  103. package/dist/commands/state/multi-repo.d.ts.map +1 -0
  104. package/dist/commands/state/progress.d.ts +57 -0
  105. package/dist/commands/state/progress.d.ts.map +1 -0
  106. package/dist/commands/state/resume.d.ts +11 -0
  107. package/dist/commands/state/resume.d.ts.map +1 -0
  108. package/dist/commands/state/workspace-commands.d.ts +207 -0
  109. package/dist/commands/state/workspace-commands.d.ts.map +1 -0
  110. package/dist/dashboard/lib/port-finder.d.ts +10 -0
  111. package/dist/dashboard/lib/port-finder.d.ts.map +1 -0
  112. package/dist/dashboard/lib/port-finder.test.d.ts +2 -0
  113. package/dist/dashboard/lib/port-finder.test.d.ts.map +1 -0
  114. package/dist/dashboard/lib/state-reader.d.ts +3 -0
  115. package/dist/dashboard/lib/state-reader.d.ts.map +1 -0
  116. package/dist/dashboard/server.d.ts +2 -0
  117. package/dist/dashboard/server.d.ts.map +1 -0
  118. package/dist/dashboard/server.mjs +13649 -0
  119. package/dist/dashboard/types.d.ts +72 -0
  120. package/dist/dashboard/types.d.ts.map +1 -0
  121. package/dist/dashboard/views/index.ejs +391 -0
  122. package/dist/dashboard/views/partials/blockers.ejs +10 -0
  123. package/dist/dashboard/views/partials/header.ejs +20 -0
  124. package/dist/dashboard/views/partials/phase-timeline.ejs +40 -0
  125. package/dist/dashboard/views/partials/progress.ejs +12 -0
  126. package/dist/hooks/approval-hook.d.ts +13 -0
  127. package/dist/hooks/approval-hook.d.ts.map +1 -0
  128. package/dist/hooks/compaction-hook.d.ts +23 -0
  129. package/dist/hooks/compaction-hook.d.ts.map +1 -0
  130. package/dist/hooks/context-window-monitor.d.ts +21 -0
  131. package/dist/hooks/context-window-monitor.d.ts.map +1 -0
  132. package/dist/hooks/decision-trace-hook.d.ts +13 -0
  133. package/dist/hooks/decision-trace-hook.d.ts.map +1 -0
  134. package/dist/hooks/file-tracker.d.ts +29 -0
  135. package/dist/hooks/file-tracker.d.ts.map +1 -0
  136. package/dist/hooks/guard-rails.d.ts +33 -0
  137. package/dist/hooks/guard-rails.d.ts.map +1 -0
  138. package/dist/hooks/index.d.ts +5 -0
  139. package/dist/hooks/index.d.ts.map +1 -0
  140. package/dist/hooks/notifications.d.ts +21 -0
  141. package/dist/hooks/notifications.d.ts.map +1 -0
  142. package/dist/hooks/patch-trust.d.ts +27 -0
  143. package/dist/hooks/patch-trust.d.ts.map +1 -0
  144. package/dist/hooks/patch-trust.test.d.ts +2 -0
  145. package/dist/hooks/patch-trust.test.d.ts.map +1 -0
  146. package/dist/hooks/session-events.d.ts +8 -0
  147. package/dist/hooks/session-events.d.ts.map +1 -0
  148. package/dist/hooks/session-idle-hook.d.ts +21 -0
  149. package/dist/hooks/session-idle-hook.d.ts.map +1 -0
  150. package/dist/hooks/session-start.d.ts +10 -0
  151. package/dist/hooks/session-start.d.ts.map +1 -0
  152. package/dist/hooks/shell-env-hook.d.ts +21 -0
  153. package/dist/hooks/shell-env-hook.d.ts.map +1 -0
  154. package/dist/hooks/telemetry-hook.d.ts +25 -0
  155. package/dist/hooks/telemetry-hook.d.ts.map +1 -0
  156. package/dist/hooks/todo-hook.d.ts +25 -0
  157. package/dist/hooks/todo-hook.d.ts.map +1 -0
  158. package/dist/hooks/tool-guard.d.ts +41 -0
  159. package/dist/hooks/tool-guard.d.ts.map +1 -0
  160. package/dist/hooks/tool-guard.test.d.ts +2 -0
  161. package/dist/hooks/tool-guard.test.d.ts.map +1 -0
  162. package/dist/index.d.ts +4 -0
  163. package/dist/index.d.ts.map +1 -0
  164. package/dist/index.js +6639 -0
  165. package/dist/lib/confirmation.d.ts +20 -0
  166. package/dist/lib/confirmation.d.ts.map +1 -0
  167. package/dist/lib/impact-radar.d.ts +35 -0
  168. package/dist/lib/impact-radar.d.ts.map +1 -0
  169. package/dist/lib/signatures.d.ts +12 -0
  170. package/dist/lib/signatures.d.ts.map +1 -0
  171. package/dist/lib/timestamps.d.ts +23 -0
  172. package/dist/lib/timestamps.d.ts.map +1 -0
  173. package/dist/mcp/index.d.ts +20 -0
  174. package/dist/mcp/index.d.ts.map +1 -0
  175. package/dist/services/agent-performance.d.ts +29 -0
  176. package/dist/services/agent-performance.d.ts.map +1 -0
  177. package/dist/services/approval-manager.d.ts +30 -0
  178. package/dist/services/approval-manager.d.ts.map +1 -0
  179. package/dist/services/index.d.ts +7 -0
  180. package/dist/services/index.d.ts.map +1 -0
  181. package/dist/services/model-router.d.ts +35 -0
  182. package/dist/services/model-router.d.ts.map +1 -0
  183. package/dist/services/policy-compiler.d.ts +27 -0
  184. package/dist/services/policy-compiler.d.ts.map +1 -0
  185. package/dist/services/run-trace.d.ts +34 -0
  186. package/dist/services/run-trace.d.ts.map +1 -0
  187. package/dist/services/services.test.d.ts +2 -0
  188. package/dist/services/services.test.d.ts.map +1 -0
  189. package/dist/services/telemetry.d.ts +34 -0
  190. package/dist/services/telemetry.d.ts.map +1 -0
  191. package/dist/tools/agent-dispatch.test.d.ts +2 -0
  192. package/dist/tools/agent-dispatch.test.d.ts.map +1 -0
  193. package/dist/tools/codebase-state.d.ts +4 -0
  194. package/dist/tools/codebase-state.d.ts.map +1 -0
  195. package/dist/tools/context-generator.d.ts +3 -0
  196. package/dist/tools/context-generator.d.ts.map +1 -0
  197. package/dist/tools/council.d.ts +4 -0
  198. package/dist/tools/council.d.ts.map +1 -0
  199. package/dist/tools/decision-trace.d.ts +16 -0
  200. package/dist/tools/decision-trace.d.ts.map +1 -0
  201. package/dist/tools/delegate.d.ts +4 -0
  202. package/dist/tools/delegate.d.ts.map +1 -0
  203. package/dist/tools/failure-replay.d.ts +19 -0
  204. package/dist/tools/failure-replay.d.ts.map +1 -0
  205. package/dist/tools/failure-replay.test.d.ts +2 -0
  206. package/dist/tools/failure-replay.test.d.ts.map +1 -0
  207. package/dist/tools/hash-edit.d.ts +3 -0
  208. package/dist/tools/hash-edit.d.ts.map +1 -0
  209. package/dist/tools/planning-state-lib.d.ts +65 -0
  210. package/dist/tools/planning-state-lib.d.ts.map +1 -0
  211. package/dist/tools/planning-state.d.ts +3 -0
  212. package/dist/tools/planning-state.d.ts.map +1 -0
  213. package/dist/tools/policy-engine.d.ts +19 -0
  214. package/dist/tools/policy-engine.d.ts.map +1 -0
  215. package/dist/tools/repo-memory.d.ts +20 -0
  216. package/dist/tools/repo-memory.d.ts.map +1 -0
  217. package/dist/tools/repo-memory.test.d.ts +2 -0
  218. package/dist/tools/repo-memory.test.d.ts.map +1 -0
  219. package/dist/tools/run-parallel.d.ts +4 -0
  220. package/dist/tools/run-parallel.d.ts.map +1 -0
  221. package/dist/tools/run-pipeline.d.ts +4 -0
  222. package/dist/tools/run-pipeline.d.ts.map +1 -0
  223. package/dist/tools/volatility-map.d.ts +18 -0
  224. package/dist/tools/volatility-map.d.ts.map +1 -0
  225. package/dist/tools/volatility-map.test.d.ts +2 -0
  226. package/dist/tools/volatility-map.test.d.ts.map +1 -0
  227. package/dist/tools/workspace-state.d.ts +3 -0
  228. package/dist/tools/workspace-state.d.ts.map +1 -0
  229. package/docs/USER_GUIDE.md +20 -0
  230. package/docs/agents.md +562 -0
  231. package/docs/best-practices.md +47 -0
  232. package/docs/command-migration.md +175 -0
  233. package/docs/commands/fd-analyze-change.md +107 -0
  234. package/docs/commands/fd-ask.md +51 -0
  235. package/docs/commands/fd-checkpoint.md +10 -0
  236. package/docs/commands/fd-dashboard.md +11 -0
  237. package/docs/commands/fd-deploy-check.md +11 -0
  238. package/docs/commands/fd-discuss.md +28 -0
  239. package/docs/commands/fd-evaluate-risk.md +134 -0
  240. package/docs/commands/fd-fix-bug.md +24 -0
  241. package/docs/commands/fd-guarded-edit.md +105 -0
  242. package/docs/commands/fd-map-codebase.md +27 -0
  243. package/docs/commands/fd-multi-repo.md +63 -0
  244. package/docs/commands/fd-new-feature.md +25 -0
  245. package/docs/commands/fd-new-project.md +24 -0
  246. package/docs/commands/fd-plan.md +33 -0
  247. package/docs/commands/fd-progress.md +11 -0
  248. package/docs/commands/fd-resume.md +10 -0
  249. package/docs/commands/fd-review-code.md +29 -0
  250. package/docs/commands/fd-roadmap.md +10 -0
  251. package/docs/commands/fd-settings.md +10 -0
  252. package/docs/commands/fd-write-docs.md +10 -0
  253. package/docs/commands.md +476 -0
  254. package/docs/configuration.md +211 -0
  255. package/docs/feature-integration-architecture.md +255 -0
  256. package/docs/index.md +75 -0
  257. package/docs/installation.md +134 -0
  258. package/docs/intelligence.md +294 -0
  259. package/docs/multi-repo.md +201 -0
  260. package/docs/notifications.md +170 -0
  261. package/docs/parallel-execution.md +227 -0
  262. package/docs/quick-start.md +174 -0
  263. package/docs/rules.md +459 -0
  264. package/docs/skills.md +408 -0
  265. package/docs/workflows.md +376 -0
  266. package/package.json +58 -0
  267. package/postinstall.mjs +102 -0
  268. package/src/rules/README.md +37 -0
  269. package/src/rules/common/agent-orchestration.md +86 -0
  270. package/src/rules/common/coding-style.md +120 -0
  271. package/src/rules/common/git-workflow.md +77 -0
  272. package/src/rules/common/security.md +94 -0
  273. package/src/rules/common/testing.md +105 -0
  274. package/src/rules/golang/patterns.md +187 -0
  275. package/src/rules/java/patterns.md +204 -0
  276. package/src/rules/python/patterns.md +141 -0
  277. package/src/rules/rust/patterns.md +210 -0
  278. package/src/rules/typescript/patterns.md +168 -0
  279. package/src/skills/api-design/SKILL.md +143 -0
  280. package/src/skills/arch-constraint-guard/SKILL.md +61 -0
  281. package/src/skills/blast-radius-preview/SKILL.md +65 -0
  282. package/src/skills/change-impact-radar/SKILL.md +63 -0
  283. package/src/skills/code-review/SKILL.md +108 -0
  284. package/src/skills/code-tour/SKILL.md +101 -0
  285. package/src/skills/codebase-mapping/SKILL.md +87 -0
  286. package/src/skills/codebase-onboarding/SKILL.md +133 -0
  287. package/src/skills/confidence-aware-planning/SKILL.md +67 -0
  288. package/src/skills/context-load/SKILL.md +63 -0
  289. package/src/skills/debug-flow/SKILL.md +75 -0
  290. package/src/skills/decision-trace/SKILL.md +72 -0
  291. package/src/skills/dependency-audit/SKILL.md +126 -0
  292. package/src/skills/deploy-check/SKILL.md +87 -0
  293. package/src/skills/documentation-writer/SKILL.md +154 -0
  294. package/src/skills/failure-replay-engine/SKILL.md +59 -0
  295. package/src/skills/git-release/SKILL.md +94 -0
  296. package/src/skills/git-workflow/SKILL.md +177 -0
  297. package/src/skills/golang-patterns/SKILL.md +511 -0
  298. package/src/skills/human-review-routing/SKILL.md +65 -0
  299. package/src/skills/intent-translator/SKILL.md +57 -0
  300. package/src/skills/java-patterns/SKILL.md +479 -0
  301. package/src/skills/multi-repo/SKILL.md +187 -0
  302. package/src/skills/parallel-execute/SKILL.md +92 -0
  303. package/src/skills/patch-trust-score/SKILL.md +44 -0
  304. package/src/skills/performance-profiling/SKILL.md +153 -0
  305. package/src/skills/plan-task/SKILL.md +101 -0
  306. package/src/skills/python-patterns/SKILL.md +529 -0
  307. package/src/skills/refactor-guide/SKILL.md +117 -0
  308. package/src/skills/regression-prediction/SKILL.md +57 -0
  309. package/src/skills/repo-memory-graph/SKILL.md +49 -0
  310. package/src/skills/rust-patterns/SKILL.md +492 -0
  311. package/src/skills/security-scan/SKILL.md +91 -0
  312. package/src/skills/self-healing-policies/SKILL.md +76 -0
  313. package/src/skills/tdd-workflow/SKILL.md +126 -0
  314. package/src/skills/test-coverage/SKILL.md +94 -0
  315. package/src/skills/test-gap-detector/SKILL.md +58 -0
  316. package/src/skills/volatility-map/SKILL.md +52 -0
  317. package/src/workflows/debug-flow.md +119 -0
  318. package/src/workflows/deploy-check-flow.md +98 -0
  319. package/src/workflows/discuss-flow.md +97 -0
  320. package/src/workflows/execute-flow.md +233 -0
  321. package/src/workflows/execute-phase.md +142 -0
  322. package/src/workflows/fix-bug-flow.md +210 -0
  323. package/src/workflows/map-codebase-flow.md +92 -0
  324. package/src/workflows/multi-repo-flow.md +226 -0
  325. package/src/workflows/parallel-execution-flow.md +236 -0
  326. package/src/workflows/plan-flow.md +126 -0
  327. package/src/workflows/plan-phase.md +101 -0
  328. package/src/workflows/refactor-flow.md +122 -0
  329. package/src/workflows/review-code-flow.md +105 -0
  330. package/src/workflows/spec-driven-flow.md +43 -0
  331. package/src/workflows/write-docs-flow.md +95 -0
@@ -0,0 +1,120 @@
1
+ # Coding Style
2
+
3
+ Language-agnostic coding conventions followed by all FlowDeck agents.
4
+
5
+ ## Immutability
6
+
7
+ Always create new objects and arrays. Never mutate parameters.
8
+
9
+ ```typescript
10
+ // ❌ NEVER — mutating a parameter
11
+ function addRole(user: User, role: string): void {
12
+ user.roles.push(role);
13
+ }
14
+
15
+ // ✅ ALWAYS — return new object
16
+ function addRole(user: User, role: string): User {
17
+ return { ...user, roles: [...user.roles, role] };
18
+ }
19
+ ```
20
+
21
+ ## KISS / DRY / YAGNI
22
+
23
+ | Principle | Rule |
24
+ |-----------|------|
25
+ | **KISS** (Keep It Simple) | The simplest solution that works is the right solution |
26
+ | **DRY** (Don't Repeat Yourself) | Extract duplication only when you have 3+ identical instances |
27
+ | **YAGNI** (You Aren't Gonna Need It) | Don't add features for hypothetical future needs |
28
+
29
+ ```typescript
30
+ // ❌ YAGNI — configurable for no reason
31
+ function createUser(email: string, options: {
32
+ hashAlgorithm?: 'bcrypt' | 'argon2'; // only ever bcrypt in practice
33
+ saltRounds?: number;
34
+ legacyCompatMode?: boolean;
35
+ }) { ... }
36
+
37
+ // ✅ Simple
38
+ function createUser(email: string, password: string): Promise<User> { ... }
39
+ ```
40
+
41
+ ## File Organization
42
+
43
+ - Many small, focused files > few large files
44
+ - **Typical file size**: 200-400 lines
45
+ - **Maximum**: 800 lines — if larger, split it
46
+ - **One responsibility per file**: `user-service.ts`, not `all-services.ts`
47
+
48
+ ## Error Handling
49
+
50
+ Handle errors explicitly at every level. Never swallow errors silently.
51
+
52
+ ```typescript
53
+ // ❌ Silent catch — hides failures
54
+ try {
55
+ await saveUser(user);
56
+ } catch (e) {}
57
+
58
+ // ❌ Logging without rethrowing — caller doesn't know it failed
59
+ try {
60
+ await saveUser(user);
61
+ } catch (e) {
62
+ console.error(e);
63
+ }
64
+
65
+ // ✅ Explicit — log context, rethrow or convert to domain error
66
+ try {
67
+ await saveUser(user);
68
+ } catch (error) {
69
+ logger.error('Failed to save user', { userId: user.id, error });
70
+ throw new ServiceError('USER_SAVE_FAILED', { cause: error });
71
+ }
72
+ ```
73
+
74
+ Errors propagate upward unless you have a specific reason to handle them at this level.
75
+
76
+ ## Input Validation
77
+
78
+ Validate all external inputs at the system boundary:
79
+
80
+ ```typescript
81
+ // System boundaries where validation is required:
82
+ // - API endpoints (HTTP request body, query params, headers)
83
+ // - File uploads (type, size, content)
84
+ // - Environment variables (on startup)
85
+ // - User input from forms
86
+
87
+ // ✅ Validate at the boundary — not deep in business logic
88
+ router.post('/users', async (req, res) => {
89
+ const result = createUserSchema.safeParse(req.body);
90
+ if (!result.success) {
91
+ return res.status(422).json({ error: result.error.flatten() });
92
+ }
93
+ const user = await userService.create(result.data);
94
+ res.status(201).json(user);
95
+ });
96
+ ```
97
+
98
+ ## Naming Conventions
99
+
100
+ | Type | Convention | Example |
101
+ |------|-----------|---------|
102
+ | Variables | camelCase | `userEmail`, `isActive` |
103
+ | Functions | camelCase | `createUser()`, `fetchProfile()` |
104
+ | Types / Interfaces | PascalCase | `User`, `CreateUserInput` |
105
+ | Classes | PascalCase | `UserService`, `PaymentGateway` |
106
+ | React Components | PascalCase | `UserCard`, `LoginForm` |
107
+ | Constants | UPPER_SNAKE_CASE | `MAX_RETRY_COUNT`, `DEFAULT_TIMEOUT` |
108
+ | Files | kebab-case | `user-service.ts`, `auth-middleware.ts` |
109
+ | Directories | kebab-case | `user-management/`, `api-routes/` |
110
+
111
+ ## Code Smells to Avoid
112
+
113
+ | Smell | Threshold | Fix |
114
+ |-------|-----------|-----|
115
+ | Deep nesting | > 3 levels | Extract guard clauses or helper functions |
116
+ | Magic numbers | Any unlabeled number | Name the constant: `MAX_ITEMS = 100` |
117
+ | Long functions | > 50 lines | Extract smaller functions |
118
+ | Boolean parameters | Any `doThing(true)` | Use options object: `doThing({ verbose: true })` |
119
+ | Long argument lists | > 3 parameters | Use an options object |
120
+ | Implicit any | Any untyped value | Add explicit type annotation |
@@ -0,0 +1,77 @@
1
+ # Git Workflow
2
+
3
+ Conventional commits, clean history, and structured PR workflow.
4
+
5
+ ## Conventional Commit Format
6
+
7
+ ```
8
+ type(scope): description
9
+
10
+ [optional body — explain the why, not the what]
11
+
12
+ [optional footer — breaking changes, issue references]
13
+ ```
14
+
15
+ All commits on the main branch must follow this format.
16
+
17
+ ## Commit Types
18
+
19
+ | Type | Version Bump | When to Use | Example |
20
+ |------|-------------|-------------|---------|
21
+ | `feat` | minor | New feature | `feat(auth): add JWT refresh endpoint` |
22
+ | `fix` | patch | Bug fix | `fix(auth): correct token expiry calculation` |
23
+ | `perf` | patch | Performance | `perf(db): replace N+1 with single JOIN query` |
24
+ | `refactor` | patch | Restructure | `refactor(user): extract password validation` |
25
+ | `docs` | none | Documentation | `docs(api): document authentication endpoints` |
26
+ | `test` | none | Tests | `test(auth): add coverage for expired tokens` |
27
+ | `chore` | none | Maintenance | `chore(deps): update express to 4.18.2` |
28
+ | `ci` | none | CI/CD | `ci(github): add node 20 to test matrix` |
29
+ | `build` | none | Build system | `build: switch to esbuild` |
30
+
31
+ ### Breaking Changes
32
+
33
+ ```
34
+ feat!: remove deprecated v1 authentication endpoints
35
+
36
+ BREAKING CHANGE: The /api/v1/auth/* endpoints have been removed.
37
+ Migrate to /api/v2/auth/* before upgrading.
38
+ See MIGRATION.md for details.
39
+ ```
40
+
41
+ ## Branch Naming
42
+
43
+ ```
44
+ feature/user-authentication — new features
45
+ fix/login-redirect-loop — bug fixes
46
+ chore/update-dependencies — maintenance
47
+ release/v1.2.0 — release preparation
48
+ hotfix/critical-null-dereference — urgent production fix
49
+ refactor/extract-auth-middleware — restructuring
50
+ docs/update-api-reference — docs only
51
+ ```
52
+
53
+ ## PR Workflow
54
+
55
+ 1. Create branch from `main` with proper naming
56
+ 2. Make small, atomic commits with conventional messages
57
+ 3. Rebase onto latest `main` before creating PR
58
+ 4. Create PR with descriptive title and description
59
+ 5. Requires at least 1 reviewer approval
60
+ 6. All checks must pass (tests, types, lint)
61
+ 7. Merge via squash merge for small features, regular merge for large ones
62
+
63
+ ## Rebase vs Merge
64
+
65
+ | Situation | Use | Command |
66
+ |-----------|-----|---------|
67
+ | Local feature before PR | Rebase | `git rebase origin/main` |
68
+ | PR → main | Squash (small features) or Merge (large) | GitHub UI |
69
+ | Release branch | Merge with `--no-ff` | `git merge --no-ff release/v1.2.0` |
70
+ | **Never** | Force-push to main | — |
71
+
72
+ ## Commit Hygiene
73
+
74
+ - **Atomic commits** — one logical change per commit
75
+ - **No WIP commits** on shared branches
76
+ - **Fix typos** by amending the last commit (`git commit --amend`), not a new commit
77
+ - **No "fix build" commits** — fix locally, amend, and force-push the feature branch
@@ -0,0 +1,94 @@
1
+ # Security Standards
2
+
3
+ Security requirements that apply to all code. These are checked before every merge and deployment.
4
+
5
+ ## Pre-Commit Security Checklist
6
+
7
+ Before every commit touching auth, data access, or API routes:
8
+
9
+ - [ ] No hardcoded credentials, API keys, or secrets
10
+ - [ ] All database queries use parameterized inputs (no string concatenation)
11
+ - [ ] Input validated at all API boundaries
12
+ - [ ] Auth middleware present on all protected routes
13
+ - [ ] No passwords, tokens, or sensitive data in log statements
14
+ - [ ] New dependencies checked for known CVEs (`npm audit`)
15
+
16
+ ## Secret Management
17
+
18
+ ```typescript
19
+ // ❌ NEVER — hardcoded secret
20
+ const JWT_SECRET = "my-super-secret-key-abc123";
21
+
22
+ // ✅ ALWAYS — environment variable
23
+ const JWT_SECRET = process.env.JWT_SECRET;
24
+ if (!JWT_SECRET) throw new Error('JWT_SECRET environment variable is required');
25
+ ```
26
+
27
+ Rules:
28
+ - Use `process.env` for all secrets
29
+ - Use `.env.local` (never `.env`) for local development
30
+ - Add `.env*` to `.gitignore` (verify it's there)
31
+ - Use a secret manager (AWS Secrets Manager, Vault) in production
32
+ - Rotate any secret that was accidentally committed
33
+
34
+ ## OWASP Top 10 Quick Reference
35
+
36
+ | ID | Vulnerability | One-Line Check |
37
+ |----|--------------|---------------|
38
+ | A01 | Broken Access Control | Does every protected route check auth AND authorization? |
39
+ | A02 | Cryptographic Failures | Is sensitive data encrypted in transit and at rest? |
40
+ | A03 | Injection | Are all queries parameterized? All shell commands sanitized? |
41
+ | A04 | Insecure Design | Is there rate limiting? Account lockout after failed logins? |
42
+ | A05 | Security Misconfiguration | Is debug mode off? Are default credentials changed? |
43
+ | A06 | Vulnerable Components | Does `npm audit` show zero critical/high? |
44
+ | A07 | Auth Failures | Are JWTs validated? Sessions invalidated on logout? |
45
+ | A08 | Integrity Failures | Is all user input validated before processing? |
46
+ | A09 | Logging Failures | Are errors logged? Are passwords/tokens excluded from logs? |
47
+ | A10 | SSRF | Are server-side URL fetches restricted to allowlisted domains? |
48
+
49
+ ## Security Response Protocol
50
+
51
+ **If a secret is accidentally committed:**
52
+ 1. Rotate the secret immediately — assume it is compromised
53
+ 2. Force-push or use BFG Repo Cleaner to remove from git history
54
+ 3. Audit access logs for the period the secret was exposed
55
+ 4. Notify your security team
56
+
57
+ ```bash
58
+ # Remove secret from git history (after rotating it)
59
+ git filter-branch --force --index-filter \
60
+ 'git rm --cached --ignore-unmatch path/to/secret-file' \
61
+ --prune-empty --tag-name-filter cat -- --all
62
+ ```
63
+
64
+ ## Input Validation Requirements
65
+
66
+ Validate at every trust boundary:
67
+
68
+ ```typescript
69
+ // Required validations for every external input:
70
+ // 1. Type — is it a string? number? object?
71
+ // 2. Length — is it within expected bounds?
72
+ // 3. Format — does it match the expected pattern?
73
+ // 4. Range — for numbers, within acceptable range?
74
+
75
+ // ✅ Example with Zod
76
+ const createUserSchema = z.object({
77
+ email: z.string().email().max(255),
78
+ password: z.string().min(8).max(128),
79
+ role: z.enum(['user', 'admin']).default('user'),
80
+ });
81
+ ```
82
+
83
+ For security-critical fields (passwords, tokens, IDs): **reject** invalid input, do not sanitize.
84
+
85
+ ## Rate Limiting Requirements
86
+
87
+ All public-facing endpoints must have rate limiting:
88
+
89
+ ```typescript
90
+ // Minimum rate limits:
91
+ // - Authentication endpoints: 5 attempts per minute per IP
92
+ // - Public API: 100 requests per minute per user/IP
93
+ // - Password reset: 3 attempts per hour per email
94
+ ```
@@ -0,0 +1,105 @@
1
+ # Testing Standards
2
+
3
+ All code must meet these testing standards before being considered done.
4
+
5
+ ## Minimum Coverage
6
+
7
+ **80% line coverage** — non-negotiable.
8
+
9
+ ```bash
10
+ npx vitest --coverage # vitest
11
+ npx jest --coverage # jest
12
+ ```
13
+
14
+ A task is not complete until coverage is ≥ 80%.
15
+
16
+ ## TDD Workflow
17
+
18
+ Follow Red-Green-Refactor for all new code:
19
+
20
+ 1. **Red** — write a failing test that describes the desired behavior
21
+ 2. **Green** — write the minimum code to make it pass
22
+ 3. **Refactor** — clean up while keeping tests green
23
+ 4. **Commit** — commit the test + implementation together
24
+
25
+ Never write implementation before writing a failing test.
26
+
27
+ ## Test Types
28
+
29
+ | Type | Purpose | Tools | When Required |
30
+ |------|---------|-------|--------------|
31
+ | Unit | Functions in isolation, mocked deps | vitest, jest | Every function with logic |
32
+ | Integration | API + database end-to-end | supertest, vitest | Every API route |
33
+ | E2E | Full user flow in browser | playwright, cypress | Critical user journeys |
34
+
35
+ ## AAA Pattern
36
+
37
+ Every test uses Arrange-Act-Assert:
38
+
39
+ ```typescript
40
+ describe('UserService.create', () => {
41
+ it('should throw ValidationError when email format is invalid', async () => {
42
+ // Arrange
43
+ const service = new UserService(mockDb);
44
+ const input = { email: 'not-an-email', password: 'valid-pass' };
45
+
46
+ // Act
47
+ const result = service.create(input);
48
+
49
+ // Assert
50
+ await expect(result).rejects.toThrow('ValidationError');
51
+ });
52
+ });
53
+ ```
54
+
55
+ ## Test Naming
56
+
57
+ Test names describe behavior in plain language:
58
+
59
+ ```typescript
60
+ // ✅ Describes behavior
61
+ it('should return empty array when user has no orders')
62
+ it('should throw AuthError when token is expired')
63
+ it('should send confirmation email after successful registration')
64
+
65
+ // ❌ Vague
66
+ it('test1')
67
+ it('works')
68
+ it('handles the error case')
69
+ ```
70
+
71
+ Format: `should [expected behavior] when [condition]`
72
+
73
+ ## Test Organization
74
+
75
+ - **Co-locate** tests with source: `user-service.ts` → `user-service.test.ts`
76
+ - Or use a parallel `__tests__/` directory — be consistent within the project
77
+ - One `describe` block per module or class
78
+ - Group related tests with nested `describe` blocks
79
+
80
+ ## What to Test
81
+
82
+ - Public interfaces and API contracts
83
+ - Error conditions and edge cases
84
+ - Auth scenarios (unauthenticated, unauthorized, correct role)
85
+ - Empty inputs, null, undefined
86
+ - Boundary values (max length, zero, negative numbers)
87
+
88
+ ## What NOT to Test
89
+
90
+ - Private methods (test via public interface)
91
+ - Third-party library behavior
92
+ - Simple getters with no logic
93
+ - Framework internals (Express routing, ORM query builder)
94
+
95
+ ## Troubleshooting Test Failures
96
+
97
+ | Situation | Action |
98
+ |-----------|--------|
99
+ | Test fails after code change | Fix the implementation |
100
+ | Test fails after refactor | Undo the refactor; take smaller steps |
101
+ | Test fails and assertion is wrong | Fix the assertion (rare — verify carefully) |
102
+ | Tests are flaky | Find and isolate the shared mutable state |
103
+ | Coverage below 80% | Add tests for uncovered branches and edge cases |
104
+
105
+ **Never change a test to make it pass unless the assertion logic itself is wrong.**
@@ -0,0 +1,187 @@
1
+ # Go Patterns
2
+
3
+ Go conventions for FlowDeck projects.
4
+
5
+ ## Always Handle Errors Explicitly
6
+
7
+ Never discard error return values with `_`. Every error must be checked and either handled or propagated.
8
+
9
+ ```go
10
+ // ❌ Silently discarding the error
11
+ result, _ := parseConfig(path)
12
+
13
+ // ✅ Check and handle or propagate
14
+ result, err := parseConfig(path)
15
+ if err != nil {
16
+ return fmt.Errorf("startup: %w", err)
17
+ }
18
+ ```
19
+
20
+ ## Error String Style
21
+
22
+ Error strings must be lowercase and have no trailing punctuation. They are often wrapped and appear mid-sentence in logs.
23
+
24
+ ```go
25
+ // ❌ Uppercase, trailing period
26
+ errors.New("Connection refused.")
27
+
28
+ // ✅ Lowercase, no trailing punctuation
29
+ errors.New("connection refused")
30
+ fmt.Errorf("user %d: record not found", id)
31
+ ```
32
+
33
+ ## Interface Naming
34
+
35
+ - Single-method interfaces: use the method name with the `-er` suffix.
36
+ - Multi-method interfaces: use a noun that describes the role.
37
+
38
+ ```go
39
+ // ✅ Single-method
40
+ type Reader interface { Read(p []byte) (int, error) }
41
+ type Stringer interface { String() string }
42
+ type Notifier interface { Notify(ctx context.Context, msg Message) error }
43
+
44
+ // ✅ Multi-method
45
+ type UserStore interface {
46
+ FindByID(ctx context.Context, id int64) (*User, error)
47
+ Save(ctx context.Context, u *User) error
48
+ }
49
+ ```
50
+
51
+ ## Exported Names Must Have Doc Comments
52
+
53
+ Every exported function, type, method, and variable requires a doc comment beginning with the name.
54
+
55
+ ```go
56
+ // ❌ Missing doc comment
57
+ func ProcessOrder(o *Order) error { ... }
58
+
59
+ // ✅ Doc comment starting with the name
60
+ // ProcessOrder validates and persists an order, charging the associated payment method.
61
+ func ProcessOrder(o *Order) error { ... }
62
+ ```
63
+
64
+ ## context.Context as First Parameter
65
+
66
+ All functions that perform I/O, call external services, or could be long-running must accept `context.Context` as their first parameter.
67
+
68
+ ```go
69
+ // ❌ No context — cannot be cancelled or carry deadlines
70
+ func FetchUser(id int64) (*User, error) { ... }
71
+
72
+ // ✅ context.Context first
73
+ func FetchUser(ctx context.Context, id int64) (*User, error) { ... }
74
+ ```
75
+
76
+ ## Never panic for Expected Errors
77
+
78
+ Use `panic` only for programmer errors (invariant violations, impossible states). Use error returns for expected failure modes.
79
+
80
+ ```go
81
+ // ❌ panic for expected failure
82
+ func ParseConfig(data []byte) Config {
83
+ var cfg Config
84
+ if err := json.Unmarshal(data, &cfg); err != nil {
85
+ panic(err) // config may be invalid at runtime — this is expected
86
+ }
87
+ return cfg
88
+ }
89
+
90
+ // ✅ Return error for expected failure
91
+ func ParseConfig(data []byte) (Config, error) {
92
+ var cfg Config
93
+ if err := json.Unmarshal(data, &cfg); err != nil {
94
+ return Config{}, fmt.Errorf("parse config: %w", err)
95
+ }
96
+ return cfg, nil
97
+ }
98
+ ```
99
+
100
+ ## Table-Driven Tests
101
+
102
+ Any function with more than one meaningful input/output combination requires a table-driven test using `t.Run`.
103
+
104
+ ```go
105
+ func TestDivide(t *testing.T) {
106
+ cases := []struct {
107
+ name string
108
+ a, b float64
109
+ want float64
110
+ wantErr bool
111
+ }{
112
+ {name: "simple division", a: 10, b: 2, want: 5},
113
+ {name: "divide by zero", a: 5, b: 0, wantErr: true},
114
+ {name: "negative divisor", a: 9, b: -3, want: -3},
115
+ }
116
+ for _, tc := range cases {
117
+ t.Run(tc.name, func(t *testing.T) {
118
+ got, err := Divide(tc.a, tc.b)
119
+ if (err != nil) != tc.wantErr {
120
+ t.Fatalf("Divide(%v, %v) err = %v, wantErr %v", tc.a, tc.b, err, tc.wantErr)
121
+ }
122
+ if !tc.wantErr && got != tc.want {
123
+ t.Errorf("Divide(%v, %v) = %v, want %v", tc.a, tc.b, got, tc.want)
124
+ }
125
+ })
126
+ }
127
+ }
128
+ ```
129
+
130
+ ## Static Analysis
131
+
132
+ All code must pass:
133
+
134
+ ```bash
135
+ go vet ./...
136
+ staticcheck ./...
137
+ golangci-lint run
138
+ ```
139
+
140
+ Run these in CI before merge. Do not suppress linter warnings without a comment explaining why.
141
+
142
+ ## Avoid Global State
143
+
144
+ Prefer dependency injection via struct fields over package-level variables. Global state makes testing and concurrent use difficult.
145
+
146
+ ```go
147
+ // ❌ Package-level global
148
+ var defaultClient = &http.Client{Timeout: 10 * time.Second}
149
+
150
+ func Fetch(url string) ([]byte, error) {
151
+ resp, err := defaultClient.Get(url)
152
+ ...
153
+ }
154
+
155
+ // ✅ Injected via struct
156
+ type APIClient struct {
157
+ http *http.Client
158
+ }
159
+
160
+ func NewAPIClient(http *http.Client) *APIClient {
161
+ return &APIClient{http: http}
162
+ }
163
+
164
+ func (c *APIClient) Fetch(ctx context.Context, url string) ([]byte, error) {
165
+ req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
166
+ resp, err := c.http.Do(req)
167
+ ...
168
+ }
169
+ ```
170
+
171
+ ## Never Start Goroutines in init() or Package-Level Vars
172
+
173
+ Goroutines started at package init time cannot be cancelled, cannot propagate errors, and make test isolation impossible.
174
+
175
+ ```go
176
+ // ❌ Goroutine in init
177
+ func init() {
178
+ go backgroundWorker() // leaks, cannot cancel, runs in every test
179
+ }
180
+
181
+ // ✅ Start goroutines from an explicit lifecycle method
182
+ type Worker struct { done chan struct{} }
183
+
184
+ func (w *Worker) Start(ctx context.Context) {
185
+ go w.run(ctx)
186
+ }
187
+ ```