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,264 @@
1
+ ---
2
+ name: style
3
+ description: Unified visual style guide. Defines the Alpharius color system, typography, spacing, and semantic palette shared across pi TUI theme, Excalidraw diagrams, D2 diagrams, and generated images. Use when creating any visual output to ensure consistency.
4
+ ---
5
+
6
+ # Style Guide
7
+
8
+ Canonical design system for all visual output. Every diagram, theme, and generated image should derive from these tokens. When in doubt, reference this — not ad-hoc hex values.
9
+
10
+ ## Design Philosophy
11
+
12
+ **Alpharius** — dark, cold, precise. Deep void backgrounds with iridescent ceramite teal, silver-chrome highlights, and muted brass-gold signal warmth. The aesthetic of the XX Legion: disciplined, mercurial, beautiful in its deception. Every surface gleams like polished power armour under starlight.
13
+
14
+ Principles:
15
+ 1. **Semantic color, not decorative** — every color communicates purpose
16
+ 2. **Contrast over subtlety** — void backgrounds demand bright, readable foregrounds
17
+ 3. **Consistency across mediums** — same palette whether it's a TUI, an Excalidraw diagram, or a D2 chart
18
+ 4. **Hierarchy through scale and weight** — not through color proliferation
19
+ 5. **Document survivability matters** — technical diagrams are often embedded in documents and scaled down, so composition must preserve text and relationship legibility at page-fit sizes
20
+
21
+ ---
22
+
23
+ ## Color System
24
+
25
+ ### Core Palette
26
+
27
+ Derived from `themes/alpharius.json`. These are the ground-truth tokens.
28
+
29
+ | Token | Hex | Role |
30
+ |-------|-----|------|
31
+ | `primary` | `#2ab4c8` | Brand accent, interactive elements, focus — iridescent ceramite |
32
+ | `primaryMuted` | `#1a8898` | Secondary accent, labels, links |
33
+ | `primaryBright` | `#6ecad8` | Headings, highlighted text — silver-teal shimmer |
34
+ | `fg` | `#c4d8e4` | Primary text — cool silver-white |
35
+ | `mutedFg` | `#607888` | Secondary text, tool output, muted content |
36
+ | `dimFg` | `#344858` | Tertiary text, comments, inactive elements |
37
+ | `bg` | `#06080e` | Main background — the void |
38
+ | `cardBg` | `#0e1622` | Elevated surface (cards, panels) |
39
+ | `surfaceBg` | `#131e2e` | Secondary surface |
40
+ | `borderColor` | `#1a3448` | Standard borders |
41
+ | `borderDim` | `#0e1e30` | Subtle borders, separators |
42
+
43
+ ### Signal Colors
44
+
45
+ | Signal | Hex | Usage |
46
+ |--------|-----|-------|
47
+ | `green` | `#1ab878` | Success, completion, positive — hydra emerald |
48
+ | `red` | `#c83030` | Error, destructive, critical — blood of the false emperor |
49
+ | `orange` | `#c86418` | Warning, attention needed — hot metal |
50
+ | `yellow` | `#b89020` | Caution, numbers, highlights — tarnished brass |
51
+
52
+ ### Excalidraw Semantic Palette
53
+
54
+ For diagram elements. Maps purpose → fill/stroke pairs. Defined in `extensions/render/excalidraw/types.ts`.
55
+
56
+ | Purpose | Fill | Stroke | When to Use |
57
+ |---------|------|--------|-------------|
58
+ | `primary` | `#1a4a6e` | `#2ab4c8` | Default components, neutral nodes |
59
+ | `secondary` | `#1a3a5a` | `#1a8898` | Supporting/related components |
60
+ | `tertiary` | `#0e2a40` | `#344858` | Third-level, background detail |
61
+ | `start` | `#0e2e20` | `#1ab878` | Entry points, triggers, inputs |
62
+ | `end` | `#2e2010` | `#b89020` | Outputs, completion, results |
63
+ | `decision` | `#2a1010` | `#c83030` | Conditionals, branches, choices |
64
+ | `ai` | `#1a1040` | `#6060c0` | AI/LLM components, inference |
65
+ | `warning` | `#2a1808` | `#c86418` | Warnings, degraded states |
66
+ | `error` | `#2e0e0e` | `#c83030` | Error states, failures |
67
+ | `evidence` | `#06080e` | `#1a3448` | Code snippets, data samples, dark blocks |
68
+ | `inactive` | `#0e1622` | `#344858` | Disabled, inactive, future-state |
69
+
70
+ **Text on all semantic fills:** use `#c4d8e4` (Alpharius silver-white foreground) — all fills are dark enough to support it.
71
+
72
+ ### D2 Diagram Styling
73
+
74
+ When using `render_diagram` (D2), apply Alpharius colors via `style` blocks.
75
+
76
+ **Document-fit guidance for technical capability diagrams:**
77
+ - Assume the diagram may be embedded in a document and scaled down to fit a page column or page width.
78
+ - Prefer balanced aspect ratios that survive downscaling; avoid long, thin banners and tall skinny towers unless the document format explicitly demands them.
79
+ - Preserve legibility of both node text and relationship labels/arrows after reduction.
80
+ - If a layout becomes hard to read when scaled down, restructure it into a more compact cluster, multi-row arrangement, or grouped composition instead of relying on zoom.
81
+ - For capability maps, favor compact grouping and short labeled edges over sprawling left-to-right chains.
82
+
83
+ ```d2
84
+ component: API Server {
85
+ style: {
86
+ fill: "#1a4a6e"
87
+ stroke: "#2ab4c8"
88
+ font-color: "#c4d8e4"
89
+ border-radius: 8
90
+ }
91
+ }
92
+ ```
93
+
94
+ **Defaults:** D2 renders with `--theme 200` (dark) and `--layout elk`. Use semantic colors from the Excalidraw palette table above — they work identically in D2 style blocks.
95
+
96
+ **D2 connection styling:**
97
+ ```d2
98
+ a -> b: label {
99
+ style: {
100
+ stroke: "#2ab4c8"
101
+ font-color: "#c4d8e4"
102
+ }
103
+ }
104
+ ```
105
+
106
+ **D2 container styling (for groups/subgraphs):**
107
+ ```d2
108
+ group: Infrastructure {
109
+ style: {
110
+ fill: "#06080e"
111
+ stroke: "#1a3448"
112
+ font-color: "#6ecad8"
113
+ }
114
+
115
+ db: Database
116
+ cache: Redis
117
+ }
118
+ ```
119
+
120
+ ---
121
+
122
+ ## Kitty Compatibility
123
+
124
+ Pi renders everything in 24-bit RGB — Kitty's ANSI palette does **not** affect pi's own output. `themes/alpharius.conf` is a *compatibility layer*, not a full mirror. It sets only what matters:
125
+
126
+ | What | Why it must match |
127
+ |------|-------------------|
128
+ | `background` / `foreground` | Seamless blend between pi regions and naked terminal |
129
+ | `cursor` | On-palette feel in the editor |
130
+ | `selection_background` | Readable text selection |
131
+ | Tab bar / borders | Kitty chrome the agent can't control |
132
+ | ANSI signal colours (red/green/yellow) | Shell prompt, `ls`, `git diff` use these; matching alpharius values avoids jarring contrast |
133
+
134
+ Everything else (the remaining ANSI slots) uses reasonable dark-theme defaults that won't clash. They do not need to be exact alpharius values.
135
+
136
+ ### Install
137
+
138
+ ```conf
139
+ # in kitty.conf:
140
+ include /path/to/omegon/themes/alpharius.conf
141
+ ```
142
+
143
+ Regenerate after changing `background`, `foreground`, `cursor`, or border vars:
144
+
145
+ ```bash
146
+ npx tsx scripts/export-kitty-theme.ts
147
+ ```
148
+
149
+ ---
150
+
151
+ ## Typography
152
+
153
+ ### Font Stack
154
+
155
+ | Context | Font | Family ID | Notes |
156
+ |---------|------|-----------|-------|
157
+ | Diagrams (Excalidraw) | Cascadia | `3` | Monospace, clean, technical |
158
+ | Code blocks | Cascadia | — | Matches diagram text |
159
+ | TUI | Terminal default | — | Inherits from terminal emulator |
160
+
161
+ ### Scale
162
+
163
+ | Level | Size | Color | Use |
164
+ |-------|------|-------|-----|
165
+ | Title | 28px | `#2ab4c8` | Diagram titles, section headers |
166
+ | Subtitle | 20px | `#1a8898` | Sub-sections, group labels |
167
+ | Body | 16px | `#607888` | Default text, labels |
168
+ | Small | 12px | `#344858` | Annotations, fine print |
169
+
170
+ ### Text on Backgrounds
171
+
172
+ | Background | Text Color | Example |
173
+ |------------|------------|---------|
174
+ | Dark (all Alpharius fills) | `#c4d8e4` | Silver-white on void |
175
+ | Transparent / no fill | Stroke color or `#607888` | Inherits from context |
176
+
177
+ ---
178
+
179
+ ## Spacing & Layout
180
+
181
+ ### Grid
182
+
183
+ - Base unit: **20px**
184
+ - Excalidraw grid: 20px, step 5
185
+ - Minimum element gap: 20px
186
+ - Comfortable gap: 40px
187
+ - Section gap: 80px
188
+
189
+ ### Element Sizes (Excalidraw)
190
+
191
+ | Scale | Width × Height | Use |
192
+ |-------|---------------|-----|
193
+ | Hero | 300 × 150 | Visual anchor, primary focus |
194
+ | Primary | 180 × 90 | Standard components |
195
+ | Secondary | 120 × 60 | Supporting elements |
196
+ | Small | 60 × 40 | Indicators, dots, badges |
197
+ | Dot | 12 × 12 | Timeline markers, bullets |
198
+
199
+ ### Stroke
200
+
201
+ | Style | Width | Use |
202
+ |-------|-------|-----|
203
+ | Standard | 2px | Default for all elements |
204
+ | Emphasized | 3px | Highlighted paths, primary flow |
205
+ | Subtle | 1px | Background connections, annotations |
206
+
207
+ ---
208
+
209
+ ## Rendering Defaults
210
+
211
+ ### D2
212
+
213
+ - `--theme 200` — dark theme
214
+ - `--layout elk` — ELK layered algorithm (cleaner than dagre for most diagrams)
215
+ - `--pad 40` — comfortable padding
216
+ - Apply Alpharius colors via style blocks (see D2 Diagram Styling above)
217
+ - D2 is the default tool for straightforward structural diagrams with regular graph layout
218
+ - When the target is a document, prefer compact page-friendly compositions over panoramic or skyscraper aspect ratios
219
+ - Treat readability at reduced size as a first-class constraint for node labels and edge relationships
220
+ - Prefer the native SVG backend for document-bound technical diagrams that fit canonical motifs such as pipeline, fanout, or panel-split and need deterministic SVG/PNG output
221
+ - Switch to Excalidraw when the diagram needs explicit whitespace lanes, trust-boundary placement, phased panels, control-plane vs data-plane separation, or other layout-sensitive spatial composition beyond the native motif set
222
+
223
+ ### Excalidraw
224
+
225
+ - `roughness: 0` — clean, not hand-drawn
226
+ - `fillStyle: "solid"` — no hatching
227
+ - `strokeStyle: "solid"` — default; use `"dashed"` for optional/future
228
+ - `roundness: { type: 3 }` — adaptive corners on rectangles
229
+ - `fontFamily: 3` — Cascadia (monospace)
230
+ - `viewBackgroundColor: "#06080e"` — void black canvas
231
+ - Prefer Excalidraw for layout-sensitive capability maps, trust boundaries, phased flows, and other diagrams where local spacing and connector routing matter more than pure graph regularity
232
+ - When generating Excalidraw programmatically, keep it minimal and hand-crafted; prefer the native SVG backend for repeatable canonical document diagrams
233
+ - Use canonical layouts (`pipeline`, `fanout`, `converge`, `grid`) as the starting grammar for repeated architecture diagrams
234
+
235
+ ### FLUX.1 (Image Generation)
236
+
237
+ - Use `diagram` preset (1024×768) for technical visuals
238
+ - Use `schnell` for iteration, `dev` for finals
239
+ - Quantize to `4` bits on 16GB machines
240
+ - Prompts should reference the palette by description: "iridescent blue-green ceramite on deep void-black background, silver chrome highlights, alpha legion aesthetic"
241
+
242
+ ---
243
+
244
+ ## Quick Reference Card
245
+
246
+ ```
247
+ BACKGROUNDS ACCENTS SIGNALS
248
+ bg: #06080e primary: #2ab4c8 green: #1ab878
249
+ cardBg: #0e1622 primaryMu: #1a8898 red: #c83030
250
+ surfaceBg:#131e2e primaryBr: #6ecad8 orange: #c86418
251
+ yellow: #b89020
252
+
253
+ TEXT BORDERS
254
+ fg: #c4d8e4 border: #1a3448
255
+ mutedFg: #607888 borderDim: #0e1e30
256
+ dimFg: #344858
257
+
258
+ EXCALIDRAW SEMANTICS (fill / stroke)
259
+ primary: #1a4a6e / #2ab4c8 start: #0e2e20 / #1ab878
260
+ secondary: #1a3a5a / #1a8898 end: #2e2010 / #b89020
261
+ decision: #2a1010 / #c83030 ai: #1a1040 / #6060c0
262
+ warning: #2a1808 / #c86418 error: #2e0e0e / #c83030
263
+ evidence: #06080e / #1a3448 inactive: #0e1622 / #344858
264
+ ```
@@ -0,0 +1,225 @@
1
+ ---
2
+ name: typescript
3
+ description: TypeScript development conventions for Omegon. Covers strict typing, async patterns, error handling, Node.js API usage, and testing with node:test. Use when creating or modifying TypeScript code.
4
+ guardrails:
5
+ - name: typecheck
6
+ cmd: npx tsc --noEmit
7
+ timeout: 30
8
+ condition: file_exists(tsconfig.json)
9
+ ---
10
+
11
+ # TypeScript Development Skill
12
+
13
+ Conventions for TypeScript code in Omegon and related projects.
14
+
15
+ ## Strict Typing
16
+
17
+ - **Never use `any`** as a type annotation. Use `unknown` and narrow, or define a proper interface.
18
+ - **Prefer `interface` over `type`** for object shapes (better error messages, extensibility).
19
+ - **Use `as const` assertions** for literal arrays used as union sources.
20
+ - **Import types separately**: `import type { Foo } from "./bar.js"` — keeps runtime imports clean.
21
+
22
+ ```typescript
23
+ // ❌ Bad
24
+ const data: any = await resp.json();
25
+ function process(items: any[]) { ... }
26
+
27
+ // ✅ Good
28
+ interface ApiResponse { data: Model[]; total: number; }
29
+ const data: ApiResponse = await resp.json();
30
+ function process(items: readonly Model[]) { ... }
31
+ ```
32
+
33
+ ## Async Patterns
34
+
35
+ ### Don't mark functions `async` unless they `await`
36
+
37
+ ```typescript
38
+ // ❌ Unnecessarily async — wraps return value in an extra promise
39
+ const text = async (msg: string) => ({ content: msg });
40
+
41
+ // ✅ Sync function returns plain object
42
+ const text = (msg: string) => ({ content: msg });
43
+ ```
44
+
45
+ ### Don't `.then(r => r)` — it's a no-op identity transform
46
+
47
+ ```typescript
48
+ // ❌ Pointless promise chain
49
+ resolve(text("done").then(r => r));
50
+
51
+ // ✅ Direct
52
+ resolve(text("done"));
53
+ ```
54
+
55
+ ### Avoid `new Promise()` when `async/await` suffices
56
+
57
+ ```typescript
58
+ // ❌ Promise constructor anti-pattern
59
+ function doWork(): Promise<string> {
60
+ return new Promise((resolve) => {
61
+ someCallback((result) => resolve(result));
62
+ });
63
+ }
64
+
65
+ // ✅ Use promisify or async/await when possible
66
+ import { promisify } from "node:util";
67
+ const doWork = promisify(someCallback);
68
+ ```
69
+
70
+ ### Exception: `new Promise()` is correct for wrapping event-emitter APIs
71
+
72
+ ```typescript
73
+ // ✅ Correct use — child process exit is event-based, not promise-based
74
+ function runCommand(cmd: string): Promise<number> {
75
+ return new Promise((resolve) => {
76
+ const child = spawn("sh", ["-c", cmd]);
77
+ child.on("exit", (code) => resolve(code ?? 1));
78
+ child.on("error", () => resolve(1));
79
+ });
80
+ }
81
+ ```
82
+
83
+ ## Error Handling
84
+
85
+ - **Never swallow errors silently** — at minimum log or return an error indicator.
86
+ - **Use `catch` with typed narrowing**, not `catch (e: any)`.
87
+ - **Prefer returning error objects** over throwing in tool handlers.
88
+
89
+ ```typescript
90
+ // ❌ Swallowed error
91
+ try { await riskyOp(); } catch { }
92
+
93
+ // ✅ Intentional ignore with comment
94
+ try { await riskyOp(); } catch { /* expected: file may not exist */ }
95
+
96
+ // ✅ Error narrowing
97
+ try {
98
+ await riskyOp();
99
+ } catch (err) {
100
+ const message = err instanceof Error ? err.message : String(err);
101
+ return { error: message };
102
+ }
103
+ ```
104
+
105
+ ## Node.js API Usage
106
+
107
+ ### Use `node:` prefix for built-in modules
108
+
109
+ ```typescript
110
+ // ❌
111
+ import { readFileSync } from "fs";
112
+
113
+ // ✅
114
+ import { readFileSync } from "node:fs";
115
+ ```
116
+
117
+ ### Use `execSync` only for quick checks, never for long-running operations
118
+
119
+ ```typescript
120
+ // ✅ Quick binary check
121
+ function hasBinary(name: string): boolean {
122
+ try { execSync(`which ${name}`, { stdio: "ignore" }); return true; }
123
+ catch { return false; }
124
+ }
125
+
126
+ // ❌ Blocking install (hangs TUI for minutes)
127
+ execSync("cargo install my-tool");
128
+
129
+ // ✅ Async spawn for install
130
+ const child = spawn("cargo", ["install", "my-tool"], { stdio: "pipe" });
131
+ ```
132
+
133
+ ### Cache expensive checks that won't change mid-session
134
+
135
+ ```typescript
136
+ // ❌ Spawns a shell on every call
137
+ function hasOllama(): boolean {
138
+ try { execSync("which ollama", { stdio: "ignore" }); return true; }
139
+ catch { return false; }
140
+ }
141
+
142
+ // ✅ Cached
143
+ let _hasOllama: boolean | null = null;
144
+ function hasOllama(): boolean {
145
+ if (_hasOllama !== null) return _hasOllama;
146
+ try { execSync("which ollama", { stdio: "ignore" }); _hasOllama = true; }
147
+ catch { _hasOllama = false; }
148
+ return _hasOllama;
149
+ }
150
+ ```
151
+
152
+ ## Testing with `node:test`
153
+
154
+ Omegon uses the built-in Node.js test runner. Run with: `npx tsx --test extensions/**/*.test.ts`
155
+
156
+ ```typescript
157
+ import { describe, it } from "node:test";
158
+ import * as assert from "node:assert/strict";
159
+
160
+ describe("myModule", () => {
161
+ it("does the thing", () => {
162
+ assert.equal(myFunc(1), 2);
163
+ });
164
+
165
+ it("handles edge cases", () => {
166
+ assert.throws(() => myFunc(-1), /must be positive/);
167
+ });
168
+ });
169
+ ```
170
+
171
+ ### Test conventions
172
+
173
+ - **Test files**: `*.test.ts` co-located with source.
174
+ - **Import from source**, not compiled output — tsx handles compilation.
175
+ - **Test behavior, not implementation** — assert on public API results, not internal state.
176
+ - **Include negative tests** — error paths, invalid inputs, boundary values.
177
+ - **No mocking frameworks** — use dependency injection or simple stubs.
178
+
179
+ ## Module Conventions
180
+
181
+ - **Use `.js` extensions in imports** — TypeScript requires this for ESM resolution even though source files are `.ts`.
182
+ - **Export `default function`** for extension entry points.
183
+ - **Named exports** for utility modules (types, helpers).
184
+ - **No barrel files** (`index.ts` that re-exports everything) — import directly from the source module.
185
+
186
+ ```typescript
187
+ // ❌ Bare specifier
188
+ import { checkAll } from "./deps";
189
+
190
+ // ✅ With .js extension
191
+ import { checkAll } from "./deps.js";
192
+ ```
193
+
194
+ ## Code Organization
195
+
196
+ - **Single responsibility**: one concept per file. Split when a file exceeds ~400 lines.
197
+ - **Types first**: define interfaces at the top or in a `types.ts` file.
198
+ - **Pure functions in separate modules**: domain logic (`auth.ts`, `spec.ts`) separate from extension wiring (`index.ts`).
199
+ - **Avoid God objects**: don't accumulate state in a single closure. Extract helper functions.
200
+
201
+ ## Type Checking
202
+
203
+ Projects using runtime transpilation (jiti, tsx, esbuild, etc.) **must** run `tsc --noEmit` as a separate type-checking gate. Runtime transpilers strip types without checking them — type errors compile and run but silently produce incorrect behavior.
204
+
205
+ ```bash
206
+ # Add to package.json scripts
207
+ "typecheck": "tsc --noEmit"
208
+ "check": "tsc --noEmit && npm test"
209
+ ```
210
+
211
+ ### The Shadow Interface Anti-Pattern
212
+
213
+ **Never redefine types that exist in an upstream SDK.** When you copy-paste an interface instead of importing it, your local "shadow" drifts from the real type as the SDK evolves. The compiler can't catch the mismatch because it doesn't know they're supposed to be the same type.
214
+
215
+ ```typescript
216
+ // ❌ Shadow interface — drifts silently
217
+ interface ToolResult {
218
+ content: { type: string; text: string }[];
219
+ }
220
+
221
+ // ✅ Import from SDK
222
+ import type { AgentToolResult } from "@cwilson613/pi-coding-agent";
223
+ ```
224
+
225
+ **Directive:** Always import SDK types. Never redefine them locally. If an SDK type is not exported, file an issue or use module augmentation — don't copy the shape.
@@ -0,0 +1,102 @@
1
+ ---
2
+ name: vault
3
+ description: Obsidian-compatible markdown conventions for human-readable knowledge bases. Use when generating documentation, design docs, specs, or any interlinked markdown that humans will browse. Teaches wikilink syntax, frontmatter conventions, and vault-friendly file organization.
4
+ ---
5
+
6
+ # Vault Skill — Interlinked Markdown Conventions
7
+
8
+ Write markdown that renders beautifully in mdserve, Obsidian, and GitHub.
9
+
10
+ ## Wikilink Syntax
11
+
12
+ Use `[[wikilinks]]` to create navigable connections between documents:
13
+
14
+ ```markdown
15
+ See [[vision]] for the big picture.
16
+ Related: [[design-tree|Design Exploration Tree]]
17
+ ```
18
+
19
+ - `[[target]]` — links to the file whose slug matches `target`
20
+ - `[[target|Display Text]]` — links with custom display text
21
+ - Slugs are case-insensitive, spaces become hyphens
22
+ - Both filename-only (`[[vision]]`) and path slugs (`[[docs/vision]]`) resolve
23
+
24
+ Unresolved wikilinks render as styled concept references (italic, muted) — they're safe to use as forward references or concept tags.
25
+
26
+ ## Frontmatter
27
+
28
+ Always include YAML frontmatter with at least `title`:
29
+
30
+ ```yaml
31
+ ---
32
+ title: Architecture Decision Record
33
+ status: decided
34
+ tags: [architecture, crdt, storage]
35
+ ---
36
+ ```
37
+
38
+ Common fields:
39
+ - `title` — displayed in sidebar and graph labels
40
+ - `status` — seed, exploring, decided, blocked, deferred
41
+ - `tags` — for filtering and grouping
42
+ - `date` — ISO date for temporal ordering
43
+
44
+ ## File Organization
45
+
46
+ Structure directories so the hierarchy IS the navigation:
47
+
48
+ ```
49
+ project/
50
+ .pi/
51
+ design/ ← design tree nodes
52
+ memory/ ← memory index (generated)
53
+ openspec/
54
+ changes/
55
+ feature-name/
56
+ proposal.md ← what and why
57
+ design.md ← how (architecture decisions)
58
+ tasks.md ← work breakdown
59
+ specs/ ← Given/When/Then scenarios
60
+ docs/ ← long-lived documentation
61
+ ```
62
+
63
+ ## Graph-Friendly Patterns
64
+
65
+ - **Link generously** — every doc should link to at least one other doc
66
+ - **Backlink naturally** — if A links to B, B should mention A
67
+ - **Hub pages** — create index/MOC (Map of Content) files that link to all docs in a directory
68
+ - **Consistent naming** — use kebab-case for filenames (`architecture-decisions.md`)
69
+
70
+ ## Running the Viewer
71
+
72
+ ```bash
73
+ # Serve current project (recursive, all .md files)
74
+ mdserve .
75
+
76
+ # Serve specific directory
77
+ mdserve openspec/
78
+
79
+ # Auto-open browser
80
+ mdserve . --open
81
+
82
+ # Custom port
83
+ mdserve . --port 8080
84
+ ```
85
+
86
+ The viewer provides:
87
+ - Sidebar navigation with directory tree
88
+ - Live reload on file changes (WebSocket)
89
+ - Interactive graph view at `/graph`
90
+ - Theme picker (including Styrene dark theme)
91
+ - Per-project persistent settings
92
+
93
+ ## Installation
94
+
95
+ ```bash
96
+ # From source (requires Rust toolchain)
97
+ cargo install --git https://github.com/cwilson613/mdserve --branch feature/wikilinks-graph
98
+
99
+ # Or build locally
100
+ git clone https://github.com/cwilson613/mdserve
101
+ cd mdserve && cargo install --path .
102
+ ```
@@ -0,0 +1,85 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
3
+ "name": "default",
4
+ "vars": {
5
+ "primary": "#3dc9b0",
6
+ "primaryMuted": "#4a9e90",
7
+ "primaryBright": "#8ac4b8",
8
+ "fg": "#d4e8e4",
9
+ "mutedFg": "#8a9a96",
10
+ "dimFg": "#5c6b67",
11
+ "bg": "#0c0e12",
12
+ "cardBg": "#151c20",
13
+ "surfaceBg": "#1a2428",
14
+ "borderColor": "#2d4a47",
15
+ "borderDim": "#1e3533",
16
+ "green": "#34d399",
17
+ "red": "#f44747",
18
+ "orange": "#e98100",
19
+ "yellow": "#e9c400"
20
+ },
21
+ "colors": {
22
+ "accent": "primary",
23
+ "border": "borderColor",
24
+ "borderAccent": "primary",
25
+ "borderMuted": "borderDim",
26
+ "success": "green",
27
+ "error": "red",
28
+ "warning": "yellow",
29
+ "muted": "mutedFg",
30
+ "dim": "dimFg",
31
+ "text": "",
32
+ "thinkingText": "dimFg",
33
+
34
+ "selectedBg": "#1a2e2e",
35
+ "userMessageBg": "cardBg",
36
+ "userMessageText": "",
37
+ "customMessageBg": "surfaceBg",
38
+ "customMessageText": "",
39
+ "customMessageLabel": "primaryMuted",
40
+ "toolPendingBg": "#111820",
41
+ "toolSuccessBg": "#0f1f1a",
42
+ "toolErrorBg": "#1f1210",
43
+ "toolTitle": "primary",
44
+ "toolOutput": "mutedFg",
45
+
46
+ "mdHeading": "primaryBright",
47
+ "mdLink": "primaryMuted",
48
+ "mdLinkUrl": "dimFg",
49
+ "mdCode": "primary",
50
+ "mdCodeBlock": "fg",
51
+ "mdCodeBlockBorder": "borderColor",
52
+ "mdQuote": "mutedFg",
53
+ "mdQuoteBorder": "borderDim",
54
+ "mdHr": "borderColor",
55
+ "mdListBullet": "primary",
56
+
57
+ "toolDiffAdded": "green",
58
+ "toolDiffRemoved": "red",
59
+ "toolDiffContext": "mutedFg",
60
+
61
+ "syntaxComment": "#5c6b67",
62
+ "syntaxKeyword": "#3dc9b0",
63
+ "syntaxFunction": "#8ac4b8",
64
+ "syntaxVariable": "#d4e8e4",
65
+ "syntaxString": "#34d399",
66
+ "syntaxNumber": "#e9c400",
67
+ "syntaxType": "#5fb8a8",
68
+ "syntaxOperator": "#8a9a96",
69
+ "syntaxPunctuation": "#8a9a96",
70
+
71
+ "thinkingOff": "borderDim",
72
+ "thinkingMinimal": "dimFg",
73
+ "thinkingLow": "borderColor",
74
+ "thinkingMedium": "#357a6c",
75
+ "thinkingHigh": "primaryMuted",
76
+ "thinkingXhigh": "primary",
77
+
78
+ "bashMode": "primaryMuted"
79
+ },
80
+ "export": {
81
+ "pageBg": "#090b0e",
82
+ "cardBg": "#111820",
83
+ "infoBg": "#152a2a"
84
+ }
85
+ }