diff --git a/01 Projects/Barclays-banner-builder/Barclays Banner Builder.md b/01 Projects/Barclays-banner-builder/Barclays Banner Builder.md index 8aa6191..e98211c 100644 --- a/01 Projects/Barclays-banner-builder/Barclays Banner Builder.md +++ b/01 Projects/Barclays-banner-builder/Barclays Banner Builder.md @@ -23,6 +23,14 @@ created: 2026-04-17 - **Local path:** `/Volumes/SSD/Projects/Oliver/Barclays-banner-builder` ## Sessions +### 2026-04-17 – Create an idempotent deployment script for +**Asked:** Create an idempotent deployment script for Ubuntu server with Docker, database initialization, and migrations. +**Done:** Verified login page is functional at optical-dev.oliver.solutions with working authentication flow. + +### 2026-04-17 – Create an idempotent deployment script for +**Asked:** Create an idempotent deployment script for Docker containers on Ubuntu with Apache reverse proxy and database migrations. +**Done:** Deployment script created and Apache configuration added to sites-enabled with health check verification and login page successfully loading. + ### 2026-04-17 – Create an idempotent deployment script for **Asked:** Create an idempotent deployment script for Docker app on Ubuntu with Apache reverse proxy. **Done:** Identified Apache configuration issue (sites-enabled vs sites-available) and updated deploy script to patch correct file. @@ -151,6 +159,8 @@ created: 2026-04-17 ## Change Log | Date | Requested | Changed | Files | |------|-----------|---------|-------| +| 2026-04-17 | Deployment automation | Docker build caching, database migrations, idempotent script logic | deploy.sh, docker-compose.yml | +| 2026-04-17 | Deployment script | Docker build with cache refresh, database initialization and migrations, Apache Include configuration | deploy-ubuntu.sh, apache-barclays.conf, sites-enabled/optical-dev.oliver.solutions.conf | | 2026-04-17 | Deployment script & Apache config | Fixed sites-enabled patching, updated deploy.sh for correct config file | deploy.sh, apache-config-patch | | 2026-04-17 | Deployment automation | Docker build cache, database migrations, Apache reload script, .env production config | deploy.sh, docker-compose.yml, apache-vhost.conf | | 2026-04-17 | Apache config fix | ProxyPass to Location blocks, FallbackResource instead of RewriteRule, Alias priority resolution | apache2.conf | diff --git a/99 Daily/2026-04-17.md b/99 Daily/2026-04-17.md index a08cbb6..c606f9d 100644 --- a/99 Daily/2026-04-17.md +++ b/99 Daily/2026-04-17.md @@ -215,3 +215,12 @@ tags: [daily] - 13:00 (<1min) | `memory-compiler` - **Asked:** Update the wiki index to reflect a duplicate raw article that was already compiled. - **Done:** Added both raw source files to the `sources` field in the compiled article and its parent index. +- 13:00 (<1min) | `Barclays-banner-builder` + - **Asked:** Create an idempotent deployment script for Docker containers on Ubuntu with Apache reverse proxy and database migrations. + - **Done:** Deployment script created and Apache configuration added to sites-enabled with health check verification and login page successfully loading. +- 13:00 | `memory-compiler` + - **Asked:** Compile a new raw wiki article into the knowledge base structure. + - **Done:** Categorized the article under the dotfiles topic with existing WezTerm documentation. +- 13:00 | `Barclays-banner-builder` + - **Asked:** Create an idempotent deployment script for Ubuntu server with Docker, database initialization, and migrations. + - **Done:** Verified login page is functional at optical-dev.oliver.solutions with working authentication flow. diff --git a/raw/Mouse Binding - Wez's Terminal Emulator.md b/raw/_processed/Mouse Binding - Wez's Terminal Emulator.md similarity index 100% rename from raw/Mouse Binding - Wez's Terminal Emulator.md rename to raw/_processed/Mouse Binding - Wez's Terminal Emulator.md diff --git a/wiki/_master-index.md b/wiki/_master-index.md index 3519f2b..8296d35 100644 --- a/wiki/_master-index.md +++ b/wiki/_master-index.md @@ -28,7 +28,7 @@ This 3-hop pattern works for hundreds of articles without vector search. | [[wiki/qa/_index\|qa/]] | Filed answers to queries (saved with `--file-back`) | 0 | | [[wiki/homelab/_index\|homelab/]] | Self-hosted infra: Proxmox install, IOMMU/PCI passthrough, hypervisor setup, budget builds | 2 | | [[wiki/web-agency/_index\|web-agency/]] | AI-assisted website building & selling: Claude Code, Nanobanana 2, Kling, LaunchPath MCP | 1 | -| [[wiki/dotfiles/_index\|dotfiles/]] | Linux terminal ricing: Kitty, Fish, WezTerm CLI, modern Rust CLI tools, LazyVim, unified themes, Tabby | 15 | +| [[wiki/dotfiles/_index\|dotfiles/]] | Linux terminal ricing: Kitty, Fish, WezTerm CLI, modern Rust CLI tools, LazyVim, unified themes, Tabby | 16 | | [[wiki/agent-sdk/_index\|agent-sdk/]] | Claude Agent SDK (formerly Claude Code SDK) — build autonomous AI agents in Python and TypeScript | 16 | | [[wiki/llm-models/_index\|llm-models/]] | OpenAI model catalog — GPT-5.x, o-series reasoning, audio/realtime, embeddings, moderation | 1 | diff --git a/wiki/agent-sdk/_index.md b/wiki/agent-sdk/_index.md index 33513b9..408a982 100644 --- a/wiki/agent-sdk/_index.md +++ b/wiki/agent-sdk/_index.md @@ -30,3 +30,4 @@ Build production AI agents using the same tools, agent loop, and context managem | [[wiki/agent-sdk/sdk-hooks\|sdk-hooks]] | In-process SDK hooks: PreToolUse/PostToolUse callbacks, matchers, block/modify/approve patterns, Slack notifications, troubleshooting | raw/Intercept and control agent behavior with hooks.md | 2026-04-17 | | [[wiki/agent-sdk/migration-guide\|migration-guide]] | Migrate from claude-code-sdk to claude-agent-sdk: package rename, import updates, v0.1.0 breaking changes (system prompt, settingSources) | raw/Migrate to Claude Agent SDK.md | 2026-04-17 | | [[wiki/agent-sdk/modifying-system-prompts\|modifying-system-prompts]] | Four methods to customize system prompts: CLAUDE.md, output styles, append preset, custom string; prompt caching with excludeDynamicSections | raw/Modifying system prompts.md, raw/Modifying system prompts 1.md | 2026-04-17 | +| [[wiki/agent-sdk/observability-opentelemetry\|observability-opentelemetry]] | Export traces, metrics, log events via OTEL to any OTLP backend; span names, sensitive data controls, flush config | raw/Observability with OpenTelemetry.md | 2026-04-17 | diff --git a/wiki/agent-sdk/observability-opentelemetry.md b/wiki/agent-sdk/observability-opentelemetry.md new file mode 100644 index 0000000..a179ff7 --- /dev/null +++ b/wiki/agent-sdk/observability-opentelemetry.md @@ -0,0 +1,124 @@ +--- +title: "Observability with OpenTelemetry" +aliases: [otel-agent-sdk, agent-sdk-telemetry, opentelemetry-traces] +tags: [agent-sdk, observability, opentelemetry, monitoring, tracing, metrics] +sources: [raw/Observability with OpenTelemetry.md] +created: 2026-04-17 +updated: 2026-04-17 +--- + +# Observability with OpenTelemetry + +Export traces, metrics, and log events from the Agent SDK to any OTLP-compatible backend (Honeycomb, Datadog, Grafana, Langfuse, self-hosted collector). + +## How Telemetry Flows + +- The SDK runs the Claude Code CLI as a child process — **the CLI emits telemetry, not the SDK itself** +- Configuration is passed via environment variables inherited by the child process +- Two configuration strategies: + - **Process environment** (recommended for production): set vars in shell/container/orchestrator — all `query()` calls pick them up automatically + - **Per-call `options.env`**: use when different agents need different telemetry settings + - Python: `env` merges on top of inherited environment + - TypeScript: `env` **replaces** inherited environment — always include `...process.env` + +## Three Signals + +| Signal | What it contains | Enable with | +|--------|-----------------|-------------| +| Metrics | Token/cost counters, sessions, lines of code, tool decisions | `OTEL_METRICS_EXPORTER` | +| Log events | Structured records per prompt, API request, error, tool result | `OTEL_LOGS_EXPORTER` | +| Traces (beta) | Spans per interaction, model request, tool call, hook | `OTEL_TRACES_EXPORTER` + `CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1` | + +## Enabling Telemetry + +Telemetry is **off by default**. Minimum required: + +```python +OTEL_ENV = { + "CLAUDE_CODE_ENABLE_TELEMETRY": "1", + "CLAUDE_CODE_ENHANCED_TELEMETRY_BETA": "1", # required for traces + "OTEL_TRACES_EXPORTER": "otlp", + "OTEL_METRICS_EXPORTER": "otlp", + "OTEL_LOGS_EXPORTER": "otlp", + "OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf", + "OTEL_EXPORTER_OTLP_ENDPOINT": "http://collector.example.com:4318", + "OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer your-token", +} + +options = ClaudeAgentOptions(env=OTEL_ENV) +async for message in query(prompt="...", options=options): + print(message) +``` + +> **Do not use `console` exporter** — the SDK uses stdout as its message channel. Use a local OTLP collector or Jaeger for local inspection instead. + +## Flushing Short-Lived Calls + +Default export intervals are slow (metrics: 60s, traces/logs: 5s). For short tasks, lower the intervals: + +```python +"OTEL_METRIC_EXPORT_INTERVAL": "1000", # ms +"OTEL_LOGS_EXPORT_INTERVAL": "1000", +"OTEL_TRACES_EXPORT_INTERVAL": "1000", +``` + +- The CLI flushes on clean exit but is bounded by a timeout — spans can be dropped if the collector is slow +- Spans are lost entirely if the process is killed before CLI shutdown + +## Span Names (Traces) + +| Span | Wraps | +|------|-------| +| `claude_code.interaction` | One full agent turn (prompt → response) | +| `claude_code.llm_request` | Single Claude API call; carries model, latency, token counts | +| `claude_code.tool` | Tool invocation; child spans: `claude_code.tool.blocked_on_user`, `claude_code.tool.execution` | +| `claude_code.hook` | Hook execution | + +- All spans carry `session.id` — filter on it to group multi-turn sessions into one timeline +- Set `OTEL_METRICS_INCLUDE_SESSION_ID=false` to omit the attribute + +## Tagging Telemetry + +Override the default `service.name = "claude-code"` when running multiple agents: + +```python +options = ClaudeAgentOptions( + env={ + "OTEL_SERVICE_NAME": "support-triage-agent", + "OTEL_RESOURCE_ATTRIBUTES": "service.version=1.4.0,deployment.environment=production", + }, +) +``` + +## Sensitive Data Controls + +Content is **not** recorded by default. Opt-in variables: + +| Variable | Adds | +|----------|------| +| `OTEL_LOG_USER_PROMPTS=1` | Prompt text on events and interaction span | +| `OTEL_LOG_TOOL_DETAILS=1` | Tool input args (file paths, shell commands) on tool_result events | +| `OTEL_LOG_TOOL_CONTENT=1` | Full tool input/output bodies as span events (max 60 KB, requires tracing enabled) | + +Leave unset unless your observability pipeline is approved to store the data your agent handles. + +## Key Takeaways + +- Telemetry comes from the CLI child process, not the SDK — configure via env vars +- Must set `CLAUDE_CODE_ENABLE_TELEMETRY=1` plus at least one `OTEL_*_EXPORTER` +- Traces require an additional beta flag: `CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1` +- TypeScript `options.env` replaces the environment — always spread `...process.env` +- Lower export intervals for short-lived agent calls to avoid dropped spans +- Content (prompts, tool I/O) is redacted by default; three opt-in vars add it back +- Use `OTEL_SERVICE_NAME` to distinguish multiple agents in the same collector + +## Related + +- [[wiki/agent-sdk/hosting-production|Hosting the Agent SDK]] — set OTEL vars at container/orchestrator level +- [[wiki/agent-sdk/agent-loop|How the Agent Loop Works]] — understand what each span represents +- [[wiki/agent-sdk/hooks-guide|Hooks Guide]] — `claude_code.hook` spans wrap hook executions +- [[wiki/claude-code/monitoring-usage|Monitoring Reference]] — full list of env vars, metric names, event names + +## Sources + +- `raw/Observability with OpenTelemetry.md` diff --git a/wiki/dotfiles/_index.md b/wiki/dotfiles/_index.md index fc3cee5..f93c72c 100644 --- a/wiki/dotfiles/_index.md +++ b/wiki/dotfiles/_index.md @@ -19,3 +19,4 @@ Linux terminal customization, shell configs, CLI tool setups, and ricing guides. | [[wiki/dotfiles/wezterm-keyboard-concepts\|wezterm-keyboard-concepts]] | OS input concepts (IME, dead keys, AltGr, physical vs mapped keys) and how WezTerm processes them | wezterm.org/config/keyboard-concepts.html | 2026-04-17 | | [[wiki/dotfiles/wezterm-keyboard-encoding\|wezterm-keyboard-encoding]] | xterm, modifyOtherKeys, CSI-u, Kitty protocol, Win32 Input Mode — priority order and config options | wezterm.org/config/key-encoding.html | 2026-04-17 | | [[wiki/dotfiles/wezterm-launching-programs\|wezterm-launching-programs]] | Shell resolution, default_prog, one-off CLI launch, CWD inheritance, env vars, Launcher Menu | wezterm.org/config/launch.html | 2026-04-17 | +| [[wiki/dotfiles/wezterm-mouse-bindings\|wezterm-mouse-bindings]] | Mouse binding config: default assignments, custom bindings, wheel events, Up/Down event gotcha | wezterm.org/config/mouse.html | 2026-04-17 | diff --git a/wiki/dotfiles/wezterm-mouse-bindings.md b/wiki/dotfiles/wezterm-mouse-bindings.md new file mode 100644 index 0000000..fae7a45 --- /dev/null +++ b/wiki/dotfiles/wezterm-mouse-bindings.md @@ -0,0 +1,152 @@ +--- +title: "WezTerm Mouse Bindings" +aliases: [wezterm-mouse, wezterm-mouse-config] +tags: [wezterm, mouse, terminal, dotfiles, lua] +sources: [raw/Mouse Binding - Wez's Terminal Emulator.md] +created: 2026-04-17 +updated: 2026-04-17 +--- + +## Overview + +WezTerm mouse bindings are fully configurable via Lua. By default, terminal applications can capture mouse events — WezTerm hands them through unless you intervene with a modifier key. + +## Mouse Reporting Bypass + +When an app enables mouse tracking, WezTerm passes all mouse events to it rather than matching bindings. To force your bindings to fire anyway, hold `SHIFT` (default bypass modifier). + +- Change the bypass key via `config.bypass_mouse_reporting_modifiers` +- Use `mouse_reporting = true` in a binding entry to target app-captured state (generally avoid this) + +## Default Mouse Assignments + +| Event | Modifiers | Action | +|-------|-----------|--------| +| Single Left Down | `NONE` | `SelectTextAtMouseCursor("Cell")` | +| Double Left Down | `NONE` | `SelectTextAtMouseCursor("Word")` | +| Triple Left Down | `NONE` | `SelectTextAtMouseCursor("Line")` | +| Single Left Down | `SHIFT` | `ExtendSelectionToMouseCursor("Cell")` | +| Single Left Down | `ALT` | `SelectTextAtMouseCursor("Block")` | +| Single Left Up | `NONE` | `CompleteSelectionOrOpenLinkAtMouseCursor(...)` | +| Single Left Up | `SHIFT` | `CompleteSelectionOrOpenLinkAtMouseCursor(...)` | +| Single Left Drag | `NONE` | `ExtendSelectionToMouseCursor("Cell")` | +| Single Left Drag | `ALT` | `ExtendSelectionToMouseCursor("Block")` | +| Double Left Drag | `NONE` | `ExtendSelectionToMouseCursor("Word")` | +| Triple Left Drag | `NONE` | `ExtendSelectionToMouseCursor("Line")` | +| Single Middle Down | `NONE` | `PasteFrom("PrimarySelection")` | +| Single Left Drag | `SUPER` / `CTRL+SHIFT` | `StartWindowDrag` | + +Run `wezterm show-keys` to inspect the effective bindings at runtime. + +Disable all defaults with: +```lua +config.disable_default_mouse_bindings = true +``` + +## Configuring Custom Mouse Bindings + +```lua +local wezterm = require 'wezterm' +local act = wezterm.action + +config.mouse_bindings = { + -- Right click sends a string + { + event = { Down = { streak = 1, button = 'Right' } }, + mods = 'NONE', + action = act.SendString 'woot', + }, + -- CTRL-Click opens hyperlinks + { + event = { Up = { streak = 1, button = 'Left' } }, + mods = 'CTRL', + action = act.OpenLinkAtMouseCursor, + }, + -- Disable Down event to prevent leaking to app (see gotcha below) + { + event = { Down = { streak = 1, button = 'Left' } }, + mods = 'CTRL', + action = act.Nop, + }, +} +``` + +### Binding Entry Fields + +| Field | Required | Description | +|-------|----------|-------------| +| `event` | yes | `Down`, `Up`, or `Drag` + `streak` + `button` | +| `mods` | yes | Modifier keys (same syntax as key bindings) | +| `action` | yes | `KeyAssignment` action to perform | +| `mouse_reporting` | no | Match only when app mouse reporting is active (default `false`) | +| `alt_screen` | no | `'Any'` (default), `true`, or `false` — match only in/out of alt screen | + +### Event Lua Representation + +```lua +-- Triple Left Down +event = { Down = { streak = 3, button = "Left" } } + +-- Double Left Up +event = { Up = { streak = 2, button = "Left" } } + +-- Single Left Drag +event = { Drag = { streak = 1, button = "Left" } } +``` + +Arbitrary click streaks are supported — `streak = 4` for quadruple-click, etc. + +## Mouse Wheel Bindings + +Wheel events use `WheelUp` / `WheelDown` as the button value: + +```lua +-- CTRL+Scroll to resize font +{ + event = { Down = { streak = 1, button = { WheelUp = 1 } } }, + mods = 'CTRL', + action = act.IncreaseFontSize, +}, +{ + event = { Down = { streak = 1, button = { WheelDown = 1 } } }, + mods = 'CTRL', + action = act.DecreaseFontSize, +}, +``` + +`streak` and `amount` are fixed at `1` for wheel events in pattern matching. Use `window:current_event` inside a callback to get the actual delta. + +Note: default scroll bindings use `alt_screen = false` — wheel maps to arrow keys in alt screen mode instead. + +## Gotcha: Binding Only the 'Up' Event + +If you bind `Up` but not `Down`, the `Down` event is still forwarded to the running app (e.g. tmux, vim). This causes the app to see a Down without a matching Up — leading to stuck selection state or other glitches. + +**Fix:** always pair an `Up` binding with a `Down = act.Nop` to suppress the Down event: + +```lua +-- Good: suppress Down so app never sees it +{ event = { Up = { streak = 1, button = 'Left' } }, mods = 'CTRL', action = act.OpenLinkAtMouseCursor }, +{ event = { Down = { streak = 1, button = 'Left' } }, mods = 'CTRL', action = act.Nop }, +``` + +## Key Takeaways + +- Default bindings cover selection (cell/word/line/block), clipboard, link-open, and window drag +- Apps can capture mouse events; hold `SHIFT` (or configured bypass mod) to force your bindings +- Custom bindings go in `config.mouse_bindings` as a Lua table +- Every entry needs `event`, `mods`, and `action`; `mouse_reporting` and `alt_screen` are optional filters +- Wheel events use `{ WheelUp = 1 }` / `{ WheelDown = 1 }` as the button value +- Always pair an `Up` binding with a `Down = act.Nop` to avoid leaking events to apps +- `wezterm show-keys` shows the live effective binding table + +## Related + +- [[wiki/dotfiles/wezterm-key-bindings|WezTerm Key Bindings]] — keyboard equivalent, same `mods` syntax +- [[wiki/dotfiles/wezterm-key-tables|WezTerm Key Tables]] — modal layers that also affect input routing +- [[wiki/dotfiles/wezterm-keyboard-concepts|WezTerm Keyboard Concepts]] — how WezTerm handles input at the OS level +- [[wiki/dotfiles/wezterm-config|WezTerm Config]] — config file structure and live reload + +## Sources + +- [wezterm.org/config/mouse.html](https://wezterm.org/config/mouse.html)