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,260 @@
1
+ /**
2
+ * cleave/planner — Split planning via LLM.
3
+ *
4
+ * Builds a planning prompt and delegates to either:
5
+ * - Local model (via ask_local_model) for faster/cheaper planning
6
+ * - Cloud model (via sendUserMessage) for complex splits
7
+ *
8
+ * The planner analyzes the directive + repo structure and produces
9
+ * a JSON split strategy with 2-4 children.
10
+ */
11
+
12
+ import type { ExtensionAPI } from "@cwilson613/pi-coding-agent";
13
+ import type { ChildPlan, SplitPlan } from "./types.ts";
14
+
15
+ /**
16
+ * Build the planning prompt.
17
+ *
18
+ * Adapted from styrene-lab/cleave orchestrator/prompt.py build_planner_prompt().
19
+ */
20
+ export function buildPlannerPrompt(
21
+ directive: string,
22
+ repoTree: string,
23
+ successCriteria: string[],
24
+ ): string {
25
+ const criteriaBlock = successCriteria.length > 0
26
+ ? "\n\nSuccess criteria:\n" + successCriteria.map((c) => `- ${c}`).join("\n")
27
+ : "";
28
+
29
+ return `Analyze this directive and produce a JSON split strategy for parallel execution.
30
+
31
+ Directive: ${directive}${criteriaBlock}
32
+
33
+ Repository structure (top-level):
34
+ ${repoTree}
35
+
36
+ Respond with ONLY a JSON object (no markdown fences, no explanation) matching this schema:
37
+
38
+ {
39
+ "children": [
40
+ {
41
+ "label": "short-kebab-case-label",
42
+ "description": "What this child task should accomplish in detail",
43
+ "scope": ["list", "of", "file/dir", "glob patterns", "this child owns"],
44
+ "depends_on": ["label-of-child-that-must-finish-first"]
45
+ }
46
+ ],
47
+ "rationale": "Brief explanation of why this decomposition makes sense"
48
+ }
49
+
50
+ Rules:
51
+ - 2-4 children
52
+ - Use depends_on only when one child's output feeds another. Omit or leave empty when children are independent.
53
+ - Children should have minimal file overlap
54
+ - Labels must be unique, kebab-case, max 40 chars
55
+ - Scope patterns use glob syntax (e.g., "src/auth/**", "tests/test_auth*")
56
+ - Each child must be completable with standard development tools`;
57
+ }
58
+
59
+ /**
60
+ * Get the top-level repo tree for context (directories and key files).
61
+ */
62
+ export async function getRepoTree(
63
+ pi: ExtensionAPI,
64
+ repoPath: string,
65
+ ): Promise<string> {
66
+ const result = await pi.exec(
67
+ "find",
68
+ [repoPath, "-maxdepth", "2", "-not", "-path", "*/.*", "-not", "-path", "*/node_modules/*",
69
+ "-not", "-path", "*/__pycache__/*", "-not", "-path", "*/dist/*"],
70
+ { timeout: 5_000 },
71
+ );
72
+
73
+ if (result.code !== 0) return "(unable to list directory)";
74
+
75
+ const lines = result.stdout
76
+ .split("\n")
77
+ .filter(Boolean)
78
+ .map((p) => {
79
+ const rel = p.replace(repoPath + "/", "").replace(repoPath, ".");
80
+ return rel;
81
+ })
82
+ .slice(0, 50);
83
+
84
+ return lines.join("\n");
85
+ }
86
+
87
+ /**
88
+ * Parse the planner's JSON response, handling common issues.
89
+ */
90
+ export function parsePlanResponse(response: string): SplitPlan {
91
+ let text = response.trim();
92
+
93
+ // Strip markdown code fences
94
+ if (text.startsWith("```")) {
95
+ const lines = text.split("\n");
96
+ lines.shift(); // remove opening fence
97
+ if (lines.length > 0 && lines[lines.length - 1].trim() === "```") {
98
+ lines.pop();
99
+ }
100
+ text = lines.join("\n").trim();
101
+ }
102
+
103
+ let data: any;
104
+ try {
105
+ data = JSON.parse(text);
106
+ } catch {
107
+ // Try to extract JSON object from surrounding text
108
+ const start = text.indexOf("{");
109
+ const end = text.lastIndexOf("}");
110
+ if (start >= 0 && end > start) {
111
+ try {
112
+ data = JSON.parse(text.slice(start, end + 1));
113
+ } catch {
114
+ throw new Error(`Could not parse planner response as JSON:\n${text.slice(0, 500)}`);
115
+ }
116
+ } else {
117
+ throw new Error(`No JSON found in planner response:\n${text.slice(0, 500)}`);
118
+ }
119
+ }
120
+
121
+ if (!data || typeof data !== "object") {
122
+ throw new Error("Planner response is not a JSON object");
123
+ }
124
+
125
+ const children: ChildPlan[] = data.children;
126
+ if (!Array.isArray(children) || children.length < 2) {
127
+ throw new Error(`Planner must produce at least 2 children, got ${children?.length ?? 0}`);
128
+ }
129
+
130
+ // Truncate to 4 max
131
+ if (children.length > 4) children.length = 4;
132
+
133
+ // Normalize and validate
134
+ const allLabels = new Set<string>();
135
+ for (const child of children) {
136
+ if (!child.label || !child.description) {
137
+ throw new Error("Each child must have 'label' and 'description'");
138
+ }
139
+ // Normalize label
140
+ child.label = child.label
141
+ .toLowerCase()
142
+ .replace(/[\s_]+/g, "-")
143
+ .replace(/[^a-z0-9-]/g, "")
144
+ .slice(0, 40);
145
+
146
+ child.scope = child.scope ?? [];
147
+ child.specDomains = child.specDomains ?? [];
148
+ child.skills = child.skills ?? [];
149
+ // Accept both camelCase and snake_case from LLM output
150
+ const rawDeps = child.dependsOn ?? (child as any).depends_on ?? [];
151
+ child.dependsOn = Array.isArray(rawDeps) ? rawDeps.map(String).filter(Boolean) : [];
152
+ delete (child as any).depends_on;
153
+
154
+ allLabels.add(child.label);
155
+ }
156
+
157
+ // Validate and prune dependencies
158
+ for (const child of children) {
159
+ // Remove self-dependencies
160
+ child.dependsOn = child.dependsOn.filter((d) => d !== child.label);
161
+ // Remove unknown references
162
+ child.dependsOn = child.dependsOn.filter((d) => allLabels.has(d));
163
+ }
164
+
165
+ // Cycle detection via Kahn's algorithm
166
+ detectAndBreakCycles(children);
167
+
168
+ return {
169
+ children,
170
+ rationale: data.rationale || "",
171
+ };
172
+ }
173
+
174
+ /**
175
+ * Detect dependency cycles via Kahn's algorithm and clear deps on cyclic nodes.
176
+ *
177
+ * Only modifies children if an actual cycle is detected — non-cyclic
178
+ * dependency chains are preserved.
179
+ */
180
+ function detectAndBreakCycles(children: ChildPlan[]): void {
181
+ const allLabels = new Set(children.map((c) => c.label));
182
+
183
+ // Compute in-degree: how many deps does each node have?
184
+ const inDegree = new Map<string, number>();
185
+ for (const c of children) {
186
+ // Only count deps that reference known labels
187
+ const validDeps = c.dependsOn.filter((d) => allLabels.has(d));
188
+ inDegree.set(c.label, validDeps.length);
189
+ }
190
+
191
+ // Start with nodes that have no dependencies (in-degree 0)
192
+ const queue = [...inDegree.entries()]
193
+ .filter(([, deg]) => deg === 0)
194
+ .map(([label]) => label);
195
+ const visited = new Set<string>();
196
+
197
+ while (queue.length > 0) {
198
+ const node = queue.shift()!;
199
+ visited.add(node);
200
+ // For each child that depends on this node, decrement its in-degree
201
+ for (const child of children) {
202
+ if (child.dependsOn.includes(node)) {
203
+ const newDeg = (inDegree.get(child.label) ?? 1) - 1;
204
+ inDegree.set(child.label, newDeg);
205
+ if (newDeg === 0) {
206
+ queue.push(child.label);
207
+ }
208
+ }
209
+ }
210
+ }
211
+
212
+ // Nodes not visited are in a cycle
213
+ const cyclic = new Set([...allLabels].filter((l) => !visited.has(l)));
214
+ if (cyclic.size > 0) {
215
+ for (const child of children) {
216
+ if (cyclic.has(child.label)) {
217
+ child.dependsOn = [];
218
+ }
219
+ }
220
+ }
221
+ }
222
+
223
+ /**
224
+ * Compute dispatch waves from children with dependency ordering.
225
+ *
226
+ * Children with no unmet deps go in wave 0, children whose deps
227
+ * are all in earlier waves go in the next wave, etc.
228
+ */
229
+ export function computeDispatchWaves(children: Array<{ label: string; dependsOn: string[] }>): string[][] {
230
+ if (children.length === 0) return [];
231
+
232
+ const remaining = new Set(children.map((c) => c.label));
233
+ const satisfied = new Set<string>();
234
+ const childMap = new Map(children.map((c) => [c.label, c]));
235
+ const waves: string[][] = [];
236
+
237
+ while (remaining.size > 0) {
238
+ const ready: string[] = [];
239
+ for (const label of [...remaining].sort()) {
240
+ const child = childMap.get(label)!;
241
+ const deps = new Set(child.dependsOn.filter((d) => childMap.has(d)));
242
+ if ([...deps].every((d) => satisfied.has(d))) {
243
+ ready.push(label);
244
+ }
245
+ }
246
+
247
+ if (ready.length === 0) {
248
+ // Deadlock breaker: dispatch all remaining
249
+ ready.push(...[...remaining].sort());
250
+ }
251
+
252
+ waves.push(ready);
253
+ for (const label of ready) {
254
+ remaining.delete(label);
255
+ satisfied.add(label);
256
+ }
257
+ }
258
+
259
+ return waves;
260
+ }