@robbiesrobotics/alice-agents 1.5.11 → 1.5.13

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 (628) hide show
  1. package/README.md +15 -24
  2. package/bin/alice-install.mjs +5 -22
  3. package/lib/agent-registry.mjs +50 -9
  4. package/lib/alice-runtime-adapter.mjs +50 -0
  5. package/lib/doctor.mjs +1 -32
  6. package/lib/hermes-installer.mjs +33 -51
  7. package/lib/installer.mjs +134 -257
  8. package/lib/manifest.mjs +14 -9
  9. package/lib/prompter.mjs +2 -34
  10. package/lib/workspace-scaffolder.mjs +193 -17
  11. package/package.json +14 -9
  12. package/templates/agents-pro.json +147 -36
  13. package/templates/agents-starter.json +207 -7
  14. package/templates/workspaces/_shared/AGENTS-orchestrator.md +19 -9
  15. package/templates/workspaces/_shared/AGENTS.md +9 -0
  16. package/templates/workspaces/_shared/HEARTBEAT.md +18 -0
  17. package/templates/workspaces/_shared/PLAYBOOK.md +6 -6
  18. package/templates/workspaces/_shared/SOUL-coding.md +20 -0
  19. package/templates/workspaces/_shared/SOUL-hermes.md +20 -0
  20. package/templates/workspaces/_shared/SOUL-orchestrator.md +20 -0
  21. package/templates/workspaces/_shared/SOUL.md +20 -0
  22. package/templates/workspaces/athena/AGENTS.md +172 -0
  23. package/templates/workspaces/athena/SOUL.md +59 -0
  24. package/templates/workspaces/athena/TOOLS.md +63 -0
  25. package/templates/workspaces/devon/AGENTS.md +50 -34
  26. package/templates/workspaces/devon/TOOLS.md +20 -37
  27. package/templates/workspaces/dylan/AGENTS.md +44 -34
  28. package/templates/workspaces/dylan/TOOLS.md +11 -35
  29. package/templates/workspaces/felix/AGENTS.md +50 -34
  30. package/templates/workspaces/felix/TOOLS.md +20 -45
  31. package/templates/workspaces/morgan/AGENTS.md +48 -39
  32. package/templates/workspaces/morgan/TOOLS.md +26 -9
  33. package/templates/workspaces/priya/AGENTS.md +68 -0
  34. package/templates/workspaces/priya/TOOLS.md +32 -0
  35. package/templates/workspaces/quinn/AGENTS.md +50 -34
  36. package/templates/workspaces/quinn/TOOLS.md +30 -48
  37. package/templates/workspaces/sasha/AGENTS.md +68 -0
  38. package/templates/workspaces/sasha/TOOLS.md +32 -0
  39. package/bin/alice-cloud.cjs +0 -385
  40. package/lib/mission-control.mjs +0 -242
  41. package/snapshots/.gitkeep +0 -0
  42. package/templates/mission-control-bridge/index.ts +0 -695
  43. package/templates/mission-control-bridge/openclaw.plugin.json +0 -8
  44. package/templates/mission-control-bridge/package.json +0 -11
  45. package/templates/skills/.gitkeep +0 -0
  46. package/templates/skills/acculynx/SKILL.md +0 -183
  47. package/templates/skills/acculynx/references/analysis_template.py +0 -116
  48. package/templates/skills/acculynx/references/dashboard_page.tsx +0 -641
  49. package/templates/skills/claude-code/.gitkeep +0 -0
  50. package/templates/skills/claude-code/SKILL.md +0 -111
  51. package/templates/skills/coding-agent/SKILL.md +0 -68
  52. package/templates/skills/crawl4ai/SKILL.md +0 -119
  53. package/templates/skills/crawl4ai/scripts/crwl +0 -3
  54. package/templates/workspaces/.gitkeep +0 -0
  55. package/templates/workspaces/_shared/.gitkeep +0 -0
  56. package/templates/workspaces/accuscope/AGENTS.md +0 -38
  57. package/templates/workspaces/accuscope/FEEDBACK.md +0 -27
  58. package/templates/workspaces/accuscope/HEARTBEAT.md +0 -26
  59. package/templates/workspaces/accuscope/IDENTITY.md +0 -48
  60. package/templates/workspaces/accuscope/LEARNINGS.md +0 -46
  61. package/templates/workspaces/accuscope/MEMORY.md +0 -47
  62. package/templates/workspaces/accuscope/PLAYBOOK.md +0 -65
  63. package/templates/workspaces/accuscope/SOUL.md +0 -40
  64. package/templates/workspaces/accuscope/TOOLS.md +0 -63
  65. package/templates/workspaces/accuscope/USER.md +0 -39
  66. package/templates/workspaces/aiden/AGENTS.md +0 -52
  67. package/templates/workspaces/aiden/FEEDBACK.md +0 -12
  68. package/templates/workspaces/aiden/HEARTBEAT.md +0 -9
  69. package/templates/workspaces/aiden/IDENTITY.md +0 -6
  70. package/templates/workspaces/aiden/LEARNINGS.md +0 -6
  71. package/templates/workspaces/aiden/MEMORY.md +0 -22
  72. package/templates/workspaces/aiden/PLAYBOOK.md +0 -16
  73. package/templates/workspaces/aiden/SOUL.md +0 -39
  74. package/templates/workspaces/aiden/TOOLS.md +0 -57
  75. package/templates/workspaces/aiden/USER.md +0 -17
  76. package/templates/workspaces/alex/AGENTS.md +0 -52
  77. package/templates/workspaces/alex/FEEDBACK.md +0 -11
  78. package/templates/workspaces/alex/HEARTBEAT.md +0 -9
  79. package/templates/workspaces/alex/IDENTITY.md +0 -6
  80. package/templates/workspaces/alex/LEARNINGS.md +0 -5
  81. package/templates/workspaces/alex/MEMORY.md +0 -22
  82. package/templates/workspaces/alex/PLAYBOOK.md +0 -16
  83. package/templates/workspaces/alex/SOUL.md +0 -40
  84. package/templates/workspaces/alex/TOOLS.md +0 -56
  85. package/templates/workspaces/alex/USER.md +0 -13
  86. package/templates/workspaces/aria/AGENTS.md +0 -18
  87. package/templates/workspaces/aria/FEEDBACK.md +0 -12
  88. package/templates/workspaces/aria/HEARTBEAT.md +0 -32
  89. package/templates/workspaces/aria/IDENTITY.md +0 -12
  90. package/templates/workspaces/aria/LEARNINGS.md +0 -31
  91. package/templates/workspaces/aria/MEMORY.md +0 -29
  92. package/templates/workspaces/aria/PLAYBOOK.md +0 -71
  93. package/templates/workspaces/aria/SOUL.md +0 -57
  94. package/templates/workspaces/aria/TOOLS.md +0 -47
  95. package/templates/workspaces/aria/USER.md +0 -18
  96. package/templates/workspaces/audrey/AGENTS.md +0 -59
  97. package/templates/workspaces/audrey/FEEDBACK.md +0 -11
  98. package/templates/workspaces/audrey/HEARTBEAT.md +0 -9
  99. package/templates/workspaces/audrey/IDENTITY.md +0 -6
  100. package/templates/workspaces/audrey/LEARNINGS.md +0 -5
  101. package/templates/workspaces/audrey/MEMORY.md +0 -22
  102. package/templates/workspaces/audrey/PLAYBOOK.md +0 -16
  103. package/templates/workspaces/audrey/SOUL.md +0 -39
  104. package/templates/workspaces/audrey/TOOLS.md +0 -15
  105. package/templates/workspaces/audrey/USER.md +0 -13
  106. package/templates/workspaces/avery/AGENTS.md +0 -52
  107. package/templates/workspaces/avery/FEEDBACK.md +0 -12
  108. package/templates/workspaces/avery/HEARTBEAT.md +0 -5
  109. package/templates/workspaces/avery/IDENTITY.md +0 -6
  110. package/templates/workspaces/avery/LEARNINGS.md +0 -6
  111. package/templates/workspaces/avery/MEMORY.md +0 -22
  112. package/templates/workspaces/avery/PLAYBOOK.md +0 -16
  113. package/templates/workspaces/avery/SOUL.md +0 -40
  114. package/templates/workspaces/avery/TOOLS.md +0 -47
  115. package/templates/workspaces/avery/USER.md +0 -17
  116. package/templates/workspaces/avery/skills/claude-code/SKILL.md +0 -38
  117. package/templates/workspaces/avery/skills/claude-code/claude_code +0 -55
  118. package/templates/workspaces/caleb/AGENTS.md +0 -52
  119. package/templates/workspaces/caleb/FEEDBACK.md +0 -11
  120. package/templates/workspaces/caleb/HEARTBEAT.md +0 -9
  121. package/templates/workspaces/caleb/IDENTITY.md +0 -6
  122. package/templates/workspaces/caleb/LEARNINGS.md +0 -5
  123. package/templates/workspaces/caleb/MEMORY.md +0 -22
  124. package/templates/workspaces/caleb/PLAYBOOK.md +0 -16
  125. package/templates/workspaces/caleb/SOUL.md +0 -39
  126. package/templates/workspaces/caleb/TOOLS.md +0 -30
  127. package/templates/workspaces/caleb/USER.md +0 -13
  128. package/templates/workspaces/clara/AGENTS.md +0 -59
  129. package/templates/workspaces/clara/FEEDBACK.md +0 -12
  130. package/templates/workspaces/clara/HEARTBEAT.md +0 -5
  131. package/templates/workspaces/clara/IDENTITY.md +0 -6
  132. package/templates/workspaces/clara/LEARNINGS.md +0 -6
  133. package/templates/workspaces/clara/MEMORY.md +0 -22
  134. package/templates/workspaces/clara/PLAYBOOK.md +0 -16
  135. package/templates/workspaces/clara/SOUL.md +0 -39
  136. package/templates/workspaces/clara/TOOLS.md +0 -15
  137. package/templates/workspaces/clara/USER.md +0 -17
  138. package/templates/workspaces/daphne/AGENTS.md +0 -59
  139. package/templates/workspaces/daphne/FEEDBACK.md +0 -18
  140. package/templates/workspaces/daphne/HEARTBEAT.md +0 -5
  141. package/templates/workspaces/daphne/IDENTITY.md +0 -6
  142. package/templates/workspaces/daphne/LEARNINGS.md +0 -6
  143. package/templates/workspaces/daphne/MEMORY.md +0 -22
  144. package/templates/workspaces/daphne/PLAYBOOK.md +0 -48
  145. package/templates/workspaces/daphne/SOUL.md +0 -39
  146. package/templates/workspaces/daphne/TOOLS.md +0 -15
  147. package/templates/workspaces/daphne/USER.md +0 -17
  148. package/templates/workspaces/darius/AGENTS.md +0 -52
  149. package/templates/workspaces/darius/FEEDBACK.md +0 -12
  150. package/templates/workspaces/darius/HEARTBEAT.md +0 -5
  151. package/templates/workspaces/darius/IDENTITY.md +0 -6
  152. package/templates/workspaces/darius/LEARNINGS.md +0 -6
  153. package/templates/workspaces/darius/MEMORY.md +0 -22
  154. package/templates/workspaces/darius/PLAYBOOK.md +0 -16
  155. package/templates/workspaces/darius/SOUL.md +0 -40
  156. package/templates/workspaces/darius/TOOLS.md +0 -57
  157. package/templates/workspaces/darius/USER.md +0 -17
  158. package/templates/workspaces/darius/skills/claude-code/SKILL.md +0 -38
  159. package/templates/workspaces/darius/skills/claude-code/claude_code +0 -55
  160. package/templates/workspaces/devon/FEEDBACK.md +0 -11
  161. package/templates/workspaces/devon/HEARTBEAT.md +0 -5
  162. package/templates/workspaces/devon/IDENTITY.md +0 -6
  163. package/templates/workspaces/devon/LEARNINGS.md +0 -11
  164. package/templates/workspaces/devon/MEMORY.md +0 -22
  165. package/templates/workspaces/devon/PLAYBOOK.md +0 -16
  166. package/templates/workspaces/devon/SOUL.md +0 -40
  167. package/templates/workspaces/devon/USER.md +0 -13
  168. package/templates/workspaces/devon/check_github.py +0 -12
  169. package/templates/workspaces/devon/check_mc_env.py +0 -30
  170. package/templates/workspaces/devon/check_sb.py +0 -34
  171. package/templates/workspaces/devon/check_vercel.py +0 -12
  172. package/templates/workspaces/devon/get_mc_files.py +0 -17
  173. package/templates/workspaces/devon/write_heartbeat.py +0 -67
  174. package/templates/workspaces/dylan/.env.example +0 -33
  175. package/templates/workspaces/dylan/00007_verify_licenses_table.sql +0 -100
  176. package/templates/workspaces/dylan/FEEDBACK.md +0 -28
  177. package/templates/workspaces/dylan/HEARTBEAT.md +0 -5
  178. package/templates/workspaces/dylan/IDENTITY.md +0 -6
  179. package/templates/workspaces/dylan/LEARNINGS.md +0 -70
  180. package/templates/workspaces/dylan/MEMORY.md +0 -22
  181. package/templates/workspaces/dylan/PLAYBOOK.md +0 -16
  182. package/templates/workspaces/dylan/SOUL.md +0 -42
  183. package/templates/workspaces/dylan/STRIPE_PIPELINE.md +0 -185
  184. package/templates/workspaces/dylan/USER.md +0 -17
  185. package/templates/workspaces/dylan/n8n-stripe-welcome-workflow.json +0 -123
  186. package/templates/workspaces/dylan/skills/claude-code/SKILL.md +0 -38
  187. package/templates/workspaces/dylan/skills/claude-code/claude_code +0 -55
  188. package/templates/workspaces/dylan/stripe-webhook-handler.py +0 -433
  189. package/templates/workspaces/dylan/test_mock_webhook.py +0 -103
  190. package/templates/workspaces/elena/AGENTS.md +0 -59
  191. package/templates/workspaces/elena/FEEDBACK.md +0 -11
  192. package/templates/workspaces/elena/HEARTBEAT.md +0 -9
  193. package/templates/workspaces/elena/IDENTITY.md +0 -6
  194. package/templates/workspaces/elena/LEARNINGS.md +0 -5
  195. package/templates/workspaces/elena/MEMORY.md +0 -22
  196. package/templates/workspaces/elena/PLAYBOOK.md +0 -16
  197. package/templates/workspaces/elena/SOUL.md +0 -39
  198. package/templates/workspaces/elena/TOOLS.md +0 -15
  199. package/templates/workspaces/elena/USER.md +0 -13
  200. package/templates/workspaces/eva/AGENTS.md +0 -59
  201. package/templates/workspaces/eva/FEEDBACK.md +0 -11
  202. package/templates/workspaces/eva/HEARTBEAT.md +0 -9
  203. package/templates/workspaces/eva/IDENTITY.md +0 -6
  204. package/templates/workspaces/eva/LEARNINGS.md +0 -5
  205. package/templates/workspaces/eva/MEMORY.md +0 -22
  206. package/templates/workspaces/eva/PLAYBOOK.md +0 -16
  207. package/templates/workspaces/eva/SOUL.md +0 -39
  208. package/templates/workspaces/eva/TOOLS.md +0 -15
  209. package/templates/workspaces/eva/USER.md +0 -13
  210. package/templates/workspaces/felix/FEEDBACK.md +0 -11
  211. package/templates/workspaces/felix/HEARTBEAT.md +0 -5
  212. package/templates/workspaces/felix/IDENTITY.md +0 -6
  213. package/templates/workspaces/felix/LEARNINGS.md +0 -17
  214. package/templates/workspaces/felix/MEMORY.md +0 -22
  215. package/templates/workspaces/felix/PLAYBOOK.md +0 -16
  216. package/templates/workspaces/felix/SOUL.md +0 -40
  217. package/templates/workspaces/felix/USER.md +0 -13
  218. package/templates/workspaces/felix/fidelia-psychology.html +0 -1594
  219. package/templates/workspaces/felix/task.txt +0 -164
  220. package/templates/workspaces/hannah/AGENTS.md +0 -59
  221. package/templates/workspaces/hannah/FEEDBACK.md +0 -12
  222. package/templates/workspaces/hannah/HEARTBEAT.md +0 -5
  223. package/templates/workspaces/hannah/IDENTITY.md +0 -6
  224. package/templates/workspaces/hannah/LEARNINGS.md +0 -6
  225. package/templates/workspaces/hannah/MEMORY.md +0 -22
  226. package/templates/workspaces/hannah/PLAYBOOK.md +0 -16
  227. package/templates/workspaces/hannah/SOUL.md +0 -39
  228. package/templates/workspaces/hannah/TOOLS.md +0 -15
  229. package/templates/workspaces/hannah/USER.md +0 -17
  230. package/templates/workspaces/isaac/AGENTS.md +0 -52
  231. package/templates/workspaces/isaac/FEEDBACK.md +0 -12
  232. package/templates/workspaces/isaac/HEARTBEAT.md +0 -9
  233. package/templates/workspaces/isaac/IDENTITY.md +0 -6
  234. package/templates/workspaces/isaac/LEARNINGS.md +0 -6
  235. package/templates/workspaces/isaac/MEMORY.md +0 -22
  236. package/templates/workspaces/isaac/PLAYBOOK.md +0 -16
  237. package/templates/workspaces/isaac/SOUL.md +0 -40
  238. package/templates/workspaces/isaac/TOOLS.md +0 -52
  239. package/templates/workspaces/isaac/USER.md +0 -17
  240. package/templates/workspaces/isaac/skills/claude-code/SKILL.md +0 -38
  241. package/templates/workspaces/isaac/skills/claude-code/claude_code +0 -55
  242. package/templates/workspaces/logan/AGENTS.md +0 -59
  243. package/templates/workspaces/logan/FEEDBACK.md +0 -11
  244. package/templates/workspaces/logan/HEARTBEAT.md +0 -9
  245. package/templates/workspaces/logan/IDENTITY.md +0 -6
  246. package/templates/workspaces/logan/LEARNINGS.md +0 -5
  247. package/templates/workspaces/logan/MEMORY.md +0 -22
  248. package/templates/workspaces/logan/PLAYBOOK.md +0 -16
  249. package/templates/workspaces/logan/SOUL.md +0 -39
  250. package/templates/workspaces/logan/TOOLS.md +0 -15
  251. package/templates/workspaces/logan/USER.md +0 -13
  252. package/templates/workspaces/maxxipro/AGENTS.md +0 -29
  253. package/templates/workspaces/maxxipro/FEEDBACK.md +0 -19
  254. package/templates/workspaces/maxxipro/HEARTBEAT.md +0 -22
  255. package/templates/workspaces/maxxipro/IDENTITY.md +0 -35
  256. package/templates/workspaces/maxxipro/KNOWLEDGE.md +0 -335
  257. package/templates/workspaces/maxxipro/LEARNINGS.md +0 -47
  258. package/templates/workspaces/maxxipro/MEMORY.md +0 -60
  259. package/templates/workspaces/maxxipro/OUTREACH_TEMPLATES.md +0 -143
  260. package/templates/workspaces/maxxipro/PLAYBOOK.md +0 -81
  261. package/templates/workspaces/maxxipro/SOUL.md +0 -146
  262. package/templates/workspaces/maxxipro/TOOLS.md +0 -81
  263. package/templates/workspaces/maxxipro/USER.md +0 -40
  264. package/templates/workspaces/morgan/FEEDBACK.md +0 -19
  265. package/templates/workspaces/morgan/HEARTBEAT.md +0 -5
  266. package/templates/workspaces/morgan/IDENTITY.md +0 -6
  267. package/templates/workspaces/morgan/LEARNINGS.md +0 -18
  268. package/templates/workspaces/morgan/MEMORY.md +0 -22
  269. package/templates/workspaces/morgan/PLAYBOOK.md +0 -16
  270. package/templates/workspaces/morgan/SOUL.md +0 -39
  271. package/templates/workspaces/morgan/USER.md +0 -13
  272. package/templates/workspaces/nadia/AGENTS.md +0 -59
  273. package/templates/workspaces/nadia/FEEDBACK.md +0 -12
  274. package/templates/workspaces/nadia/HEARTBEAT.md +0 -5
  275. package/templates/workspaces/nadia/IDENTITY.md +0 -6
  276. package/templates/workspaces/nadia/LEARNINGS.md +0 -6
  277. package/templates/workspaces/nadia/MEMORY.md +0 -22
  278. package/templates/workspaces/nadia/PLAYBOOK.md +0 -16
  279. package/templates/workspaces/nadia/SOUL.md +0 -39
  280. package/templates/workspaces/nadia/TOOLS.md +0 -15
  281. package/templates/workspaces/nadia/USER.md +0 -13
  282. package/templates/workspaces/nate/AGENTS.md +0 -24
  283. package/templates/workspaces/nate/FEEDBACK.md +0 -12
  284. package/templates/workspaces/nate/HEARTBEAT.md +0 -33
  285. package/templates/workspaces/nate/IDENTITY.md +0 -15
  286. package/templates/workspaces/nate/LEARNINGS.md +0 -33
  287. package/templates/workspaces/nate/MEMORY.md +0 -39
  288. package/templates/workspaces/nate/PLAYBOOK.md +0 -160
  289. package/templates/workspaces/nate/SOUL.md +0 -50
  290. package/templates/workspaces/nate/TOOLS.md +0 -111
  291. package/templates/workspaces/nate/USER.md +0 -32
  292. package/templates/workspaces/olivia/.last-openclaw-version +0 -1
  293. package/templates/workspaces/olivia/.npmrc.tmp +0 -0
  294. package/templates/workspaces/olivia/AGENTS.md +0 -77
  295. package/templates/workspaces/olivia/ALPHA_CODING_BENCHMARK.txt +0 -148
  296. package/templates/workspaces/olivia/ALPHA_MODEL_GUIDE.md +0 -393
  297. package/templates/workspaces/olivia/FEEDBACK.md +0 -13
  298. package/templates/workspaces/olivia/HEADTOHEAD_BENCHMARK.txt +0 -1289
  299. package/templates/workspaces/olivia/HEARTBEAT.md +0 -267
  300. package/templates/workspaces/olivia/IDENTITY.md +0 -6
  301. package/templates/workspaces/olivia/LEARNINGS.md +0 -708
  302. package/templates/workspaces/olivia/MEMORY.md +0 -202
  303. package/templates/workspaces/olivia/MISSION_CONTROL_DESIGN_SPEC_v1.md +0 -1143
  304. package/templates/workspaces/olivia/MVP-COMPLETION-SUMMARY.md +0 -175
  305. package/templates/workspaces/olivia/NETWORK_IMPLEMENTATION_PLAN.md +0 -1556
  306. package/templates/workspaces/olivia/NEW_NODES_BENCHMARK.txt +0 -947
  307. package/templates/workspaces/olivia/PLAYBOOK.md +0 -42
  308. package/templates/workspaces/olivia/SELF-HEALING-COMPLETE.md +0 -150
  309. package/templates/workspaces/olivia/SOUL.md +0 -42
  310. package/templates/workspaces/olivia/TOOLS.md +0 -15
  311. package/templates/workspaces/olivia/USER.md +0 -17
  312. package/templates/workspaces/olivia/alicefleet-supabase-credentials.md +0 -50
  313. package/templates/workspaces/olivia/dzombo-copy-rewrite.md +0 -115
  314. package/templates/workspaces/olivia/dzombo-implementation-plan.md +0 -1248
  315. package/templates/workspaces/olivia/fidelia-psychology.html +0 -1594
  316. package/templates/workspaces/olivia/lead_debug.png +0 -0
  317. package/templates/workspaces/olivia/minimatch-10.2.4.tgz +0 -0
  318. package/templates/workspaces/olivia/operation-bllm-research.md +0 -157
  319. package/templates/workspaces/olivia/qa-audit-mission-control-v2.md +0 -538
  320. package/templates/workspaces/olivia/roofmaxx_logo.svg +0 -1
  321. package/templates/workspaces/olivia/roofmaxx_social.jpg +0 -0
  322. package/templates/workspaces/olivia/skills/1password/SKILL.md +0 -53
  323. package/templates/workspaces/olivia/skills/1password/_meta.json +0 -6
  324. package/templates/workspaces/olivia/skills/afrexai-recruiting-engine/README.md +0 -57
  325. package/templates/workspaces/olivia/skills/afrexai-recruiting-engine/SKILL.md +0 -534
  326. package/templates/workspaces/olivia/skills/afrexai-recruiting-engine/_meta.json +0 -6
  327. package/templates/workspaces/olivia/skills/agent-security/SKILL.md +0 -69
  328. package/templates/workspaces/olivia/skills/agent-security/_meta.json +0 -6
  329. package/templates/workspaces/olivia/skills/agentic-security-audit/SKILL.md +0 -855
  330. package/templates/workspaces/olivia/skills/agentic-security-audit/_meta.json +0 -6
  331. package/templates/workspaces/olivia/skills/ai-automation-consulting/SKILL.md +0 -67
  332. package/templates/workspaces/olivia/skills/ai-automation-consulting/_meta.json +0 -6
  333. package/templates/workspaces/olivia/skills/ai-automation-consulting/skill.json +0 -12
  334. package/templates/workspaces/olivia/skills/ai-presentation-maker/SKILL.md +0 -1104
  335. package/templates/workspaces/olivia/skills/ai-presentation-maker/_meta.json +0 -6
  336. package/templates/workspaces/olivia/skills/ai-productivity-audit/SKILL.md +0 -181
  337. package/templates/workspaces/olivia/skills/ai-productivity-audit/_meta.json +0 -6
  338. package/templates/workspaces/olivia/skills/ai-researcher/README.md +0 -31
  339. package/templates/workspaces/olivia/skills/ai-researcher/SKILL.md +0 -59
  340. package/templates/workspaces/olivia/skills/ai-researcher/_meta.json +0 -6
  341. package/templates/workspaces/olivia/skills/ai-seo-writer/README.md +0 -19
  342. package/templates/workspaces/olivia/skills/ai-seo-writer/SKILL.md +0 -100
  343. package/templates/workspaces/olivia/skills/ai-seo-writer/_meta.json +0 -6
  344. package/templates/workspaces/olivia/skills/analytics-tracking-2/SKILL.md +0 -309
  345. package/templates/workspaces/olivia/skills/analytics-tracking-2/_meta.json +0 -6
  346. package/templates/workspaces/olivia/skills/api-doc-writer/SKILL.md +0 -232
  347. package/templates/workspaces/olivia/skills/api-doc-writer/_meta.json +0 -6
  348. package/templates/workspaces/olivia/skills/api-generator/SKILL.md +0 -49
  349. package/templates/workspaces/olivia/skills/api-generator/_meta.json +0 -6
  350. package/templates/workspaces/olivia/skills/api-generator/tips.md +0 -10
  351. package/templates/workspaces/olivia/skills/apple-notes/SKILL.md +0 -50
  352. package/templates/workspaces/olivia/skills/apple-notes/_meta.json +0 -6
  353. package/templates/workspaces/olivia/skills/apple-reminders/SKILL.md +0 -67
  354. package/templates/workspaces/olivia/skills/apple-reminders/_meta.json +0 -6
  355. package/templates/workspaces/olivia/skills/automation-workflows/SKILL.md +0 -267
  356. package/templates/workspaces/olivia/skills/automation-workflows/_meta.json +0 -6
  357. package/templates/workspaces/olivia/skills/autoresearch/SKILL.md +0 -46
  358. package/templates/workspaces/olivia/skills/autoresearch/aria_write.py +0 -148
  359. package/templates/workspaces/olivia/skills/autoresearch/autoresearch.py +0 -75
  360. package/templates/workspaces/olivia/skills/azure-devops/SKILL.md +0 -115
  361. package/templates/workspaces/olivia/skills/azure-devops/_meta.json +0 -6
  362. package/templates/workspaces/olivia/skills/blogwatcher/SKILL.md +0 -46
  363. package/templates/workspaces/olivia/skills/blogwatcher/_meta.json +0 -6
  364. package/templates/workspaces/olivia/skills/blucli/SKILL.md +0 -27
  365. package/templates/workspaces/olivia/skills/blucli/_meta.json +0 -6
  366. package/templates/workspaces/olivia/skills/check-analytics/SKILL.md +0 -92
  367. package/templates/workspaces/olivia/skills/check-analytics/_meta.json +0 -6
  368. package/templates/workspaces/olivia/skills/cloud-architect/SKILL.md +0 -89
  369. package/templates/workspaces/olivia/skills/cloud-architect/_meta.json +0 -6
  370. package/templates/workspaces/olivia/skills/cloud-infra-automation/SKILL.md +0 -50
  371. package/templates/workspaces/olivia/skills/cloud-infra-automation/_meta.json +0 -6
  372. package/templates/workspaces/olivia/skills/cloud-storage/SKILL.md +0 -61
  373. package/templates/workspaces/olivia/skills/cloud-storage/_meta.json +0 -6
  374. package/templates/workspaces/olivia/skills/cloud-storage/auth.md +0 -97
  375. package/templates/workspaces/olivia/skills/cloud-storage/costs.md +0 -88
  376. package/templates/workspaces/olivia/skills/cloud-storage/providers.md +0 -55
  377. package/templates/workspaces/olivia/skills/copywriting-pro/SKILL.md +0 -107
  378. package/templates/workspaces/olivia/skills/copywriting-pro/_meta.json +0 -6
  379. package/templates/workspaces/olivia/skills/data-analyst-pro/SKILL.md +0 -21
  380. package/templates/workspaces/olivia/skills/data-analyst-pro/_meta.json +0 -6
  381. package/templates/workspaces/olivia/skills/database-designer/README.md +0 -388
  382. package/templates/workspaces/olivia/skills/database-designer/SKILL.md +0 -66
  383. package/templates/workspaces/olivia/skills/database-designer/_meta.json +0 -6
  384. package/templates/workspaces/olivia/skills/database-designer/index_optimizer.py +0 -926
  385. package/templates/workspaces/olivia/skills/database-designer/migration_generator.py +0 -1199
  386. package/templates/workspaces/olivia/skills/database-designer/schema_analyzer.py +0 -982
  387. package/templates/workspaces/olivia/skills/deploy-agent/SKILL.md +0 -255
  388. package/templates/workspaces/olivia/skills/deploy-agent/_meta.json +0 -6
  389. package/templates/workspaces/olivia/skills/devops-automation-pack/SKILL.md +0 -72
  390. package/templates/workspaces/olivia/skills/devops-automation-pack/_meta.json +0 -6
  391. package/templates/workspaces/olivia/skills/devops-automation-pack/deploy.sh +0 -0
  392. package/templates/workspaces/olivia/skills/financial-analysis-agent/SKILL.md +0 -489
  393. package/templates/workspaces/olivia/skills/financial-analysis-agent/_meta.json +0 -6
  394. package/templates/workspaces/olivia/skills/gdpr-compliance-tracker/README.md +0 -72
  395. package/templates/workspaces/olivia/skills/gdpr-compliance-tracker/SKILL.md +0 -226
  396. package/templates/workspaces/olivia/skills/gdpr-compliance-tracker/_meta.json +0 -6
  397. package/templates/workspaces/olivia/skills/gifgrep/SKILL.md +0 -47
  398. package/templates/workspaces/olivia/skills/gifgrep/_meta.json +0 -6
  399. package/templates/workspaces/olivia/skills/github/SKILL.md +0 -47
  400. package/templates/workspaces/olivia/skills/github/_meta.json +0 -6
  401. package/templates/workspaces/olivia/skills/gog/SKILL.md +0 -36
  402. package/templates/workspaces/olivia/skills/gog/_meta.json +0 -6
  403. package/templates/workspaces/olivia/skills/growth-strategy-hub/SKILL.md +0 -135
  404. package/templates/workspaces/olivia/skills/growth-strategy-hub/_meta.json +0 -6
  405. package/templates/workspaces/olivia/skills/growth-strategy-hub/metadata.json +0 -4
  406. package/templates/workspaces/olivia/skills/hetzner-cloud/SKILL.md +0 -130
  407. package/templates/workspaces/olivia/skills/hetzner-cloud/_meta.json +0 -6
  408. package/templates/workspaces/olivia/skills/himalaya/SKILL.md +0 -217
  409. package/templates/workspaces/olivia/skills/himalaya/_meta.json +0 -6
  410. package/templates/workspaces/olivia/skills/hotel-recommendation/SKILL.md +0 -117
  411. package/templates/workspaces/olivia/skills/hotel-recommendation/_meta.json +0 -6
  412. package/templates/workspaces/olivia/skills/hr-policy-generator/SKILL.md +0 -54
  413. package/templates/workspaces/olivia/skills/hr-policy-generator/_meta.json +0 -6
  414. package/templates/workspaces/olivia/skills/human-writing/SKILL.md +0 -41
  415. package/templates/workspaces/olivia/skills/human-writing/_meta.json +0 -6
  416. package/templates/workspaces/olivia/skills/imsg/SKILL.md +0 -25
  417. package/templates/workspaces/olivia/skills/imsg/_meta.json +0 -6
  418. package/templates/workspaces/olivia/skills/in-depth-research/SKILL.md +0 -124
  419. package/templates/workspaces/olivia/skills/in-depth-research/_meta.json +0 -6
  420. package/templates/workspaces/olivia/skills/in-depth-research/methodology.md +0 -75
  421. package/templates/workspaces/olivia/skills/in-depth-research/output-formats.md +0 -168
  422. package/templates/workspaces/olivia/skills/in-depth-research/sources.md +0 -80
  423. package/templates/workspaces/olivia/skills/javascript-skills/README.md +0 -71
  424. package/templates/workspaces/olivia/skills/javascript-skills/SKILL.md +0 -746
  425. package/templates/workspaces/olivia/skills/javascript-skills/_meta.json +0 -6
  426. package/templates/workspaces/olivia/skills/leadership-strategy-playbook/SKILL.md +0 -147
  427. package/templates/workspaces/olivia/skills/leadership-strategy-playbook/_meta.json +0 -6
  428. package/templates/workspaces/olivia/skills/market-research-agent/README.md +0 -29
  429. package/templates/workspaces/olivia/skills/market-research-agent/SKILL.md +0 -52
  430. package/templates/workspaces/olivia/skills/market-research-agent/_meta.json +0 -6
  431. package/templates/workspaces/olivia/skills/marketing-analytics/SKILL.md +0 -74
  432. package/templates/workspaces/olivia/skills/marketing-analytics/_meta.json +0 -6
  433. package/templates/workspaces/olivia/skills/marketing-master-io/SKILL.md +0 -125
  434. package/templates/workspaces/olivia/skills/marketing-master-io/_meta.json +0 -6
  435. package/templates/workspaces/olivia/skills/marketing-strategy-pmm/SKILL.md +0 -398
  436. package/templates/workspaces/olivia/skills/marketing-strategy-pmm/_meta.json +0 -6
  437. package/templates/workspaces/olivia/skills/meta-ads-analytics/SKILL.md +0 -53
  438. package/templates/workspaces/olivia/skills/meta-ads-analytics/_meta.json +0 -6
  439. package/templates/workspaces/olivia/skills/obsidian/SKILL.md +0 -55
  440. package/templates/workspaces/olivia/skills/obsidian/_meta.json +0 -6
  441. package/templates/workspaces/olivia/skills/openclaw-accounting/SKILL.md +0 -125
  442. package/templates/workspaces/olivia/skills/openclaw-accounting/_meta.json +0 -6
  443. package/templates/workspaces/olivia/skills/openclaw-security-toolkit/CHANGELOG.md +0 -35
  444. package/templates/workspaces/olivia/skills/openclaw-security-toolkit/CHANNELLOG.md +0 -73
  445. package/templates/workspaces/olivia/skills/openclaw-security-toolkit/README.md +0 -161
  446. package/templates/workspaces/olivia/skills/openclaw-security-toolkit/SKILL.md +0 -130
  447. package/templates/workspaces/olivia/skills/openclaw-security-toolkit/_meta.json +0 -6
  448. package/templates/workspaces/olivia/skills/openclaw-security-toolkit/config.json +0 -36
  449. package/templates/workspaces/olivia/skills/openclaw-security-toolkit/metadata.json +0 -19
  450. package/templates/workspaces/olivia/skills/openhue/SKILL.md +0 -30
  451. package/templates/workspaces/olivia/skills/openhue/_meta.json +0 -6
  452. package/templates/workspaces/olivia/skills/orgx-operations-agent/SKILL.md +0 -41
  453. package/templates/workspaces/olivia/skills/orgx-operations-agent/_meta.json +0 -6
  454. package/templates/workspaces/olivia/skills/outreach/SKILL.md +0 -84
  455. package/templates/workspaces/olivia/skills/outreach/_meta.json +0 -6
  456. package/templates/workspaces/olivia/skills/outreach/by-type.md +0 -166
  457. package/templates/workspaces/olivia/skills/outreach/templates.md +0 -154
  458. package/templates/workspaces/olivia/skills/outreach/tracking.md +0 -145
  459. package/templates/workspaces/olivia/skills/persona-hr-coordinator/SKILL.md +0 -38
  460. package/templates/workspaces/olivia/skills/persona-hr-coordinator/_meta.json +0 -6
  461. package/templates/workspaces/olivia/skills/personal-productivity/SKILL.md +0 -161
  462. package/templates/workspaces/olivia/skills/personal-productivity/_meta.json +0 -6
  463. package/templates/workspaces/olivia/skills/personal-productivity/index.js +0 -363
  464. package/templates/workspaces/olivia/skills/personal-productivity/package.json +0 -15
  465. package/templates/workspaces/olivia/skills/personal-travel/README.md +0 -34
  466. package/templates/workspaces/olivia/skills/personal-travel/SKILL.md +0 -46
  467. package/templates/workspaces/olivia/skills/personal-travel/_meta.json +0 -6
  468. package/templates/workspaces/olivia/skills/presentation-html-generator-skill/SKILL.md +0 -185
  469. package/templates/workspaces/olivia/skills/presentation-html-generator-skill/_meta.json +0 -6
  470. package/templates/workspaces/olivia/skills/product-manager/SKILL.md +0 -77
  471. package/templates/workspaces/olivia/skills/product-manager/_meta.json +0 -6
  472. package/templates/workspaces/olivia/skills/quant-strategy/SKILL.md +0 -28
  473. package/templates/workspaces/olivia/skills/quant-strategy/_meta.json +0 -6
  474. package/templates/workspaces/olivia/skills/sales-pipeline-tracker/README.md +0 -29
  475. package/templates/workspaces/olivia/skills/sales-pipeline-tracker/SKILL.md +0 -45
  476. package/templates/workspaces/olivia/skills/sales-pipeline-tracker/_meta.json +0 -6
  477. package/templates/workspaces/olivia/skills/security-auditor/SKILL.md +0 -399
  478. package/templates/workspaces/olivia/skills/security-auditor/_meta.json +0 -6
  479. package/templates/workspaces/olivia/skills/security-hardening/SKILL.md +0 -296
  480. package/templates/workspaces/olivia/skills/security-hardening/_meta.json +0 -6
  481. package/templates/workspaces/olivia/skills/security-scanner/SKILL.md +0 -67
  482. package/templates/workspaces/olivia/skills/security-scanner/_meta.json +0 -6
  483. package/templates/workspaces/olivia/skills/seo-optimization/SKILL.md +0 -31
  484. package/templates/workspaces/olivia/skills/seo-optimization/_meta.json +0 -6
  485. package/templates/workspaces/olivia/skills/service-booking/SKILL.md +0 -193
  486. package/templates/workspaces/olivia/skills/service-booking/_meta.json +0 -6
  487. package/templates/workspaces/olivia/skills/sme-hr-automation/SKILL.md +0 -131
  488. package/templates/workspaces/olivia/skills/sme-hr-automation/_meta.json +0 -6
  489. package/templates/workspaces/olivia/skills/social-media-scheduler/README.md +0 -29
  490. package/templates/workspaces/olivia/skills/social-media-scheduler/SKILL.md +0 -49
  491. package/templates/workspaces/olivia/skills/social-media-scheduler/_meta.json +0 -6
  492. package/templates/workspaces/olivia/skills/sonoscli/SKILL.md +0 -26
  493. package/templates/workspaces/olivia/skills/sonoscli/_meta.json +0 -6
  494. package/templates/workspaces/olivia/skills/strategy-advisor/SKILL.md +0 -33
  495. package/templates/workspaces/olivia/skills/strategy-advisor/_meta.json +0 -6
  496. package/templates/workspaces/olivia/skills/summarize/SKILL.md +0 -49
  497. package/templates/workspaces/olivia/skills/summarize/_meta.json +0 -6
  498. package/templates/workspaces/olivia/skills/things-mac/SKILL.md +0 -61
  499. package/templates/workspaces/olivia/skills/things-mac/_meta.json +0 -6
  500. package/templates/workspaces/olivia/skills/travel-itinerary-planner/SKILL.md +0 -121
  501. package/templates/workspaces/olivia/skills/travel-itinerary-planner/_meta.json +0 -6
  502. package/templates/workspaces/olivia/skills/travel-manager/SKILL.md +0 -36
  503. package/templates/workspaces/olivia/skills/travel-manager/_meta.json +0 -6
  504. package/templates/workspaces/olivia/skills/travel-planning/SKILL.md +0 -238
  505. package/templates/workspaces/olivia/skills/travel-planning/_meta.json +0 -6
  506. package/templates/workspaces/olivia/skills/travel-planning/booking-guide.md +0 -91
  507. package/templates/workspaces/olivia/skills/travel-planning/memory-template.md +0 -111
  508. package/templates/workspaces/olivia/skills/travel-planning/multi-city.md +0 -131
  509. package/templates/workspaces/olivia/skills/travel-planning/packing-templates.md +0 -155
  510. package/templates/workspaces/olivia/skills/travel-planning/setup.md +0 -66
  511. package/templates/workspaces/olivia/skills/update-it-all/SKILL.md +0 -143
  512. package/templates/workspaces/olivia/skills/update-it-all/_meta.json +0 -6
  513. package/templates/workspaces/olivia/skills/voice/SKILL.md +0 -62
  514. package/templates/workspaces/olivia/skills/weather/SKILL.md +0 -49
  515. package/templates/workspaces/olivia/skills/weather/_meta.json +0 -6
  516. package/templates/workspaces/olivia/skills/web-researcher/SKILL.md +0 -21
  517. package/templates/workspaces/olivia/skills/web-researcher/_meta.json +0 -6
  518. package/templates/workspaces/olivia/skills/website-seo/SKILL.md +0 -284
  519. package/templates/workspaces/olivia/skills/website-seo/_meta.json +0 -6
  520. package/templates/workspaces/olivia/stripe-welcome-n8n.json +0 -103
  521. package/templates/workspaces/olivia/test2.wav.wav +0 -0
  522. package/templates/workspaces/olivia/test_speech.json +0 -1
  523. package/templates/workspaces/olivia/test_speech.srt +0 -0
  524. package/templates/workspaces/olivia/test_speech.tsv +0 -1
  525. package/templates/workspaces/olivia/test_speech.txt +0 -0
  526. package/templates/workspaces/olivia/test_speech.vtt +0 -2
  527. package/templates/workspaces/owen/AGENTS.md +0 -59
  528. package/templates/workspaces/owen/FEEDBACK.md +0 -12
  529. package/templates/workspaces/owen/HEARTBEAT.md +0 -5
  530. package/templates/workspaces/owen/IDENTITY.md +0 -6
  531. package/templates/workspaces/owen/LEARNINGS.md +0 -46
  532. package/templates/workspaces/owen/MEMORY.md +0 -22
  533. package/templates/workspaces/owen/PLAYBOOK.md +0 -16
  534. package/templates/workspaces/owen/SOUL.md +0 -39
  535. package/templates/workspaces/owen/TOOLS.md +0 -15
  536. package/templates/workspaces/owen/USER.md +0 -17
  537. package/templates/workspaces/parker/AGENTS.md +0 -59
  538. package/templates/workspaces/parker/FEEDBACK.md +0 -11
  539. package/templates/workspaces/parker/HEARTBEAT.md +0 -5
  540. package/templates/workspaces/parker/IDENTITY.md +0 -6
  541. package/templates/workspaces/parker/LEARNINGS.md +0 -17
  542. package/templates/workspaces/parker/MEMORY.md +0 -22
  543. package/templates/workspaces/parker/PLAYBOOK.md +0 -16
  544. package/templates/workspaces/parker/SOUL.md +0 -39
  545. package/templates/workspaces/parker/TOOLS.md +0 -15
  546. package/templates/workspaces/parker/USER.md +0 -13
  547. package/templates/workspaces/quinn/FEEDBACK.md +0 -11
  548. package/templates/workspaces/quinn/HEARTBEAT.md +0 -5
  549. package/templates/workspaces/quinn/IDENTITY.md +0 -6
  550. package/templates/workspaces/quinn/LEARNINGS.md +0 -35
  551. package/templates/workspaces/quinn/MEMORY.md +0 -22
  552. package/templates/workspaces/quinn/PLAYBOOK.md +0 -16
  553. package/templates/workspaces/quinn/SOUL.md +0 -40
  554. package/templates/workspaces/quinn/USER.md +0 -17
  555. package/templates/workspaces/quinn/alice-login-page.png +0 -0
  556. package/templates/workspaces/rowan/AGENTS.md +0 -59
  557. package/templates/workspaces/rowan/FEEDBACK.md +0 -12
  558. package/templates/workspaces/rowan/HEARTBEAT.md +0 -5
  559. package/templates/workspaces/rowan/IDENTITY.md +0 -6
  560. package/templates/workspaces/rowan/LEARNINGS.md +0 -12
  561. package/templates/workspaces/rowan/MEMORY.md +0 -22
  562. package/templates/workspaces/rowan/PLAYBOOK.md +0 -16
  563. package/templates/workspaces/rowan/SOUL.md +0 -40
  564. package/templates/workspaces/rowan/TOOLS.md +0 -59
  565. package/templates/workspaces/rowan/USER.md +0 -17
  566. package/templates/workspaces/selena/AGENTS.md +0 -59
  567. package/templates/workspaces/selena/FEEDBACK.md +0 -12
  568. package/templates/workspaces/selena/HEARTBEAT.md +0 -5
  569. package/templates/workspaces/selena/IDENTITY.md +0 -6
  570. package/templates/workspaces/selena/LEARNINGS.md +0 -24
  571. package/templates/workspaces/selena/MEMORY.md +0 -22
  572. package/templates/workspaces/selena/PLAYBOOK.md +0 -16
  573. package/templates/workspaces/selena/SOUL.md +0 -40
  574. package/templates/workspaces/selena/TOOLS.md +0 -47
  575. package/templates/workspaces/selena/USER.md +0 -17
  576. package/templates/workspaces/selena/kids-ai-security-compliance-plan.md +0 -791
  577. package/templates/workspaces/selena/kidspark-coppa-compliance-audit.md +0 -866
  578. package/templates/workspaces/sloane/AGENTS.md +0 -59
  579. package/templates/workspaces/sloane/FEEDBACK.md +0 -12
  580. package/templates/workspaces/sloane/HEARTBEAT.md +0 -9
  581. package/templates/workspaces/sloane/IDENTITY.md +0 -6
  582. package/templates/workspaces/sloane/LEARNINGS.md +0 -6
  583. package/templates/workspaces/sloane/MEMORY.md +0 -22
  584. package/templates/workspaces/sloane/PLAYBOOK.md +0 -16
  585. package/templates/workspaces/sloane/SOUL.md +0 -39
  586. package/templates/workspaces/sloane/TOOLS.md +0 -15
  587. package/templates/workspaces/sloane/USER.md +0 -13
  588. package/templates/workspaces/smoketestagent/AGENTS.md +0 -52
  589. package/templates/workspaces/smoketestagent/FEEDBACK.md +0 -3
  590. package/templates/workspaces/smoketestagent/HEARTBEAT.md +0 -14
  591. package/templates/workspaces/smoketestagent/IDENTITY.md +0 -6
  592. package/templates/workspaces/smoketestagent/LEARNINGS.md +0 -3
  593. package/templates/workspaces/smoketestagent/MEMORY.md +0 -24
  594. package/templates/workspaces/smoketestagent/PLAYBOOK.md +0 -7
  595. package/templates/workspaces/smoketestagent/SOUL.md +0 -32
  596. package/templates/workspaces/smoketestagent/TOOLS.md +0 -13
  597. package/templates/workspaces/smoketestagent/USER.md +0 -5
  598. package/templates/workspaces/sophie/AGENTS.md +0 -59
  599. package/templates/workspaces/sophie/FEEDBACK.md +0 -12
  600. package/templates/workspaces/sophie/HEARTBEAT.md +0 -9
  601. package/templates/workspaces/sophie/IDENTITY.md +0 -6
  602. package/templates/workspaces/sophie/LEARNINGS.md +0 -6
  603. package/templates/workspaces/sophie/MEMORY.md +0 -22
  604. package/templates/workspaces/sophie/PLAYBOOK.md +0 -16
  605. package/templates/workspaces/sophie/SOUL.md +0 -39
  606. package/templates/workspaces/sophie/TOOLS.md +0 -15
  607. package/templates/workspaces/sophie/USER.md +0 -17
  608. package/templates/workspaces/tommy/AGENTS.md +0 -59
  609. package/templates/workspaces/tommy/FEEDBACK.md +0 -12
  610. package/templates/workspaces/tommy/HEARTBEAT.md +0 -9
  611. package/templates/workspaces/tommy/IDENTITY.md +0 -6
  612. package/templates/workspaces/tommy/LEARNINGS.md +0 -6
  613. package/templates/workspaces/tommy/MEMORY.md +0 -22
  614. package/templates/workspaces/tommy/PLAYBOOK.md +0 -16
  615. package/templates/workspaces/tommy/SOUL.md +0 -39
  616. package/templates/workspaces/tommy/TOOLS.md +0 -15
  617. package/templates/workspaces/tommy/USER.md +0 -17
  618. package/templates/workspaces/uma/AGENTS.md +0 -59
  619. package/templates/workspaces/uma/FEEDBACK.md +0 -11
  620. package/templates/workspaces/uma/HEARTBEAT.md +0 -5
  621. package/templates/workspaces/uma/IDENTITY.md +0 -6
  622. package/templates/workspaces/uma/LEARNINGS.md +0 -11
  623. package/templates/workspaces/uma/MEMORY.md +0 -22
  624. package/templates/workspaces/uma/PLAYBOOK.md +0 -16
  625. package/templates/workspaces/uma/SOUL.md +0 -39
  626. package/templates/workspaces/uma/TOOLS.md +0 -15
  627. package/templates/workspaces/uma/USER.md +0 -13
  628. package/tools/.gitkeep +0 -0
@@ -1,947 +0,0 @@
1
- NEW NODES CODING BENCHMARK — Mon Mar 23 06:57:19 EDT 2026
2
- Task: Thread-safe LRU Cache with per-key TTL
3
- Nodes: Mac Studio (100.115.74.106) + Mac Mini (100.107.132.71)
4
- ==========================================
5
-
6
- ==========================================
7
- MODEL: mac-studio/llama3.2:3b
8
- ==========================================
9
- LOAD: 7.8s | TOKENS: 860 | DURATION: 6.5s | SPEED: 132.9 tok/s
10
-
11
- import threading
12
- import time
13
-
14
- class Node:
15
- """Node in the doubly linked list."""
16
- def __init__(self, key, value, ttl_seconds):
17
- self.key = key
18
- self.value = value
19
- self.ttl_seconds = ttl_seconds
20
- self.prev = None
21
- self.next = None
22
-
23
- class LRUCache:
24
- """Thread-safe LRU cache with per-key TTL expiration."""
25
- def __init__(self, capacity: int):
26
- """Initialize the LRU cache with given capacity."""
27
- self.capacity = capacity
28
- self.size = 0
29
- self.map = {}
30
- self.lock = threading.Lock()
31
- self.head = Node(0, None, 0)
32
- self.tail = Node(0, None, 0)
33
- self.head.next = self.tail
34
- self.tail.prev = self.head
35
-
36
- def _remove(self, node: Node):
37
- """Remove a node from the doubly linked list."""
38
- prev_node = node.prev
39
- next_node = node.next
40
- prev_node.next = next_node
41
- next_node.prev = prev_node
42
-
43
- def _add(self, node: Node):
44
- """Add a node to the doubly linked list."""
45
- prev_node = self.tail.prev
46
- prev_node.next = node
47
- node.prev = prev_node
48
- node.next = self.tail
49
- self.tail.prev = node
50
-
51
- def _get(self, key: str) -> str:
52
- """Get the value for a given key."""
53
- with self.lock:
54
- if key not in self.map:
55
- return None
56
- node = self.map[key]
57
- if node.ttl_seconds <= time.time():
58
- self._remove(node)
59
- if self.size == self.capacity:
60
- lru_key = min(self.map, key=lambda k: self.map[k].ttl_seconds)
61
- del self.map[lru_key]
62
- self._remove(self.map[lru_key])
63
- self._remove(node)
64
- del self.map[key]
65
- self.size -= 1
66
- else:
67
- node.ttl_seconds = time.time() + node.ttl_seconds
68
- self._add(node)
69
- self.size += 1
70
- return node.value
71
-
72
- def put(self, key: str, value: str, ttl_seconds: int):
73
- """Put a value for a given key with a TTL."""
74
- with self.lock:
75
- if key in self.map:
76
- self._remove(self.map[key])
77
- del self.map[key]
78
- self.map[key] = Node(key, value, ttl_seconds)
79
- self._add(self.map[key])
80
- self.size += 1
81
- if self.size > self.capacity:
82
- lru_key = min(self.map, key=lambda k: self.map[k].ttl_seconds)
83
- del self.map[lru_key]
84
- self._remove(self.map[lru_key])
85
- self.size -= 1
86
-
87
- def delete(self, key: str):
88
- """Delete a key."""
89
- with self.lock:
90
- if key not in self.map:
91
- return
92
- self._remove(self.map[key])
93
- del self.map[key]
94
- self.size -= 1
95
-
96
- def get(self, key: str) -> str:
97
- """Get the value for a given key."""
98
- return self._get(key)
99
-
100
- def put(self, key: str, value: str, ttl_seconds: int):
101
- """Put a value for a given key with a TTL."""
102
- return self.put(key, value, ttl_seconds)
103
-
104
- def delete(self, key: str):
105
- """Delete a key."""
106
- return self.delete(key)
107
-
108
- # Usage example
109
- if __name__ == "__main__":
110
- cache = LRUCache(2)
111
-
112
- def put_and_get(cache: LRUCache, key: str, value: str, ttl_seconds: int):
113
- cache.put(key, value, ttl_seconds)
114
- time.sleep(1) # Simulate a delay
115
- print(cache.get(key))
116
-
117
- threads = []
118
- for i in range(3):
119
- thread = threading.Thread(target=put_and_get, args=(cache, f"key{i}", f"value{i}", 2))
120
- thread.start()
121
- threads.append(thread)
122
-
123
- for thread in threads:
124
- thread.join()
125
-
126
- ==========================================
127
- MODEL: mac-studio/ministral-3:14b
128
- ==========================================
129
- LOAD: 4.0s | TOKENS: 1500 | DURATION: 36.4s | SPEED: 41.2 tok/s
130
-
131
- Here's a complete, production-quality implementation of a thread-safe LRU cache with per-key TTL expiration in Python:
132
-
133
- ```python
134
- import time
135
- from threading import Lock
136
- from typing import Any, Dict, Generic, Optional, TypeVar
137
-
138
- K = TypeVar('K')
139
- V = TypeVar('V')
140
-
141
- class Node(Generic[K, V]):
142
- """Doubly linked list node for the LRU cache implementation."""
143
- def __init__(self, key: K, value: V, expiration: float):
144
- self.key = key
145
- self.value = value
146
- self.expiration = expiration
147
- self.prev: Optional['Node[K, V]'] = None
148
- self.next: Optional['Node[K, V]'] = None
149
-
150
- class LRUCacheWithTTL(Generic[K, V]):
151
- """Thread-safe LRU cache with per-key TTL expiration.
152
-
153
- This implementation uses a doubly linked list for O(1) access to most recently used items
154
- and a hashmap for O(1) lookups. Each key has its own TTL (time-to-live) expiration.
155
-
156
- Attributes:
157
- capacity: Maximum number of items the cache can hold
158
- _cache: Dictionary mapping keys to nodes
159
- _head: Most recently used node (dummy head)
160
- _tail: Least recently used node (dummy tail)
161
- _lock: Threading lock for thread safety
162
- """
163
-
164
- def __init__(self, capacity: int = 128):
165
- """Initialize the cache with a given capacity.
166
-
167
- Args:
168
- capacity: Maximum number of items the cache can hold
169
- """
170
- if capacity <= 0:
171
- raise ValueError("Capacity must be positive")
172
-
173
- self.capacity = capacity
174
- self._cache: Dict[K, Node[K, V]] = {}
175
- self._head = Node(None, None, 0) # dummy head
176
- self._tail = Node(None, None, 0) # dummy tail
177
- self._head.next = self._tail
178
- self._tail.prev = self._head
179
- self._lock = Lock()
180
-
181
- def _remove_node(self, node: Node[K, V]) -> None:
182
- """Remove a node from the linked list."""
183
- prev_node = node.prev
184
- next_node = node.next
185
- prev_node.next = next_node
186
- next_node.prev = prev_node
187
-
188
- def _add_to_head(self, node: Node[K, V]) -> None:
189
- """Add a node right after the dummy head (most recently used)."""
190
- node.next = self._head.next
191
- node.prev = self._head
192
- self._head.next.prev = node
193
- self._head.next = node
194
-
195
- def _move_to_head(self, node: Node[K, V]) -> None:
196
- """Move an existing node to the head (most recently used)."""
197
- self._remove_node(node)
198
- self._add_to_head(node)
199
-
200
- def _evict_tail(self) -> None:
201
- """Remove and return the tail node (least recently used)."""
202
- if self._tail.prev == self._head:
203
- return None
204
-
205
- tail_node = self._tail.prev
206
- self._remove_node(tail_node)
207
- del self._cache[tail_node.key]
208
- return tail_node
209
-
210
- def _is_expired(self, node: Node[K, V]) -> bool:
211
- """Check if a node has expired based on its TTL."""
212
- return time.time() > node.expiration
213
-
214
- def get(self, key: K) -> Optional[V]:
215
- """Get a value from the cache.
216
-
217
- Args:
218
- key: The key to look up
219
-
220
- Returns:
221
- The cached value if found and not expired, None otherwise
222
- """
223
- with self._lock:
224
- node = self._cache.get(key)
225
- if node is None:
226
- return None
227
-
228
- if self._is_expired(node):
229
- self._remove_node(node)
230
- del self._cache[key]
231
- return None
232
-
233
- self._move_to_head(node)
234
- return node.value
235
-
236
- def put(self, key: K, value: V, ttl_seconds: float) -> None:
237
- """Put a value into the cache with a TTL.
238
-
239
- Args:
240
- key: The key to store
241
- value: The value to cache
242
- ttl_seconds: Time-to-live in seconds
243
- """
244
- with self._lock:
245
- # Check if key exists and is not expired
246
- node = self._cache.get(key)
247
- if node is not None:
248
- if not self._is_expired(node):
249
- self._remove_node(node)
250
- else:
251
- del self._cache[key]
252
-
253
- # Create new node
254
- expiration = time.time() + ttl_seconds
255
- new_node = Node(key, value, expiration)
256
- self._cache[key] = new_node
257
- self._add_to_head(new_node)
258
-
259
- # Evict if over capacity
260
- if len(self._cache) > self.capacity:
261
- self._evict_tail()
262
-
263
- def delete(self, key: K) -> bool:
264
- """Delete a key from the cache.
265
-
266
- Args:
267
- key: The key to remove
268
-
269
- Returns:
270
- True if the key was found and removed, False otherwise
271
- """
272
- with self._lock:
273
- node = self._cache.get(key)
274
- if node is None:
275
- return False
276
-
277
- self._remove_node(node)
278
- del self._cache[key]
279
- return True
280
-
281
- def __contains__(self, key: K) -> bool:
282
- """Check if a key exists in the cache and is not expired.
283
-
284
- Args:
285
- key: The key to check
286
-
287
- Returns:
288
- True if the key exists and is not expired, False otherwise
289
- """
290
- with self._lock:
291
- node = self._cache.get(key)
292
- if node is None:
293
- return False
294
- return not self._is_expired(node)
295
-
296
- def __len__(self) -> int:
297
- """Get the current number of items in the cache (non-expired)."""
298
- with self._lock:
299
- return sum(1 for node in self._cache.values() if not self._is_expired(node))
300
-
301
- def clear(self) -> None:
302
- """Clear all items from the cache."""
303
- with self._lock:
304
- self._cache.clear()
305
- self._head.next = self._tail
306
- self._tail.prev = self._head
307
-
308
- # Example usage
309
- if __name__ == "__main__":
310
- # Create a cache with capacity of 3
311
- cache = LRUCacheWithTTL[int, str](capacity=3)
312
-
313
- # Put some items with different TTLs
314
- cache.put(1, "value1", ttl_seconds=5) # expires in 5 seconds
315
- cache.put(2, "value2", ttl_seconds=10) # expires in 10 seconds
316
- cache.put(3, "value3", ttl_seconds=2) # expires in 2 seconds
317
-
318
- # Get items
319
- print(cache.get(1)) # "value1"
320
- print(cache.get(2))
321
-
322
- ==========================================
323
- MODEL: mac-studio/gpt-oss:20b
324
- ==========================================
325
- LOAD: 5.6s | TOKENS: 1500 | DURATION: 19.6s | SPEED: 76.4 tok/s
326
-
327
- ```python
328
- #!/usr/bin/env python3
329
- """
330
- A production‑ready, thread‑safe LRU cache with per‑key TTL support.
331
-
332
- Features
333
- --------
334
- * O(1) `get`, `put` and `delete` operations.
335
- * Internally uses a doubly‑linked list plus a hash map – no
336
- `OrderedDict` or other high‑level helpers.
337
- * Thread‑safe: all public methods acquire a `threading.Lock`.
338
- * Expired keys are removed lazily when accessed.
339
- * Capacity (maximum number of entries) can be configured; when the
340
- limit is reached the least‑recently used item is evicted.
341
- * Full type hints and detailed docstrings.
342
- """
343
-
344
- from __future__ import annotations
345
-
346
- from dataclasses import dataclass
347
- import time
348
- import threading
349
- from typing import Any, Dict, Optional
350
-
351
-
352
- @dataclass
353
- class _Node:
354
- """
355
- Doubly‑linked list node used internally by :class:`LRUCache`.
356
-
357
- Attributes
358
- ----------
359
- key : Any
360
- The key stored in this node.
361
- value : Any
362
- The value stored in this node.
363
- expire_at : float
364
- Unix timestamp (seconds since epoch) when this entry expires.
365
- prev : Optional[_Node]
366
- Reference to the previous node in the list.
367
- next : Optional[_Node]
368
- Reference to the next node in the list.
369
- """
370
- key: Any
371
- value: Any
372
- expire_at: float
373
- prev: Optional["_Node"] = None
374
- next: Optional["_Node"] = None
375
-
376
-
377
- class LRUCache:
378
- """
379
- A least‑recently‑used (LRU) cache with per‑key time‑to‑live (TTL).
380
-
381
- Parameters
382
- ----------
383
- capacity : int, optional
384
- Maximum number of items the cache can hold. When the limit is
385
- exceeded the least‑recently used item is evicted. If omitted,
386
- the cache defaults to 128 items.
387
-
388
- Notes
389
- -----
390
- All public methods are thread‑safe. The cache stores expiration
391
- timestamps in UTC seconds (`time.time()`), so TTL values should be
392
- given in seconds.
393
- """
394
-
395
- def __init__(self, capacity: int = 128) -> None:
396
- if capacity <= 0:
397
- raise ValueError("capacity must be a positive integer")
398
- self.capacity: int = capacity
399
- self.cache: Dict[Any, _Node] = {}
400
-
401
- # Dummy head and tail nodes to simplify edge cases
402
- self._head: _Node = _Node(key=None, value=None, expire_at=0.0)
403
- self._tail: _Node = _Node(key=None, value=None, expire_at=0.0)
404
- self._head.next = self._tail
405
- self._tail.prev = self._head
406
-
407
- self._lock = threading.Lock()
408
-
409
- # ----------------------------------------------------------------------
410
- # Private helper methods (all assume the lock is held)
411
- # ----------------------------------------------------------------------
412
- def _add_to_front(self, node: _Node) -> None:
413
- """Insert *node* immediately after the dummy head."""
414
- node.next = self._head.next
415
- node.prev = self._head
416
- self._head.next.prev = node
417
- self._head.next = node
418
-
419
- def _remove(self, node: _Node) -> None:
420
- """Remove *node* from the linked list."""
421
- prev_node = node.prev
422
- next_node = node.next
423
- if prev_node is not None:
424
- prev_node.next = next_node
425
- if next_node is not None:
426
- next_node.prev = prev_node
427
- node.prev = node.next = None
428
-
429
- def _move_to_front(self, node: _Node) -> None:
430
- """Move an existing node to the front (most‑recently used)."""
431
- self._remove(node)
432
- self._add_to_front(node)
433
-
434
- def _pop_tail(self) -> Optional[_Node]:
435
- """
436
- Remove and return the least‑recently used node (the one just
437
-
438
- ==========================================
439
- MODEL: mac-studio/devstral-small-2:24b
440
- ==========================================
441
- LOAD: 5.2s | TOKENS: 1500 | DURATION: 60.5s | SPEED: 24.8 tok/s
442
-
443
- Here's a thread-safe LRU cache implementation with per-key TTL expiration using a doubly linked list and hashmap:
444
-
445
- ```python
446
- import threading
447
- import time
448
- from typing import Any, Generic, TypeVar, Optional
449
-
450
- K = TypeVar('K')
451
- V = TypeVar('V')
452
-
453
- class Node(Generic[K, V]):
454
- """Node in the doubly linked list."""
455
- def __init__(self, key: K, value: V, expiration: float) -> None:
456
- self.key = key
457
- self.value = value
458
- self.expiration = expiration
459
- self.prev: Optional['Node[K, V]'] = None
460
- self.next: Optional['Node[K, V]'] = None
461
-
462
- class ThreadSafeLRUCache(Generic[K, V]):
463
- """Thread-safe LRU cache with per-key TTL expiration.
464
-
465
- Uses a doubly linked list for O(1) access to most recent items and a hashmap for O(1) lookups.
466
- Expired items are lazily evicted on access.
467
- """
468
-
469
- def __init__(self, capacity: int) -> None:
470
- """Initialize the cache with given capacity.
471
-
472
- Args:
473
- capacity: Maximum number of items the cache can hold.
474
- """
475
- if capacity <= 0:
476
- raise ValueError("Capacity must be positive")
477
-
478
- self.capacity = capacity
479
- self.cache: dict[K, Node[K, V]] = {}
480
- self.head: Optional[Node[K, V]] = None
481
- self.tail: Optional[Node[K, V]] = None
482
- self.lock = threading.Lock()
483
-
484
- def _add_to_head(self, node: Node[K, V]) -> None:
485
- """Add node to the head of the list (most recently used)."""
486
- node.prev = None
487
- node.next = self.head
488
-
489
- if self.head is not None:
490
- self.head.prev = node
491
-
492
- self.head = node
493
-
494
- if self.tail is None:
495
- self.tail = node
496
-
497
- def _remove_node(self, node: Node[K, V]) -> None:
498
- """Remove node from the linked list."""
499
- if node.prev is not None:
500
- node.prev.next = node.next
501
- else:
502
- self.head = node.next
503
-
504
- if node.next is not None:
505
- node.next.prev = node.prev
506
- else:
507
- self.tail = node.prev
508
-
509
- def _move_to_head(self, node: Node[K, V]) -> None:
510
- """Move node to the head of the list (mark as recently used)."""
511
- self._remove_node(node)
512
- self._add_to_head(node)
513
-
514
- def _pop_tail(self) -> Optional[Node[K, V]]:
515
- """Remove and return the tail node (least recently used)."""
516
- if self.tail is None:
517
- return None
518
-
519
- node = self.tail
520
- self._remove_node(node)
521
- return node
522
-
523
- def _is_expired(self, node: Node[K, V]) -> bool:
524
- """Check if node has expired based on its TTL."""
525
- return time.time() > node.expiration
526
-
527
- def get(self, key: K) -> Optional[V]:
528
- """Get value for key if it exists and hasn't expired.
529
-
530
- Args:
531
- key: Key to look up in cache.
532
-
533
- Returns:
534
- Value if found and not expired, None otherwise.
535
- """
536
- with self.lock:
537
- node = self.cache.get(key)
538
- if node is None:
539
- return None
540
-
541
- if self._is_expired(node):
542
- self._remove_node(node)
543
- del self.cache[key]
544
- return None
545
-
546
- self._move_to_head(node)
547
- return node.value
548
-
549
- def put(self, key: K, value: V, ttl_seconds: float) -> None:
550
- """Insert or update key-value pair with TTL.
551
-
552
- Args:
553
- key: Key to insert/update.
554
- value: Value to store.
555
- ttl_seconds: Time-to-live in seconds for this key.
556
- """
557
- with self.lock:
558
- expiration = time.time() + ttl_seconds
559
-
560
- if key in self.cache:
561
- node = self.cache[key]
562
- node.value = value
563
- node.expiration = expiration
564
- self._move_to_head(node)
565
- else:
566
- if len(self.cache) >= self.capacity:
567
- tail = self._pop_tail()
568
- if tail is not None:
569
- del self.cache[tail.key]
570
-
571
- new_node = Node(key, value, expiration)
572
- self.cache[key] = new_node
573
- self._add_to_head(new_node)
574
-
575
- def delete(self, key: K) -> bool:
576
- """Remove key from cache if it exists.
577
-
578
- Args:
579
- key: Key to remove.
580
-
581
- Returns:
582
- True if key was found and removed, False otherwise.
583
- """
584
- with self.lock:
585
- node = self.cache.get(key)
586
- if node is None:
587
- return False
588
-
589
- self._remove_node(node)
590
- del self.cache[key]
591
- return True
592
-
593
- # Usage example
594
- if __name__ == "__main__":
595
- cache = ThreadSafeLRUCache[str, int](capacity=2)
596
-
597
- # Test basic operations
598
- cache.put("a", 1, ttl_seconds=1)
599
- cache.put("b", 2, ttl_seconds=2)
600
-
601
- print(cache.get("a")) # Output: 1
602
- print(cache.get("b")) # Output: 2
603
-
604
- # Test LRU eviction
605
- cache.put("c", 3, ttl_seconds=3)
606
- print(cache.get("a")) # Output: None (evicted)
607
- print(cache.get("b")) # Output: 2
608
- print(cache.get("c")) # Output: 3
609
-
610
- # Test TTL expiration
611
- time.sleep(1.5)
612
- print(cache.get("b")) # Output: None (expired)
613
- print(cache.get("c")) # Output: 3
614
-
615
- # Test thread safety
616
- def worker(key: str, value: int, ttl: float) -> None:
617
- cache.put(key, value, ttl_seconds=ttl)
618
- print(f"Put {key}: {cache.get(key)}")
619
-
620
- threads = []
621
- for i in range(5):
622
- t = threading.Thread(target=worker, args=(f"key{i}", i, 5))
623
- threads.append(t)
624
- t.start()
625
-
626
- for t in threads:
627
- t.join()
628
-
629
- # Test delete
630
- print(cache.delete("key0")) # Output: True
631
- print(cache.delete("nonexistent")) # Output: False
632
- ```
633
-
634
- This implementation includes:
635
-
636
- 1. A doubly linked list (`Node` class) to track usage order
637
- 2. A hashmap (`cache` dict) for O(1) lookups
638
- 3. Thread safety using `threading.Lock`
639
- 4. Lazy expiration checking on `get()` operations
640
- 5. Full type hints and docstrings
641
- 6. A working usage example demonstrating:
642
- - Basic put/get operations
643
- - LRU eviction
644
- - TTL expiration
645
-
646
- ==========================================
647
- MODEL: mac-studio/qwen3-coder:30b
648
- ==========================================
649
- LOAD: 7.3s | TOKENS: 1500 | DURATION: 17.3s | SPEED: 86.6 tok/s
650
-
651
- ```python
652
- import threading
653
- import time
654
- from typing import Optional, Any, Dict
655
-
656
-
657
- class LRUCacheNode:
658
- """Doubly linked list node for LRU cache."""
659
-
660
- def __init__(self, key: str, value: Any, ttl_seconds: Optional[int] = None):
661
- self.key = key
662
- self.value = value
663
- self.ttl_seconds = ttl_seconds
664
- self.expiration_time = time.time() + ttl_seconds if ttl_seconds is not None else None
665
- self.prev = None
666
- self.next = None
667
-
668
-
669
- class LRUCache:
670
- """
671
- Thread-safe LRU cache with per-key TTL expiration.
672
-
673
- This implementation uses a doubly linked list combined with a hash map to achieve
674
- O(1) get and put operations. Keys are lazily evicted when accessed if expired.
675
- """
676
-
677
- def __init__(self, capacity: int = 128):
678
- """
679
- Initialize the LRU cache with given capacity.
680
-
681
- Args:
682
- capacity: Maximum number of items the cache can hold
683
- """
684
- self.capacity = capacity
685
- self.cache_map: Dict[str, LRUCacheNode] = {}
686
- self.head = LRUCacheNode("", None) # Dummy head node
687
- self.tail = LRUCacheNode("", None) # Dummy tail node
688
- self.head.next = self.tail
689
- self.tail.prev = self.head
690
- self.lock = threading.Lock()
691
-
692
- def _remove_node(self, node: LRUCacheNode) -> None:
693
- """
694
- Remove a node from the doubly linked list.
695
-
696
- Args:
697
- node: Node to remove
698
- """
699
- node.prev.next = node.next
700
- node.next.prev = node.prev
701
-
702
- def _add_to_front(self, node: LRUCacheNode) -> None:
703
- """
704
- Add a node to the front of the doubly linked list (most recently used).
705
-
706
- Args:
707
- node: Node to add
708
- """
709
- node.next = self.head.next
710
- node.prev = self.head
711
- self.head.next.prev = node
712
- self.head.next = node
713
-
714
- def _move_to_front(self, node: LRUCacheNode) -> None:
715
- """
716
- Move a node to the front of the list (mark as most recently used).
717
-
718
- Args:
719
- node: Node to move
720
- """
721
- self._remove_node(node)
722
- self._add_to_front(node)
723
-
724
- def _is_expired(self, node: LRUCacheNode) -> bool:
725
- """
726
- Check if a node is expired based on its TTL.
727
-
728
- Args:
729
- node: Node to check
730
-
731
- Returns:
732
- True if the node is expired, False otherwise
733
- """
734
- if node.expiration_time is None:
735
- return False
736
- return time.time() > node.expiration_time
737
-
738
- def _evict_expired(self) -> None:
739
- """
740
- Evict all expired nodes from the cache.
741
- """
742
- current = self.tail.prev
743
- while current != self.head and self._is_expired(current):
744
- self._remove_node(current)
745
- del self.cache_map[current.key]
746
- current = self.tail.prev
747
-
748
- def get(self, key: str) -> Optional[Any]:
749
- """
750
- Get a value from the cache by key.
751
-
752
- If the key is not found or has expired, returns None.
753
- Also removes expired keys lazily during access.
754
-
755
- Args:
756
- key: Key to look up
757
-
758
- Returns:
759
- Value associated with key, or None if not found or expired
760
- """
761
- with self.lock:
762
- if key not in self.cache_map:
763
- return None
764
-
765
- node = self.cache_map[key]
766
-
767
- # Check for expiration before returning
768
- if self._is_expired(node):
769
- self._remove_node(node)
770
- del self.cache_map[key]
771
- return None
772
-
773
- # Move to front (most recently used)
774
- self._move_to_front(node)
775
- return node.value
776
-
777
- def put(self, key: str, value: Any, ttl_seconds: Optional[int] = None) -> None:
778
- """
779
- Put a key-value pair in the cache with optional TTL.
780
-
781
- If key already exists, updates its value and TTL.
782
- Evicts least recently used items if necessary.
783
-
784
- Args:
785
- key: Key to store
786
- value: Value to store
787
- ttl_seconds: Time-to-live in seconds (None means no expiration)
788
- """
789
- with self.lock:
790
- if key in self.cache_map:
791
- # Update existing node
792
- node = self.cache_map[key]
793
- node.value = value
794
- node.ttl_seconds = ttl_seconds
795
- node.expiration_time = time.time() + ttl_seconds if ttl_seconds is not None else None
796
- self._move_to_front(node)
797
- else:
798
- # Create new node
799
- new_node = LRUCacheNode(key, value, ttl_seconds)
800
-
801
- # Evict expired nodes before adding new one
802
- self._evict_expired()
803
-
804
- # Check if we need to evict oldest items
805
- if len(self.cache_map) >= self.capacity:
806
- # Remove least recently used (tail.prev)
807
- lru_node = self.tail.prev
808
- self._remove_node(lru_node)
809
- del self.cache_map[lru_node.key]
810
-
811
- # Add new node to front
812
- self._add_to_front(new_node)
813
- self.cache_map[key] = new_node
814
-
815
- def delete(self, key: str) -> bool:
816
- """
817
- Delete a key from the cache.
818
-
819
- Args:
820
- key: Key to delete
821
-
822
- Returns:
823
- True if key was found and deleted, False otherwise
824
- """
825
- with self.lock:
826
- if key not in self.cache_map:
827
- return False
828
-
829
- node = self.cache_map[key]
830
- self._remove_node(node)
831
- del self.cache_map[key]
832
- return True
833
-
834
- def size(self) -> int:
835
- """
836
- Get the current number of items in the cache.
837
-
838
- Returns:
839
- Number of items in the cache
840
- """
841
- with self.lock:
842
- return len(self.cache_map)
843
-
844
- def clear(self) -> None:
845
- """
846
- Clear all items from the cache.
847
- """
848
- with self.lock:
849
- self.cache_map.clear()
850
- self.head.next = self.tail
851
- self.tail.prev = self.head
852
-
853
-
854
- # Example usage
855
- if __name__ == "__main__":
856
- # Create a cache with capacity of 3
857
- cache = LRUCache(capacity=3)
858
-
859
- # Put some values
860
- cache.put("a", 1, ttl_seconds=2) # Expires in 2 seconds
861
- cache.put("b", 2, ttl_seconds=5) # Expires in 5 seconds
862
- cache.put("c", 3) # No expiration
863
-
864
- print(f"Cache size: {cache.size()}") # Should be 3
865
-
866
- # Get values
867
- print(cache.get("a")) # Should return 1
868
- print(cache.get("b")) # Should return 2
869
-
870
- # Wait for key "a" to expire
871
- time.sleep(2.5)
872
-
873
- # Try accessing expired key
874
- print(cache.get("a")) # Should return None
875
-
876
- ==========================================
877
- MODEL: mac-mini/qwen3.5:27b
878
- ==========================================
879
- LOAD: 11.8s | TOKENS: 1500 | DURATION: 406.5s | SPEED: 3.7 tok/s
880
-
881
- Here's a thinking process that leads to the suggested implementation:
882
-
883
- 1. **Analyze the Request:**
884
- * **Goal:** Implement a thread-safe LRU (Least Recently Used) cache in Python.
885
- * **Specific Feature:** Per-key TTL (Time-To-Live).
886
- * **Internal Structure:** Doubly Linked List + Hash Map (Dictionary). Explicitly forbids `OrderedDict` and `functools.lru_cache`.
887
- * **Methods:** `get(key)`, `put(key, value, ttl_seconds)`, `delete(key)`.
888
- * **Concurrency:** Thread-safe using `threading.Lock`.
889
- * **Expiration Logic:** Lazy eviction (keys expire only when accessed if TTL passed). Note: This usually implies checking expiry on `get` or `put`.
890
- * **Quality:** Production-quality, full type hints, docstrings.
891
- * **Output:** Working usage example included.
892
-
893
- 2. **Design the Data Structures:**
894
- * **Node Class:** Needs to hold `key`, `value`, `expiry_time` (absolute timestamp), and pointers `prev`/`next`.
895
- * **HashMap:** A standard `dict[str, Node]` mapping keys to node objects for O(1) access.
896
- * **Doubly Linked List:** Needs head and tail sentinel nodes (dummy nodes) to simplify insertion/removal at ends.
897
- * Head: Most Recently Used (MRU).
898
- * Tail: Least Recently Used (LRU).
899
- * **Lock:** A `threading.RLock` or `threading.Lock`. Since we might be calling internal methods that hold locks, an `RLock` is often safer to prevent deadlocks if a method re-enters the lock context, though for simple cache ops `Lock` usually suffices. Let's stick to `threading.Lock` as per strict requirement, but `RLock` handles recursion better. The prompt says `threading.Lock`, so I will use `threading.Lock`. Wait, actually, if I have a method that calls another synchronized method holding the lock, I need `RLock`. However, standard cache implementations usually wrap the critical section in one block. I will use `threading.Lock` but structure code carefully to avoid recursion. Actually, `RLock` is safer for re-entrancy (e.g., if `delete` calls internal cleanup that might try to acquire). Let's stick to the prompt: "Thread-safe using threading.Lock". I'll use `threading.Lock` but be mindful of critical sections.
900
-
901
- 3. **Design the Logic:**
902
- * **Capacity:** The prompt didn't specify a max size limit, just LRU behavior + TTL. However, a cache usually implies eviction based on size. Without a max size, it's technically an "LRU dictionary with expiration". But to make it truly an LRU *Cache*, I need a `capacity` parameter in `__init__`. If I don't implement capacity, the Linked List logic for LRU is less meaningful (we only move nodes to front on access). Let's add `capacity` but default it to infinite or None. To strictly satisfy "LRU Cache", eviction based on size is crucial. I will include `max_size` in `__init__`.
903
- * **`put(key, value, ttl)`:**
904
- 1. Acquire lock.
905
- 2. Check if key exists.
906
- * If yes: Update node (value, expiry, move to MRU).
907
- * If no: Create new node. Insert at MRU. Increment size.
908
- 3. If capacity exceeded and new node added: Evict LRU node (tail.next). Check map deletion.
909
- 4. Release lock.
910
- * **`get(key)`:**
911
- 1. Acquire lock.
912
- 2. Check if key exists in map.
913
- 3. If exists:
914
- * Check TTL (time.time() > expiry_time).
915
- * If expired: Remove node, remove from map, return None.
916
- * If not expired: Move to MRU, return value.
917
- 4. Release lock.
918
- * **`delete(key)`:**
919
- 1. Acquire lock.
920
- 2. Check if key exists.
921
- 3. Remove node from list and map.
922
- 4. Release lock.
923
-
924
- 4. **Refining Expiration Logic (Lazy vs Active):**
925
- * Requirement: "Expired keys are lazily evicted on access".
926
- * This means `get(key)` checks TTL. If expired, remove it.
927
- * What about `put`? If we overwrite an existing key, we should update its TTL.
928
- * What about background cleanup? The requirement specifically says "lazy eviction on access", implying no background threads for expiration. I will follow this strictly. However, relying solely on lazy eviction means expired entries stay in memory until accessed again, which might bloat memory. A production-quality cache usually has a mechanism to handle this, but adhering to the prompt's constraint ("lazily evicted"), I will not add a background cleaner thread. I will focus on the "access" part.
929
- * Wait, if I don't check expiration in `put` (when overwriting), an old key stays expired until `get` or next access? No, `put` updates it. The issue is keys that are never accessed again after expiring. They remain in the map/list until a size eviction happens (if capacity exists) or until explicitly deleted. This is acceptable for "lazy".
930
-
931
- 5. **Drafting the Code (Mental or Scratchpad):**
932
- * `Node` class: `key`, `value`, `expire_at`, `prev`, `next`.
933
- * `_DoublyLinkedList`: Head, Tail pointers. Methods `_add_to_head(node)`, `_remove_node(node)`.
934
- * `LRUCache`: `__init__(self, capacity=...)`. `_cache` dict. `current_size`. `lock`.
935
- * Imports: `time`, `threading`, `typing` (Optional).
936
-
937
- 6. **Addressing "Production Quality":**
938
- * Type hints everywhere.
939
- * Docstrings for class and methods.
940
- * Handle `None` inputs gracefully? Key should be hashable. Value any object. TTL float/int >= 0.
941
- * Context manager for lock (`with self.lock:`).
942
- * Sentinel nodes (dummy head/tail) simplify edge cases (empty list).
943
-
944
- 7. **Potential Edge Cases:**
945
- * `ttl_seconds` = 0? Should expire immediately or act like no TTL? Usually 0 means immediate expiry or effectively "cache for a moment". Standard logic: `time.time() + ttl`. If 0, it expires immediately on next check. Let
946
- ==========================================
947
- BENCHMARK COMPLETE: Mon Mar 23 07:09:03 EDT 2026