omegon 0.6.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 (160) hide show
  1. package/.gitattributes +3 -0
  2. package/AGENTS.md +16 -0
  3. package/LICENSE +15 -0
  4. package/README.md +289 -0
  5. package/bin/pi.mjs +30 -0
  6. package/extensions/00-secrets/index.ts +1126 -0
  7. package/extensions/01-auth/auth.ts +401 -0
  8. package/extensions/01-auth/index.ts +289 -0
  9. package/extensions/auto-compact.ts +42 -0
  10. package/extensions/bootstrap/deps.ts +291 -0
  11. package/extensions/bootstrap/index.ts +811 -0
  12. package/extensions/chronos/chronos.sh +487 -0
  13. package/extensions/chronos/index.ts +148 -0
  14. package/extensions/cleave/assessment.ts +754 -0
  15. package/extensions/cleave/bridge.ts +31 -0
  16. package/extensions/cleave/conflicts.ts +250 -0
  17. package/extensions/cleave/dispatcher.ts +808 -0
  18. package/extensions/cleave/guardrails.ts +426 -0
  19. package/extensions/cleave/index.ts +3121 -0
  20. package/extensions/cleave/lifecycle-emitter.ts +20 -0
  21. package/extensions/cleave/openspec.ts +811 -0
  22. package/extensions/cleave/planner.ts +260 -0
  23. package/extensions/cleave/review.ts +579 -0
  24. package/extensions/cleave/skills.ts +355 -0
  25. package/extensions/cleave/types.ts +261 -0
  26. package/extensions/cleave/workspace.ts +861 -0
  27. package/extensions/cleave/worktree.ts +243 -0
  28. package/extensions/core-renderers.ts +253 -0
  29. package/extensions/dashboard/context-gauge.ts +58 -0
  30. package/extensions/dashboard/file-watch.ts +14 -0
  31. package/extensions/dashboard/footer.ts +1145 -0
  32. package/extensions/dashboard/git.ts +185 -0
  33. package/extensions/dashboard/index.ts +478 -0
  34. package/extensions/dashboard/memory-audit.ts +34 -0
  35. package/extensions/dashboard/overlay-data.ts +705 -0
  36. package/extensions/dashboard/overlay.ts +365 -0
  37. package/extensions/dashboard/render-utils.ts +54 -0
  38. package/extensions/dashboard/types.ts +191 -0
  39. package/extensions/dashboard/uri-helper.ts +45 -0
  40. package/extensions/debug.ts +69 -0
  41. package/extensions/defaults.ts +282 -0
  42. package/extensions/design-tree/dashboard-state.ts +161 -0
  43. package/extensions/design-tree/design-card.ts +362 -0
  44. package/extensions/design-tree/index.ts +2130 -0
  45. package/extensions/design-tree/lifecycle-emitter.ts +41 -0
  46. package/extensions/design-tree/tree.ts +1607 -0
  47. package/extensions/design-tree/types.ts +163 -0
  48. package/extensions/distill.ts +127 -0
  49. package/extensions/effort/index.ts +395 -0
  50. package/extensions/effort/tiers.ts +146 -0
  51. package/extensions/effort/types.ts +105 -0
  52. package/extensions/lib/git-state.ts +227 -0
  53. package/extensions/lib/local-models.ts +157 -0
  54. package/extensions/lib/model-preferences.ts +51 -0
  55. package/extensions/lib/model-routing.ts +720 -0
  56. package/extensions/lib/operator-fallback.ts +205 -0
  57. package/extensions/lib/operator-profile.ts +360 -0
  58. package/extensions/lib/slash-command-bridge.ts +253 -0
  59. package/extensions/lib/typebox-helpers.ts +16 -0
  60. package/extensions/local-inference/index.ts +727 -0
  61. package/extensions/mcp-bridge/README.md +220 -0
  62. package/extensions/mcp-bridge/index.ts +951 -0
  63. package/extensions/mcp-bridge/lib.ts +365 -0
  64. package/extensions/mcp-bridge/mcp.json +3 -0
  65. package/extensions/mcp-bridge/package.json +11 -0
  66. package/extensions/model-budget.ts +752 -0
  67. package/extensions/offline-driver.ts +403 -0
  68. package/extensions/openspec/archive-gate.ts +164 -0
  69. package/extensions/openspec/branch-cleanup.ts +64 -0
  70. package/extensions/openspec/dashboard-state.ts +50 -0
  71. package/extensions/openspec/index.ts +1917 -0
  72. package/extensions/openspec/lifecycle-emitter.ts +65 -0
  73. package/extensions/openspec/lifecycle-files.ts +70 -0
  74. package/extensions/openspec/lifecycle.ts +50 -0
  75. package/extensions/openspec/reconcile.ts +187 -0
  76. package/extensions/openspec/spec.ts +1385 -0
  77. package/extensions/openspec/types.ts +98 -0
  78. package/extensions/project-memory/DESIGN-global-mind.md +198 -0
  79. package/extensions/project-memory/README.md +202 -0
  80. package/extensions/project-memory/api-types.ts +382 -0
  81. package/extensions/project-memory/compaction-policy.ts +29 -0
  82. package/extensions/project-memory/core.ts +164 -0
  83. package/extensions/project-memory/embeddings.ts +230 -0
  84. package/extensions/project-memory/extraction-v2.ts +861 -0
  85. package/extensions/project-memory/factstore.ts +2177 -0
  86. package/extensions/project-memory/index.ts +3459 -0
  87. package/extensions/project-memory/injection-metrics.ts +91 -0
  88. package/extensions/project-memory/jsonl-io.ts +12 -0
  89. package/extensions/project-memory/lifecycle.ts +331 -0
  90. package/extensions/project-memory/migration.ts +293 -0
  91. package/extensions/project-memory/package.json +9 -0
  92. package/extensions/project-memory/sci-renderers.ts +7 -0
  93. package/extensions/project-memory/template.ts +103 -0
  94. package/extensions/project-memory/triggers.ts +52 -0
  95. package/extensions/project-memory/types.ts +102 -0
  96. package/extensions/render/composition/fonts/Inter-Bold.ttf +0 -0
  97. package/extensions/render/composition/fonts/Inter-Regular.ttf +0 -0
  98. package/extensions/render/composition/fonts/Tomorrow-Bold.ttf +0 -0
  99. package/extensions/render/composition/fonts/Tomorrow-Regular.ttf +0 -0
  100. package/extensions/render/composition/package-lock.json +534 -0
  101. package/extensions/render/composition/package.json +22 -0
  102. package/extensions/render/composition/render.mjs +246 -0
  103. package/extensions/render/composition/test-comp.tsx +87 -0
  104. package/extensions/render/composition/types.ts +24 -0
  105. package/extensions/render/excalidraw/UPSTREAM.md +81 -0
  106. package/extensions/render/excalidraw/elements.ts +764 -0
  107. package/extensions/render/excalidraw/index.ts +66 -0
  108. package/extensions/render/excalidraw/types.ts +223 -0
  109. package/extensions/render/excalidraw-renderer/pyproject.toml +8 -0
  110. package/extensions/render/excalidraw-renderer/render_excalidraw.py +182 -0
  111. package/extensions/render/excalidraw-renderer/render_template.html +59 -0
  112. package/extensions/render/index.ts +830 -0
  113. package/extensions/render/native-diagrams/index.ts +57 -0
  114. package/extensions/render/native-diagrams/motifs.ts +542 -0
  115. package/extensions/render/native-diagrams/raster.ts +8 -0
  116. package/extensions/render/native-diagrams/scene.ts +75 -0
  117. package/extensions/render/native-diagrams/spec.ts +204 -0
  118. package/extensions/render/native-diagrams/svg.ts +116 -0
  119. package/extensions/sci-ui.ts +304 -0
  120. package/extensions/session-log.ts +174 -0
  121. package/extensions/shared-state.ts +146 -0
  122. package/extensions/spinner-verbs.ts +91 -0
  123. package/extensions/style.ts +281 -0
  124. package/extensions/terminal-title.ts +191 -0
  125. package/extensions/tool-profile/index.ts +291 -0
  126. package/extensions/tool-profile/profiles.ts +290 -0
  127. package/extensions/types.d.ts +9 -0
  128. package/extensions/vault/index.ts +185 -0
  129. package/extensions/version-check.ts +90 -0
  130. package/extensions/view/index.ts +859 -0
  131. package/extensions/view/uri-resolver.ts +148 -0
  132. package/extensions/web-search/index.ts +182 -0
  133. package/extensions/web-search/providers.ts +121 -0
  134. package/extensions/web-ui/index.ts +110 -0
  135. package/extensions/web-ui/server.ts +265 -0
  136. package/extensions/web-ui/state.ts +462 -0
  137. package/extensions/web-ui/static/index.html +145 -0
  138. package/extensions/web-ui/types.ts +284 -0
  139. package/package.json +76 -0
  140. package/prompts/init.md +75 -0
  141. package/prompts/new-repo.md +54 -0
  142. package/prompts/oci-login.md +56 -0
  143. package/prompts/status.md +50 -0
  144. package/settings.json +4 -0
  145. package/skills/cleave/SKILL.md +218 -0
  146. package/skills/git/SKILL.md +209 -0
  147. package/skills/git/_reference/ci-validation.md +204 -0
  148. package/skills/oci/SKILL.md +338 -0
  149. package/skills/openspec/SKILL.md +346 -0
  150. package/skills/pi-extensions/SKILL.md +191 -0
  151. package/skills/pi-tui/SKILL.md +517 -0
  152. package/skills/python/SKILL.md +189 -0
  153. package/skills/rust/SKILL.md +268 -0
  154. package/skills/security/SKILL.md +206 -0
  155. package/skills/style/SKILL.md +264 -0
  156. package/skills/typescript/SKILL.md +225 -0
  157. package/skills/vault/SKILL.md +102 -0
  158. package/themes/alpharius-legacy.json +85 -0
  159. package/themes/alpharius.conf +59 -0
  160. package/themes/alpharius.json +88 -0
@@ -0,0 +1,189 @@
1
+ ---
2
+ name: python
3
+ description: Python development guidance. Covers project setup (pyproject.toml, src/ layout), testing (pytest), linting (ruff), type checking (mypy), packaging, venv management, and CI/CD patterns. Use when creating, modifying, or debugging Python code.
4
+ guardrails:
5
+ - name: typecheck
6
+ cmd: mypy src/
7
+ timeout: 60
8
+ condition: file_exists(pyproject.toml)
9
+ - name: lint
10
+ cmd: ruff check .
11
+ timeout: 30
12
+ condition: file_exists(pyproject.toml)
13
+ ---
14
+
15
+ # Python Development Skill
16
+
17
+ Conventions, tooling, and patterns for Python development.
18
+
19
+ ## Core Conventions
20
+
21
+ - **Python 3.11+** minimum
22
+ - **src/ layout** (PEP 517) for all packages
23
+ - **pyproject.toml** is the single config file — no `.cfg`, `.ini`, or separate `.toml`
24
+ - **venv + pip** for environment management — no poetry, no conda
25
+ - **Makefile** (or justfile) wraps all dev commands
26
+ - **Editable install**: `pip install -e ".[dev]"` for development
27
+
28
+ ## Project Scaffold
29
+
30
+ ```
31
+ <project>/
32
+ ├── pyproject.toml # All config: build, deps, ruff, mypy, pytest
33
+ ├── Makefile # Dev workflow: test, lint, format, typecheck, validate
34
+ ├── src/<package>/ # Source code (src/ layout)
35
+ │ ├── __init__.py # __version__ = "0.1.0"
36
+ │ └── ...
37
+ ├── tests/
38
+ │ ├── conftest.py # Shared fixtures
39
+ │ └── test_*.py
40
+ └── .github/workflows/ci.yml
41
+ ```
42
+
43
+ **Build backend choice:**
44
+ | Project Type | Backend |
45
+ |-------------|---------|
46
+ | Library / CLI tool | hatchling |
47
+ | Daemon / application | setuptools |
48
+
49
+ ## Tooling Quick Reference
50
+
51
+ ### Ruff (Linting + Formatting)
52
+
53
+ ```toml
54
+ [tool.ruff]
55
+ line-length = 100
56
+ target-version = "py311"
57
+
58
+ [tool.ruff.lint]
59
+ select = ["E", "F", "I", "UP", "B", "SIM", "RUF"]
60
+ ignore = ["E501"]
61
+
62
+ [tool.ruff.lint.per-file-ignores]
63
+ "__init__.py" = ["F401"]
64
+
65
+ [tool.ruff.lint.isort]
66
+ known-first-party = ["<package>"]
67
+ ```
68
+
69
+ ```bash
70
+ ruff check . # Lint
71
+ ruff check --fix . # Lint + auto-fix
72
+ ruff format . # Format (replaces black)
73
+ ruff format --check . # Format check (CI)
74
+ ```
75
+
76
+ ### Mypy (Type Checking)
77
+
78
+ **New projects** — use `strict = true`.
79
+ **Projects with untyped deps** — use `ignore_missing_imports = true`, `disallow_untyped_defs = false`.
80
+
81
+ ```toml
82
+ [tool.mypy]
83
+ python_version = "3.11"
84
+ strict = true
85
+ warn_return_any = true
86
+ warn_unused_ignores = true
87
+ ```
88
+
89
+ ### Pytest
90
+
91
+ ```toml
92
+ [tool.pytest.ini_options]
93
+ testpaths = ["tests"]
94
+ addopts = "-v --strict-markers"
95
+ asyncio_mode = "auto"
96
+ markers = [
97
+ "slow: marks tests as slow",
98
+ "smoke: quick validation tests",
99
+ "integration: requires external services",
100
+ ]
101
+ ```
102
+
103
+ **Key commands:**
104
+ ```bash
105
+ pytest # All tests
106
+ pytest -m smoke # Quick validation only
107
+ pytest -m "not slow" # Skip slow tests
108
+ pytest -x # Stop on first failure
109
+ pytest --lf # Rerun last failures
110
+ pytest -k "test_connect" # Name pattern
111
+ pytest --cov=src --cov-report=term-missing # Coverage
112
+ ```
113
+
114
+ ## Virtual Environment
115
+
116
+ ```bash
117
+ python3 -m venv .venv
118
+ source .venv/bin/activate
119
+ pip install --upgrade pip
120
+ pip install -e ".[dev]"
121
+ ```
122
+
123
+ ## Testing Patterns
124
+
125
+ ### Async Tests
126
+
127
+ With `asyncio_mode = "auto"`, async tests work without decorators:
128
+
129
+ ```python
130
+ async def test_connection():
131
+ client = await connect()
132
+ assert client.is_connected
133
+ ```
134
+
135
+ ## Python Idioms
136
+
137
+ | Pattern | Convention |
138
+ |---------|-----------|
139
+ | Paths | `pathlib.Path`, never `os.path` |
140
+ | Data models | `dataclasses` for internal, Pydantic at validation boundaries |
141
+ | Imports | stdlib / third-party / local (ruff `I` rule enforces) |
142
+ | Async | `asyncio.gather` for concurrency, `asyncio.wait_for` for timeouts |
143
+ | Logging | `logging.getLogger(__name__)` |
144
+ | Entry points | `def main() -> int:` registered via `[project.scripts]` |
145
+ | Version | Single source in `__init__.py`, read by build backend |
146
+
147
+ ## Packaging
148
+
149
+ ```bash
150
+ python -m build # Produces dist/*.whl + dist/*.tar.gz
151
+ twine upload dist/* # Publish to PyPI
152
+ ```
153
+
154
+ Use trusted publishing (OIDC) via `pypa/gh-action-pypi-publish` in CI.
155
+
156
+ ## CI/CD Template
157
+
158
+ ```yaml
159
+ name: CI
160
+ on: [push, pull_request]
161
+ jobs:
162
+ test:
163
+ runs-on: ubuntu-latest
164
+ strategy:
165
+ matrix:
166
+ python-version: ["3.11", "3.12"]
167
+ steps:
168
+ - uses: actions/checkout@v4
169
+ - uses: actions/setup-python@v5
170
+ with:
171
+ python-version: ${{ matrix.python-version }}
172
+ - run: pip install -e ".[dev]"
173
+ - run: ruff format --check .
174
+ - run: ruff check .
175
+ - run: mypy src/
176
+ - run: pytest --cov=src --cov-report=term-missing
177
+ ```
178
+
179
+ ## Common Gotchas
180
+
181
+ | Issue | Fix |
182
+ |-------|-----|
183
+ | Import from src/ fails | `pip install -e ".[dev]"` |
184
+ | `ModuleNotFoundError` in tests | Check `testpaths`, verify conftest.py exists |
185
+ | Async test hangs | Missing `await`, or add `asyncio.wait_for` timeout |
186
+ | Type stubs missing | Add `types-<pkg>` to dev deps, or `ignore_missing_imports` |
187
+ | Version mismatch | Single source: `__version__` in `__init__.py`, read by build backend |
188
+ </content>
189
+ </invoke>
@@ -0,0 +1,268 @@
1
+ ---
2
+ name: rust
3
+ description: Rust development guidance including Zellij WASM plugin development. Covers project setup (Cargo.toml), testing, clippy, rustfmt, CI/CD patterns, and the zellij-tile plugin API. Use when creating, modifying, or debugging Rust code or Zellij plugins.
4
+ guardrails:
5
+ - name: clippy
6
+ cmd: cargo clippy -- -D warnings
7
+ timeout: 120
8
+ condition: file_exists(Cargo.toml)
9
+ - name: test
10
+ cmd: cargo test
11
+ timeout: 120
12
+ condition: file_exists(Cargo.toml)
13
+ ---
14
+
15
+ # Rust Development Skill
16
+
17
+ Conventions for Rust development, with a dedicated section for Zellij WASM plugin development.
18
+
19
+ ## Core Conventions
20
+
21
+ - **Rust stable** toolchain (`rustup default stable`)
22
+ - **Cargo** for build, test, lint, format — no external build tools needed
23
+ - **clippy** for linting, **rustfmt** for formatting
24
+ - **Edition 2021** minimum
25
+ - Workspace layout for multi-crate projects, single `Cargo.toml` otherwise
26
+
27
+ ## Project Scaffold
28
+
29
+ ```
30
+ <project>/
31
+ ├── Cargo.toml # Package metadata, deps, lint config
32
+ ├── rustfmt.toml # max_width = 100
33
+ ├── src/
34
+ │ ├── lib.rs # Library root (or main.rs for binary)
35
+ │ └── ...
36
+ ├── tests/
37
+ │ └── integration_test.rs
38
+ └── .github/workflows/ci.yml
39
+ ```
40
+
41
+ ## Tooling Quick Reference
42
+
43
+ ### Clippy (Linting)
44
+
45
+ ```bash
46
+ cargo clippy # Lint
47
+ cargo clippy -- -D warnings # Warnings as errors (CI)
48
+ cargo clippy --all-targets # Include tests/benches
49
+ cargo clippy --fix # Auto-fix
50
+ ```
51
+
52
+ Project config in `Cargo.toml`:
53
+ ```toml
54
+ [lints.clippy]
55
+ pedantic = { level = "warn", priority = -1 }
56
+ unwrap_used = "warn"
57
+ ```
58
+
59
+ ### Rustfmt (Formatting)
60
+
61
+ ```bash
62
+ cargo fmt # Format
63
+ cargo fmt -- --check # Check only (CI)
64
+ ```
65
+
66
+ ### Build & Test
67
+
68
+ ```bash
69
+ cargo build # Debug build
70
+ cargo build --release # Release build
71
+ cargo test # All tests
72
+ cargo test -- --nocapture # Show println output
73
+ cargo test test_name # Specific test
74
+ cargo test --lib # Unit tests only
75
+ cargo test --test integration_test # Specific integration test
76
+ ```
77
+
78
+ ### Other Useful Commands
79
+
80
+ ```bash
81
+ cargo doc --open # Generate and browse docs
82
+ cargo audit # Security vulnerability check
83
+ cargo tree # Dependency tree
84
+ cargo expand # Macro expansion
85
+ ```
86
+
87
+ ## Testing Patterns
88
+
89
+ ### Unit Tests (in-module)
90
+
91
+ ```rust
92
+ #[cfg(test)]
93
+ mod tests {
94
+ use super::*;
95
+
96
+ #[test]
97
+ fn test_parse_valid() {
98
+ let result = parse("input");
99
+ assert_eq!(result, expected);
100
+ }
101
+ }
102
+ ```
103
+
104
+ ### Async Tests (tokio)
105
+
106
+ ```rust
107
+ #[tokio::test]
108
+ async fn test_async_op() {
109
+ let result = fetch_data().await;
110
+ assert!(result.is_ok());
111
+ }
112
+ ```
113
+
114
+ ## Error Handling
115
+
116
+ | Context | Pattern |
117
+ |---------|---------|
118
+ | Libraries | `thiserror::Error` derive for custom error types |
119
+ | Applications | `anyhow::Result` for ergonomic error propagation |
120
+ | Unwrap | Never in library code; `expect("reason")` in main/tests only |
121
+
122
+ ## Common Dependencies
123
+
124
+ | Crate | Purpose |
125
+ |-------|---------|
126
+ | `serde` + `serde_json` | Serialization |
127
+ | `tokio` | Async runtime |
128
+ | `anyhow` / `thiserror` | Error handling |
129
+ | `clap` | CLI parsing |
130
+ | `tracing` | Structured logging |
131
+
132
+ ## CI/CD
133
+
134
+ ```yaml
135
+ name: CI
136
+ on: [push, pull_request]
137
+ jobs:
138
+ check:
139
+ runs-on: ubuntu-latest
140
+ steps:
141
+ - uses: actions/checkout@v4
142
+ - uses: dtolnay/rust-toolchain@stable
143
+ - run: cargo fmt -- --check
144
+ - run: cargo clippy -- -D warnings
145
+ - run: cargo test
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Zellij WASM Plugin Development
151
+
152
+ Zellij plugins are Rust crates compiled to `wasm32-wasip1`, loaded by the Zellij multiplexer. The `zellij-tile` crate provides the plugin API.
153
+
154
+ ### Setup
155
+
156
+ ```bash
157
+ rustup target add wasm32-wasip1
158
+ cargo build --release --target wasm32-wasip1
159
+ # Output: target/wasm32-wasip1/release/<name>.wasm
160
+ ```
161
+
162
+ ### Plugin Cargo.toml
163
+
164
+ ```toml
165
+ [dependencies]
166
+ zellij-tile = "0.41" # Match your Zellij version
167
+ serde = { version = "1", features = ["derive"] }
168
+ serde_json = "1"
169
+
170
+ [profile.release]
171
+ opt-level = "s" # Optimize for WASM size
172
+ lto = true
173
+ strip = true
174
+ ```
175
+
176
+ ### Plugin Lifecycle
177
+
178
+ ```rust
179
+ use zellij_tile::prelude::*;
180
+
181
+ #[derive(Default)]
182
+ struct MyPlugin { /* state */ }
183
+
184
+ impl ZellijPlugin for MyPlugin {
185
+ fn load(&mut self, config: BTreeMap<String, String>) {
186
+ subscribe(&[EventType::Timer, EventType::Key]);
187
+ request_permission(&[PermissionType::ReadApplicationState]);
188
+ set_timeout(10.0);
189
+ }
190
+
191
+ fn update(&mut self, event: Event) -> bool {
192
+ match event {
193
+ Event::Timer(_) => { set_timeout(10.0); true }
194
+ _ => false,
195
+ }
196
+ }
197
+
198
+ fn render(&mut self, rows: usize, cols: usize) {
199
+ print!("status: ok");
200
+ }
201
+
202
+ fn pipe(&mut self, pipe_message: PipeMessage) -> bool {
203
+ false
204
+ }
205
+ }
206
+
207
+ register_plugin!(MyPlugin);
208
+ ```
209
+
210
+ ### Permissions
211
+
212
+ | Permission | Allows |
213
+ |-----------|--------|
214
+ | `ReadApplicationState` | Query panes, tabs, session info |
215
+ | `ChangeApplicationState` | Create/close panes/tabs, switch focus |
216
+ | `RunCommands` | Execute commands in panes |
217
+ | `OpenFiles` | Open files in editor panes |
218
+ | `WriteToStdin` | Write to pane stdin |
219
+ | `ReadCliPipes` | Receive `zellij pipe` messages |
220
+
221
+ ### External Communication via Pipes
222
+
223
+ ```bash
224
+ echo '{"status":"ok"}' | zellij pipe --plugin "file:plugin.wasm" --name "update"
225
+ ```
226
+
227
+ Plugin handles in `fn pipe()`. Primary pattern for bridging external events into WASM plugins (WASM can't open sockets directly).
228
+
229
+ ### Loading in KDL Layouts
230
+
231
+ ```kdl
232
+ pane size=1 borderless=true {
233
+ plugin location="file:/path/to/plugin.wasm"
234
+ }
235
+ ```
236
+
237
+ ### WASM Constraints
238
+
239
+ | Limitation | Workaround |
240
+ |-----------|------------|
241
+ | No sockets | `zellij pipe` bridge from external script |
242
+ | No threads | `ZellijWorker` for background work |
243
+ | No system clock | `set_timeout()` for time-based logic |
244
+ | Binary size | `opt-level = "s"`, LTO, strip |
245
+
246
+ ## Debugging
247
+
248
+ ```bash
249
+ cargo test -- --nocapture # Show test output
250
+ RUST_BACKTRACE=1 cargo test # Full backtraces
251
+ RUST_LOG=debug cargo run # With tracing/env_logger
252
+
253
+ # WASM plugins
254
+ tail -f /tmp/zellij-*/zellij-log/zellij.log
255
+ ```
256
+
257
+ ## Common Gotchas
258
+
259
+ | Issue | Fix |
260
+ |-------|-----|
261
+ | `wasm32-wasip1` not found | `rustup target add wasm32-wasip1` |
262
+ | Plugin won't load | Check Zellij version matches `zellij-tile` crate version |
263
+ | Clippy too noisy | Tune via `[lints.clippy]` in Cargo.toml |
264
+ | WASM binary too large | `opt-level = "s"`, `lto = true`, `strip = true` |
265
+ | Can't open sockets in WASM | Use `zellij pipe` bridge pattern |
266
+ | Plugin doesn't re-render | Return `true` from `update()` or `pipe()` |
267
+ </content>
268
+ </invoke>
@@ -0,0 +1,206 @@
1
+ ---
2
+ name: security
3
+ description: Security checklist for code review and implementation. Covers input escaping, injection prevention, path traversal, process safety, dependency integrity, and secrets management. Load when working on user-facing code, template rendering, or process spawning.
4
+ ---
5
+
6
+ # Security Skill
7
+
8
+ Defensive coding practices. Apply these checks during implementation and review.
9
+
10
+ ## Input Escaping
11
+
12
+ ### Never interpolate user input into templates, scripts, or SQL
13
+
14
+ ```rust
15
+ // ❌ XSS: user-controlled value injected into JS string
16
+ let js = format!("var id = '{}';", user_input);
17
+
18
+ // ✅ Escape special characters before interpolation
19
+ fn escape_js_string(s: &str) -> String {
20
+ s.replace('\\', "\\\\")
21
+ .replace('\'', "\\'")
22
+ .replace('"', "\\\"")
23
+ .replace('<', "\\x3c")
24
+ .replace('>', "\\x3e")
25
+ .replace('\n', "\\n")
26
+ .replace('\r', "\\r")
27
+ }
28
+ let js = format!("var id = '{}';", escape_js_string(user_input));
29
+ ```
30
+
31
+ ```typescript
32
+ // ❌ Template injection
33
+ const html = `<div>${userInput}</div>`;
34
+
35
+ // ✅ Escape HTML entities
36
+ function escapeHtml(s: string): string {
37
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;")
38
+ .replace(/>/g, "&gt;").replace(/"/g, "&quot;");
39
+ }
40
+ const html = `<div>${escapeHtml(userInput)}</div>`;
41
+ ```
42
+
43
+ ### Context matters — escape for the target language
44
+
45
+ | Context | Escape | Characters |
46
+ |---------|--------|------------|
47
+ | HTML body | HTML entities | `& < > "` |
48
+ | HTML attribute | HTML entities + quote | `& < > " '` |
49
+ | JavaScript string | JS escapes | `\ ' " < > \n \r` |
50
+ | URL parameter | `encodeURIComponent` | All non-unreserved |
51
+ | SQL | Parameterized queries | Never interpolate |
52
+ | Shell command | Avoid if possible | Use `spawn(cmd, [args])` not `exec(string)` |
53
+
54
+ ## Path Traversal
55
+
56
+ ### Validate that resolved paths stay within the expected root
57
+
58
+ ```typescript
59
+ // ❌ User can escape with ../../etc/passwd
60
+ const filePath = join(rootDir, userInput);
61
+
62
+ // ✅ Resolve and verify containment
63
+ const resolved = resolve(rootDir, userInput);
64
+ if (!resolved.startsWith(resolve(rootDir) + sep) && resolved !== resolve(rootDir)) {
65
+ throw new Error("Path traversal attempt");
66
+ }
67
+ ```
68
+
69
+ ```rust
70
+ // ❌ No validation
71
+ let path = root.join(&user_path);
72
+
73
+ // ✅ Canonicalize and check prefix
74
+ let canonical = path.canonicalize()?;
75
+ if !canonical.starts_with(&root.canonicalize()?) {
76
+ return Err("Path traversal".into());
77
+ }
78
+ ```
79
+
80
+ ### Reject suspicious path components
81
+
82
+ - `..` segments
83
+ - Null bytes (`%00`, `\0`)
84
+ - Absolute paths when relative expected
85
+ - Symlinks that escape the root (use `canonicalize`/`realpath`)
86
+
87
+ ## Process Spawning
88
+
89
+ ### Use `spawn` with argument arrays, never shell interpolation
90
+
91
+ ```typescript
92
+ // ❌ Shell injection via userInput
93
+ execSync(`grep ${userInput} file.txt`);
94
+
95
+ // ✅ Arguments are not shell-interpreted
96
+ spawn("grep", [userInput, "file.txt"], { stdio: "pipe" });
97
+ ```
98
+
99
+ ### Never use `stdio: "inherit"` in TUI applications
100
+
101
+ Inherited stdio corrupts the terminal UI. Always use `"pipe"` or `"ignore"`.
102
+
103
+ ```typescript
104
+ // ❌ Corrupts TUI
105
+ spawn("some-tool", [], { stdio: "inherit" });
106
+
107
+ // ✅ Capture or discard
108
+ spawn("some-tool", [], { stdio: "pipe" });
109
+ spawn("some-tool", [], { stdio: "ignore" }); // fire-and-forget
110
+ ```
111
+
112
+ ### Limit `pkill`/`killall` scope
113
+
114
+ ```typescript
115
+ // ❌ Matches any process with "serve" in its command line
116
+ execSync("pkill -f 'ollama serve'");
117
+
118
+ // ✅ Track the PID you spawned and kill that specifically
119
+ if (child) { child.kill("SIGTERM"); child = null; }
120
+ ```
121
+
122
+ ### Set timeouts on child processes
123
+
124
+ ```typescript
125
+ const child = spawn("cmd", args);
126
+ const timer = setTimeout(() => {
127
+ child.kill("SIGTERM");
128
+ }, 300_000); // 5 min timeout
129
+
130
+ child.on("exit", () => clearTimeout(timer));
131
+ ```
132
+
133
+ ## Dependency Integrity
134
+
135
+ ### Pin CDN resources with Subresource Integrity (SRI)
136
+
137
+ ```html
138
+ <!-- ❌ No integrity check — CDN compromise = XSS -->
139
+ <script src="https://cdn.example.com/lib.js"></script>
140
+
141
+ <!-- ✅ SRI hash — browser rejects tampered content -->
142
+ <script src="https://cdn.example.com/lib.js"
143
+ integrity="sha384-abc123..."
144
+ crossorigin="anonymous"></script>
145
+ ```
146
+
147
+ ### Prefer bundling over CDN for offline-first tools
148
+
149
+ ```rust
150
+ // ✅ Bundle at compile time — no network dependency
151
+ const JS: &str = include_str!("../static/lib.min.js");
152
+ ```
153
+
154
+ ```typescript
155
+ // ✅ Import from node_modules, bundler handles it
156
+ import { force } from "force-graph";
157
+ ```
158
+
159
+ ## Secrets Management
160
+
161
+ - **Never hardcode secrets** — use environment variables or secret managers.
162
+ - **Never log secrets** — mask or omit sensitive values from log output.
163
+ - **Never commit secrets** — use `.gitignore` and pre-commit hooks.
164
+ - **Rotate on exposure** — if a secret appears in a commit, rotate immediately.
165
+
166
+ ```typescript
167
+ // ❌ Hardcoded
168
+ const apiKey = "sk-abc123";
169
+
170
+ // ✅ Environment variable
171
+ const apiKey = process.env.API_KEY;
172
+ if (!apiKey) throw new Error("API_KEY not set");
173
+ ```
174
+
175
+ ## TOCTOU (Time-of-Check to Time-of-Use)
176
+
177
+ When you check a condition and then act on it, the condition may change between check and action.
178
+
179
+ ```typescript
180
+ // ❌ TOCTOU: file may be deleted between check and read
181
+ if (existsSync(path)) {
182
+ const data = readFileSync(path); // may throw ENOENT
183
+ }
184
+
185
+ // ✅ Just try the operation and handle the error
186
+ try {
187
+ const data = readFileSync(path);
188
+ } catch (err) {
189
+ if ((err as NodeJS.ErrnoException).code === "ENOENT") {
190
+ // file doesn't exist — handle gracefully
191
+ } else throw err;
192
+ }
193
+ ```
194
+
195
+ ## Checklist
196
+
197
+ Before submitting code that handles external input:
198
+
199
+ - [ ] All user/external input is escaped for its target context
200
+ - [ ] File paths are validated against a root directory
201
+ - [ ] Child processes use argument arrays, not shell strings
202
+ - [ ] No `stdio: "inherit"` in TUI-hosted code
203
+ - [ ] CDN resources have SRI hashes or are bundled locally
204
+ - [ ] No secrets in source code or logs
205
+ - [ ] Error messages don't leak internal paths or stack traces to end users
206
+ - [ ] Timeouts set on all network requests and child processes