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,265 @@
1
+ /**
2
+ * Localhost-only HTTP server for the web UI extension.
3
+ *
4
+ * Binds exclusively to 127.0.0.1 (never 0.0.0.0).
5
+ * Serves a read-only dashboard shell and JSON slice routes.
6
+ * All mutation verbs are refused.
7
+ */
8
+
9
+ import * as http from "node:http";
10
+ import * as fs from "node:fs";
11
+ import * as path from "node:path";
12
+ import { fileURLToPath } from "node:url";
13
+ import { buildControlPlaneState, buildSlice } from "./state.ts";
14
+ import type { ControlPlaneState } from "./types.ts";
15
+
16
+ // ── Types ─────────────────────────────────────────────────────────────────────
17
+
18
+ export interface WebUIServerOptions {
19
+ /** Port to listen on. 0 = OS-assigned ephemeral port. Default: 0. */
20
+ port?: number;
21
+ /** Repository root used for state scans. Default: process.cwd(). */
22
+ repoRoot?: string;
23
+ }
24
+
25
+ export interface WebUIServer {
26
+ /** Bound port (available after start). */
27
+ readonly port: number;
28
+ /** Full localhost URL. */
29
+ readonly url: string;
30
+ /** Unix epoch ms when the server started. */
31
+ readonly startedAt: number;
32
+ /** Stop the server, rejecting new connections. */
33
+ stop(): Promise<void>;
34
+ }
35
+
36
+ // ── HTML shell ────────────────────────────────────────────────────────────────
37
+
38
+ const STATIC_DIR = path.join(path.dirname(fileURLToPath(import.meta.url)), "static");
39
+
40
+ // Cache shell content at module load time to avoid synchronous I/O on every request.
41
+ let _shellCache: string | null = null;
42
+
43
+ export function _resetShellCache(): void {
44
+ _shellCache = null;
45
+ }
46
+
47
+ function serveShell(): string {
48
+ if (_shellCache !== null) return _shellCache;
49
+ const indexPath = path.join(STATIC_DIR, "index.html");
50
+ if (fs.existsSync(indexPath)) {
51
+ _shellCache = fs.readFileSync(indexPath, "utf8");
52
+ } else {
53
+ // Inline fallback if static dir is unavailable
54
+ _shellCache = buildInlineShell();
55
+ }
56
+ return _shellCache;
57
+ }
58
+
59
+ function buildInlineShell(): string {
60
+ return `<!DOCTYPE html>
61
+ <html lang="en">
62
+ <head>
63
+ <meta charset="UTF-8" />
64
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
65
+ <title>omegon dashboard</title>
66
+ <style>
67
+ * { box-sizing: border-box; margin: 0; padding: 0; }
68
+ body { font-family: 'Menlo', 'Monaco', monospace; background: #0d1117; color: #c9d1d9; padding: 1rem; }
69
+ h1 { font-size: 1.2rem; margin-bottom: 1rem; color: #58a6ff; }
70
+ #status { font-size: 0.8rem; color: #8b949e; margin-bottom: 1rem; }
71
+ section { margin-bottom: 1.5rem; }
72
+ section h2 { font-size: 0.9rem; color: #79c0ff; border-bottom: 1px solid #30363d; padding-bottom: 0.25rem; margin-bottom: 0.5rem; }
73
+ pre { font-size: 0.75rem; background: #161b22; padding: 0.75rem; border-radius: 4px; overflow: auto; white-space: pre-wrap; }
74
+ .badge { display: inline-block; padding: 0.1rem 0.4rem; border-radius: 3px; font-size: 0.7rem; background: #21262d; color: #8b949e; margin-right: 0.25rem; }
75
+ .ok { background: #0d4429; color: #3fb950; }
76
+ </style>
77
+ </head>
78
+ <body>
79
+ <h1>omegon dashboard</h1>
80
+ <div id="status">Loading…</div>
81
+ <div id="root"></div>
82
+ <script>
83
+ const POLL_INTERVAL_MS = 3000;
84
+ let pollTimer = null;
85
+
86
+ async function fetchState() {
87
+ const res = await fetch('/api/state');
88
+ if (!res.ok) throw new Error('HTTP ' + res.status);
89
+ return res.json();
90
+ }
91
+
92
+ function renderSection(title, data) {
93
+ const section = document.createElement('section');
94
+ const h2 = document.createElement('h2');
95
+ h2.textContent = title;
96
+ const pre = document.createElement('pre');
97
+ pre.textContent = JSON.stringify(data, null, 2);
98
+ section.appendChild(h2);
99
+ section.appendChild(pre);
100
+ return section;
101
+ }
102
+
103
+ function render(state) {
104
+ const root = document.getElementById('root');
105
+ root.innerHTML = '';
106
+ root.appendChild(renderSection('Session', state.session));
107
+ root.appendChild(renderSection('Dashboard', state.dashboard));
108
+ root.appendChild(renderSection('Design Tree', state.designTree));
109
+ root.appendChild(renderSection('OpenSpec', state.openspec));
110
+ root.appendChild(renderSection('Cleave', state.cleave));
111
+ root.appendChild(renderSection('Models', state.models));
112
+ root.appendChild(renderSection('Memory', state.memory));
113
+ root.appendChild(renderSection('Health', state.health));
114
+ }
115
+
116
+ async function poll() {
117
+ try {
118
+ const state = await fetchState();
119
+ const now = new Date().toLocaleTimeString();
120
+ document.getElementById('status').innerHTML =
121
+ '<span class="badge ok">live</span> Last updated: ' + now +
122
+ ' &mdash; schema v' + state.schemaVersion;
123
+ render(state);
124
+ } catch (err) {
125
+ document.getElementById('status').textContent = 'Error: ' + err.message;
126
+ }
127
+ }
128
+
129
+ poll();
130
+ pollTimer = setInterval(poll, POLL_INTERVAL_MS);
131
+ </script>
132
+ </body>
133
+ </html>`;
134
+ }
135
+
136
+ // ── Routing ───────────────────────────────────────────────────────────────────
137
+
138
+ const SLICE_ROUTES: Record<string, keyof Omit<ControlPlaneState, "schemaVersion">> = {
139
+ "/api/session": "session",
140
+ "/api/dashboard": "dashboard",
141
+ "/api/design-tree": "designTree",
142
+ "/api/openspec": "openspec",
143
+ "/api/cleave": "cleave",
144
+ "/api/models": "models",
145
+ "/api/memory": "memory",
146
+ "/api/health": "health",
147
+ "/api/design-pipeline": "designPipeline",
148
+ };
149
+
150
+ function jsonResponse(
151
+ res: http.ServerResponse,
152
+ status: number,
153
+ body: unknown,
154
+ method = "GET"
155
+ ): void {
156
+ const payload = JSON.stringify(body);
157
+ res.writeHead(status, {
158
+ "Content-Type": "application/json",
159
+ "Content-Length": Buffer.byteLength(payload),
160
+ "Cache-Control": "no-store",
161
+ "X-Content-Type-Options": "nosniff",
162
+ });
163
+ res.end(method === "HEAD" ? undefined : payload);
164
+ }
165
+
166
+ function handleRequest(
167
+ req: http.IncomingMessage,
168
+ res: http.ServerResponse,
169
+ repoRoot: string,
170
+ startedAt: number
171
+ ): void {
172
+ const rawUrl = req.url ?? "/";
173
+ const url = new URL(rawUrl, "http://x").pathname;
174
+ const method = (req.method ?? "GET").toUpperCase();
175
+
176
+ // ── Root shell ──
177
+ if (url === "/" || url === "/index.html") {
178
+ if (method !== "GET" && method !== "HEAD") {
179
+ res.writeHead(405, { Allow: "GET, HEAD" });
180
+ res.end();
181
+ return;
182
+ }
183
+ const html = serveShell();
184
+ res.writeHead(200, {
185
+ "Content-Type": "text/html; charset=utf-8",
186
+ "Content-Length": Buffer.byteLength(html),
187
+ "Cache-Control": "no-store",
188
+ "X-Content-Type-Options": "nosniff",
189
+ });
190
+ res.end(method === "HEAD" ? undefined : html);
191
+ return;
192
+ }
193
+
194
+ // ── Full state snapshot ──
195
+ if (url === "/api/state") {
196
+ if (method !== "GET" && method !== "HEAD") {
197
+ // Refuse any mutation verb
198
+ return jsonResponse(res, 405, {
199
+ error: "Method Not Allowed",
200
+ detail: "This endpoint is read-only. POST/PUT/PATCH/DELETE are not supported.",
201
+ }, method);
202
+ }
203
+ const state = buildControlPlaneState(repoRoot, startedAt);
204
+ return jsonResponse(res, 200, state, method);
205
+ }
206
+
207
+ // ── Slice routes ──
208
+ const sliceKey = SLICE_ROUTES[url];
209
+ if (sliceKey !== undefined) {
210
+ if (method !== "GET" && method !== "HEAD") {
211
+ return jsonResponse(res, 405, { error: "Method Not Allowed" }, method);
212
+ }
213
+ const slice = buildSlice(sliceKey, repoRoot, startedAt);
214
+ return jsonResponse(res, 200, slice, method);
215
+ }
216
+
217
+ // ── 404 for everything else ──
218
+ jsonResponse(res, 404, { error: "Not Found" }, method);
219
+ }
220
+
221
+ // ── Server lifecycle ──────────────────────────────────────────────────────────
222
+
223
+ /**
224
+ * Start a localhost-only HTTP server.
225
+ *
226
+ * Binds to 127.0.0.1 only. The OS assigns an ephemeral port when port=0.
227
+ */
228
+ export function startWebUIServer(options: WebUIServerOptions = {}): Promise<WebUIServer> {
229
+ const repoRoot = options.repoRoot ?? process.cwd();
230
+ const port = options.port ?? 0;
231
+ const startedAt = Date.now();
232
+
233
+ return new Promise<WebUIServer>((resolve, reject) => {
234
+ const server = http.createServer((req, res) => {
235
+ handleRequest(req, res, repoRoot, startedAt);
236
+ });
237
+
238
+ server.once("error", reject);
239
+
240
+ server.listen(port, "127.0.0.1", () => {
241
+ const addr = server.address();
242
+ if (!addr || typeof addr === "string") {
243
+ server.close();
244
+ return reject(new Error("Failed to obtain server address"));
245
+ }
246
+
247
+ const boundPort = addr.port;
248
+ const url = `http://127.0.0.1:${boundPort}`;
249
+
250
+ const handle: WebUIServer = {
251
+ get port() { return boundPort; },
252
+ get url() { return url; },
253
+ get startedAt() { return startedAt; },
254
+ stop(): Promise<void> {
255
+ return new Promise((fulfill, fail) => {
256
+ server.closeAllConnections();
257
+ server.close((err) => (err ? fail(err) : fulfill()));
258
+ });
259
+ },
260
+ };
261
+
262
+ resolve(handle);
263
+ });
264
+ });
265
+ }