@coralai/sps-cli 0.55.13 → 0.56.1

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 (437) hide show
  1. package/dist/commands/cardMarkComplete.d.ts.map +1 -1
  2. package/dist/commands/cardMarkComplete.js +6 -3
  3. package/dist/commands/cardMarkComplete.js.map +1 -1
  4. package/dist/commands/projectInit.d.ts +18 -16
  5. package/dist/commands/projectInit.d.ts.map +1 -1
  6. package/dist/commands/projectInit.js +59 -186
  7. package/dist/commands/projectInit.js.map +1 -1
  8. package/dist/commands/skillCommand.js +7 -4
  9. package/dist/commands/skillCommand.js.map +1 -1
  10. package/dist/commands/tick.d.ts +2 -20
  11. package/dist/commands/tick.d.ts.map +1 -1
  12. package/dist/commands/tick.js +58 -1
  13. package/dist/commands/tick.js.map +1 -1
  14. package/dist/console/index.d.ts.map +1 -1
  15. package/dist/console/index.js +4 -0
  16. package/dist/console/index.js.map +1 -1
  17. package/dist/console/routes/chat.d.ts.map +1 -1
  18. package/dist/console/routes/chat.js +211 -6
  19. package/dist/console/routes/chat.js.map +1 -1
  20. package/dist/console/routes/projects.d.ts +0 -6
  21. package/dist/console/routes/projects.d.ts.map +1 -1
  22. package/dist/console/routes/projects.js +11 -2
  23. package/dist/console/routes/projects.js.map +1 -1
  24. package/dist/console/routes/providers.d.ts +10 -0
  25. package/dist/console/routes/providers.d.ts.map +1 -0
  26. package/dist/console/routes/providers.js +63 -0
  27. package/dist/console/routes/providers.js.map +1 -0
  28. package/dist/console/routes/smartarrange.d.ts +4 -0
  29. package/dist/console/routes/smartarrange.d.ts.map +1 -0
  30. package/dist/console/routes/smartarrange.js +107 -0
  31. package/dist/console/routes/smartarrange.js.map +1 -0
  32. package/dist/console/routes/system.d.ts.map +1 -1
  33. package/dist/console/routes/system.js +28 -0
  34. package/dist/console/routes/system.js.map +1 -1
  35. package/dist/console/routes/workers.d.ts.map +1 -1
  36. package/dist/console/routes/workers.js +36 -4
  37. package/dist/console/routes/workers.js.map +1 -1
  38. package/dist/console-assets/assets/index-CWkYVI5d.js +600 -0
  39. package/dist/console-assets/assets/index-CnUBHNsN.css +10 -0
  40. package/dist/console-assets/index.html +2 -2
  41. package/dist/core/agents/AcpBackend.d.ts +24 -0
  42. package/dist/core/agents/AcpBackend.d.ts.map +1 -0
  43. package/dist/core/agents/AcpBackend.js +86 -0
  44. package/dist/core/agents/AcpBackend.js.map +1 -0
  45. package/dist/core/agents/AgentBackend.d.ts +53 -0
  46. package/dist/core/agents/AgentBackend.d.ts.map +1 -0
  47. package/dist/core/agents/AgentBackend.js +18 -0
  48. package/dist/core/agents/AgentBackend.js.map +1 -0
  49. package/dist/core/agents/ClaudeAcpBackend.d.ts +13 -0
  50. package/dist/core/agents/ClaudeAcpBackend.d.ts.map +1 -0
  51. package/dist/core/agents/ClaudeAcpBackend.js +14 -0
  52. package/dist/core/agents/ClaudeAcpBackend.js.map +1 -0
  53. package/dist/core/agents/ClaudeSdkBackend.d.ts +26 -0
  54. package/dist/core/agents/ClaudeSdkBackend.d.ts.map +1 -0
  55. package/dist/core/agents/ClaudeSdkBackend.js +102 -0
  56. package/dist/core/agents/ClaudeSdkBackend.js.map +1 -0
  57. package/dist/core/agents/CodexAppServerBackend.d.ts +33 -0
  58. package/dist/core/agents/CodexAppServerBackend.d.ts.map +1 -0
  59. package/dist/core/agents/CodexAppServerBackend.js +168 -0
  60. package/dist/core/agents/CodexAppServerBackend.js.map +1 -0
  61. package/dist/core/agents/OpenAiAgentBackend.d.ts +39 -0
  62. package/dist/core/agents/OpenAiAgentBackend.d.ts.map +1 -0
  63. package/dist/core/agents/OpenAiAgentBackend.js +132 -0
  64. package/dist/core/agents/OpenAiAgentBackend.js.map +1 -0
  65. package/dist/core/agents/agentsMd.d.ts +2 -0
  66. package/dist/core/agents/agentsMd.d.ts.map +1 -0
  67. package/dist/core/agents/agentsMd.js +22 -0
  68. package/dist/core/agents/agentsMd.js.map +1 -0
  69. package/dist/core/agents/localTracing.d.ts +3 -0
  70. package/dist/core/agents/localTracing.d.ts.map +1 -0
  71. package/dist/core/agents/localTracing.js +42 -0
  72. package/dist/core/agents/localTracing.js.map +1 -0
  73. package/dist/core/agents/resolveBackend.d.ts +26 -0
  74. package/dist/core/agents/resolveBackend.d.ts.map +1 -0
  75. package/dist/core/agents/resolveBackend.js +27 -0
  76. package/dist/core/agents/resolveBackend.js.map +1 -0
  77. package/dist/core/agents/workerOutputSink.d.ts +4 -0
  78. package/dist/core/agents/workerOutputSink.d.ts.map +1 -0
  79. package/dist/core/agents/workerOutputSink.js +39 -0
  80. package/dist/core/agents/workerOutputSink.js.map +1 -0
  81. package/dist/core/config.d.ts +6 -0
  82. package/dist/core/config.d.ts.map +1 -1
  83. package/dist/core/config.js +4 -0
  84. package/dist/core/config.js.map +1 -1
  85. package/dist/core/intel/RuntimeSession.d.ts +16 -0
  86. package/dist/core/intel/RuntimeSession.d.ts.map +1 -0
  87. package/dist/core/intel/RuntimeSession.js +89 -0
  88. package/dist/core/intel/RuntimeSession.js.map +1 -0
  89. package/dist/core/intel/agentsConfig.d.ts +20 -0
  90. package/dist/core/intel/agentsConfig.d.ts.map +1 -0
  91. package/dist/core/intel/agentsConfig.js +68 -0
  92. package/dist/core/intel/agentsConfig.js.map +1 -0
  93. package/dist/core/intel/planStore.d.ts +23 -0
  94. package/dist/core/intel/planStore.d.ts.map +1 -0
  95. package/dist/core/intel/planStore.js +67 -0
  96. package/dist/core/intel/planStore.js.map +1 -0
  97. package/dist/core/intel/types.d.ts +86 -0
  98. package/dist/core/intel/types.d.ts.map +1 -0
  99. package/dist/core/intel/types.js +8 -0
  100. package/dist/core/intel/types.js.map +1 -0
  101. package/dist/core/memoryIngest.d.ts +18 -0
  102. package/dist/core/memoryIngest.d.ts.map +1 -0
  103. package/dist/core/memoryIngest.js +56 -0
  104. package/dist/core/memoryIngest.js.map +1 -0
  105. package/dist/core/memoryProvider.d.ts +63 -0
  106. package/dist/core/memoryProvider.d.ts.map +1 -0
  107. package/dist/core/memoryProvider.js +205 -0
  108. package/dist/core/memoryProvider.js.map +1 -0
  109. package/dist/core/skillStore.d.ts.map +1 -1
  110. package/dist/core/skillStore.js +2 -1
  111. package/dist/core/skillStore.js.map +1 -1
  112. package/dist/core/skills/SkillsManager.d.ts +38 -0
  113. package/dist/core/skills/SkillsManager.d.ts.map +1 -0
  114. package/dist/core/skills/SkillsManager.js +231 -0
  115. package/dist/core/skills/SkillsManager.js.map +1 -0
  116. package/dist/core/skills/distribution.d.ts +64 -0
  117. package/dist/core/skills/distribution.d.ts.map +1 -0
  118. package/dist/core/skills/distribution.js +269 -0
  119. package/dist/core/skills/distribution.js.map +1 -0
  120. package/dist/core/skills/index.d.ts +13 -0
  121. package/dist/core/skills/index.d.ts.map +1 -0
  122. package/dist/core/skills/index.js +13 -0
  123. package/dist/core/skills/index.js.map +1 -0
  124. package/dist/core/skills/types.d.ts +44 -0
  125. package/dist/core/skills/types.d.ts.map +1 -0
  126. package/dist/core/skills/types.js +9 -0
  127. package/dist/core/skills/types.js.map +1 -0
  128. package/dist/core/taskPrompts.d.ts +0 -12
  129. package/dist/core/taskPrompts.d.ts.map +1 -1
  130. package/dist/core/taskPrompts.js +0 -14
  131. package/dist/core/taskPrompts.js.map +1 -1
  132. package/dist/core/transcriptIngest.d.ts +37 -0
  133. package/dist/core/transcriptIngest.d.ts.map +1 -0
  134. package/dist/core/transcriptIngest.js +137 -0
  135. package/dist/core/transcriptIngest.js.map +1 -0
  136. package/dist/core/wiki/types.d.ts +282 -745
  137. package/dist/core/wiki/types.d.ts.map +1 -1
  138. package/dist/core/wiki/types.js +1 -1
  139. package/dist/core/wiki/types.js.map +1 -1
  140. package/dist/daemon/daemonClient.d.ts +6 -0
  141. package/dist/daemon/daemonClient.d.ts.map +1 -1
  142. package/dist/daemon/daemonClient.js.map +1 -1
  143. package/dist/daemon/sessionDaemon.d.ts.map +1 -1
  144. package/dist/daemon/sessionDaemon.js.map +1 -1
  145. package/dist/engines/SmartArrangeEngine.d.ts +75 -0
  146. package/dist/engines/SmartArrangeEngine.d.ts.map +1 -0
  147. package/dist/engines/SmartArrangeEngine.js +112 -0
  148. package/dist/engines/SmartArrangeEngine.js.map +1 -0
  149. package/dist/engines/StageEngine.d.ts +3 -17
  150. package/dist/engines/StageEngine.d.ts.map +1 -1
  151. package/dist/engines/StageEngine.js +13 -91
  152. package/dist/engines/StageEngine.js.map +1 -1
  153. package/dist/engines/smartarrange/AcpWorkerExec.d.ts +35 -0
  154. package/dist/engines/smartarrange/AcpWorkerExec.d.ts.map +1 -0
  155. package/dist/engines/smartarrange/AcpWorkerExec.js +71 -0
  156. package/dist/engines/smartarrange/AcpWorkerExec.js.map +1 -0
  157. package/dist/engines/smartarrange/cardSink.d.ts +29 -0
  158. package/dist/engines/smartarrange/cardSink.d.ts.map +1 -0
  159. package/dist/engines/smartarrange/cardSink.js +43 -0
  160. package/dist/engines/smartarrange/cardSink.js.map +1 -0
  161. package/dist/engines/smartarrange/runner.d.ts +24 -0
  162. package/dist/engines/smartarrange/runner.d.ts.map +1 -0
  163. package/dist/engines/smartarrange/runner.js +116 -0
  164. package/dist/engines/smartarrange/runner.js.map +1 -0
  165. package/dist/engines/smartarrange/screenshot.d.ts +5 -0
  166. package/dist/engines/smartarrange/screenshot.d.ts.map +1 -0
  167. package/dist/engines/smartarrange/screenshot.js +117 -0
  168. package/dist/engines/smartarrange/screenshot.js.map +1 -0
  169. package/dist/main.js +127 -92
  170. package/dist/main.js.map +1 -1
  171. package/dist/manager/worker-manager-impl.d.ts.map +1 -1
  172. package/dist/manager/worker-manager-impl.js +7 -0
  173. package/dist/manager/worker-manager-impl.js.map +1 -1
  174. package/dist/providers/ACPWorkerRuntime.d.ts +2 -0
  175. package/dist/providers/ACPWorkerRuntime.d.ts.map +1 -1
  176. package/dist/providers/ACPWorkerRuntime.js +1 -0
  177. package/dist/providers/ACPWorkerRuntime.js.map +1 -1
  178. package/dist/providers/LLMClient.d.ts +32 -0
  179. package/dist/providers/LLMClient.d.ts.map +1 -0
  180. package/dist/providers/LLMClient.js +108 -0
  181. package/dist/providers/LLMClient.js.map +1 -0
  182. package/dist/providers/MarkdownTaskBackend.d.ts.map +1 -1
  183. package/dist/providers/MarkdownTaskBackend.js +3 -2
  184. package/dist/providers/MarkdownTaskBackend.js.map +1 -1
  185. package/dist/providers/llm/chatTools.d.ts +11 -0
  186. package/dist/providers/llm/chatTools.d.ts.map +1 -0
  187. package/dist/providers/llm/chatTools.js +57 -0
  188. package/dist/providers/llm/chatTools.js.map +1 -0
  189. package/dist/providers/llm/codexAuth.d.ts +8 -0
  190. package/dist/providers/llm/codexAuth.d.ts.map +1 -0
  191. package/dist/providers/llm/codexAuth.js +57 -0
  192. package/dist/providers/llm/codexAuth.js.map +1 -0
  193. package/dist/providers/llm/codexModel.d.ts +14 -0
  194. package/dist/providers/llm/codexModel.d.ts.map +1 -0
  195. package/dist/providers/llm/codexModel.js +96 -0
  196. package/dist/providers/llm/codexModel.js.map +1 -0
  197. package/dist/providers/llm/localSubscription.d.ts +15 -0
  198. package/dist/providers/llm/localSubscription.d.ts.map +1 -0
  199. package/dist/providers/llm/localSubscription.js +66 -0
  200. package/dist/providers/llm/localSubscription.js.map +1 -0
  201. package/dist/providers/llm/modelFactory.d.ts +14 -0
  202. package/dist/providers/llm/modelFactory.d.ts.map +1 -0
  203. package/dist/providers/llm/modelFactory.js +22 -0
  204. package/dist/providers/llm/modelFactory.js.map +1 -0
  205. package/dist/providers/llm/monitorSkills.d.ts +6 -0
  206. package/dist/providers/llm/monitorSkills.d.ts.map +1 -0
  207. package/dist/providers/llm/monitorSkills.js +37 -0
  208. package/dist/providers/llm/monitorSkills.js.map +1 -0
  209. package/dist/providers/llm/probeTools.d.ts +7 -0
  210. package/dist/providers/llm/probeTools.d.ts.map +1 -0
  211. package/dist/providers/llm/probeTools.js +84 -0
  212. package/dist/providers/llm/probeTools.js.map +1 -0
  213. package/dist/providers/llm/providers.d.ts +26 -0
  214. package/dist/providers/llm/providers.d.ts.map +1 -0
  215. package/dist/providers/llm/providers.js +68 -0
  216. package/dist/providers/llm/providers.js.map +1 -0
  217. package/dist/providers/llm/skillTools.d.ts +4 -0
  218. package/dist/providers/llm/skillTools.d.ts.map +1 -0
  219. package/dist/providers/llm/skillTools.js +42 -0
  220. package/dist/providers/llm/skillTools.js.map +1 -0
  221. package/dist/providers/llm/workerTools.d.ts +9 -0
  222. package/dist/providers/llm/workerTools.d.ts.map +1 -0
  223. package/dist/providers/llm/workerTools.js +111 -0
  224. package/dist/providers/llm/workerTools.js.map +1 -0
  225. package/dist/providers/mcp/spsMcpServer.d.ts +15 -0
  226. package/dist/providers/mcp/spsMcpServer.d.ts.map +1 -0
  227. package/dist/providers/mcp/spsMcpServer.js +67 -0
  228. package/dist/providers/mcp/spsMcpServer.js.map +1 -0
  229. package/dist/providers/mcp/spsMcpStdio.d.ts +2 -0
  230. package/dist/providers/mcp/spsMcpStdio.d.ts.map +1 -0
  231. package/dist/providers/mcp/spsMcpStdio.js +32 -0
  232. package/dist/providers/mcp/spsMcpStdio.js.map +1 -0
  233. package/dist/providers/mcp/spsMcpStdioConfig.d.ts +11 -0
  234. package/dist/providers/mcp/spsMcpStdioConfig.d.ts.map +1 -0
  235. package/dist/providers/mcp/spsMcpStdioConfig.js +19 -0
  236. package/dist/providers/mcp/spsMcpStdioConfig.js.map +1 -0
  237. package/dist/server.d.ts +23 -0
  238. package/dist/server.d.ts.map +1 -1
  239. package/dist/server.js +23 -0
  240. package/dist/server.js.map +1 -1
  241. package/dist/services/ChatService.d.ts +10 -0
  242. package/dist/services/ChatService.d.ts.map +1 -1
  243. package/dist/services/ChatService.js +2 -0
  244. package/dist/services/ChatService.js.map +1 -1
  245. package/dist/services/LogService.d.ts +1 -1
  246. package/dist/services/LogService.d.ts.map +1 -1
  247. package/dist/services/LogService.js +3 -2
  248. package/dist/services/LogService.js.map +1 -1
  249. package/dist/services/ProjectService.d.ts +12 -2
  250. package/dist/services/ProjectService.d.ts.map +1 -1
  251. package/dist/services/ProjectService.js +1 -0
  252. package/dist/services/ProjectService.js.map +1 -1
  253. package/dist/services/SkillService.js +11 -13
  254. package/dist/services/SkillService.js.map +1 -1
  255. package/dist/services/SmartArrangeService.d.ts +12 -0
  256. package/dist/services/SmartArrangeService.d.ts.map +1 -0
  257. package/dist/services/SmartArrangeService.js +37 -0
  258. package/dist/services/SmartArrangeService.js.map +1 -0
  259. package/dist/services/SystemService.d.ts +20 -0
  260. package/dist/services/SystemService.d.ts.map +1 -1
  261. package/dist/services/SystemService.js +93 -0
  262. package/dist/services/SystemService.js.map +1 -1
  263. package/dist/services/WorkerService.d.ts +8 -0
  264. package/dist/services/WorkerService.d.ts.map +1 -1
  265. package/dist/services/WorkerService.js +73 -3
  266. package/dist/services/WorkerService.js.map +1 -1
  267. package/dist/services/container.d.ts +2 -0
  268. package/dist/services/container.d.ts.map +1 -1
  269. package/dist/services/container.js +2 -0
  270. package/dist/services/container.js.map +1 -1
  271. package/dist/shared/localTime.d.ts +8 -0
  272. package/dist/shared/localTime.d.ts.map +1 -0
  273. package/dist/shared/localTime.js +11 -0
  274. package/dist/shared/localTime.js.map +1 -0
  275. package/dist/shared/runtimePaths.d.ts +1 -1
  276. package/dist/shared/runtimePaths.d.ts.map +1 -1
  277. package/dist/shared/runtimePaths.js +2 -2
  278. package/dist/shared/runtimePaths.js.map +1 -1
  279. package/dist/shared/runtimeSchemas.d.ts +74 -245
  280. package/dist/shared/runtimeSchemas.d.ts.map +1 -1
  281. package/dist/shared/runtimeSchemas.js +2 -2
  282. package/dist/shared/runtimeSchemas.js.map +1 -1
  283. package/monitor-skills/probe-playbook/SKILL.md +32 -0
  284. package/monitor-skills/visual-rubric/SKILL.md +34 -0
  285. package/package.json +8 -8
  286. package/project-template/.claude/hooks/stop.sh +3 -1
  287. package/dist/console-assets/assets/index-BvWWj69G.js +0 -557
  288. package/dist/console-assets/assets/index-Eo4PuNPl.css +0 -10
  289. package/dist/interfaces/ACPClient.d.ts +0 -107
  290. package/dist/interfaces/ACPClient.d.ts.map +0 -1
  291. package/dist/interfaces/ACPClient.js +0 -17
  292. package/dist/interfaces/ACPClient.js.map +0 -1
  293. package/dist/interfaces/AgentRuntime.d.ts +0 -40
  294. package/dist/interfaces/AgentRuntime.d.ts.map +0 -1
  295. package/dist/interfaces/AgentRuntime.js +0 -17
  296. package/dist/interfaces/AgentRuntime.js.map +0 -1
  297. package/dist/manager/agentmemory.d.ts +0 -6
  298. package/dist/manager/agentmemory.d.ts.map +0 -1
  299. package/dist/manager/agentmemory.js +0 -73
  300. package/dist/manager/agentmemory.js.map +0 -1
  301. package/dist/models/acp.d.ts +0 -64
  302. package/dist/models/acp.d.ts.map +0 -1
  303. package/dist/models/acp.js +0 -17
  304. package/dist/models/acp.js.map +0 -1
  305. package/dist/providers/LocalACPClient.d.ts +0 -27
  306. package/dist/providers/LocalACPClient.d.ts.map +0 -1
  307. package/dist/providers/LocalACPClient.js +0 -26
  308. package/dist/providers/LocalACPClient.js.map +0 -1
  309. package/dist/providers/adapters/AcpSdkAdapter.d.ts +0 -24
  310. package/dist/providers/adapters/AcpSdkAdapter.d.ts.map +0 -1
  311. package/dist/providers/adapters/AcpSdkAdapter.js +0 -439
  312. package/dist/providers/adapters/AcpSdkAdapter.js.map +0 -1
  313. package/dist/providers/adapters/acp-fs-handlers.d.ts +0 -26
  314. package/dist/providers/adapters/acp-fs-handlers.d.ts.map +0 -1
  315. package/dist/providers/adapters/acp-fs-handlers.js +0 -61
  316. package/dist/providers/adapters/acp-fs-handlers.js.map +0 -1
  317. package/dist/providers/adapters/acp-permissions.d.ts +0 -42
  318. package/dist/providers/adapters/acp-permissions.d.ts.map +0 -1
  319. package/dist/providers/adapters/acp-permissions.js +0 -76
  320. package/dist/providers/adapters/acp-permissions.js.map +0 -1
  321. package/dist/providers/adapters/acp-session-accumulator.d.ts +0 -55
  322. package/dist/providers/adapters/acp-session-accumulator.d.ts.map +0 -1
  323. package/dist/providers/adapters/acp-session-accumulator.js +0 -133
  324. package/dist/providers/adapters/acp-session-accumulator.js.map +0 -1
  325. package/dist/providers/adapters/acp-terminal-manager.d.ts +0 -56
  326. package/dist/providers/adapters/acp-terminal-manager.d.ts.map +0 -1
  327. package/dist/providers/adapters/acp-terminal-manager.js +0 -127
  328. package/dist/providers/adapters/acp-terminal-manager.js.map +0 -1
  329. package/project-template/logs/.gitkeep +0 -0
  330. package/skills/architecture-decision-records/SKILL.md +0 -207
  331. package/skills/backend/SKILL.md +0 -62
  332. package/skills/backend/references/api-design.md +0 -168
  333. package/skills/backend/references/caching.md +0 -181
  334. package/skills/backend/references/data-access.md +0 -173
  335. package/skills/backend/references/layering.md +0 -181
  336. package/skills/backend/references/observability.md +0 -190
  337. package/skills/backend/references/resilience.md +0 -201
  338. package/skills/backend/references/security.md +0 -186
  339. package/skills/backend-architect/SKILL.md +0 -119
  340. package/skills/code-reviewer/SKILL.md +0 -143
  341. package/skills/coding-standards/SKILL.md +0 -60
  342. package/skills/coding-standards/references/clean-code.md +0 -258
  343. package/skills/coding-standards/references/code-review.md +0 -192
  344. package/skills/coding-standards/references/commits-and-prs.md +0 -226
  345. package/skills/coding-standards/references/error-strategy.md +0 -193
  346. package/skills/coding-standards/references/naming.md +0 -185
  347. package/skills/coding-standards/references/tdd.md +0 -171
  348. package/skills/database/SKILL.md +0 -53
  349. package/skills/database/references/indexing.md +0 -190
  350. package/skills/database/references/migrations.md +0 -199
  351. package/skills/database/references/nosql.md +0 -185
  352. package/skills/database/references/queries.md +0 -295
  353. package/skills/database/references/scaling.md +0 -203
  354. package/skills/database/references/schema.md +0 -191
  355. package/skills/database-optimizer/SKILL.md +0 -168
  356. package/skills/debugging-workflow/SKILL.md +0 -244
  357. package/skills/dev-worker/SKILL.md +0 -40
  358. package/skills/dev-worker/references/architect.md +0 -139
  359. package/skills/dev-worker/references/backend.md +0 -163
  360. package/skills/dev-worker/references/frontend.md +0 -122
  361. package/skills/dev-worker/references/fullstack.md +0 -179
  362. package/skills/dev-worker/references/optimizer.md +0 -151
  363. package/skills/dev-worker/references/phaser.md +0 -109
  364. package/skills/dev-worker/references/prototyper.md +0 -171
  365. package/skills/dev-worker/references/reviewer.md +0 -122
  366. package/skills/dev-worker/references/security.md +0 -154
  367. package/skills/dev-worker/references/senior.md +0 -155
  368. package/skills/dev-worker/references/typescript.md +0 -65
  369. package/skills/dev-worker/references/writer.md +0 -201
  370. package/skills/devops/SKILL.md +0 -55
  371. package/skills/devops/references/ci-cd.md +0 -204
  372. package/skills/devops/references/containers.md +0 -272
  373. package/skills/devops/references/deploy.md +0 -201
  374. package/skills/devops/references/iac.md +0 -252
  375. package/skills/devops/references/observability.md +0 -228
  376. package/skills/devops/references/secrets.md +0 -178
  377. package/skills/devops-automator/SKILL.md +0 -164
  378. package/skills/frontend/SKILL.md +0 -52
  379. package/skills/frontend/references/accessibility.md +0 -222
  380. package/skills/frontend/references/components.md +0 -206
  381. package/skills/frontend/references/performance.md +0 -219
  382. package/skills/frontend/references/routing.md +0 -209
  383. package/skills/frontend/references/state.md +0 -190
  384. package/skills/frontend/references/testing.md +0 -216
  385. package/skills/frontend-developer/SKILL.md +0 -115
  386. package/skills/git-workflow/SKILL.md +0 -355
  387. package/skills/golang/SKILL.md +0 -49
  388. package/skills/golang/references/concurrency.md +0 -284
  389. package/skills/golang/references/errors.md +0 -241
  390. package/skills/golang/references/idioms.md +0 -285
  391. package/skills/golang/references/testing.md +0 -238
  392. package/skills/java/SKILL.md +0 -50
  393. package/skills/java/references/concurrency.md +0 -194
  394. package/skills/java/references/idioms.md +0 -283
  395. package/skills/java/references/testing.md +0 -228
  396. package/skills/kotlin/SKILL.md +0 -47
  397. package/skills/kotlin/references/coroutines.md +0 -240
  398. package/skills/kotlin/references/idioms.md +0 -268
  399. package/skills/kotlin/references/testing.md +0 -219
  400. package/skills/mobile/SKILL.md +0 -50
  401. package/skills/mobile/references/architecture.md +0 -204
  402. package/skills/mobile/references/navigation.md +0 -158
  403. package/skills/mobile/references/performance.md +0 -152
  404. package/skills/mobile/references/platform.md +0 -166
  405. package/skills/mobile/references/state-and-data.md +0 -174
  406. package/skills/python/SKILL.md +0 -51
  407. package/skills/python/THIRD_PARTY.md +0 -14
  408. package/skills/python/references/async.md +0 -218
  409. package/skills/python/references/error-handling.md +0 -254
  410. package/skills/python/references/idioms.md +0 -279
  411. package/skills/python/references/packaging.md +0 -233
  412. package/skills/python/references/testing.md +0 -269
  413. package/skills/python/references/typing.md +0 -292
  414. package/skills/qa-tester/SKILL.md +0 -186
  415. package/skills/rust/SKILL.md +0 -50
  416. package/skills/rust/references/async.md +0 -224
  417. package/skills/rust/references/errors.md +0 -240
  418. package/skills/rust/references/ownership.md +0 -263
  419. package/skills/rust/references/testing.md +0 -274
  420. package/skills/rust/references/traits.md +0 -250
  421. package/skills/security-engineer/SKILL.md +0 -157
  422. package/skills/sps-memory/SKILL.md +0 -213
  423. package/skills/sps-pipeline/SKILL.md +0 -476
  424. package/skills/swift/SKILL.md +0 -48
  425. package/skills/swift/references/concurrency.md +0 -280
  426. package/skills/swift/references/idioms.md +0 -334
  427. package/skills/swift/references/testing.md +0 -229
  428. package/skills/tax-worker/SKILL.md +0 -150
  429. package/skills/tax-worker/references/account-codes.md +0 -165
  430. package/skills/typescript/SKILL.md +0 -51
  431. package/skills/typescript/references/async.md +0 -241
  432. package/skills/typescript/references/errors.md +0 -208
  433. package/skills/typescript/references/idioms.md +0 -246
  434. package/skills/typescript/references/testing.md +0 -225
  435. package/skills/typescript/references/tooling.md +0 -208
  436. package/skills/typescript/references/types.md +0 -259
  437. package/skills/wiki-update/SKILL.md +0 -300
@@ -1,241 +0,0 @@
1
- # TypeScript — Async
2
-
3
- Promises, async/await, error propagation, cancellation, concurrency.
4
-
5
- ## `async/await` is sugar for promises
6
-
7
- ```ts
8
- // These are equivalent
9
- async function f() { const x = await g(); return x + 1; }
10
- function f() { return g().then(x => x + 1); }
11
- ```
12
-
13
- Prefer `async/await` for linear flows, `.then` chains for pipelines on a single value.
14
-
15
- ## Every promise must be awaited or handled
16
-
17
- Unhandled rejections crash Node (in strict mode) or log cryptic warnings.
18
-
19
- ```ts
20
- // ❌ fire-and-forget
21
- sendEmail(user.email); // if it rejects → unhandled
22
- doThing().then(logSuccess); // no .catch
23
-
24
- // ✅
25
- await sendEmail(user.email);
26
-
27
- // ✅ intentional fire-and-forget: use .catch
28
- void sendEmail(user.email).catch(err => log.error(err));
29
- ```
30
-
31
- TS/ESLint rules: `@typescript-eslint/no-floating-promises` catches these.
32
-
33
- ## Error propagation
34
-
35
- Throws inside `async` become rejections. `try/catch` catches them.
36
-
37
- ```ts
38
- async function load() {
39
- try {
40
- const r = await fetch(url);
41
- if (!r.ok) throw new HttpError(r.status);
42
- return await r.json();
43
- } catch (e) {
44
- if (e instanceof HttpError && e.status === 404) return null;
45
- throw e;
46
- }
47
- }
48
- ```
49
-
50
- `catch (e: unknown)` — always. `e` is not an `Error` in JS; could be anything thrown.
51
-
52
- ```ts
53
- try { ... } catch (e) {
54
- if (e instanceof Error) log.error(e.message);
55
- else log.error('non-Error thrown', { e });
56
- }
57
- ```
58
-
59
- ## Concurrency
60
-
61
- ### Parallel, all must succeed
62
-
63
- ```ts
64
- const [u, o, p] = await Promise.all([
65
- getUser(id),
66
- getOrders(id),
67
- getPrefs(id),
68
- ]);
69
- ```
70
-
71
- One rejection → whole thing rejects; other in-flight promises continue but their results are discarded.
72
-
73
- ### Parallel, any may fail
74
-
75
- ```ts
76
- const results = await Promise.allSettled(tasks);
77
- for (const r of results) {
78
- if (r.status === 'fulfilled') use(r.value);
79
- else log.warn(r.reason);
80
- }
81
- ```
82
-
83
- ### First to finish wins
84
-
85
- ```ts
86
- const winner = await Promise.race([req, timeout(5000)]);
87
- ```
88
-
89
- ### First to succeed (any)
90
-
91
- ```ts
92
- const first = await Promise.any([primary(), secondary(), tertiary()]);
93
- // rejects only if all fail
94
- ```
95
-
96
- ## Sequential vs. parallel — don't accidentally serialize
97
-
98
- ```ts
99
- // ❌ serial (each waits for the prior)
100
- for (const id of ids) {
101
- await fetchUser(id);
102
- }
103
-
104
- // ✅ parallel
105
- await Promise.all(ids.map(fetchUser));
106
- ```
107
-
108
- Sequential is correct when order matters or when you want backpressure. Parallel is often what you wanted but wrote wrong.
109
-
110
- ## Bounded parallelism
111
-
112
- Unlimited parallelism blows up memory and hammers downstreams. Bound it.
113
-
114
- ```ts
115
- import pLimit from 'p-limit';
116
-
117
- const limit = pLimit(10);
118
- const results = await Promise.all(ids.map(id => limit(() => fetchUser(id))));
119
- ```
120
-
121
- Or chunk manually:
122
-
123
- ```ts
124
- async function inChunks<T, R>(xs: T[], size: number, fn: (x: T) => Promise<R>) {
125
- const out: R[] = [];
126
- for (let i = 0; i < xs.length; i += size) {
127
- const chunk = xs.slice(i, i + size);
128
- out.push(...await Promise.all(chunk.map(fn)));
129
- }
130
- return out;
131
- }
132
- ```
133
-
134
- ## Cancellation — `AbortController`
135
-
136
- The standard cancellation primitive for fetch, streams, timers.
137
-
138
- ```ts
139
- const ac = new AbortController();
140
- setTimeout(() => ac.abort(), 5000);
141
-
142
- try {
143
- const r = await fetch(url, { signal: ac.signal });
144
- return await r.json();
145
- } catch (e) {
146
- if (e instanceof DOMException && e.name === 'AbortError') {
147
- // cancelled
148
- } else {
149
- throw e;
150
- }
151
- }
152
- ```
153
-
154
- For your own async functions, accept a `signal` and check / propagate it:
155
-
156
- ```ts
157
- async function work({ signal }: { signal?: AbortSignal }) {
158
- if (signal?.aborted) throw new DOMException('aborted', 'AbortError');
159
- signal?.addEventListener('abort', () => { /* clean up */ }, { once: true });
160
- ...
161
- }
162
- ```
163
-
164
- ## Timeouts — `AbortSignal.timeout` (modern)
165
-
166
- ```ts
167
- const r = await fetch(url, { signal: AbortSignal.timeout(5000) });
168
- ```
169
-
170
- Falls back to `AbortController` + `setTimeout` on older runtimes.
171
-
172
- ## Retry with backoff
173
-
174
- ```ts
175
- async function withRetry<T>(
176
- fn: () => Promise<T>,
177
- { attempts = 3, baseMs = 100, maxMs = 10_000 } = {},
178
- ): Promise<T> {
179
- for (let i = 0; i < attempts; i++) {
180
- try { return await fn(); }
181
- catch (e) {
182
- if (i === attempts - 1) throw e;
183
- const delay = Math.min(maxMs, baseMs * 2 ** i) * (0.5 + Math.random());
184
- await new Promise(r => setTimeout(r, delay));
185
- }
186
- }
187
- throw new Error('unreachable');
188
- }
189
- ```
190
-
191
- Only retry idempotent operations. See `backend/references/resilience.md`.
192
-
193
- ## Async iterators & streams
194
-
195
- For data you consume one chunk at a time.
196
-
197
- ```ts
198
- async function* readLines(stream: ReadableStream<Uint8Array>) {
199
- const decoder = new TextDecoder();
200
- const reader = stream.getReader();
201
- let buf = '';
202
- while (true) {
203
- const { value, done } = await reader.read();
204
- if (done) break;
205
- buf += decoder.decode(value, { stream: true });
206
- const lines = buf.split('\n');
207
- buf = lines.pop()!;
208
- for (const line of lines) yield line;
209
- }
210
- if (buf) yield buf;
211
- }
212
-
213
- for await (const line of readLines(resp.body!)) {
214
- process(line);
215
- }
216
- ```
217
-
218
- ## Microtasks & the event loop
219
-
220
- `await` queues continuation as a microtask — runs before macro-tasks (`setTimeout`) even at delay 0.
221
-
222
- ```ts
223
- Promise.resolve().then(() => console.log('A')); // microtask
224
- setTimeout(() => console.log('B'), 0); // macrotask
225
- // A then B
226
- ```
227
-
228
- You rarely need to know this, until you're debugging an out-of-order log.
229
-
230
- ## Anti-patterns
231
-
232
- | Anti-pattern | Fix |
233
- |---|---|
234
- | `new Promise((res) => { ... res(x) })` wrapping a callback API | Use `util.promisify` (Node) or a library wrapper |
235
- | Rejecting with a string | Always `new Error(...)` |
236
- | Nested `.then` chains | Flatten with `await` |
237
- | `.catch` without re-throw on unknown errors | Narrow or rethrow |
238
- | `await` inside a `.forEach` | Use `for...of` or `Promise.all` |
239
- | `async` function returning `Promise<Promise<T>>` | Unnecessary; one `async` is enough |
240
- | Dangling `setTimeout`/`setInterval` in React effects | Return cleanup or use a library |
241
- | Fire-and-forget without `.catch` | Silent failures; add `.catch(log)` |
@@ -1,208 +0,0 @@
1
- # TypeScript — Errors
2
-
3
- Error classes, `Result` types, catch semantics. For general strategy (when to raise vs return, where to log), see `coding-standards/references/error-strategy.md`.
4
-
5
- ## Custom error classes
6
-
7
- Subclass `Error`. Always set `name`. Use `cause` to chain.
8
-
9
- ```ts
10
- export class AppError extends Error {
11
- constructor(message: string, options?: { cause?: unknown }) {
12
- super(message, options);
13
- this.name = 'AppError';
14
- }
15
- }
16
-
17
- export class NotFoundError extends AppError {
18
- constructor(resource: string) {
19
- super(`${resource} not found`);
20
- this.name = 'NotFoundError';
21
- }
22
- }
23
-
24
- export class ValidationError extends AppError {
25
- constructor(public issues: { path: string; message: string }[]) {
26
- super('validation failed');
27
- this.name = 'ValidationError';
28
- }
29
- }
30
- ```
31
-
32
- Why `name`: stack traces use it, and `instanceof` can be unreliable across realms / duplicated module loads — the name string survives.
33
-
34
- ## Chain with `cause`
35
-
36
- Preserve the original error (available in every modern runtime).
37
-
38
- ```ts
39
- try {
40
- await db.query(...);
41
- } catch (e) {
42
- throw new AppError('failed to load user', { cause: e });
43
- }
44
- ```
45
-
46
- Stack and `.cause` are both available for debugging / logging.
47
-
48
- ## Catch `unknown`
49
-
50
- `catch (e)` in modern TS types `e` as `unknown`. Narrow before use.
51
-
52
- ```ts
53
- try { ... } catch (e) {
54
- if (e instanceof NotFoundError) return null;
55
- if (e instanceof ValidationError) return { errors: e.issues };
56
- throw e; // propagate the rest
57
- }
58
- ```
59
-
60
- Never assume `e instanceof Error` without checking. Anything can be thrown — strings, numbers, `{}`, `null`.
61
-
62
- ## `Result` types — optional, not always
63
-
64
- For operations where a failure is **expected**, a `Result` type makes the possibility visible in the signature and skips `try/catch`.
65
-
66
- ```ts
67
- type Result<T, E> =
68
- | { ok: true; value: T }
69
- | { ok: false; error: E };
70
-
71
- async function findUser(id: string): Promise<Result<User, 'not_found' | 'db_down'>> {
72
- try {
73
- const u = await db.users.find(id);
74
- if (!u) return { ok: false, error: 'not_found' };
75
- return { ok: true, value: u };
76
- } catch (e) {
77
- return { ok: false, error: 'db_down' };
78
- }
79
- }
80
-
81
- const r = await findUser(id);
82
- if (!r.ok) return handle(r.error);
83
- use(r.value);
84
- ```
85
-
86
- Libraries (`neverthrow`, `true-myth`) give you chainable `Result`s with more ergonomics.
87
-
88
- **When NOT to use**: if every caller re-throws the error anyway, `Result` just adds noise. Use it when the choice is local and important.
89
-
90
- ## Mapping errors at the edge
91
-
92
- Internal: throw freely. Edge (HTTP handler, CLI main, queue consumer): translate into response.
93
-
94
- ```ts
95
- // The one translation layer
96
- export function toHttpResponse(e: unknown): Response {
97
- if (e instanceof ValidationError)
98
- return json({ errors: e.issues }, { status: 422 });
99
- if (e instanceof NotFoundError)
100
- return json({ error: e.message }, { status: 404 });
101
- if (e instanceof AuthError)
102
- return json({ error: 'unauthorized' }, { status: 401 });
103
-
104
- log.error('unexpected', { err: e });
105
- return json({ error: 'internal error' }, { status: 500 });
106
- }
107
- ```
108
-
109
- One place for the mapping. Handlers just throw.
110
-
111
- ## Never silently swallow
112
-
113
- ```ts
114
- // ❌ swallow
115
- try { doThing(); } catch { /* oops, silently ignored */ }
116
-
117
- // ✅ log and continue if that's really what you want
118
- try { doThing(); }
119
- catch (e) { log.warn('doThing failed', { err: e }); }
120
-
121
- // ✅ best: the caller decides
122
- ```
123
-
124
- ## `finally` for cleanup
125
-
126
- ```ts
127
- const conn = await pool.acquire();
128
- try {
129
- await work(conn);
130
- } finally {
131
- conn.release();
132
- }
133
- ```
134
-
135
- Don't put business logic in `finally` — it runs even on error.
136
-
137
- ## Assertion helpers
138
-
139
- Cheap way to narrow + fail fast.
140
-
141
- ```ts
142
- export function invariant(c: unknown, msg: string): asserts c {
143
- if (!c) throw new AppError(`invariant failed: ${msg}`);
144
- }
145
-
146
- invariant(user.active, 'user must be active by this point');
147
- user.email; // narrowed; no null check needed
148
- ```
149
-
150
- Keep messages short and specific. `"user must be active"` beats `"check failed"`.
151
-
152
- ## Error handling across async boundaries
153
-
154
- An error in an async function becomes a rejected promise. Don't mix sync `throw` with async rejection in a way callers can't predict.
155
-
156
- ```ts
157
- // ❌ sometimes throws synchronously, sometimes rejects
158
- async function bad(x: unknown) {
159
- if (!x) throw new Error('bad'); // rejection (we're in async)
160
- return await f(x); // rejection
161
- }
162
-
163
- function worse(x: unknown) {
164
- if (!x) throw new Error('bad'); // sync throw
165
- return f(x); // returns a rejected promise
166
- }
167
-
168
- // ✅ consistently one or the other
169
- async function good(x: unknown) {
170
- if (!x) throw new Error('bad');
171
- return await f(x);
172
- }
173
- // callers can always `await good(x)` and catch both cases with try/catch
174
- ```
175
-
176
- ## Validation at boundaries
177
-
178
- Validate at parse time, never deep inside.
179
-
180
- ```ts
181
- import { z } from 'zod';
182
-
183
- const Body = z.object({ email: z.string().email(), age: z.number().int().min(0) });
184
-
185
- export async function POST(req: Request) {
186
- let input;
187
- try {
188
- input = Body.parse(await req.json());
189
- } catch (e) {
190
- return json({ errors: (e as z.ZodError).issues }, { status: 422 });
191
- }
192
- // inside the function, `input` is strongly typed and trusted
193
- await service.signup(input);
194
- return json({ ok: true });
195
- }
196
- ```
197
-
198
- ## Anti-patterns
199
-
200
- | Anti-pattern | Fix |
201
- |---|---|
202
- | `throw 'bad'` (string) | Always `throw new Error(...)` — strings lose stack |
203
- | `catch (e: any)` | Use `catch (e)` (unknown) + narrow |
204
- | `catch { return null }` | Log + handle specifically, or rethrow |
205
- | Checking error with `.message.includes('...')` | Use instanceof + a typed error class |
206
- | `Promise.reject('...')` with a string | Reject with an `Error` |
207
- | Over-broad error class hierarchy with 40 subtypes | Usually 5–8 is enough |
208
- | Error messages leaking PII / secrets | Redact before logging; never in client response |
@@ -1,246 +0,0 @@
1
- # TypeScript — Idioms
2
-
3
- Destructuring, optional chaining, nullish coalescing, modules.
4
-
5
- ## `const` / `let` / `var`
6
-
7
- `const` by default. `let` only when reassigning. Never `var` — it has function scope and hoisting surprises.
8
-
9
- ```ts
10
- const MAX = 10;
11
- let count = 0;
12
- for (const x of xs) count += x;
13
- ```
14
-
15
- ## Destructuring
16
-
17
- ```ts
18
- // Object
19
- const { id, email, name = 'unknown' } = user;
20
-
21
- // Array
22
- const [first, second, ...rest] = xs;
23
-
24
- // Rename + default
25
- const { id: userId, role = 'user' } = req;
26
-
27
- // Nested
28
- const { user: { id, email } } = response;
29
- ```
30
-
31
- Avoid deep destructuring across many levels — it becomes hard to read. Two levels max.
32
-
33
- ## Optional chaining (`?.`) and nullish coalescing (`??`)
34
-
35
- ```ts
36
- const city = user?.address?.city; // undefined if any part is null/undef
37
- const port = config.port ?? 3000; // only falls back on null/undef
38
- const items = maybeResponse?.items ?? [];
39
- ```
40
-
41
- Don't confuse `??` with `||`:
42
-
43
- ```ts
44
- const port = config.port || 3000; // also falls back on 0, '', false
45
- const port = config.port ?? 3000; // only on null/undef
46
- ```
47
-
48
- Use `||` when any falsy value should fall back; `??` when only "nothing" should.
49
-
50
- ## Spread & rest
51
-
52
- ```ts
53
- // Spread — copy + override
54
- const updated = { ...user, email: newEmail };
55
- const concat = [...xs, ...ys];
56
-
57
- // Rest in params
58
- function log(first: string, ...rest: unknown[]) { ... }
59
-
60
- // Rest in destructuring
61
- const { password, ...publicUser } = user;
62
- ```
63
-
64
- Rest destructuring is a cheap way to drop a field (`publicUser` above).
65
-
66
- ## Arrow vs. `function`
67
-
68
- - Arrow for callbacks, one-liners, closures that need lexical `this`.
69
- - `function` for top-level named functions that might be hoisted or recursive.
70
-
71
- ```ts
72
- const double = (x: number) => x * 2;
73
-
74
- function fibonacci(n: number): number {
75
- return n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
76
- }
77
- ```
78
-
79
- ## Immutable updates
80
-
81
- ```ts
82
- // ❌ mutation
83
- user.email = newEmail;
84
- xs.push(item);
85
-
86
- // ✅ new value
87
- const updated = { ...user, email: newEmail };
88
- const next = [...xs, item];
89
- ```
90
-
91
- Mutation is cheap but makes change hard to trace. In frontends (React, Vue) and any concurrent code, immutable updates are usually required, not optional.
92
-
93
- Use `structuredClone(x)` (global, Node 17+, browsers) for deep clones. Avoid `JSON.parse(JSON.stringify(x))` — loses dates, maps, undefined.
94
-
95
- ## Modules — ESM, named exports
96
-
97
- Use ESM (`import` / `export`) everywhere. No `require` in new code (TS emits `require` if the target is CommonJS; that's a toolchain choice, not a source style).
98
-
99
- ```ts
100
- // ✅ named exports — grep-friendly, IDEs auto-import
101
- export function parse(raw: string): Config { ... }
102
- export const DEFAULT_TIMEOUT = 5000;
103
-
104
- // ❌ default export + anonymous
105
- export default function (raw: string): Config { ... }
106
- ```
107
-
108
- Default exports make renames invisible (`import Foo from './x'`) and break auto-import. Use named exports and let the import name match the export name.
109
-
110
- Allow `default` only when the language / framework demands it (React lazy routes, JSX component files by convention — team choice).
111
-
112
- ## `for...of` over `.forEach`
113
-
114
- ```ts
115
- // ✅ — supports `await`, `break`, `continue`, `return`
116
- for (const x of xs) {
117
- await process(x);
118
- if (done) break;
119
- }
120
-
121
- // ⚠️ .forEach ignores `return` and can't be awaited
122
- xs.forEach(async x => await process(x)); // fires in parallel; next line doesn't wait
123
- ```
124
-
125
- `forEach` is fine for pure synchronous side effects on small arrays. For anything else, `for...of`.
126
-
127
- ## Map / Set over object / array when keys aren't known strings
128
-
129
- ```ts
130
- // ❌ object-as-map
131
- const counts: Record<string, number> = {};
132
- counts[key] = (counts[key] ?? 0) + 1;
133
- // keys stringified; `constructor`, `__proto__` are footguns
134
-
135
- // ✅ Map
136
- const counts = new Map<string, number>();
137
- counts.set(key, (counts.get(key) ?? 0) + 1);
138
- ```
139
-
140
- Use `Map` when keys are dynamic, need iteration in insertion order, or aren't strings. Use `Set` for unique values.
141
-
142
- ## JSON at boundaries
143
-
144
- Parse with a schema; never trust `JSON.parse(raw) as Config`.
145
-
146
- ```ts
147
- // ❌
148
- const config: Config = JSON.parse(raw); // wrong at runtime; TS can't stop it
149
-
150
- // ✅
151
- const config = ConfigSchema.parse(JSON.parse(raw)); // zod throws on bad data
152
- ```
153
-
154
- ## String templates
155
-
156
- Backticks for interpolation and multi-line.
157
-
158
- ```ts
159
- const msg = `Hello ${name}, you have ${count} messages`;
160
-
161
- const html = `
162
- <div>
163
- ${items.map(i => `<li>${i.name}</li>`).join('')}
164
- </div>
165
- `;
166
- ```
167
-
168
- For anything user-controlled rendered into HTML/SQL/shell, you need escaping, not templates. Templates are for formatting, not safety.
169
-
170
- ## Narrowing with `in`
171
-
172
- ```ts
173
- function area(s: Circle | Square) {
174
- if ('radius' in s) return Math.PI * s.radius ** 2;
175
- return s.side ** 2;
176
- }
177
- ```
178
-
179
- `in` narrows to the variant that has the property. Works well with discriminated unions too, but `.kind` / `.type` discriminators are clearer.
180
-
181
- ## Short-circuit guards
182
-
183
- Prefer guards at the top to deep nesting.
184
-
185
- ```ts
186
- function process(user: User | null) {
187
- if (!user) return null;
188
- if (!user.active) return null;
189
- return doWork(user);
190
- }
191
- ```
192
-
193
- ## Assertion functions
194
-
195
- Marks a path as unreachable without narrowing.
196
-
197
- ```ts
198
- function assert(c: unknown, msg: string): asserts c {
199
- if (!c) throw new Error(msg);
200
- }
201
-
202
- const x: string | null = maybe();
203
- assert(x !== null, 'x must be set by now');
204
- x.toLowerCase(); // narrowed to string
205
- ```
206
-
207
- ## `bigint`, `Date`, and friends
208
-
209
- - `Date` has sharp edges (month 0-indexed, mutation). Prefer a lib (`date-fns`, `luxon`, native `Temporal` when widely available).
210
- - `bigint` for integers > 2^53. Mixing `bigint` and `number` is a type error — good.
211
- - `Symbol` — useful for unique keys and well-known protocols. Rarely needed in application code.
212
-
213
- ## `void` vs `undefined` in return types
214
-
215
- - `void` for "I don't care what you return" (callbacks whose return is ignored).
216
- - `undefined` when the function explicitly returns nothing.
217
-
218
- ```ts
219
- function subscribe(cb: () => void) { ... }
220
- // subscriber may return something; we ignore it.
221
-
222
- function log(msg: string): undefined {
223
- console.log(msg);
224
- return;
225
- }
226
- ```
227
-
228
- Trivia, but CR-worthy in library code.
229
-
230
- ## `this` — lexical or bound, never `function` inside callbacks
231
-
232
- ```ts
233
- // ❌ `this` is whatever called the callback
234
- btn.addEventListener('click', function() { this.count++ });
235
-
236
- // ✅ lexical `this` via arrow
237
- btn.addEventListener('click', () => { this.count++ });
238
- ```
239
-
240
- In classes, use `.bind(this)` at construction time, or use arrow-method field syntax:
241
-
242
- ```ts
243
- class X {
244
- handle = () => { /* `this` is X, always */ };
245
- }
246
- ```