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.
- package/.env.example +20 -0
- package/.github/workflows/ci.yml +70 -0
- package/.github/workflows/publish.yml +250 -0
- package/.gitmodules +3 -0
- package/Cargo.lock +3584 -0
- package/Cargo.toml +97 -0
- package/crates/enact/Cargo.toml +27 -0
- package/crates/enact/src/lib.rs +60 -0
- package/crates/enact-a2a/Cargo.toml +25 -0
- package/crates/enact-a2a/src/lib.rs +411 -0
- package/crates/enact-channels/Cargo.toml +64 -0
- package/crates/enact-channels/examples/README.md +80 -0
- package/crates/enact-channels/examples/channel_bot.rs +169 -0
- package/crates/enact-channels/examples/telegram-echo.rs +34 -0
- package/crates/enact-channels/examples/whatsapp-echo.rs +142 -0
- package/crates/enact-channels/src/config.rs +213 -0
- package/crates/enact-channels/src/lib.rs +25 -0
- package/crates/enact-channels/src/runtime.rs +237 -0
- package/crates/enact-channels/src/security/mod.rs +5 -0
- package/crates/enact-channels/src/security/pairing.rs +205 -0
- package/crates/enact-channels/src/teams.rs +601 -0
- package/crates/enact-channels/src/telegram.rs +2833 -0
- package/crates/enact-channels/src/traits.rs +200 -0
- package/crates/enact-channels/src/webhook.rs +262 -0
- package/crates/enact-channels/src/whatsapp.rs +310 -0
- package/crates/enact-cli/Cargo.toml +40 -0
- package/crates/enact-cli/src/commands/doctor.rs +62 -0
- package/crates/enact-cli/src/commands/mod.rs +3 -0
- package/crates/enact-cli/src/commands/run.rs +69 -0
- package/crates/enact-cli/src/commands/serve.rs +81 -0
- package/crates/enact-cli/src/config.rs +2 -0
- package/crates/enact-cli/src/main.rs +79 -0
- package/crates/enact-config/Cargo.toml +36 -0
- package/crates/enact-config/ENV_VAR_MAPPING.md +135 -0
- package/crates/enact-config/QUICK_REFERENCE.md +92 -0
- package/crates/enact-config/README.md +107 -0
- package/crates/enact-config/TESTING.md +161 -0
- package/crates/enact-config/examples/test-env-vars.rs +100 -0
- package/crates/enact-config/src/config.rs +399 -0
- package/crates/enact-config/src/encrypted_store.rs +211 -0
- package/crates/enact-config/src/lib.rs +298 -0
- package/crates/enact-config/src/secrets.rs +149 -0
- package/crates/enact-config/src/sync.rs +260 -0
- package/crates/enact-config/test-env-vars.sh +34 -0
- package/crates/enact-config/tests/README.md +99 -0
- package/crates/enact-config/tests/config_integration_test.rs +202 -0
- package/crates/enact-config/tests/security_test.rs +140 -0
- package/crates/enact-context/Cargo.toml +41 -0
- package/crates/enact-context/src/budget.rs +314 -0
- package/crates/enact-context/src/calibrator.rs +535 -0
- package/crates/enact-context/src/compactor.rs +392 -0
- package/crates/enact-context/src/condenser.rs +826 -0
- package/crates/enact-context/src/lib.rs +94 -0
- package/crates/enact-context/src/segment.rs +238 -0
- package/crates/enact-context/src/step_context.rs +645 -0
- package/crates/enact-context/src/token_counter.rs +148 -0
- package/crates/enact-context/src/window.rs +372 -0
- package/crates/enact-core/Cargo.toml +42 -0
- package/crates/enact-core/README.md +98 -0
- package/crates/enact-core/src/background/executor.rs +524 -0
- package/crates/enact-core/src/background/mod.rs +48 -0
- package/crates/enact-core/src/background/target_binding.rs +390 -0
- package/crates/enact-core/src/background/trigger.rs +511 -0
- package/crates/enact-core/src/callable/callable.rs +152 -0
- package/crates/enact-core/src/callable/composite.rs +817 -0
- package/crates/enact-core/src/callable/graph.rs +104 -0
- package/crates/enact-core/src/callable/llm.rs +211 -0
- package/crates/enact-core/src/callable/mod.rs +64 -0
- package/crates/enact-core/src/callable/registry.rs +206 -0
- package/crates/enact-core/src/context/execution_context.rs +757 -0
- package/crates/enact-core/src/context/invocation.rs +99 -0
- package/crates/enact-core/src/context/mod.rs +50 -0
- package/crates/enact-core/src/context/tenant.rs +175 -0
- package/crates/enact-core/src/context/trace.rs +127 -0
- package/crates/enact-core/src/flow/conditional.rs +293 -0
- package/crates/enact-core/src/flow/mod.rs +43 -0
- package/crates/enact-core/src/flow/parallel.rs +437 -0
- package/crates/enact-core/src/flow/repeat.rs +534 -0
- package/crates/enact-core/src/flow/sequential.rs +248 -0
- package/crates/enact-core/src/graph/checkpoint.rs +79 -0
- package/crates/enact-core/src/graph/checkpoint_store.rs +76 -0
- package/crates/enact-core/src/graph/compiled.rs +189 -0
- package/crates/enact-core/src/graph/edge.rs +59 -0
- package/crates/enact-core/src/graph/graph_schema.rs +218 -0
- package/crates/enact-core/src/graph/loader.rs +155 -0
- package/crates/enact-core/src/graph/mod.rs +18 -0
- package/crates/enact-core/src/graph/node/function.rs +49 -0
- package/crates/enact-core/src/graph/node/mod.rs +48 -0
- package/crates/enact-core/src/graph/schema.rs +62 -0
- package/crates/enact-core/src/inbox/message.rs +405 -0
- package/crates/enact-core/src/inbox/mod.rs +31 -0
- package/crates/enact-core/src/inbox/store.rs +355 -0
- package/crates/enact-core/src/kernel/artifact/filesystem.rs +546 -0
- package/crates/enact-core/src/kernel/artifact/metadata.rs +283 -0
- package/crates/enact-core/src/kernel/artifact/mod.rs +27 -0
- package/crates/enact-core/src/kernel/artifact/store.rs +427 -0
- package/crates/enact-core/src/kernel/enforcement.rs +1315 -0
- package/crates/enact-core/src/kernel/error.rs +1200 -0
- package/crates/enact-core/src/kernel/event.rs +1394 -0
- package/crates/enact-core/src/kernel/execution_model.rs +831 -0
- package/crates/enact-core/src/kernel/execution_state.rs +189 -0
- package/crates/enact-core/src/kernel/execution_strategy.rs +117 -0
- package/crates/enact-core/src/kernel/ids.rs +2086 -0
- package/crates/enact-core/src/kernel/interrupt.rs +125 -0
- package/crates/enact-core/src/kernel/kernel.rs +1283 -0
- package/crates/enact-core/src/kernel/mod.rs +205 -0
- package/crates/enact-core/src/kernel/persistence/event_store.rs +270 -0
- package/crates/enact-core/src/kernel/persistence/message_store.rs +908 -0
- package/crates/enact-core/src/kernel/persistence/mod.rs +102 -0
- package/crates/enact-core/src/kernel/persistence/state_store.rs +228 -0
- package/crates/enact-core/src/kernel/persistence/vector_store.rs +299 -0
- package/crates/enact-core/src/kernel/reducer.rs +808 -0
- package/crates/enact-core/src/kernel/replay.rs +153 -0
- package/crates/enact-core/src/lib.rs +413 -0
- package/crates/enact-core/src/memory/episodic.rs +0 -0
- package/crates/enact-core/src/memory/mod.rs +6 -0
- package/crates/enact-core/src/memory/semantic.rs +0 -0
- package/crates/enact-core/src/memory/trait.rs +0 -0
- package/crates/enact-core/src/memory/vector_db.rs +0 -0
- package/crates/enact-core/src/memory/working.rs +0 -0
- package/crates/enact-core/src/policy/execution_policy.rs +292 -0
- package/crates/enact-core/src/policy/filters.rs +458 -0
- package/crates/enact-core/src/policy/input_processor.rs +407 -0
- package/crates/enact-core/src/policy/long_running.rs +134 -0
- package/crates/enact-core/src/policy/mod.rs +193 -0
- package/crates/enact-core/src/policy/pii_input.rs +274 -0
- package/crates/enact-core/src/policy/tenant_policy.rs +453 -0
- package/crates/enact-core/src/policy/tool_policy.rs +407 -0
- package/crates/enact-core/src/providers/mod.rs +63 -0
- package/crates/enact-core/src/providers/trait.rs +292 -0
- package/crates/enact-core/src/runner/callbacks.rs +6 -0
- package/crates/enact-core/src/runner/execution_runner.rs +476 -0
- package/crates/enact-core/src/runner/loop.rs +117 -0
- package/crates/enact-core/src/runner/mod.rs +58 -0
- package/crates/enact-core/src/runner/protected_runner.rs +280 -0
- package/crates/enact-core/src/signal/inmemory.rs +231 -0
- package/crates/enact-core/src/signal/mod.rs +108 -0
- package/crates/enact-core/src/streaming/event_logger.rs +195 -0
- package/crates/enact-core/src/streaming/event_stream.rs +1423 -0
- package/crates/enact-core/src/streaming/mod.rs +108 -0
- package/crates/enact-core/src/streaming/pause_cancel.rs +0 -0
- package/crates/enact-core/src/streaming/protected_emitter.rs +173 -0
- package/crates/enact-core/src/streaming/protection/context.rs +136 -0
- package/crates/enact-core/src/streaming/protection/encryption.rs +289 -0
- package/crates/enact-core/src/streaming/protection/mod.rs +43 -0
- package/crates/enact-core/src/streaming/protection/pii_protection.rs +243 -0
- package/crates/enact-core/src/streaming/protection/processor.rs +166 -0
- package/crates/enact-core/src/streaming/sse.rs +0 -0
- package/crates/enact-core/src/telemetry/exporter.rs +0 -0
- package/crates/enact-core/src/telemetry/init.rs +0 -0
- package/crates/enact-core/src/telemetry/mod.rs +49 -0
- package/crates/enact-core/src/telemetry/spans.rs +245 -0
- package/crates/enact-core/src/tool/agent_tool.rs +177 -0
- package/crates/enact-core/src/tool/browser/mod.rs +0 -0
- package/crates/enact-core/src/tool/browser/webdriver.rs +0 -0
- package/crates/enact-core/src/tool/cost.rs +247 -0
- package/crates/enact-core/src/tool/discovery.rs +0 -0
- package/crates/enact-core/src/tool/dispatcher.rs +347 -0
- package/crates/enact-core/src/tool/filesystem.rs +231 -0
- package/crates/enact-core/src/tool/function.rs +99 -0
- package/crates/enact-core/src/tool/git.rs +162 -0
- package/crates/enact-core/src/tool/http.rs +214 -0
- package/crates/enact-core/src/tool/mcp/client.rs +0 -0
- package/crates/enact-core/src/tool/mcp/mod.rs +0 -0
- package/crates/enact-core/src/tool/mod.rs +51 -0
- package/crates/enact-core/src/tool/reasoning/debugging.rs +0 -0
- package/crates/enact-core/src/tool/reasoning/mcts.rs +0 -0
- package/crates/enact-core/src/tool/reasoning/mod.rs +0 -0
- package/crates/enact-core/src/tool/reasoning/sequential.rs +0 -0
- package/crates/enact-core/src/tool/sandbox/dagger.rs +0 -0
- package/crates/enact-core/src/tool/sandbox/mod.rs +0 -0
- package/crates/enact-core/src/tool/shell.rs +147 -0
- package/crates/enact-core/src/tool/trait.rs +33 -0
- package/crates/enact-core/src/tool/web_search.rs +277 -0
- package/crates/enact-core/src/util/config.rs +0 -0
- package/crates/enact-core/src/util/errors.rs +0 -0
- package/crates/enact-core/src/util/mod.rs +6 -0
- package/crates/enact-core/tests/airgapped_e2e_test.rs +291 -0
- package/crates/enact-core/tests/e2e_agentic_loop.rs +119 -0
- package/crates/enact-core/tests/e2e_test.rs +259 -0
- package/crates/enact-core/tests/graph_test.rs +130 -0
- package/crates/enact-core/tests/stream_event_id_validation.rs +435 -0
- package/crates/enact-cron/Cargo.toml +28 -0
- package/crates/enact-cron/src/lib.rs +44 -0
- package/crates/enact-cron/src/schedule.rs +156 -0
- package/crates/enact-cron/src/store.rs +589 -0
- package/crates/enact-cron/src/types.rs +148 -0
- package/crates/enact-gateway/Cargo.toml +31 -0
- package/crates/enact-gateway/README.md +30 -0
- package/crates/enact-gateway/examples/whatsapp-gateway-runner-mock.rs +59 -0
- package/crates/enact-gateway/examples/whatsapp-gateway.rs +42 -0
- package/crates/enact-gateway/src/lib.rs +582 -0
- package/crates/enact-mcp/Cargo.toml +24 -0
- package/crates/enact-mcp/src/lib.rs +178 -0
- package/crates/enact-memory/Cargo.toml +25 -0
- package/crates/enact-memory/src/backend.rs +20 -0
- package/crates/enact-memory/src/chunker.rs +230 -0
- package/crates/enact-memory/src/embeddings.rs +221 -0
- package/crates/enact-memory/src/lib.rs +67 -0
- package/crates/enact-memory/src/markdown.rs +127 -0
- package/crates/enact-memory/src/none.rs +61 -0
- package/crates/enact-memory/src/sqlite.rs +276 -0
- package/crates/enact-memory/src/traits.rs +65 -0
- package/crates/enact-memory/src/vector.rs +198 -0
- package/crates/enact-oauth/Cargo.toml +27 -0
- package/crates/enact-oauth/src/lib.rs +584 -0
- package/crates/enact-observability/Cargo.toml +22 -0
- package/crates/enact-observability/src/lib.rs +197 -0
- package/crates/enact-providers/Cargo.toml +33 -0
- package/crates/enact-providers/examples/hello-agent.rs +33 -0
- package/crates/enact-providers/src/anthropic.rs +182 -0
- package/crates/enact-providers/src/azure.rs +96 -0
- package/crates/enact-providers/src/bridge.rs +221 -0
- package/crates/enact-providers/src/gemini.rs +227 -0
- package/crates/enact-providers/src/http.rs +78 -0
- package/crates/enact-providers/src/lib.rs +53 -0
- package/crates/enact-providers/src/openai_compatible.rs +167 -0
- package/crates/enact-providers/src/openrouter.rs +33 -0
- package/crates/enact-runner/Cargo.toml +24 -0
- package/crates/enact-runner/README.md +76 -0
- package/crates/enact-runner/src/compaction.rs +225 -0
- package/crates/enact-runner/src/config.rs +118 -0
- package/crates/enact-runner/src/lib.rs +63 -0
- package/crates/enact-runner/src/loop_driver.rs +414 -0
- package/crates/enact-runner/src/parser.rs +421 -0
- package/crates/enact-runner/src/retry.rs +262 -0
- package/crates/enact-runner/tests/integration.rs +278 -0
- package/crates/enact-security/Cargo.toml +22 -0
- package/crates/enact-security/src/audit.rs +375 -0
- package/crates/enact-security/src/lib.rs +37 -0
- package/crates/enact-security/src/policy.rs +406 -0
- package/crates/enact-skills/Cargo.toml +25 -0
- package/crates/enact-skills/src/lib.rs +506 -0
- package/crates/enact-tools/Cargo.toml +22 -0
- package/crates/enact-tools/src/file_read.rs +166 -0
- package/crates/enact-tools/src/file_write.rs +216 -0
- package/crates/enact-tools/src/git_operations.rs +513 -0
- package/crates/enact-tools/src/http_request.rs +417 -0
- package/crates/enact-tools/src/lib.rs +104 -0
- package/crates/enact-tools/src/security.rs +227 -0
- package/crates/enact-tools/src/shell.rs +191 -0
- package/crates/enact-tools/src/traits.rs +159 -0
- package/docs/Makefile +74 -0
- package/docs/config.toml +62 -0
- package/docs/content/_index.md +174 -0
- package/docs/content/a2a/_index.md +431 -0
- package/docs/content/api/_index.md +323 -0
- package/docs/content/channels/_index.md +160 -0
- package/docs/content/channels/teams.md +205 -0
- package/docs/content/channels/telegram.md +182 -0
- package/docs/content/channels/webhook.md +423 -0
- package/docs/content/channels/whatsapp.md +240 -0
- package/docs/content/cli/_index.md +261 -0
- package/docs/content/concepts/_index.md +273 -0
- package/docs/content/configuration/_index.md +241 -0
- package/docs/content/cron/_index.md +248 -0
- package/docs/content/developers/_index.md +278 -0
- package/docs/content/getting-started/_index.md +180 -0
- package/docs/content/installation/_index.md +186 -0
- package/docs/content/installation/uninstall.md +101 -0
- package/docs/content/installation/updating.md +120 -0
- package/docs/content/mcp/_index.md +215 -0
- package/docs/content/memory/_index.md +163 -0
- package/docs/content/oauth/_index.md +515 -0
- package/docs/content/providers/_index.md +206 -0
- package/docs/content/roadmap/_index.md +199 -0
- package/docs/content/security/_index.md +219 -0
- package/docs/content/skills/_index.md +228 -0
- package/docs/content/tools/_index.md +485 -0
- package/docs/content/troubleshooting/_index.md +259 -0
- package/docs/content/yaml-schema/_index.md +294 -0
- package/docs/static/giallo-dark.css +91 -0
- package/docs/static/giallo-light.css +91 -0
- package/docs/themes/tanuki/.github/workflows/deploy.yml +44 -0
- package/docs/themes/tanuki/LICENSE +21 -0
- package/docs/themes/tanuki/README.md +166 -0
- package/docs/themes/tanuki/examples/blog/config.toml +58 -0
- package/docs/themes/tanuki/examples/blog/content/_index.md +4 -0
- package/docs/themes/tanuki/examples/blog/content/about.md +33 -0
- package/docs/themes/tanuki/examples/blog/content/blog/_index.md +7 -0
- package/docs/themes/tanuki/examples/blog/content/blog/api-design-best-practices.md +245 -0
- package/docs/themes/tanuki/examples/blog/content/blog/building-accessible-websites.md +147 -0
- package/docs/themes/tanuki/examples/blog/content/blog/css-grid-vs-flexbox.md +165 -0
- package/docs/themes/tanuki/examples/blog/content/blog/customizing-catppuccin-colors.md +137 -0
- package/docs/themes/tanuki/examples/blog/content/blog/dark-mode-best-practices.md +82 -0
- package/docs/themes/tanuki/examples/blog/content/blog/docker-essentials.md +301 -0
- package/docs/themes/tanuki/examples/blog/content/blog/getting-started-with-zola.md +129 -0
- package/docs/themes/tanuki/examples/blog/content/blog/git-workflow-for-content.md +112 -0
- package/docs/themes/tanuki/examples/blog/content/blog/introduction-to-webassembly.md +183 -0
- package/docs/themes/tanuki/examples/blog/content/blog/modern-javascript-features.md +234 -0
- package/docs/themes/tanuki/examples/blog/content/blog/testing-strategies.md +311 -0
- package/docs/themes/tanuki/examples/blog/content/blog/typography-for-developers.md +104 -0
- package/docs/themes/tanuki/examples/blog/content/blog/welcome-to-tanuki.md +67 -0
- package/docs/themes/tanuki/examples/blog/content/blog/why-static-sites.md +85 -0
- package/docs/themes/tanuki/examples/blog/content/projects.md +64 -0
- package/docs/themes/tanuki/examples/book/config.toml +17 -0
- package/docs/themes/tanuki/examples/book/content/_index.md +12 -0
- package/docs/themes/tanuki/examples/book/content/chapter-1.md +90 -0
- package/docs/themes/tanuki/examples/book/content/chapter-2.md +143 -0
- package/docs/themes/tanuki/examples/book/content/chapter-3.md +217 -0
- package/docs/themes/tanuki/examples/book/content/chapter-4.md +224 -0
- package/docs/themes/tanuki/examples/book/content/chapter-5.md +297 -0
- package/docs/themes/tanuki/examples/book/content/print.md +6 -0
- package/docs/themes/tanuki/examples/docs/config.toml +28 -0
- package/docs/themes/tanuki/examples/docs/content/_index.md +20 -0
- package/docs/themes/tanuki/examples/docs/content/components.md +156 -0
- package/docs/themes/tanuki/examples/docs/content/configuration.md +94 -0
- package/docs/themes/tanuki/examples/docs/content/customization.md +202 -0
- package/docs/themes/tanuki/examples/docs/content/deployment.md +204 -0
- package/docs/themes/tanuki/examples/docs/content/installation.md +59 -0
- package/docs/themes/tanuki/examples/docs/content/print.md +6 -0
- package/docs/themes/tanuki/examples/docs/static/img/tanuki-icon.avif +0 -0
- package/docs/themes/tanuki/examples/index.html +2104 -0
- package/docs/themes/tanuki/mise.toml +108 -0
- package/docs/themes/tanuki/sass/base/_catppuccin.scss +164 -0
- package/docs/themes/tanuki/sass/base/_fonts.scss +64 -0
- package/docs/themes/tanuki/sass/base/_reset.scss +152 -0
- package/docs/themes/tanuki/sass/base/_typography.scss +523 -0
- package/docs/themes/tanuki/sass/components/_buttons.scss +209 -0
- package/docs/themes/tanuki/sass/components/_code.scss +457 -0
- package/docs/themes/tanuki/sass/components/_landing.scss +633 -0
- package/docs/themes/tanuki/sass/components/_layout.scss +294 -0
- package/docs/themes/tanuki/sass/components/_navigation.scss +1200 -0
- package/docs/themes/tanuki/sass/components/_print.scss +237 -0
- package/docs/themes/tanuki/sass/components/_search.scss +224 -0
- package/docs/themes/tanuki/sass/components/_sidebar.scss +473 -0
- package/docs/themes/tanuki/sass/components/_theme-toggle.scss +186 -0
- package/docs/themes/tanuki/sass/modes/_blog.scss +366 -0
- package/docs/themes/tanuki/sass/modes/_product.scss +875 -0
- package/docs/themes/tanuki/sass/modes/_raskell.scss +1696 -0
- package/docs/themes/tanuki/sass/patterns/_buttons.scss +183 -0
- package/docs/themes/tanuki/sass/patterns/_cards.scss +144 -0
- package/docs/themes/tanuki/sass/patterns/_index.scss +9 -0
- package/docs/themes/tanuki/sass/patterns/_lists.scss +259 -0
- package/docs/themes/tanuki/sass/patterns/_sections.scss +243 -0
- package/docs/themes/tanuki/sass/style.scss +47 -0
- package/docs/themes/tanuki/sass/tokens/_colors.scss +139 -0
- package/docs/themes/tanuki/sass/tokens/_spacing.scss +100 -0
- package/docs/themes/tanuki/sass/tokens/_typography.scss +186 -0
- package/docs/themes/tanuki/screenshot.png +0 -0
- package/docs/themes/tanuki/sentinel.kdl +59 -0
- package/docs/themes/tanuki/static/elasticlunr.min.js +10 -0
- package/docs/themes/tanuki/static/fonts/GEIST-LICENSE.txt +92 -0
- package/docs/themes/tanuki/static/fonts/Geist-Variable.woff2 +0 -0
- package/docs/themes/tanuki/static/fonts/GeistMono-Variable.woff2 +0 -0
- package/docs/themes/tanuki/static/img/tanuki-icon.avif +0 -0
- package/docs/themes/tanuki/static/img/tanuki-icon.png +0 -0
- package/docs/themes/tanuki/static/js/anchors.js +18 -0
- package/docs/themes/tanuki/static/js/app.js +274 -0
- package/docs/themes/tanuki/static/js/code.js +394 -0
- package/docs/themes/tanuki/static/js/navigation.js +778 -0
- package/docs/themes/tanuki/static/js/scroll-to-top.js +33 -0
- package/docs/themes/tanuki/static/js/search-raskell.js +240 -0
- package/docs/themes/tanuki/static/js/search.js +215 -0
- package/docs/themes/tanuki/static/js/theme.js +169 -0
- package/docs/themes/tanuki/static/syntax-dark.css +151 -0
- package/docs/themes/tanuki/static/syntax-light.css +151 -0
- package/docs/themes/tanuki/static/wasm/sentinel_playground_wasm.js +486 -0
- package/docs/themes/tanuki/static/wasm/sentinel_playground_wasm_bg.wasm +0 -0
- package/docs/themes/tanuki/templates/404.html +52 -0
- package/docs/themes/tanuki/templates/base.html +428 -0
- package/docs/themes/tanuki/templates/blog.html +66 -0
- package/docs/themes/tanuki/templates/home.html +108 -0
- package/docs/themes/tanuki/templates/index.html +178 -0
- package/docs/themes/tanuki/templates/landing.html +168 -0
- package/docs/themes/tanuki/templates/macros/nav.html +128 -0
- package/docs/themes/tanuki/templates/macros/posts.html +101 -0
- package/docs/themes/tanuki/templates/macros/ui.html +159 -0
- package/docs/themes/tanuki/templates/page.html +135 -0
- package/docs/themes/tanuki/templates/partials/footer.html +38 -0
- package/docs/themes/tanuki/templates/partials/header.html +366 -0
- package/docs/themes/tanuki/templates/partials/nav-buttons.html +55 -0
- package/docs/themes/tanuki/templates/partials/nav-overlay.html +81 -0
- package/docs/themes/tanuki/templates/partials/page-toc-panel.html +43 -0
- package/docs/themes/tanuki/templates/partials/search.html +52 -0
- package/docs/themes/tanuki/templates/partials/sidebar.html +107 -0
- package/docs/themes/tanuki/templates/partials/theme-toggle.html +35 -0
- package/docs/themes/tanuki/templates/partials/toc-overlay.html +146 -0
- package/docs/themes/tanuki/templates/partials/version-picker.html +38 -0
- package/docs/themes/tanuki/templates/print.html +244 -0
- package/docs/themes/tanuki/templates/section.html +186 -0
- package/docs/themes/tanuki/templates/taxonomy_list.html +18 -0
- package/docs/themes/tanuki/templates/taxonomy_single.html +31 -0
- package/docs/themes/tanuki/theme.toml +58 -0
- package/examples/hello-agent.rs +55 -0
- package/package.json +36 -0
- package/proto/config.proto +60 -0
- package/proto/events.proto +0 -0
- package/proto/runtime.proto +215 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
+++
|
|
2
|
+
title = "Chapter 4: Performance"
|
|
3
|
+
description = "Optimizing web application performance."
|
|
4
|
+
weight = 4
|
|
5
|
+
+++
|
|
6
|
+
|
|
7
|
+
# Chapter 4: Performance
|
|
8
|
+
|
|
9
|
+
Performance is a feature. Slow websites lose users, reduce conversions, and rank lower in search results. This chapter covers the key strategies for building fast web applications.
|
|
10
|
+
|
|
11
|
+
## Understanding Performance Metrics
|
|
12
|
+
|
|
13
|
+
Modern performance measurement focuses on user-centric metrics:
|
|
14
|
+
|
|
15
|
+
| Metric | What It Measures | Target |
|
|
16
|
+
|--------|------------------|--------|
|
|
17
|
+
| **LCP** (Largest Contentful Paint) | Loading performance | < 2.5s |
|
|
18
|
+
| **FID** (First Input Delay) | Interactivity | < 100ms |
|
|
19
|
+
| **CLS** (Cumulative Layout Shift) | Visual stability | < 0.1 |
|
|
20
|
+
| **TTFB** (Time to First Byte) | Server response | < 200ms |
|
|
21
|
+
| **FCP** (First Contentful Paint) | Initial render | < 1.8s |
|
|
22
|
+
|
|
23
|
+
## Optimizing Loading Performance
|
|
24
|
+
|
|
25
|
+
### Critical Rendering Path
|
|
26
|
+
|
|
27
|
+
The browser must complete several steps before rendering:
|
|
28
|
+
|
|
29
|
+
1. Parse HTML → Build DOM
|
|
30
|
+
2. Parse CSS → Build CSSOM
|
|
31
|
+
3. Combine → Render Tree
|
|
32
|
+
4. Layout → Paint → Composite
|
|
33
|
+
|
|
34
|
+
```html
|
|
35
|
+
<!-- Inline critical CSS -->
|
|
36
|
+
<style>
|
|
37
|
+
/* Only what's needed for above-the-fold content */
|
|
38
|
+
body { font-family: system-ui; }
|
|
39
|
+
.hero { height: 100vh; }
|
|
40
|
+
</style>
|
|
41
|
+
|
|
42
|
+
<!-- Defer non-critical CSS -->
|
|
43
|
+
<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Resource Hints
|
|
47
|
+
|
|
48
|
+
Tell the browser about resources you'll need:
|
|
49
|
+
|
|
50
|
+
```html
|
|
51
|
+
<!-- DNS prefetch for external origins -->
|
|
52
|
+
<link rel="dns-prefetch" href="//api.example.com">
|
|
53
|
+
|
|
54
|
+
<!-- Preconnect for critical third parties -->
|
|
55
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>
|
|
56
|
+
|
|
57
|
+
<!-- Preload critical resources -->
|
|
58
|
+
<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
|
|
59
|
+
|
|
60
|
+
<!-- Prefetch likely next pages -->
|
|
61
|
+
<link rel="prefetch" href="/about">
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Image Optimization
|
|
65
|
+
|
|
66
|
+
Images are often the largest assets on a page.
|
|
67
|
+
|
|
68
|
+
### Modern Formats
|
|
69
|
+
|
|
70
|
+
```html
|
|
71
|
+
<picture>
|
|
72
|
+
<source srcset="image.avif" type="image/avif">
|
|
73
|
+
<source srcset="image.webp" type="image/webp">
|
|
74
|
+
<img src="image.jpg" alt="Description" loading="lazy">
|
|
75
|
+
</picture>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Responsive Images
|
|
79
|
+
|
|
80
|
+
```html
|
|
81
|
+
<img
|
|
82
|
+
srcset="small.jpg 400w, medium.jpg 800w, large.jpg 1200w"
|
|
83
|
+
sizes="(max-width: 600px) 400px, (max-width: 1000px) 800px, 1200px"
|
|
84
|
+
src="medium.jpg"
|
|
85
|
+
alt="Description"
|
|
86
|
+
loading="lazy"
|
|
87
|
+
decoding="async"
|
|
88
|
+
>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## JavaScript Performance
|
|
92
|
+
|
|
93
|
+
### Code Splitting
|
|
94
|
+
|
|
95
|
+
Load only what's needed:
|
|
96
|
+
|
|
97
|
+
```javascript
|
|
98
|
+
// Dynamic imports
|
|
99
|
+
const module = await import('./heavy-module.js');
|
|
100
|
+
|
|
101
|
+
// Route-based splitting (framework example)
|
|
102
|
+
const routes = {
|
|
103
|
+
'/': () => import('./pages/Home.js'),
|
|
104
|
+
'/about': () => import('./pages/About.js'),
|
|
105
|
+
'/dashboard': () => import('./pages/Dashboard.js'),
|
|
106
|
+
};
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Debouncing and Throttling
|
|
110
|
+
|
|
111
|
+
Control how often functions execute:
|
|
112
|
+
|
|
113
|
+
```javascript
|
|
114
|
+
// Debounce: wait until action stops
|
|
115
|
+
function debounce(fn, delay) {
|
|
116
|
+
let timeout;
|
|
117
|
+
return (...args) => {
|
|
118
|
+
clearTimeout(timeout);
|
|
119
|
+
timeout = setTimeout(() => fn(...args), delay);
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Throttle: limit execution rate
|
|
124
|
+
function throttle(fn, limit) {
|
|
125
|
+
let inThrottle;
|
|
126
|
+
return (...args) => {
|
|
127
|
+
if (!inThrottle) {
|
|
128
|
+
fn(...args);
|
|
129
|
+
inThrottle = true;
|
|
130
|
+
setTimeout(() => inThrottle = false, limit);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Usage
|
|
136
|
+
const handleScroll = throttle(() => {
|
|
137
|
+
console.log('Scroll position:', window.scrollY);
|
|
138
|
+
}, 100);
|
|
139
|
+
|
|
140
|
+
window.addEventListener('scroll', handleScroll);
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Web Workers
|
|
144
|
+
|
|
145
|
+
Offload heavy computation:
|
|
146
|
+
|
|
147
|
+
```javascript
|
|
148
|
+
// main.js
|
|
149
|
+
const worker = new Worker('worker.js');
|
|
150
|
+
|
|
151
|
+
worker.postMessage({ data: largeArray });
|
|
152
|
+
|
|
153
|
+
worker.onmessage = (event) => {
|
|
154
|
+
console.log('Result:', event.data);
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
// worker.js
|
|
158
|
+
self.onmessage = (event) => {
|
|
159
|
+
const result = heavyComputation(event.data);
|
|
160
|
+
self.postMessage(result);
|
|
161
|
+
};
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Caching Strategies
|
|
165
|
+
|
|
166
|
+
### Service Worker Caching
|
|
167
|
+
|
|
168
|
+
```javascript
|
|
169
|
+
// sw.js
|
|
170
|
+
const CACHE_NAME = 'v1';
|
|
171
|
+
const ASSETS = [
|
|
172
|
+
'/',
|
|
173
|
+
'/styles.css',
|
|
174
|
+
'/app.js',
|
|
175
|
+
'/offline.html',
|
|
176
|
+
];
|
|
177
|
+
|
|
178
|
+
self.addEventListener('install', (event) => {
|
|
179
|
+
event.waitUntil(
|
|
180
|
+
caches.open(CACHE_NAME)
|
|
181
|
+
.then(cache => cache.addAll(ASSETS))
|
|
182
|
+
);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
self.addEventListener('fetch', (event) => {
|
|
186
|
+
event.respondWith(
|
|
187
|
+
caches.match(event.request)
|
|
188
|
+
.then(response => response || fetch(event.request))
|
|
189
|
+
);
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Measuring Performance
|
|
194
|
+
|
|
195
|
+
Use the Performance API:
|
|
196
|
+
|
|
197
|
+
```javascript
|
|
198
|
+
// Measure custom timings
|
|
199
|
+
performance.mark('start-operation');
|
|
200
|
+
|
|
201
|
+
// ... do work ...
|
|
202
|
+
|
|
203
|
+
performance.mark('end-operation');
|
|
204
|
+
performance.measure('operation', 'start-operation', 'end-operation');
|
|
205
|
+
|
|
206
|
+
// Get measurements
|
|
207
|
+
const measures = performance.getEntriesByName('operation');
|
|
208
|
+
console.log(`Operation took ${measures[0].duration}ms`);
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Summary
|
|
212
|
+
|
|
213
|
+
Performance optimization requires attention to:
|
|
214
|
+
|
|
215
|
+
- Core Web Vitals (LCP, FID, CLS)
|
|
216
|
+
- Critical rendering path optimization
|
|
217
|
+
- Image optimization and modern formats
|
|
218
|
+
- JavaScript code splitting and async loading
|
|
219
|
+
- Effective caching strategies
|
|
220
|
+
- Continuous measurement and monitoring
|
|
221
|
+
|
|
222
|
+
> **Golden Rule**: Measure first, optimize second. Don't guess where performance problems are—use real data from real users.
|
|
223
|
+
|
|
224
|
+
In our final chapter, we'll cover accessibility and inclusive design.
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
+++
|
|
2
|
+
title = "Chapter 5: Accessibility"
|
|
3
|
+
description = "Building inclusive web experiences for everyone."
|
|
4
|
+
weight = 5
|
|
5
|
+
+++
|
|
6
|
+
|
|
7
|
+
# Chapter 5: Accessibility
|
|
8
|
+
|
|
9
|
+
Accessibility (often abbreviated as a11y) ensures that websites work for everyone, including people with disabilities. It's not just about compliance—it's about creating better experiences for all users.
|
|
10
|
+
|
|
11
|
+
## Why Accessibility Matters
|
|
12
|
+
|
|
13
|
+
Consider these statistics:
|
|
14
|
+
|
|
15
|
+
- ~15% of the world's population has some form of disability
|
|
16
|
+
- Many more have temporary or situational impairments
|
|
17
|
+
- Accessible sites often have better SEO and usability for everyone
|
|
18
|
+
|
|
19
|
+
> **Remember**: Accessibility is a spectrum, not a checkbox. Every improvement helps.
|
|
20
|
+
|
|
21
|
+
## Semantic HTML
|
|
22
|
+
|
|
23
|
+
The foundation of accessibility is semantic HTML:
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<!-- Bad: Divs for everything -->
|
|
27
|
+
<div class="header">
|
|
28
|
+
<div class="nav">
|
|
29
|
+
<div class="nav-item">Home</div>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<!-- Good: Semantic elements -->
|
|
34
|
+
<header>
|
|
35
|
+
<nav aria-label="Main navigation">
|
|
36
|
+
<a href="/">Home</a>
|
|
37
|
+
</nav>
|
|
38
|
+
</header>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Key Semantic Elements
|
|
42
|
+
|
|
43
|
+
| Element | Purpose |
|
|
44
|
+
|---------|---------|
|
|
45
|
+
| `<header>` | Introductory content |
|
|
46
|
+
| `<nav>` | Navigation links |
|
|
47
|
+
| `<main>` | Primary content |
|
|
48
|
+
| `<article>` | Self-contained content |
|
|
49
|
+
| `<section>` | Thematic grouping |
|
|
50
|
+
| `<aside>` | Tangentially related content |
|
|
51
|
+
| `<footer>` | Footer content |
|
|
52
|
+
|
|
53
|
+
## ARIA: When HTML Isn't Enough
|
|
54
|
+
|
|
55
|
+
ARIA (Accessible Rich Internet Applications) enhances semantics:
|
|
56
|
+
|
|
57
|
+
```html
|
|
58
|
+
<!-- Role: Define what an element is -->
|
|
59
|
+
<div role="dialog" aria-labelledby="dialog-title">
|
|
60
|
+
<h2 id="dialog-title">Confirm Action</h2>
|
|
61
|
+
<p>Are you sure you want to proceed?</p>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<!-- State: Communicate dynamic changes -->
|
|
65
|
+
<button aria-expanded="false" aria-controls="menu">
|
|
66
|
+
Open Menu
|
|
67
|
+
</button>
|
|
68
|
+
<ul id="menu" hidden>...</ul>
|
|
69
|
+
|
|
70
|
+
<!-- Properties: Provide additional context -->
|
|
71
|
+
<input
|
|
72
|
+
type="search"
|
|
73
|
+
aria-label="Search products"
|
|
74
|
+
aria-describedby="search-help"
|
|
75
|
+
>
|
|
76
|
+
<p id="search-help">Enter product name or SKU</p>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Common ARIA Patterns
|
|
80
|
+
|
|
81
|
+
```html
|
|
82
|
+
<!-- Live regions: Announce dynamic content -->
|
|
83
|
+
<div aria-live="polite" aria-atomic="true">
|
|
84
|
+
Item added to cart
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<!-- Error messages -->
|
|
88
|
+
<input
|
|
89
|
+
type="email"
|
|
90
|
+
aria-invalid="true"
|
|
91
|
+
aria-describedby="email-error"
|
|
92
|
+
>
|
|
93
|
+
<p id="email-error" role="alert">
|
|
94
|
+
Please enter a valid email address
|
|
95
|
+
</p>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Keyboard Navigation
|
|
99
|
+
|
|
100
|
+
All functionality must be accessible via keyboard:
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
// Custom keyboard navigation
|
|
104
|
+
document.addEventListener('keydown', (event) => {
|
|
105
|
+
const { key } = event;
|
|
106
|
+
|
|
107
|
+
switch (key) {
|
|
108
|
+
case 'Escape':
|
|
109
|
+
closeModal();
|
|
110
|
+
break;
|
|
111
|
+
case 'ArrowDown':
|
|
112
|
+
focusNextItem();
|
|
113
|
+
event.preventDefault();
|
|
114
|
+
break;
|
|
115
|
+
case 'ArrowUp':
|
|
116
|
+
focusPreviousItem();
|
|
117
|
+
event.preventDefault();
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Focus Management
|
|
124
|
+
|
|
125
|
+
```css
|
|
126
|
+
/* Never hide focus entirely */
|
|
127
|
+
:focus {
|
|
128
|
+
outline: 2px solid var(--color-focus);
|
|
129
|
+
outline-offset: 2px;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* Use :focus-visible for mouse users */
|
|
133
|
+
:focus:not(:focus-visible) {
|
|
134
|
+
outline: none;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
:focus-visible {
|
|
138
|
+
outline: 2px solid var(--color-focus);
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
```javascript
|
|
143
|
+
// Manage focus when content changes
|
|
144
|
+
function openModal() {
|
|
145
|
+
modal.hidden = false;
|
|
146
|
+
modal.querySelector('[autofocus]').focus();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function closeModal() {
|
|
150
|
+
modal.hidden = true;
|
|
151
|
+
triggerButton.focus(); // Return focus to trigger
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Color and Contrast
|
|
156
|
+
|
|
157
|
+
Ensure sufficient color contrast:
|
|
158
|
+
|
|
159
|
+
| Context | Minimum Ratio (WCAG AA) |
|
|
160
|
+
|---------|-------------------------|
|
|
161
|
+
| Normal text | 4.5:1 |
|
|
162
|
+
| Large text (18px+ bold, 24px+) | 3:1 |
|
|
163
|
+
| UI components | 3:1 |
|
|
164
|
+
|
|
165
|
+
```css
|
|
166
|
+
/* Good contrast */
|
|
167
|
+
.text {
|
|
168
|
+
color: #1a1a1a;
|
|
169
|
+
background: #ffffff;
|
|
170
|
+
/* Contrast ratio: 16.1:1 */
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/* Don't rely on color alone */
|
|
174
|
+
.error {
|
|
175
|
+
color: #dc2626;
|
|
176
|
+
border-left: 4px solid #dc2626;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.error::before {
|
|
180
|
+
content: "⚠ Error: ";
|
|
181
|
+
font-weight: bold;
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Images and Media
|
|
186
|
+
|
|
187
|
+
```html
|
|
188
|
+
<!-- Informative images need alt text -->
|
|
189
|
+
<img src="chart.png" alt="Sales increased 25% in Q4 2024">
|
|
190
|
+
|
|
191
|
+
<!-- Decorative images should be hidden -->
|
|
192
|
+
<img src="decorative.svg" alt="" role="presentation">
|
|
193
|
+
|
|
194
|
+
<!-- Complex images need longer descriptions -->
|
|
195
|
+
<figure>
|
|
196
|
+
<img src="diagram.png" alt="System architecture diagram" aria-describedby="diagram-desc">
|
|
197
|
+
<figcaption id="diagram-desc">
|
|
198
|
+
The system consists of three main components:
|
|
199
|
+
the API gateway, the processing service, and the database layer...
|
|
200
|
+
</figcaption>
|
|
201
|
+
</figure>
|
|
202
|
+
|
|
203
|
+
<!-- Video with captions -->
|
|
204
|
+
<video controls>
|
|
205
|
+
<source src="tutorial.mp4" type="video/mp4">
|
|
206
|
+
<track kind="captions" src="captions.vtt" srclang="en" label="English">
|
|
207
|
+
</video>
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Forms
|
|
211
|
+
|
|
212
|
+
Accessible forms are crucial:
|
|
213
|
+
|
|
214
|
+
```html
|
|
215
|
+
<form>
|
|
216
|
+
<div class="field">
|
|
217
|
+
<label for="name">Full Name *</label>
|
|
218
|
+
<input
|
|
219
|
+
type="text"
|
|
220
|
+
id="name"
|
|
221
|
+
name="name"
|
|
222
|
+
required
|
|
223
|
+
aria-required="true"
|
|
224
|
+
autocomplete="name"
|
|
225
|
+
>
|
|
226
|
+
</div>
|
|
227
|
+
|
|
228
|
+
<fieldset>
|
|
229
|
+
<legend>Notification Preferences</legend>
|
|
230
|
+
|
|
231
|
+
<div>
|
|
232
|
+
<input type="checkbox" id="email-notify" name="notify" value="email">
|
|
233
|
+
<label for="email-notify">Email notifications</label>
|
|
234
|
+
</div>
|
|
235
|
+
|
|
236
|
+
<div>
|
|
237
|
+
<input type="checkbox" id="sms-notify" name="notify" value="sms">
|
|
238
|
+
<label for="sms-notify">SMS notifications</label>
|
|
239
|
+
</div>
|
|
240
|
+
</fieldset>
|
|
241
|
+
|
|
242
|
+
<button type="submit">Subscribe</button>
|
|
243
|
+
</form>
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Testing for Accessibility
|
|
247
|
+
|
|
248
|
+
### Automated Testing
|
|
249
|
+
|
|
250
|
+
```javascript
|
|
251
|
+
// Example with axe-core
|
|
252
|
+
import { axe } from 'axe-core';
|
|
253
|
+
|
|
254
|
+
async function runAccessibilityTests() {
|
|
255
|
+
const results = await axe.run();
|
|
256
|
+
console.log('Violations:', results.violations);
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Manual Testing Checklist
|
|
261
|
+
|
|
262
|
+
- [ ] Navigate the entire page using only keyboard
|
|
263
|
+
- [ ] Test with a screen reader (VoiceOver, NVDA)
|
|
264
|
+
- [ ] Zoom to 200% and verify layout
|
|
265
|
+
- [ ] Check with Windows High Contrast mode
|
|
266
|
+
- [ ] Verify all images have appropriate alt text
|
|
267
|
+
- [ ] Confirm form errors are announced
|
|
268
|
+
|
|
269
|
+
## Summary
|
|
270
|
+
|
|
271
|
+
Building accessible websites requires:
|
|
272
|
+
|
|
273
|
+
- Semantic HTML as the foundation
|
|
274
|
+
- ARIA for enhanced semantics where needed
|
|
275
|
+
- Full keyboard navigation support
|
|
276
|
+
- Sufficient color contrast
|
|
277
|
+
- Alternative text for images
|
|
278
|
+
- Accessible forms with proper labeling
|
|
279
|
+
- Regular testing with assistive technologies
|
|
280
|
+
|
|
281
|
+
> **Final Thought**: Accessibility benefits everyone. Curb cuts help wheelchair users, but also parents with strollers, travelers with luggage, and delivery workers with carts. Digital accessibility works the same way.
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Conclusion
|
|
286
|
+
|
|
287
|
+
Congratulations on completing "The Art of Web Development"! You've learned:
|
|
288
|
+
|
|
289
|
+
1. The foundational triad of HTML, CSS, and JavaScript
|
|
290
|
+
2. Modern CSS layout techniques with Flexbox and Grid
|
|
291
|
+
3. JavaScript essentials for interactive applications
|
|
292
|
+
4. Performance optimization strategies
|
|
293
|
+
5. Accessibility best practices for inclusive design
|
|
294
|
+
|
|
295
|
+
The web is constantly evolving, but these fundamentals remain constant. Master them, and you'll be prepared for whatever comes next.
|
|
296
|
+
|
|
297
|
+
Happy coding!
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Tanuki Theme - Documentation Mode Example
|
|
2
|
+
base_url = "/tanuki/docs"
|
|
3
|
+
title = "Acme SDK"
|
|
4
|
+
description = "Official documentation for the Acme SDK"
|
|
5
|
+
theme = "tanuki"
|
|
6
|
+
compile_sass = true
|
|
7
|
+
build_search_index = true
|
|
8
|
+
generate_feeds = false
|
|
9
|
+
|
|
10
|
+
[markdown]
|
|
11
|
+
highlight_code = true
|
|
12
|
+
highlight_theme = "css"
|
|
13
|
+
insert_anchor_links = "left"
|
|
14
|
+
|
|
15
|
+
[extra]
|
|
16
|
+
mode = "docs"
|
|
17
|
+
github = "https://github.com/raskell-io/tanuki"
|
|
18
|
+
edit_url = "https://github.com/raskell-io/tanuki/edit/main/examples/docs/content"
|
|
19
|
+
show_theme_toggle = true
|
|
20
|
+
|
|
21
|
+
# Version picker (docs mode only)
|
|
22
|
+
[extra.versions]
|
|
23
|
+
current = "1.2.0"
|
|
24
|
+
list = [
|
|
25
|
+
{ version = "1.2.0", url = "/tanuki/docs/", label = "latest" },
|
|
26
|
+
{ version = "1.1.0", url = "/tanuki/docs/v1.1/" },
|
|
27
|
+
{ version = "1.0.0", url = "/tanuki/docs/v1.0/" },
|
|
28
|
+
]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
+++
|
|
2
|
+
title = "Documentation"
|
|
3
|
+
description = "Official documentation for the Acme SDK."
|
|
4
|
+
sort_by = "weight"
|
|
5
|
+
template = "section.html"
|
|
6
|
+
+++
|
|
7
|
+
|
|
8
|
+
# Acme SDK Documentation
|
|
9
|
+
|
|
10
|
+
Welcome to the official Acme SDK documentation. This guide covers everything you need to know to build powerful applications with Acme.
|
|
11
|
+
|
|
12
|
+
> **You're viewing docs for v1.2.0** — Use the version picker above to switch between releases.
|
|
13
|
+
|
|
14
|
+
## What's New in 1.2.0
|
|
15
|
+
|
|
16
|
+
- **Async Support**: All API methods now support async/await
|
|
17
|
+
- **Improved Performance**: 40% faster response times
|
|
18
|
+
- **New Widgets API**: Build custom UI components
|
|
19
|
+
|
|
20
|
+
See the [full changelog](https://github.com/acme/sdk/releases) for details.
|