enya-agent 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (389) hide show
  1. package/.env.example +20 -0
  2. package/.github/workflows/ci.yml +70 -0
  3. package/.github/workflows/publish.yml +250 -0
  4. package/.gitmodules +3 -0
  5. package/Cargo.lock +3584 -0
  6. package/Cargo.toml +97 -0
  7. package/crates/enact/Cargo.toml +27 -0
  8. package/crates/enact/src/lib.rs +60 -0
  9. package/crates/enact-a2a/Cargo.toml +25 -0
  10. package/crates/enact-a2a/src/lib.rs +411 -0
  11. package/crates/enact-channels/Cargo.toml +64 -0
  12. package/crates/enact-channels/examples/README.md +80 -0
  13. package/crates/enact-channels/examples/channel_bot.rs +169 -0
  14. package/crates/enact-channels/examples/telegram-echo.rs +34 -0
  15. package/crates/enact-channels/examples/whatsapp-echo.rs +142 -0
  16. package/crates/enact-channels/src/config.rs +213 -0
  17. package/crates/enact-channels/src/lib.rs +25 -0
  18. package/crates/enact-channels/src/runtime.rs +237 -0
  19. package/crates/enact-channels/src/security/mod.rs +5 -0
  20. package/crates/enact-channels/src/security/pairing.rs +205 -0
  21. package/crates/enact-channels/src/teams.rs +601 -0
  22. package/crates/enact-channels/src/telegram.rs +2833 -0
  23. package/crates/enact-channels/src/traits.rs +200 -0
  24. package/crates/enact-channels/src/webhook.rs +262 -0
  25. package/crates/enact-channels/src/whatsapp.rs +310 -0
  26. package/crates/enact-cli/Cargo.toml +40 -0
  27. package/crates/enact-cli/src/commands/doctor.rs +62 -0
  28. package/crates/enact-cli/src/commands/mod.rs +3 -0
  29. package/crates/enact-cli/src/commands/run.rs +69 -0
  30. package/crates/enact-cli/src/commands/serve.rs +81 -0
  31. package/crates/enact-cli/src/config.rs +2 -0
  32. package/crates/enact-cli/src/main.rs +79 -0
  33. package/crates/enact-config/Cargo.toml +36 -0
  34. package/crates/enact-config/ENV_VAR_MAPPING.md +135 -0
  35. package/crates/enact-config/QUICK_REFERENCE.md +92 -0
  36. package/crates/enact-config/README.md +107 -0
  37. package/crates/enact-config/TESTING.md +161 -0
  38. package/crates/enact-config/examples/test-env-vars.rs +100 -0
  39. package/crates/enact-config/src/config.rs +399 -0
  40. package/crates/enact-config/src/encrypted_store.rs +211 -0
  41. package/crates/enact-config/src/lib.rs +298 -0
  42. package/crates/enact-config/src/secrets.rs +149 -0
  43. package/crates/enact-config/src/sync.rs +260 -0
  44. package/crates/enact-config/test-env-vars.sh +34 -0
  45. package/crates/enact-config/tests/README.md +99 -0
  46. package/crates/enact-config/tests/config_integration_test.rs +202 -0
  47. package/crates/enact-config/tests/security_test.rs +140 -0
  48. package/crates/enact-context/Cargo.toml +41 -0
  49. package/crates/enact-context/src/budget.rs +314 -0
  50. package/crates/enact-context/src/calibrator.rs +535 -0
  51. package/crates/enact-context/src/compactor.rs +392 -0
  52. package/crates/enact-context/src/condenser.rs +826 -0
  53. package/crates/enact-context/src/lib.rs +94 -0
  54. package/crates/enact-context/src/segment.rs +238 -0
  55. package/crates/enact-context/src/step_context.rs +645 -0
  56. package/crates/enact-context/src/token_counter.rs +148 -0
  57. package/crates/enact-context/src/window.rs +372 -0
  58. package/crates/enact-core/Cargo.toml +42 -0
  59. package/crates/enact-core/README.md +98 -0
  60. package/crates/enact-core/src/background/executor.rs +524 -0
  61. package/crates/enact-core/src/background/mod.rs +48 -0
  62. package/crates/enact-core/src/background/target_binding.rs +390 -0
  63. package/crates/enact-core/src/background/trigger.rs +511 -0
  64. package/crates/enact-core/src/callable/callable.rs +152 -0
  65. package/crates/enact-core/src/callable/composite.rs +817 -0
  66. package/crates/enact-core/src/callable/graph.rs +104 -0
  67. package/crates/enact-core/src/callable/llm.rs +211 -0
  68. package/crates/enact-core/src/callable/mod.rs +64 -0
  69. package/crates/enact-core/src/callable/registry.rs +206 -0
  70. package/crates/enact-core/src/context/execution_context.rs +757 -0
  71. package/crates/enact-core/src/context/invocation.rs +99 -0
  72. package/crates/enact-core/src/context/mod.rs +50 -0
  73. package/crates/enact-core/src/context/tenant.rs +175 -0
  74. package/crates/enact-core/src/context/trace.rs +127 -0
  75. package/crates/enact-core/src/flow/conditional.rs +293 -0
  76. package/crates/enact-core/src/flow/mod.rs +43 -0
  77. package/crates/enact-core/src/flow/parallel.rs +437 -0
  78. package/crates/enact-core/src/flow/repeat.rs +534 -0
  79. package/crates/enact-core/src/flow/sequential.rs +248 -0
  80. package/crates/enact-core/src/graph/checkpoint.rs +79 -0
  81. package/crates/enact-core/src/graph/checkpoint_store.rs +76 -0
  82. package/crates/enact-core/src/graph/compiled.rs +189 -0
  83. package/crates/enact-core/src/graph/edge.rs +59 -0
  84. package/crates/enact-core/src/graph/graph_schema.rs +218 -0
  85. package/crates/enact-core/src/graph/loader.rs +155 -0
  86. package/crates/enact-core/src/graph/mod.rs +18 -0
  87. package/crates/enact-core/src/graph/node/function.rs +49 -0
  88. package/crates/enact-core/src/graph/node/mod.rs +48 -0
  89. package/crates/enact-core/src/graph/schema.rs +62 -0
  90. package/crates/enact-core/src/inbox/message.rs +405 -0
  91. package/crates/enact-core/src/inbox/mod.rs +31 -0
  92. package/crates/enact-core/src/inbox/store.rs +355 -0
  93. package/crates/enact-core/src/kernel/artifact/filesystem.rs +546 -0
  94. package/crates/enact-core/src/kernel/artifact/metadata.rs +283 -0
  95. package/crates/enact-core/src/kernel/artifact/mod.rs +27 -0
  96. package/crates/enact-core/src/kernel/artifact/store.rs +427 -0
  97. package/crates/enact-core/src/kernel/enforcement.rs +1315 -0
  98. package/crates/enact-core/src/kernel/error.rs +1200 -0
  99. package/crates/enact-core/src/kernel/event.rs +1394 -0
  100. package/crates/enact-core/src/kernel/execution_model.rs +831 -0
  101. package/crates/enact-core/src/kernel/execution_state.rs +189 -0
  102. package/crates/enact-core/src/kernel/execution_strategy.rs +117 -0
  103. package/crates/enact-core/src/kernel/ids.rs +2086 -0
  104. package/crates/enact-core/src/kernel/interrupt.rs +125 -0
  105. package/crates/enact-core/src/kernel/kernel.rs +1283 -0
  106. package/crates/enact-core/src/kernel/mod.rs +205 -0
  107. package/crates/enact-core/src/kernel/persistence/event_store.rs +270 -0
  108. package/crates/enact-core/src/kernel/persistence/message_store.rs +908 -0
  109. package/crates/enact-core/src/kernel/persistence/mod.rs +102 -0
  110. package/crates/enact-core/src/kernel/persistence/state_store.rs +228 -0
  111. package/crates/enact-core/src/kernel/persistence/vector_store.rs +299 -0
  112. package/crates/enact-core/src/kernel/reducer.rs +808 -0
  113. package/crates/enact-core/src/kernel/replay.rs +153 -0
  114. package/crates/enact-core/src/lib.rs +413 -0
  115. package/crates/enact-core/src/memory/episodic.rs +0 -0
  116. package/crates/enact-core/src/memory/mod.rs +6 -0
  117. package/crates/enact-core/src/memory/semantic.rs +0 -0
  118. package/crates/enact-core/src/memory/trait.rs +0 -0
  119. package/crates/enact-core/src/memory/vector_db.rs +0 -0
  120. package/crates/enact-core/src/memory/working.rs +0 -0
  121. package/crates/enact-core/src/policy/execution_policy.rs +292 -0
  122. package/crates/enact-core/src/policy/filters.rs +458 -0
  123. package/crates/enact-core/src/policy/input_processor.rs +407 -0
  124. package/crates/enact-core/src/policy/long_running.rs +134 -0
  125. package/crates/enact-core/src/policy/mod.rs +193 -0
  126. package/crates/enact-core/src/policy/pii_input.rs +274 -0
  127. package/crates/enact-core/src/policy/tenant_policy.rs +453 -0
  128. package/crates/enact-core/src/policy/tool_policy.rs +407 -0
  129. package/crates/enact-core/src/providers/mod.rs +63 -0
  130. package/crates/enact-core/src/providers/trait.rs +292 -0
  131. package/crates/enact-core/src/runner/callbacks.rs +6 -0
  132. package/crates/enact-core/src/runner/execution_runner.rs +476 -0
  133. package/crates/enact-core/src/runner/loop.rs +117 -0
  134. package/crates/enact-core/src/runner/mod.rs +58 -0
  135. package/crates/enact-core/src/runner/protected_runner.rs +280 -0
  136. package/crates/enact-core/src/signal/inmemory.rs +231 -0
  137. package/crates/enact-core/src/signal/mod.rs +108 -0
  138. package/crates/enact-core/src/streaming/event_logger.rs +195 -0
  139. package/crates/enact-core/src/streaming/event_stream.rs +1423 -0
  140. package/crates/enact-core/src/streaming/mod.rs +108 -0
  141. package/crates/enact-core/src/streaming/pause_cancel.rs +0 -0
  142. package/crates/enact-core/src/streaming/protected_emitter.rs +173 -0
  143. package/crates/enact-core/src/streaming/protection/context.rs +136 -0
  144. package/crates/enact-core/src/streaming/protection/encryption.rs +289 -0
  145. package/crates/enact-core/src/streaming/protection/mod.rs +43 -0
  146. package/crates/enact-core/src/streaming/protection/pii_protection.rs +243 -0
  147. package/crates/enact-core/src/streaming/protection/processor.rs +166 -0
  148. package/crates/enact-core/src/streaming/sse.rs +0 -0
  149. package/crates/enact-core/src/telemetry/exporter.rs +0 -0
  150. package/crates/enact-core/src/telemetry/init.rs +0 -0
  151. package/crates/enact-core/src/telemetry/mod.rs +49 -0
  152. package/crates/enact-core/src/telemetry/spans.rs +245 -0
  153. package/crates/enact-core/src/tool/agent_tool.rs +177 -0
  154. package/crates/enact-core/src/tool/browser/mod.rs +0 -0
  155. package/crates/enact-core/src/tool/browser/webdriver.rs +0 -0
  156. package/crates/enact-core/src/tool/cost.rs +247 -0
  157. package/crates/enact-core/src/tool/discovery.rs +0 -0
  158. package/crates/enact-core/src/tool/dispatcher.rs +347 -0
  159. package/crates/enact-core/src/tool/filesystem.rs +231 -0
  160. package/crates/enact-core/src/tool/function.rs +99 -0
  161. package/crates/enact-core/src/tool/git.rs +162 -0
  162. package/crates/enact-core/src/tool/http.rs +214 -0
  163. package/crates/enact-core/src/tool/mcp/client.rs +0 -0
  164. package/crates/enact-core/src/tool/mcp/mod.rs +0 -0
  165. package/crates/enact-core/src/tool/mod.rs +51 -0
  166. package/crates/enact-core/src/tool/reasoning/debugging.rs +0 -0
  167. package/crates/enact-core/src/tool/reasoning/mcts.rs +0 -0
  168. package/crates/enact-core/src/tool/reasoning/mod.rs +0 -0
  169. package/crates/enact-core/src/tool/reasoning/sequential.rs +0 -0
  170. package/crates/enact-core/src/tool/sandbox/dagger.rs +0 -0
  171. package/crates/enact-core/src/tool/sandbox/mod.rs +0 -0
  172. package/crates/enact-core/src/tool/shell.rs +147 -0
  173. package/crates/enact-core/src/tool/trait.rs +33 -0
  174. package/crates/enact-core/src/tool/web_search.rs +277 -0
  175. package/crates/enact-core/src/util/config.rs +0 -0
  176. package/crates/enact-core/src/util/errors.rs +0 -0
  177. package/crates/enact-core/src/util/mod.rs +6 -0
  178. package/crates/enact-core/tests/airgapped_e2e_test.rs +291 -0
  179. package/crates/enact-core/tests/e2e_agentic_loop.rs +119 -0
  180. package/crates/enact-core/tests/e2e_test.rs +259 -0
  181. package/crates/enact-core/tests/graph_test.rs +130 -0
  182. package/crates/enact-core/tests/stream_event_id_validation.rs +435 -0
  183. package/crates/enact-cron/Cargo.toml +28 -0
  184. package/crates/enact-cron/src/lib.rs +44 -0
  185. package/crates/enact-cron/src/schedule.rs +156 -0
  186. package/crates/enact-cron/src/store.rs +589 -0
  187. package/crates/enact-cron/src/types.rs +148 -0
  188. package/crates/enact-gateway/Cargo.toml +31 -0
  189. package/crates/enact-gateway/README.md +30 -0
  190. package/crates/enact-gateway/examples/whatsapp-gateway-runner-mock.rs +59 -0
  191. package/crates/enact-gateway/examples/whatsapp-gateway.rs +42 -0
  192. package/crates/enact-gateway/src/lib.rs +582 -0
  193. package/crates/enact-mcp/Cargo.toml +24 -0
  194. package/crates/enact-mcp/src/lib.rs +178 -0
  195. package/crates/enact-memory/Cargo.toml +25 -0
  196. package/crates/enact-memory/src/backend.rs +20 -0
  197. package/crates/enact-memory/src/chunker.rs +230 -0
  198. package/crates/enact-memory/src/embeddings.rs +221 -0
  199. package/crates/enact-memory/src/lib.rs +67 -0
  200. package/crates/enact-memory/src/markdown.rs +127 -0
  201. package/crates/enact-memory/src/none.rs +61 -0
  202. package/crates/enact-memory/src/sqlite.rs +276 -0
  203. package/crates/enact-memory/src/traits.rs +65 -0
  204. package/crates/enact-memory/src/vector.rs +198 -0
  205. package/crates/enact-oauth/Cargo.toml +27 -0
  206. package/crates/enact-oauth/src/lib.rs +584 -0
  207. package/crates/enact-observability/Cargo.toml +22 -0
  208. package/crates/enact-observability/src/lib.rs +197 -0
  209. package/crates/enact-providers/Cargo.toml +33 -0
  210. package/crates/enact-providers/examples/hello-agent.rs +33 -0
  211. package/crates/enact-providers/src/anthropic.rs +182 -0
  212. package/crates/enact-providers/src/azure.rs +96 -0
  213. package/crates/enact-providers/src/bridge.rs +221 -0
  214. package/crates/enact-providers/src/gemini.rs +227 -0
  215. package/crates/enact-providers/src/http.rs +78 -0
  216. package/crates/enact-providers/src/lib.rs +53 -0
  217. package/crates/enact-providers/src/openai_compatible.rs +167 -0
  218. package/crates/enact-providers/src/openrouter.rs +33 -0
  219. package/crates/enact-runner/Cargo.toml +24 -0
  220. package/crates/enact-runner/README.md +76 -0
  221. package/crates/enact-runner/src/compaction.rs +225 -0
  222. package/crates/enact-runner/src/config.rs +118 -0
  223. package/crates/enact-runner/src/lib.rs +63 -0
  224. package/crates/enact-runner/src/loop_driver.rs +414 -0
  225. package/crates/enact-runner/src/parser.rs +421 -0
  226. package/crates/enact-runner/src/retry.rs +262 -0
  227. package/crates/enact-runner/tests/integration.rs +278 -0
  228. package/crates/enact-security/Cargo.toml +22 -0
  229. package/crates/enact-security/src/audit.rs +375 -0
  230. package/crates/enact-security/src/lib.rs +37 -0
  231. package/crates/enact-security/src/policy.rs +406 -0
  232. package/crates/enact-skills/Cargo.toml +25 -0
  233. package/crates/enact-skills/src/lib.rs +506 -0
  234. package/crates/enact-tools/Cargo.toml +22 -0
  235. package/crates/enact-tools/src/file_read.rs +166 -0
  236. package/crates/enact-tools/src/file_write.rs +216 -0
  237. package/crates/enact-tools/src/git_operations.rs +513 -0
  238. package/crates/enact-tools/src/http_request.rs +417 -0
  239. package/crates/enact-tools/src/lib.rs +104 -0
  240. package/crates/enact-tools/src/security.rs +227 -0
  241. package/crates/enact-tools/src/shell.rs +191 -0
  242. package/crates/enact-tools/src/traits.rs +159 -0
  243. package/docs/Makefile +74 -0
  244. package/docs/config.toml +62 -0
  245. package/docs/content/_index.md +174 -0
  246. package/docs/content/a2a/_index.md +431 -0
  247. package/docs/content/api/_index.md +323 -0
  248. package/docs/content/channels/_index.md +160 -0
  249. package/docs/content/channels/teams.md +205 -0
  250. package/docs/content/channels/telegram.md +182 -0
  251. package/docs/content/channels/webhook.md +423 -0
  252. package/docs/content/channels/whatsapp.md +240 -0
  253. package/docs/content/cli/_index.md +261 -0
  254. package/docs/content/concepts/_index.md +273 -0
  255. package/docs/content/configuration/_index.md +241 -0
  256. package/docs/content/cron/_index.md +248 -0
  257. package/docs/content/developers/_index.md +278 -0
  258. package/docs/content/getting-started/_index.md +180 -0
  259. package/docs/content/installation/_index.md +186 -0
  260. package/docs/content/installation/uninstall.md +101 -0
  261. package/docs/content/installation/updating.md +120 -0
  262. package/docs/content/mcp/_index.md +215 -0
  263. package/docs/content/memory/_index.md +163 -0
  264. package/docs/content/oauth/_index.md +515 -0
  265. package/docs/content/providers/_index.md +206 -0
  266. package/docs/content/roadmap/_index.md +199 -0
  267. package/docs/content/security/_index.md +219 -0
  268. package/docs/content/skills/_index.md +228 -0
  269. package/docs/content/tools/_index.md +485 -0
  270. package/docs/content/troubleshooting/_index.md +259 -0
  271. package/docs/content/yaml-schema/_index.md +294 -0
  272. package/docs/static/giallo-dark.css +91 -0
  273. package/docs/static/giallo-light.css +91 -0
  274. package/docs/themes/tanuki/.github/workflows/deploy.yml +44 -0
  275. package/docs/themes/tanuki/LICENSE +21 -0
  276. package/docs/themes/tanuki/README.md +166 -0
  277. package/docs/themes/tanuki/examples/blog/config.toml +58 -0
  278. package/docs/themes/tanuki/examples/blog/content/_index.md +4 -0
  279. package/docs/themes/tanuki/examples/blog/content/about.md +33 -0
  280. package/docs/themes/tanuki/examples/blog/content/blog/_index.md +7 -0
  281. package/docs/themes/tanuki/examples/blog/content/blog/api-design-best-practices.md +245 -0
  282. package/docs/themes/tanuki/examples/blog/content/blog/building-accessible-websites.md +147 -0
  283. package/docs/themes/tanuki/examples/blog/content/blog/css-grid-vs-flexbox.md +165 -0
  284. package/docs/themes/tanuki/examples/blog/content/blog/customizing-catppuccin-colors.md +137 -0
  285. package/docs/themes/tanuki/examples/blog/content/blog/dark-mode-best-practices.md +82 -0
  286. package/docs/themes/tanuki/examples/blog/content/blog/docker-essentials.md +301 -0
  287. package/docs/themes/tanuki/examples/blog/content/blog/getting-started-with-zola.md +129 -0
  288. package/docs/themes/tanuki/examples/blog/content/blog/git-workflow-for-content.md +112 -0
  289. package/docs/themes/tanuki/examples/blog/content/blog/introduction-to-webassembly.md +183 -0
  290. package/docs/themes/tanuki/examples/blog/content/blog/modern-javascript-features.md +234 -0
  291. package/docs/themes/tanuki/examples/blog/content/blog/testing-strategies.md +311 -0
  292. package/docs/themes/tanuki/examples/blog/content/blog/typography-for-developers.md +104 -0
  293. package/docs/themes/tanuki/examples/blog/content/blog/welcome-to-tanuki.md +67 -0
  294. package/docs/themes/tanuki/examples/blog/content/blog/why-static-sites.md +85 -0
  295. package/docs/themes/tanuki/examples/blog/content/projects.md +64 -0
  296. package/docs/themes/tanuki/examples/book/config.toml +17 -0
  297. package/docs/themes/tanuki/examples/book/content/_index.md +12 -0
  298. package/docs/themes/tanuki/examples/book/content/chapter-1.md +90 -0
  299. package/docs/themes/tanuki/examples/book/content/chapter-2.md +143 -0
  300. package/docs/themes/tanuki/examples/book/content/chapter-3.md +217 -0
  301. package/docs/themes/tanuki/examples/book/content/chapter-4.md +224 -0
  302. package/docs/themes/tanuki/examples/book/content/chapter-5.md +297 -0
  303. package/docs/themes/tanuki/examples/book/content/print.md +6 -0
  304. package/docs/themes/tanuki/examples/docs/config.toml +28 -0
  305. package/docs/themes/tanuki/examples/docs/content/_index.md +20 -0
  306. package/docs/themes/tanuki/examples/docs/content/components.md +156 -0
  307. package/docs/themes/tanuki/examples/docs/content/configuration.md +94 -0
  308. package/docs/themes/tanuki/examples/docs/content/customization.md +202 -0
  309. package/docs/themes/tanuki/examples/docs/content/deployment.md +204 -0
  310. package/docs/themes/tanuki/examples/docs/content/installation.md +59 -0
  311. package/docs/themes/tanuki/examples/docs/content/print.md +6 -0
  312. package/docs/themes/tanuki/examples/docs/static/img/tanuki-icon.avif +0 -0
  313. package/docs/themes/tanuki/examples/index.html +2104 -0
  314. package/docs/themes/tanuki/mise.toml +108 -0
  315. package/docs/themes/tanuki/sass/base/_catppuccin.scss +164 -0
  316. package/docs/themes/tanuki/sass/base/_fonts.scss +64 -0
  317. package/docs/themes/tanuki/sass/base/_reset.scss +152 -0
  318. package/docs/themes/tanuki/sass/base/_typography.scss +523 -0
  319. package/docs/themes/tanuki/sass/components/_buttons.scss +209 -0
  320. package/docs/themes/tanuki/sass/components/_code.scss +457 -0
  321. package/docs/themes/tanuki/sass/components/_landing.scss +633 -0
  322. package/docs/themes/tanuki/sass/components/_layout.scss +294 -0
  323. package/docs/themes/tanuki/sass/components/_navigation.scss +1200 -0
  324. package/docs/themes/tanuki/sass/components/_print.scss +237 -0
  325. package/docs/themes/tanuki/sass/components/_search.scss +224 -0
  326. package/docs/themes/tanuki/sass/components/_sidebar.scss +473 -0
  327. package/docs/themes/tanuki/sass/components/_theme-toggle.scss +186 -0
  328. package/docs/themes/tanuki/sass/modes/_blog.scss +366 -0
  329. package/docs/themes/tanuki/sass/modes/_product.scss +875 -0
  330. package/docs/themes/tanuki/sass/modes/_raskell.scss +1696 -0
  331. package/docs/themes/tanuki/sass/patterns/_buttons.scss +183 -0
  332. package/docs/themes/tanuki/sass/patterns/_cards.scss +144 -0
  333. package/docs/themes/tanuki/sass/patterns/_index.scss +9 -0
  334. package/docs/themes/tanuki/sass/patterns/_lists.scss +259 -0
  335. package/docs/themes/tanuki/sass/patterns/_sections.scss +243 -0
  336. package/docs/themes/tanuki/sass/style.scss +47 -0
  337. package/docs/themes/tanuki/sass/tokens/_colors.scss +139 -0
  338. package/docs/themes/tanuki/sass/tokens/_spacing.scss +100 -0
  339. package/docs/themes/tanuki/sass/tokens/_typography.scss +186 -0
  340. package/docs/themes/tanuki/screenshot.png +0 -0
  341. package/docs/themes/tanuki/sentinel.kdl +59 -0
  342. package/docs/themes/tanuki/static/elasticlunr.min.js +10 -0
  343. package/docs/themes/tanuki/static/fonts/GEIST-LICENSE.txt +92 -0
  344. package/docs/themes/tanuki/static/fonts/Geist-Variable.woff2 +0 -0
  345. package/docs/themes/tanuki/static/fonts/GeistMono-Variable.woff2 +0 -0
  346. package/docs/themes/tanuki/static/img/tanuki-icon.avif +0 -0
  347. package/docs/themes/tanuki/static/img/tanuki-icon.png +0 -0
  348. package/docs/themes/tanuki/static/js/anchors.js +18 -0
  349. package/docs/themes/tanuki/static/js/app.js +274 -0
  350. package/docs/themes/tanuki/static/js/code.js +394 -0
  351. package/docs/themes/tanuki/static/js/navigation.js +778 -0
  352. package/docs/themes/tanuki/static/js/scroll-to-top.js +33 -0
  353. package/docs/themes/tanuki/static/js/search-raskell.js +240 -0
  354. package/docs/themes/tanuki/static/js/search.js +215 -0
  355. package/docs/themes/tanuki/static/js/theme.js +169 -0
  356. package/docs/themes/tanuki/static/syntax-dark.css +151 -0
  357. package/docs/themes/tanuki/static/syntax-light.css +151 -0
  358. package/docs/themes/tanuki/static/wasm/sentinel_playground_wasm.js +486 -0
  359. package/docs/themes/tanuki/static/wasm/sentinel_playground_wasm_bg.wasm +0 -0
  360. package/docs/themes/tanuki/templates/404.html +52 -0
  361. package/docs/themes/tanuki/templates/base.html +428 -0
  362. package/docs/themes/tanuki/templates/blog.html +66 -0
  363. package/docs/themes/tanuki/templates/home.html +108 -0
  364. package/docs/themes/tanuki/templates/index.html +178 -0
  365. package/docs/themes/tanuki/templates/landing.html +168 -0
  366. package/docs/themes/tanuki/templates/macros/nav.html +128 -0
  367. package/docs/themes/tanuki/templates/macros/posts.html +101 -0
  368. package/docs/themes/tanuki/templates/macros/ui.html +159 -0
  369. package/docs/themes/tanuki/templates/page.html +135 -0
  370. package/docs/themes/tanuki/templates/partials/footer.html +38 -0
  371. package/docs/themes/tanuki/templates/partials/header.html +366 -0
  372. package/docs/themes/tanuki/templates/partials/nav-buttons.html +55 -0
  373. package/docs/themes/tanuki/templates/partials/nav-overlay.html +81 -0
  374. package/docs/themes/tanuki/templates/partials/page-toc-panel.html +43 -0
  375. package/docs/themes/tanuki/templates/partials/search.html +52 -0
  376. package/docs/themes/tanuki/templates/partials/sidebar.html +107 -0
  377. package/docs/themes/tanuki/templates/partials/theme-toggle.html +35 -0
  378. package/docs/themes/tanuki/templates/partials/toc-overlay.html +146 -0
  379. package/docs/themes/tanuki/templates/partials/version-picker.html +38 -0
  380. package/docs/themes/tanuki/templates/print.html +244 -0
  381. package/docs/themes/tanuki/templates/section.html +186 -0
  382. package/docs/themes/tanuki/templates/taxonomy_list.html +18 -0
  383. package/docs/themes/tanuki/templates/taxonomy_single.html +31 -0
  384. package/docs/themes/tanuki/theme.toml +58 -0
  385. package/examples/hello-agent.rs +55 -0
  386. package/package.json +36 -0
  387. package/proto/config.proto +60 -0
  388. package/proto/events.proto +0 -0
  389. package/proto/runtime.proto +215 -0
@@ -0,0 +1,178 @@
1
+ {% extends "base.html" %}
2
+
3
+ {% block title %}{{ config.title }}{% endblock %}
4
+
5
+ {% block content %}
6
+ {% set mode = config.extra.mode | default(value="site") %}
7
+
8
+ {% if mode == "site" or mode == "blog" %}
9
+ {# raskell.io style homepage #}
10
+ <div class="container">
11
+ <section class="hero">
12
+ <div class="content">
13
+ {% set section = get_section(path="_index.md") %}
14
+ {{ section.content | safe }}
15
+ </div>
16
+
17
+ {# Speaking & Social #}
18
+ <div class="hero-meta">
19
+ {% if config.extra.speaking_badge %}
20
+ <p class="speaking-badge"><strong>{{ config.extra.speaking_badge }}</strong> · Available for technical talks and consulting</p>
21
+ {% endif %}
22
+ <div class="bio-social">
23
+ {% if config.extra.social.github %}
24
+ <a href="{{ config.extra.social.github }}" target="_blank" rel="noreferrer" title="github" aria-label="github">
25
+ <svg width="25" height="25" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path></svg>
26
+ </a>
27
+ {% endif %}
28
+ {% if config.extra.social.twitter %}
29
+ <a href="{{ config.extra.social.twitter }}" target="_blank" rel="noreferrer" title="X (Twitter)" aria-label="X (Twitter)">
30
+ <svg width="25" height="25" viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"></path></svg>
31
+ </a>
32
+ {% endif %}
33
+ {% if config.extra.social.linkedin %}
34
+ <a href="{{ config.extra.social.linkedin }}" target="_blank" rel="noreferrer" title="linkedin" aria-label="linkedin">
35
+ <svg width="25" height="25" viewBox="0 0 24 24" fill="currentColor"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"></path></svg>
36
+ </a>
37
+ {% endif %}
38
+ </div>
39
+ </div>
40
+ </section>
41
+ </div>
42
+
43
+ {# Articles - prominent #}
44
+ {% set articles_section = get_section(path="articles/_index.md", required=false) %}
45
+ {% if articles_section %}
46
+ <div class="container">
47
+ <section>
48
+ <h2>Writing</h2>
49
+ <div class="posts">
50
+ {% for page in articles_section.pages | slice(end=10) %}
51
+ <div class="post">
52
+ <a href="{{ page.permalink }}">
53
+ <div class="post-row">
54
+ <time>{{ page.date | date(format="%Y-%m-%d") }}</time>
55
+ <h3>{{ page.title }}</h3>
56
+ </div>
57
+ {% if page.taxonomies.tags %}
58
+ <div class="post-tags">
59
+ {% for tag in page.taxonomies.tags | slice(end=3) %}
60
+ <span class="tag">{{ tag }}</span>
61
+ {% endfor %}
62
+ </div>
63
+ {% endif %}
64
+ </a>
65
+ </div>
66
+ {% endfor %}
67
+ </div>
68
+ <a class="view-all-link" href="{{ get_url(path='@/articles/_index.md') }}">View all articles →</a>
69
+ </section>
70
+ </div>
71
+ {% endif %}
72
+
73
+ {% elif mode == "product" %}
74
+ {# Product mode - Landing page for products/tools #}
75
+ <section class="product-hero">
76
+ <h1 class="product-hero__title">{{ config.title }}</h1>
77
+ <p class="product-hero__subtitle">{{ config.description }}</p>
78
+ <div class="product-hero__actions">
79
+ {% if config.extra.cta_primary %}
80
+ <a href="{{ config.extra.cta_primary.url | safe }}" class="btn btn--primary btn--lg">
81
+ {{ config.extra.cta_primary.text }}
82
+ </a>
83
+ {% endif %}
84
+ {% if config.extra.cta_secondary %}
85
+ <a href="{{ config.extra.cta_secondary.url | safe }}" class="btn btn--secondary btn--lg">
86
+ {{ config.extra.cta_secondary.text }}
87
+ </a>
88
+ {% endif %}
89
+ </div>
90
+ </section>
91
+
92
+ {# Features section from config #}
93
+ {% if config.extra.product.features is defined %}
94
+ <section class="product-features product-section">
95
+ <div class="product-section__container">
96
+ {% if config.extra.product.features_title is defined %}
97
+ <h2 class="product-section__title">{{ config.extra.product.features_title }}</h2>
98
+ {% endif %}
99
+ <div class="product-feature-grid">
100
+ {% for feature in config.extra.product.features %}
101
+ <article class="product-feature-card">
102
+ {% if feature.icon %}
103
+ <div class="product-feature-card__icon">{{ feature.icon | safe }}</div>
104
+ {% endif %}
105
+ <h3 class="product-feature-card__title">{{ feature.title }}</h3>
106
+ <p class="product-feature-card__description">{{ feature.description }}</p>
107
+ </article>
108
+ {% endfor %}
109
+ </div>
110
+ </div>
111
+ </section>
112
+ {% endif %}
113
+
114
+ {# Install section #}
115
+ {% if config.extra.product.install_command is defined %}
116
+ <section class="product-install product-section">
117
+ <div class="product-section__container">
118
+ <h2 class="product-section__title">Install</h2>
119
+ <div class="product-install__code">
120
+ <code><span class="product-install__cmd">{{ config.extra.product.install_command }}</span></code>
121
+ </div>
122
+ {% if config.extra.product.install_alternatives %}
123
+ <p class="product-install__alternatives">{{ config.extra.product.install_alternatives | safe }}</p>
124
+ {% endif %}
125
+ </div>
126
+ </section>
127
+ {% endif %}
128
+
129
+ {# Product footer #}
130
+ <footer class="product-footer">
131
+ <div class="product-footer__container">
132
+ <div class="product-footer__content">
133
+ <div class="product-footer__brand">
134
+ {% if config.extra.product.icon %}
135
+ <div class="product-footer__icon-wrapper">
136
+ <div class="product-footer__icon-glow"></div>
137
+ <img src="{{ get_url(path=config.extra.product.icon) | safe }}" alt="" class="product-footer__icon">
138
+ </div>
139
+ {% endif %}
140
+ <div class="product-footer__tagline">
141
+ <p class="product-footer__title">{{ config.extra.product.tagline | default(value=config.description) }}</p>
142
+ <p class="product-footer__description">{{ config.extra.product.footer_description | default(value="") }}</p>
143
+ </div>
144
+ </div>
145
+ <nav class="product-footer__links">
146
+ {% if config.extra.product.footer_links is defined %}
147
+ {% for col in config.extra.product.footer_links %}
148
+ <div class="product-footer__col">
149
+ <h4>{{ col.title }}</h4>
150
+ {% for link in col.links %}
151
+ <a href="{{ link.url | safe }}">{{ link.text }}</a>
152
+ {% endfor %}
153
+ </div>
154
+ {% endfor %}
155
+ {% endif %}
156
+ </nav>
157
+ </div>
158
+ <div class="product-footer__bottom">
159
+ <p>&copy; {{ now() | date(format='%Y') }} {% if config.extra.author %}<a href="{{ config.extra.author_url | default(value='#') }}">{{ config.extra.author }}</a>{% endif %}. {{ config.extra.product.license | default(value="") }}</p>
160
+ </div>
161
+ </div>
162
+ </footer>
163
+
164
+ {% elif mode == "docs" or mode == "book" %}
165
+ {# Docs/Book mode - redirect to first page or show landing #}
166
+ {% set section = get_section(path="_index.md") %}
167
+ {% if section.pages %}
168
+ {% set first_page = section.pages | first %}
169
+ <script>window.location.href = "{{ first_page.permalink | safe }}";</script>
170
+ <p>Redirecting to <a href="{{ first_page.permalink | safe }}">{{ first_page.title }}</a>...</p>
171
+ {% else %}
172
+ <section class="hero">
173
+ <h1 class="hero__title">{{ config.title }}</h1>
174
+ <p class="hero__subtitle">{{ config.description }}</p>
175
+ </section>
176
+ {% endif %}
177
+ {% endif %}
178
+ {% endblock %}
@@ -0,0 +1,168 @@
1
+ {% extends "base.html" %}
2
+
3
+ {% block title %}{{ config.title }}{% endblock %}
4
+
5
+ {% block content %}
6
+ <section class="hero hero--landing">
7
+ <div class="hero__content">
8
+ <h1 class="hero__title">
9
+ <span class="hero__icon">tanuki</span>
10
+ </h1>
11
+ <p class="hero__subtitle">{{ config.description }}</p>
12
+ <p class="hero__tagline">Named after the playful Japanese raccoon dog, this theme brings joy and whimsy to your Zola sites.</p>
13
+ </div>
14
+ </section>
15
+
16
+ <section class="modes">
17
+ <div class="container">
18
+ <h2 class="section__title">Three Modes, One Theme</h2>
19
+ <p class="section__subtitle">Choose the mode that fits your project</p>
20
+
21
+ <div class="mode-grid">
22
+ <a href="{{ get_url(path='@/docs/_index.md') }}" class="mode-card mode-card--docs">
23
+ <div class="mode-card__icon">
24
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
25
+ <path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H20v20H6.5a2.5 2.5 0 0 1 0-5H20"/>
26
+ <path d="M8 7h6"/>
27
+ <path d="M8 11h8"/>
28
+ </svg>
29
+ </div>
30
+ <h3 class="mode-card__title">Documentation</h3>
31
+ <p class="mode-card__description">Technical docs with versioning, sidebar navigation, and search. Perfect for API references and guides.</p>
32
+ <span class="mode-card__cta">Explore Docs</span>
33
+ </a>
34
+
35
+ <a href="{{ get_url(path='@/book/_index.md') }}" class="mode-card mode-card--book">
36
+ <div class="mode-card__icon">
37
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
38
+ <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/>
39
+ <path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/>
40
+ </svg>
41
+ </div>
42
+ <h3 class="mode-card__title">E-Book</h3>
43
+ <p class="mode-card__description">Long-form content with chapter navigation and reading-optimized layout. Ideal for tutorials and courses.</p>
44
+ <span class="mode-card__cta">Read Book</span>
45
+ </a>
46
+
47
+ <a href="{{ get_url(path='@/blog/_index.md') }}" class="mode-card mode-card--blog">
48
+ <div class="mode-card__icon">
49
+ <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
50
+ <path d="M12 19l7-7 3 3-7 7-3-3z"/>
51
+ <path d="M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z"/>
52
+ <path d="M2 2l7.586 7.586"/>
53
+ <circle cx="11" cy="11" r="2"/>
54
+ </svg>
55
+ </div>
56
+ <h3 class="mode-card__title">Blog</h3>
57
+ <p class="mode-card__description">Posts, articles, and landing pages. Features hero sections, card layouts, and pagination.</p>
58
+ <span class="mode-card__cta">View Blog</span>
59
+ </a>
60
+ </div>
61
+ </div>
62
+ </section>
63
+
64
+ <section class="features">
65
+ <div class="container">
66
+ <h2 class="section__title">Features</h2>
67
+
68
+ <div class="feature-grid">
69
+ <div class="feature">
70
+ <div class="feature__icon">
71
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
72
+ <circle cx="12" cy="12" r="4"/>
73
+ <path d="M12 2v2"/>
74
+ <path d="M12 20v2"/>
75
+ <path d="m4.93 4.93 1.41 1.41"/>
76
+ <path d="m17.66 17.66 1.41 1.41"/>
77
+ <path d="M2 12h2"/>
78
+ <path d="M20 12h2"/>
79
+ <path d="m6.34 17.66-1.41 1.41"/>
80
+ <path d="m19.07 4.93-1.41 1.41"/>
81
+ </svg>
82
+ </div>
83
+ <h3 class="feature__title">Catppuccin Colors</h3>
84
+ <p class="feature__description">Beautiful Mocha (dark) and Latte (light) themes with smooth transitions.</p>
85
+ </div>
86
+
87
+ <div class="feature">
88
+ <div class="feature__icon">
89
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
90
+ <polyline points="4 7 4 4 20 4 20 7"/>
91
+ <line x1="9" x2="15" y1="20" y2="20"/>
92
+ <line x1="12" x2="12" y1="4" y2="20"/>
93
+ </svg>
94
+ </div>
95
+ <h3 class="feature__title">Geist Typography</h3>
96
+ <p class="feature__description">Vercel's beautiful Geist font family for optimal readability.</p>
97
+ </div>
98
+
99
+ <div class="feature">
100
+ <div class="feature__icon">
101
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
102
+ <circle cx="11" cy="11" r="8"/>
103
+ <path d="m21 21-4.3-4.3"/>
104
+ </svg>
105
+ </div>
106
+ <h3 class="feature__title">Full-Text Search</h3>
107
+ <p class="feature__description">Elasticlunr-powered search with keyboard shortcuts.</p>
108
+ </div>
109
+
110
+ <div class="feature">
111
+ <div class="feature__icon">
112
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
113
+ <rect width="18" height="18" x="3" y="3" rx="2"/>
114
+ <path d="m9 12 2 2 4-4"/>
115
+ </svg>
116
+ </div>
117
+ <h3 class="feature__title">Accessible</h3>
118
+ <p class="feature__description">WCAG-compliant with keyboard navigation and screen reader support.</p>
119
+ </div>
120
+
121
+ <div class="feature">
122
+ <div class="feature__icon">
123
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
124
+ <path d="M6 18h8"/>
125
+ <path d="M3 22h18"/>
126
+ <path d="M14 22a7 7 0 1 0 0-14h-1"/>
127
+ <path d="M9 14h2"/>
128
+ <path d="M9 12a2 2 0 0 1-2-2V6h6v4a2 2 0 0 1-2 2Z"/>
129
+ <path d="M12 6V3a1 1 0 0 0-1-1H9a1 1 0 0 0-1 1v3"/>
130
+ </svg>
131
+ </div>
132
+ <h3 class="feature__title">Nintendo UX</h3>
133
+ <p class="feature__description">Whimsical animations and delightful interactions inspired by Nintendo.</p>
134
+ </div>
135
+
136
+ <div class="feature">
137
+ <div class="feature__icon">
138
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
139
+ <polyline points="6 9 6 2 18 2 18 9"/>
140
+ <path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/>
141
+ <rect width="12" height="8" x="6" y="14"/>
142
+ </svg>
143
+ </div>
144
+ <h3 class="feature__title">Print Ready</h3>
145
+ <p class="feature__description">Print documentation or books as a single, beautifully formatted document.</p>
146
+ </div>
147
+ </div>
148
+ </div>
149
+ </section>
150
+
151
+ <section class="cta">
152
+ <div class="container">
153
+ <h2 class="cta__title">Get Started</h2>
154
+ <p class="cta__description">Add Tanuki to your Zola project in seconds.</p>
155
+ <div class="cta__code">
156
+ <code>git submodule add https://github.com/raskell-io/tanuki themes/tanuki</code>
157
+ </div>
158
+ <div class="cta__actions">
159
+ <a href="https://github.com/raskell-io/tanuki" class="btn btn--primary btn--lg" target="_blank" rel="noopener">
160
+ View on GitHub
161
+ </a>
162
+ <a href="{{ get_url(path='@/docs/_index.md') }}" class="btn btn--secondary btn--lg">
163
+ Read the Docs
164
+ </a>
165
+ </div>
166
+ </div>
167
+ </section>
168
+ {% endblock %}
@@ -0,0 +1,128 @@
1
+ {# =============================================================================
2
+ Macros: Navigation
3
+ Reusable navigation components
4
+ ============================================================================= #}
5
+
6
+ {# -----------------------------------------------------------------------------
7
+ Nav Links - Header navigation links
8
+ Usage: {{ macros::nav_links(nav=config.extra.nav, current_path=current_path) }}
9
+ ----------------------------------------------------------------------------- #}
10
+ {% macro nav_links(nav, current_path="") %}
11
+ {% if nav %}
12
+ {% for link in nav %}
13
+ {% if link.children %}
14
+ <div class="nav-dropdown">
15
+ <button class="nav-dropdown__trigger" type="button" aria-expanded="false" aria-haspopup="true">
16
+ {{ link.name }}
17
+ <svg class="nav-dropdown__chevron" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>
18
+ </button>
19
+ <div class="nav-dropdown__menu" role="menu">
20
+ {% for child in link.children %}
21
+ <a href="{{ child.url | safe }}" role="menuitem"{% if child.external %} target="_blank" rel="noopener noreferrer"{% endif %}>
22
+ {{ child.name }}
23
+ </a>
24
+ {% endfor %}
25
+ </div>
26
+ </div>
27
+ {% else %}
28
+ <a href="{{ link.url | safe }}" class="header__link {% if current_path == link.url %}active{% endif %}"{% if link.external %} target="_blank" rel="noopener noreferrer"{% endif %}>
29
+ {{ link.name }}
30
+ </a>
31
+ {% endif %}
32
+ {% endfor %}
33
+ {% endif %}
34
+ {% endmacro %}
35
+
36
+ {# -----------------------------------------------------------------------------
37
+ Sidebar Nav - Hierarchical sidebar navigation
38
+ Usage: {{ macros::sidebar_nav(pages=section.pages, current_path=current_path) }}
39
+ ----------------------------------------------------------------------------- #}
40
+ {% macro sidebar_nav(pages, current_path="") %}
41
+ <nav class="sidebar__nav" role="navigation" aria-label="Table of contents">
42
+ <ul class="nav-list">
43
+ {% for page in pages %}
44
+ <li class="nav-item">
45
+ <a href="{{ page.permalink | safe }}" {% if current_path == page.path %}aria-current="page"{% endif %}>
46
+ {{ page.title }}
47
+ </a>
48
+ </li>
49
+ {% endfor %}
50
+ </ul>
51
+ </nav>
52
+ {% endmacro %}
53
+
54
+ {# -----------------------------------------------------------------------------
55
+ Breadcrumbs - Breadcrumb navigation
56
+ Usage: {{ macros::breadcrumbs(items=[{name: "Home", url: "/"}, {name: "Blog", url: "/blog/"}]) }}
57
+ ----------------------------------------------------------------------------- #}
58
+ {% macro breadcrumbs(items) %}
59
+ <nav class="breadcrumbs" aria-label="Breadcrumb">
60
+ <ol>
61
+ {% for item in items %}
62
+ <li>
63
+ {% if loop.last %}
64
+ <span aria-current="page">{{ item.name }}</span>
65
+ {% else %}
66
+ <a href="{{ item.url | safe }}">{{ item.name }}</a>
67
+ <span class="separator" aria-hidden="true">/</span>
68
+ {% endif %}
69
+ </li>
70
+ {% endfor %}
71
+ </ol>
72
+ </nav>
73
+ {% endmacro %}
74
+
75
+ {# -----------------------------------------------------------------------------
76
+ Table of Contents - Page TOC from headers
77
+ Usage: {{ macros::toc(toc=page.toc) }}
78
+ ----------------------------------------------------------------------------- #}
79
+ {% macro toc(toc, title="On this page") %}
80
+ {% if toc %}
81
+ <nav class="toc" aria-label="Table of contents">
82
+ {% if title %}
83
+ <h2 class="toc__title">{{ title }}</h2>
84
+ {% endif %}
85
+ <ul class="toc__list">
86
+ {% for h in toc %}
87
+ <li class="toc__item toc__item--h{{ h.level }}">
88
+ <a href="#{{ h.id }}">{{ h.title }}</a>
89
+ {% if h.children %}
90
+ <ul class="toc__list toc__list--nested">
91
+ {% for child in h.children %}
92
+ <li class="toc__item">
93
+ <a href="#{{ child.id }}">{{ child.title }}</a>
94
+ </li>
95
+ {% endfor %}
96
+ </ul>
97
+ {% endif %}
98
+ </li>
99
+ {% endfor %}
100
+ </ul>
101
+ </nav>
102
+ {% endif %}
103
+ {% endmacro %}
104
+
105
+ {# -----------------------------------------------------------------------------
106
+ Prev/Next Navigation - For sequential content (books, docs)
107
+ Usage: {{ macros::prev_next(prev=page.lower, next=page.higher) }}
108
+ ----------------------------------------------------------------------------- #}
109
+ {% macro prev_next(prev, next) %}
110
+ {% if prev or next %}
111
+ <nav class="prev-next" aria-label="Previous and next pages">
112
+ {% if prev %}
113
+ <a href="{{ prev.permalink | safe }}" class="prev-next__link prev-next__link--prev">
114
+ <span class="prev-next__label">Previous</span>
115
+ <span class="prev-next__title">{{ prev.title }}</span>
116
+ </a>
117
+ {% else %}
118
+ <div class="prev-next__spacer"></div>
119
+ {% endif %}
120
+ {% if next %}
121
+ <a href="{{ next.permalink | safe }}" class="prev-next__link prev-next__link--next">
122
+ <span class="prev-next__label">Next</span>
123
+ <span class="prev-next__title">{{ next.title }}</span>
124
+ </a>
125
+ {% endif %}
126
+ </nav>
127
+ {% endif %}
128
+ {% endmacro %}
@@ -0,0 +1,101 @@
1
+ {# =============================================================================
2
+ Macros: Posts
3
+ Reusable components for displaying posts/articles
4
+ ============================================================================= #}
5
+
6
+ {# -----------------------------------------------------------------------------
7
+ Post Row - Simple date | title format
8
+ Usage: {{ macros::post_row(page=page) }}
9
+ ----------------------------------------------------------------------------- #}
10
+ {% macro post_row(page, date_format="%b %d") %}
11
+ <article class="post">
12
+ <a href="{{ page.permalink | safe }}">
13
+ <div class="post-row">
14
+ {% if page.date %}
15
+ <time datetime="{{ page.date }}">{{ page.date | date(format=date_format) }}</time>
16
+ {% endif %}
17
+ <h3>{{ page.title }}</h3>
18
+ </div>
19
+ </a>
20
+ </article>
21
+ {% endmacro %}
22
+
23
+ {# -----------------------------------------------------------------------------
24
+ Post Card - With description and meta
25
+ Usage: {{ macros::post_card(page=page, show_description=true, show_tags=true) }}
26
+ ----------------------------------------------------------------------------- #}
27
+ {% macro post_card(page, show_description=true, show_tags=true, max_tags=3) %}
28
+ <article class="blog-card">
29
+ <div class="blog-card__content">
30
+ <h2 class="blog-card__title">
31
+ <a href="{{ page.permalink | safe }}">{{ page.title }}</a>
32
+ </h2>
33
+ {% if show_description and page.description %}
34
+ <p class="blog-card__description">{{ page.description }}</p>
35
+ {% endif %}
36
+ <div class="blog-card__meta">
37
+ {% if page.date %}
38
+ <time datetime="{{ page.date }}">{{ page.date | date(format="%B %d, %Y") }}</time>
39
+ {% endif %}
40
+ {% if show_tags and page.taxonomies.tags %}
41
+ <div class="blog-card__tags">
42
+ {% for tag in page.taxonomies.tags | slice(end=max_tags) %}
43
+ <a href="{{ get_taxonomy_url(kind='tags', name=tag) | safe }}" class="tag">{{ tag }}</a>
44
+ {% endfor %}
45
+ </div>
46
+ {% endif %}
47
+ </div>
48
+ </div>
49
+ </article>
50
+ {% endmacro %}
51
+
52
+ {# -----------------------------------------------------------------------------
53
+ Post List - List of post rows
54
+ Usage: {{ macros::post_list(pages=section.pages, limit=6) }}
55
+ ----------------------------------------------------------------------------- #}
56
+ {% macro post_list(pages, limit=10, date_format="%b %d") %}
57
+ <div class="posts">
58
+ {% for page in pages | slice(end=limit) %}
59
+ {{ self::post_row(page=page, date_format=date_format) }}
60
+ {% endfor %}
61
+ </div>
62
+ {% endmacro %}
63
+
64
+ {# -----------------------------------------------------------------------------
65
+ Post Grid - Grid of post cards
66
+ Usage: {{ macros::post_grid(pages=section.pages, limit=6) }}
67
+ ----------------------------------------------------------------------------- #}
68
+ {% macro post_grid(pages, limit=10, show_description=true, show_tags=true) %}
69
+ <div class="blog-posts">
70
+ {% for page in pages | slice(end=limit) %}
71
+ {{ self::post_card(page=page, show_description=show_description, show_tags=show_tags) }}
72
+ {% endfor %}
73
+ </div>
74
+ {% endmacro %}
75
+
76
+ {# -----------------------------------------------------------------------------
77
+ Post Meta - Date, reading time, tags
78
+ Usage: {{ macros::post_meta(page=page) }}
79
+ ----------------------------------------------------------------------------- #}
80
+ {% macro post_meta(page, show_reading_time=true, show_tags=true) %}
81
+ <div class="post-meta">
82
+ <div class="meta-line">
83
+ {% if page.date %}
84
+ <time datetime="{{ page.date }}">{{ page.date | date(format="%B %d, %Y") }}</time>
85
+ {% endif %}
86
+ {% if show_reading_time and page.reading_time %}
87
+ <span class="separator">&middot;</span>
88
+ <span class="reading-time">{{ page.reading_time }} min read</span>
89
+ {% endif %}
90
+ </div>
91
+ {% if show_tags and page.taxonomies.tags %}
92
+ <div class="article-taxonomies">
93
+ <div class="tags">
94
+ {% for tag in page.taxonomies.tags %}
95
+ <a href="{{ get_taxonomy_url(kind='tags', name=tag) | safe }}" class="tag">{{ tag }}</a>
96
+ {% endfor %}
97
+ </div>
98
+ </div>
99
+ {% endif %}
100
+ </div>
101
+ {% endmacro %}