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,31 @@
1
+ import { buildSlashCommandResult } from "../lib/slash-command-bridge.ts";
2
+ import type { AssessStructuredResult } from "./assessment.ts";
3
+
4
+ export function buildAssessBridgeResult(
5
+ bridgedArgs: string[],
6
+ result: AssessStructuredResult,
7
+ ): ReturnType<typeof buildSlashCommandResult> {
8
+ return buildSlashCommandResult(result.command, bridgedArgs, {
9
+ ok: result.ok,
10
+ summary: result.summary,
11
+ humanText: result.humanText,
12
+ data: {
13
+ subcommand: result.subcommand,
14
+ data: result.data,
15
+ completion: result.completion,
16
+ lifecycleHint: result.lifecycle,
17
+ assessEffects: result.effects,
18
+ bridge: {
19
+ completionSemantics: result.completion?.completedInBand ? "synchronous" : "follow-up-driven",
20
+ completionState: result.completion?.completed ? "completed" : "pending",
21
+ originalArgs: [...bridgedArgs],
22
+ },
23
+ },
24
+ lifecycle: result.lifecycleRecord,
25
+ effects: {
26
+ sideEffectClass: result.subcommand === "cleave" ? "workspace-write" : "read",
27
+ lifecycleTouched: result.lifecycleRecord ? [result.lifecycleRecord.changeName] : undefined,
28
+ },
29
+ nextSteps: result.nextSteps.map((step) => ({ label: step })),
30
+ });
31
+ }
@@ -0,0 +1,250 @@
1
+ /**
2
+ * cleave/conflicts — 4-step conflict detection for reunification.
3
+ *
4
+ * Ported from styrene-lab/cleave src/cleave/core/conflicts.py.
5
+ * Pure functions with no runtime dependencies.
6
+ *
7
+ * Conflict types:
8
+ * 1. File Overlap — multiple children modified same file
9
+ * 2. Decision Contradiction — incompatible technology/approach choices
10
+ * 3. Interface Mismatch — published signatures differ
11
+ * 4. Assumption Violation — contradicts sibling's decision
12
+ */
13
+
14
+ import type { Conflict, TaskResult } from "./types.ts";
15
+
16
+ // ─── Task result parsing ────────────────────────────────────────────────────
17
+
18
+ /**
19
+ * Parse a task markdown file to extract result info for conflict detection.
20
+ *
21
+ * Expects the task file format used by the cleave workspace:
22
+ * - **Status:** SUCCESS|PARTIAL|FAILED|PENDING
23
+ * - **Summary:** ...
24
+ * - **Artifacts:** bullet list of file paths
25
+ * - **Decisions Made:** bullet list
26
+ * - **Assumptions:** bullet list
27
+ * - Interface signatures in backticks: `funcName(params) -> ReturnType`
28
+ */
29
+ export function parseTaskResult(content: string, filePath: string): TaskResult {
30
+ const result: TaskResult = {
31
+ path: filePath,
32
+ status: "PENDING",
33
+ summary: null,
34
+ fileClaims: [],
35
+ interfacesPublished: [],
36
+ decisions: [],
37
+ assumptions: [],
38
+ };
39
+
40
+ // Status
41
+ if (content.includes("**Status:** SUCCESS")) result.status = "SUCCESS";
42
+ else if (content.includes("**Status:** PARTIAL")) result.status = "PARTIAL";
43
+ else if (content.includes("**Status:** FAILED")) result.status = "FAILED";
44
+
45
+ // Summary
46
+ const summaryMatch = content.match(/\*\*Summary:\*\*\s*(.+?)(?:\n\*\*|\n##|$)/s);
47
+ if (summaryMatch) {
48
+ const summary = summaryMatch[1].trim();
49
+ if (!summary.startsWith("[")) result.summary = summary;
50
+ }
51
+
52
+ // Interfaces: `function_name(params) -> return_type`
53
+ const ifaceRe = /`([a-zA-Z_]\w*\([^)]*\)\s*->\s*[^`]+)`/g;
54
+ let ifaceMatch: RegExpExecArray | null;
55
+ while ((ifaceMatch = ifaceRe.exec(content)) !== null) {
56
+ result.interfacesPublished.push(ifaceMatch[1]);
57
+ }
58
+
59
+ // File claims from Artifacts section
60
+ const artifactsMatch = content.match(/\*\*Artifacts:\*\*\s*\n((?:\s*-\s*.+\n?)+)/);
61
+ if (artifactsMatch) {
62
+ const section = artifactsMatch[1];
63
+ // Quoted paths
64
+ for (const m of section.matchAll(/-\s*[`"']([^`"']+)[`"']/g)) {
65
+ const cleaned = m[1].trim().replace(/[,;:]$/, "");
66
+ if (cleaned && !cleaned.startsWith("[")) result.fileClaims.push(cleaned);
67
+ }
68
+ // Unquoted paths with extension
69
+ for (const m of section.matchAll(/-\s*([a-zA-Z0-9_./-]+\.[a-zA-Z0-9]+)(?:\s|$|,)/g)) {
70
+ const cleaned = m[1].trim().replace(/[,;:]$/, "");
71
+ if (cleaned && !cleaned.startsWith("[")) result.fileClaims.push(cleaned);
72
+ }
73
+ result.fileClaims = [...new Set(result.fileClaims)];
74
+ }
75
+
76
+ // Decisions
77
+ const decisionsMatch = content.match(/\*\*Decisions Made:\*\*\s*\n((?:\s*-\s*.+\n?)+)/);
78
+ if (decisionsMatch) {
79
+ result.decisions = [...decisionsMatch[1].matchAll(/-\s*(.+)/g)]
80
+ .map((m) => m[1].trim())
81
+ .filter((d) => d && !d.startsWith("["));
82
+ }
83
+
84
+ // Assumptions
85
+ const assumptionsMatch = content.match(/\*\*Assumptions:\*\*\s*\n((?:\s*-\s*.+\n?)+)/);
86
+ if (assumptionsMatch) {
87
+ result.assumptions = [...assumptionsMatch[1].matchAll(/-\s*(.+)/g)]
88
+ .map((m) => m[1].trim())
89
+ .filter((a) => a && !a.startsWith("["));
90
+ }
91
+
92
+ return result;
93
+ }
94
+
95
+ // ─── Conflict detection ─────────────────────────────────────────────────────
96
+
97
+ /** Technology contradiction pairs for decision conflict detection. */
98
+ const CONTRADICTION_PAIRS: [string[], string[]][] = [
99
+ [["redis", "use redis"], ["memcached", "use memcached"]],
100
+ [["sql", "postgresql", "mysql"], ["nosql", "mongodb", "dynamodb"]],
101
+ [["sync", "synchronous"], ["async", "asynchronous"]],
102
+ [["rest", "restful"], ["graphql", "grpc"]],
103
+ [["jwt"], ["session", "cookie-based"]],
104
+ ];
105
+
106
+ const REJECTION_PHRASES = ["instead of", "not ", "rather than", "over ", "rejected"];
107
+
108
+ /**
109
+ * Run 4-step conflict detection on parsed task results.
110
+ *
111
+ * Steps:
112
+ * 1. File Overlap — multiple children modified same file
113
+ * 2. Decision Contradiction — opposing technology choices
114
+ * 3. Interface Mismatch — conflicting function signatures
115
+ * 4. Assumption Violation — assumption contradicts sibling's decision
116
+ */
117
+ export function detectConflicts(results: TaskResult[]): Conflict[] {
118
+ const conflicts: Conflict[] = [];
119
+
120
+ // ── Step 1: File Overlap ──────────────────────────────────────────────
121
+ // Collect ALL claimants per file, then emit one conflict per file with
122
+ // all involved children (handles N-way overlaps, not just pairwise).
123
+ const fileClaims = new Map<string, number[]>();
124
+ for (let i = 0; i < results.length; i++) {
125
+ for (const file of results[i].fileClaims) {
126
+ const existing = fileClaims.get(file);
127
+ if (existing) {
128
+ existing.push(i);
129
+ } else {
130
+ fileClaims.set(file, [i]);
131
+ }
132
+ }
133
+ }
134
+ for (const [file, claimants] of fileClaims) {
135
+ if (claimants.length > 1) {
136
+ conflicts.push({
137
+ type: "file_overlap",
138
+ description: `Multiple children modified ${file}`,
139
+ involved: claimants,
140
+ resolution: "3way_merge",
141
+ });
142
+ }
143
+ }
144
+
145
+ // ── Step 2: Decision Contradiction ────────────────────────────────────
146
+ const allDecisions: Array<[number, string]> = [];
147
+ for (let i = 0; i < results.length; i++) {
148
+ for (const d of results[i].decisions) {
149
+ allDecisions.push([i, d.toLowerCase()]);
150
+ }
151
+ }
152
+
153
+ for (const [termsA, termsB] of CONTRADICTION_PAIRS) {
154
+ const siblingsA = new Set<number>();
155
+ const siblingsB = new Set<number>();
156
+
157
+ for (const [i, d] of allDecisions) {
158
+ const hasA = termsA.some((t) => d.includes(t));
159
+ const rejectedA = termsB.some((t) => d.includes(t)) && REJECTION_PHRASES.some((r) => d.includes(r));
160
+ if (hasA && !rejectedA) siblingsA.add(i);
161
+
162
+ const hasB = termsB.some((t) => d.includes(t));
163
+ const rejectedB = termsA.some((t) => d.includes(t)) && REJECTION_PHRASES.some((r) => d.includes(r));
164
+ if (hasB && !rejectedB) siblingsB.add(i);
165
+ }
166
+
167
+ // Only flag if DIFFERENT siblings made opposing choices
168
+ const uniqueA = new Set([...siblingsA].filter((x) => !siblingsB.has(x)));
169
+ const uniqueB = new Set([...siblingsB].filter((x) => !siblingsA.has(x)));
170
+
171
+ if (uniqueA.size > 0 && uniqueB.size > 0) {
172
+ conflicts.push({
173
+ type: "decision_contradiction",
174
+ description: `Contradictory decisions: ${termsA[0]} vs ${termsB[0]}`,
175
+ involved: [...uniqueA, ...uniqueB],
176
+ resolution: "escalate_to_parent",
177
+ });
178
+ }
179
+ }
180
+
181
+ // ── Step 3: Interface Mismatch ────────────────────────────────────────
182
+ const published = new Map<string, { signature: string; source: number }>();
183
+ for (let i = 0; i < results.length; i++) {
184
+ for (const iface of results[i].interfacesPublished) {
185
+ const funcName = iface.includes("(") ? iface.split("(")[0] : iface;
186
+ const existing = published.get(funcName);
187
+ if (existing && existing.signature !== iface) {
188
+ conflicts.push({
189
+ type: "interface_mismatch",
190
+ description: `Interface '${funcName}' has conflicting signatures`,
191
+ involved: [existing.source, i],
192
+ resolution: "adapter_required",
193
+ });
194
+ } else if (!existing) {
195
+ published.set(funcName, { signature: iface, source: i });
196
+ }
197
+ }
198
+ }
199
+
200
+ // ── Step 4: Assumption Violation ──────────────────────────────────────
201
+ // Only check assumption violations between siblings that have overlapping
202
+ // file scopes. In greenfield projects where each child creates entirely
203
+ // new files, cross-child assumption checking produces false positives
204
+ // from generic task description language.
205
+ const allAssumptions: Array<[number, string]> = [];
206
+ for (let i = 0; i < results.length; i++) {
207
+ for (const a of results[i].assumptions) {
208
+ allAssumptions.push([i, a.toLowerCase()]);
209
+ }
210
+ }
211
+
212
+ for (const [assIdx, assumption] of allAssumptions) {
213
+ for (const [decIdx, decision] of allDecisions) {
214
+ if (assIdx === decIdx) continue;
215
+
216
+ // Skip if the two siblings have zero file scope overlap.
217
+ // Non-overlapping children are unlikely to have real assumption
218
+ // violations — the detector would fire on generic phrasing.
219
+ const filesA = new Set(results[assIdx].fileClaims);
220
+ const filesB = results[decIdx].fileClaims;
221
+ const hasOverlap = filesB.some((f) => filesA.has(f));
222
+ if (filesA.size > 0 && filesB.length > 0 && !hasOverlap) continue;
223
+
224
+ // Check negation patterns
225
+ const negInAssumption =
226
+ assumption.includes("not ") &&
227
+ assumption
228
+ .replace("not ", "")
229
+ .split(/\s+/)
230
+ .some((w) => decision.includes(w));
231
+ const negInDecision =
232
+ decision.includes("not ") &&
233
+ decision
234
+ .replace("not ", "")
235
+ .split(/\s+/)
236
+ .some((w) => assumption.includes(w));
237
+
238
+ if (negInAssumption || negInDecision) {
239
+ conflicts.push({
240
+ type: "assumption_violation",
241
+ description: `Sibling ${assIdx}'s assumption may conflict with sibling ${decIdx}'s decision`,
242
+ involved: [assIdx, decIdx],
243
+ resolution: "verify_with_parent",
244
+ });
245
+ }
246
+ }
247
+ }
248
+
249
+ return conflicts;
250
+ }