omegon 0.6.6 → 0.6.7

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.
package/README.md CHANGED
@@ -10,6 +10,8 @@ An opinionated distribution of [**pi**](https://github.com/badlogic/pi) — the
10
10
  npm install -g omegon
11
11
  ```
12
12
 
13
+ **Node requirement:** Omegon requires **Node.js 20+**. Node 18 will fail because bundled pi-tui uses modern Unicode regex features unsupported by older runtimes.
14
+
13
15
  This installs the canonical `omegon` command globally. A legacy `pi` alias may remain available for compatibility, but the supported lifecycle entrypoint is `omegon`. If a standalone pi package is already installed, omegon transparently takes ownership of the lifecycle boundary so startup, update, verification, and restart all stay inside Omegon control. To switch back to standalone pi at any time:
14
16
 
15
17
  ```bash
@@ -20,6 +20,8 @@ import { truncateTail, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize } from "
20
20
  import { Text } from "@styrene-lab/pi-tui";
21
21
  import { Type } from "@sinclair/typebox";
22
22
  import { spawn, execFile } from "node:child_process";
23
+ import * as fs from "node:fs";
24
+ import * as path from "node:path";
23
25
  import { promisify } from "node:util";
24
26
  import { createHash } from "node:crypto";
25
27
 
@@ -30,12 +32,11 @@ import { emitOpenSpecState } from "../openspec/dashboard-state.ts";
30
32
  import { getSharedBridge, buildSlashCommandResult } from "../lib/slash-command-bridge.ts";
31
33
  import { buildAssessBridgeResult } from "./bridge.ts";
32
34
  import { resolveOmegonSubprocess } from "../lib/omegon-subprocess.ts";
35
+ import { scanDesignDocs, getNodeSections } from "../design-tree/tree.ts";
33
36
  import {
34
37
  assessDirective,
35
38
  PATTERNS,
36
39
  runDesignStructuralCheck,
37
- buildDesignAssessmentPrompt,
38
- parseDesignAssessmentFindings,
39
40
  type AssessCompletion,
40
41
  type AssessEffect,
41
42
  type AssessLifecycleHint,
@@ -1422,119 +1423,6 @@ async function executeAssessComplexity(args: string): Promise<AssessStructuredRe
1422
1423
  });
1423
1424
  }
1424
1425
 
1425
- async function runDesignAssessmentSubprocess(
1426
- repoPath: string,
1427
- nodeId: string,
1428
- modelId?: string,
1429
- ): Promise<{ findings: DesignAssessmentFinding[]; nodeTitle: string; structuralPass: boolean }> {
1430
- const prompt = [
1431
- "You are performing a read-only design-tree node assessment.",
1432
- "Operate in read-only plan mode. Never call edit, write, or any workspace-mutating command.",
1433
- "",
1434
- `## Task`,
1435
- "",
1436
- `1. Call design_tree with action='node', node_id='${nodeId}' to load the node.`,
1437
- "2. Run the structural pre-check:",
1438
- " - open_questions must be empty — if not, emit a structural finding for each",
1439
- " - decisions must have at least one entry — if not, emit a structural finding",
1440
- " - acceptanceCriteria must have at least one scenario, falsifiability, or constraint — if not, emit a structural finding",
1441
- "3. If structural pre-check fails, output ONLY the JSON result below and stop.",
1442
- "4. Otherwise, evaluate each acceptance criterion against the document body:",
1443
- " - For each Scenario (Given/When/Then): does the document body address the Then clause?",
1444
- " - For each Falsifiability condition: is it addressed, ruled out, or acknowledged as a known risk?",
1445
- " - For each Constraint: is it satisfied by the document content?",
1446
- "",
1447
- "## Output Format",
1448
- "",
1449
- "Output ONLY a single JSON object (no prose, no markdown, no code blocks):",
1450
- "{",
1451
- ' "nodeTitle": "<title from node>",',
1452
- ' "structuralPass": true|false,',
1453
- ' "findings": [',
1454
- ' {"type":"scenario"|"falsifiability"|"constraint"|"structural","index":N,"pass":true|false,"finding":"<reason>"}',
1455
- " ]",
1456
- "}",
1457
- ].join("\n");
1458
-
1459
- const omegon = resolveOmegonSubprocess();
1460
- const args = [...omegon.argvPrefix, "--mode", "json", "--plan", "-p", "--no-session"];
1461
- if (modelId) args.push("--model", modelId);
1462
-
1463
- return await new Promise<{ findings: DesignAssessmentFinding[]; nodeTitle: string; structuralPass: boolean }>(
1464
- (resolve, reject) => {
1465
- const proc = spawn(omegon.command, args, {
1466
- cwd: repoPath,
1467
- shell: false,
1468
- stdio: ["pipe", "pipe", "pipe"],
1469
- env: { ...process.env, PI_CHILD: "1", TERM: process.env.TERM ?? "dumb" },
1470
- });
1471
- let buffer = "";
1472
- let assistantText = "";
1473
- let settled = false;
1474
- const settleReject = (error: Error) => {
1475
- if (settled) return;
1476
- settled = true;
1477
- clearTimeout(timer);
1478
- reject(error);
1479
- };
1480
- const settleResolve = (value: { findings: DesignAssessmentFinding[]; nodeTitle: string; structuralPass: boolean }) => {
1481
- if (settled) return;
1482
- settled = true;
1483
- clearTimeout(timer);
1484
- resolve(value);
1485
- };
1486
- const timer = setTimeout(() => {
1487
- proc.kill("SIGTERM");
1488
- setTimeout(() => { if (!proc.killed) proc.kill("SIGKILL"); }, 5_000);
1489
- settleReject(new Error(`Timed out after 120s while assessing design node ${nodeId}.`));
1490
- }, 120_000);
1491
- const processLine = (line: string) => {
1492
- if (!line.trim()) return;
1493
- let event: unknown;
1494
- try { event = JSON.parse(line); } catch { return; }
1495
- if (!event || typeof event !== "object") return;
1496
- const typed = event as { type?: string; message?: { role?: string; content?: unknown } };
1497
- if (typed.type === "message_end" && typed.message?.role === "assistant") {
1498
- assistantText = extractAssistantText(typed.message.content);
1499
- }
1500
- };
1501
- proc.stdout.on("data", (data) => {
1502
- buffer += (data as Buffer).toString();
1503
- const lines = buffer.split("\n");
1504
- buffer = lines.pop() || "";
1505
- for (const line of lines) processLine(line);
1506
- });
1507
- let stderr = "";
1508
- proc.stderr.on("data", (data) => { stderr += (data as Buffer).toString(); });
1509
- proc.on("error", (error) => settleReject(error));
1510
- proc.on("close", (code) => {
1511
- if (buffer.trim()) processLine(buffer.trim());
1512
- if ((code ?? 1) !== 0) {
1513
- settleReject(new Error(stderr.trim() || `Design assessment subprocess exited with code ${code ?? 1}.`));
1514
- return;
1515
- }
1516
- const jsonText = extractJsonObject(assistantText || buffer);
1517
- if (!jsonText) {
1518
- settleReject(new Error(`Design assessment subprocess did not return parseable JSON.\n${stderr}`));
1519
- return;
1520
- }
1521
- try {
1522
- const parsed = JSON.parse(jsonText) as { nodeTitle?: string; structuralPass?: boolean; findings?: DesignAssessmentFinding[] };
1523
- settleResolve({
1524
- nodeTitle: parsed.nodeTitle ?? nodeId,
1525
- structuralPass: parsed.structuralPass ?? true,
1526
- findings: Array.isArray(parsed.findings) ? parsed.findings : [],
1527
- });
1528
- } catch (err) {
1529
- settleReject(new Error(`Design assessment JSON was invalid: ${String(err)}`));
1530
- }
1531
- });
1532
- proc.stdin.write(prompt + "\n");
1533
- proc.stdin.end();
1534
- },
1535
- );
1536
- }
1537
-
1538
1426
  async function executeAssessDesign(
1539
1427
  pi: ExtensionAPI,
1540
1428
  ctx: AssessExecutionContext,
@@ -1604,23 +1492,69 @@ async function executeAssessDesign(
1604
1492
  }
1605
1493
 
1606
1494
  // Bridged / subprocess mode
1607
- let subResult: { findings: DesignAssessmentFinding[]; nodeTitle: string; structuralPass: boolean };
1608
- try {
1609
- subResult = await runDesignAssessmentSubprocess(cwd, nodeId, ctx.model?.id);
1610
- } catch (err) {
1611
- const msg = `Design assessment subprocess failed: ${String(err)}`;
1495
+ // Prefer an in-process deterministic fallback so design assessment does not depend
1496
+ // on a nested Omegon subprocess successfully loading a second extension graph.
1497
+ const tree = scanDesignDocs(path.join(cwd, "docs"));
1498
+ const node = tree.nodes.get(nodeId);
1499
+ if (!node) {
1500
+ const msg = `Design node '${nodeId}' not found under docs/.`;
1612
1501
  return makeAssessResult({
1613
1502
  subcommand: "design",
1614
1503
  args,
1615
1504
  ok: false,
1616
1505
  summary: msg,
1617
1506
  humanText: msg,
1618
- data: { reason: "subprocess_failed", nodeId },
1507
+ data: { reason: "node_not_found", nodeId },
1619
1508
  effects: [{ type: "view", content: msg }],
1620
1509
  });
1621
1510
  }
1622
-
1623
- const { findings, nodeTitle, structuralPass } = subResult;
1511
+ const sections = getNodeSections(node);
1512
+ const structuralFindings = runDesignStructuralCheck(nodeId, sections);
1513
+ const structuralPass = structuralFindings.length === 0;
1514
+ const documentBody = fs.readFileSync(node.filePath, "utf-8").toLowerCase();
1515
+ const normalizeCriterion = (value: string) => value.toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
1516
+ const includesCriterion = (value: string) => {
1517
+ const normalized = normalizeCriterion(value);
1518
+ if (!normalized) return true;
1519
+ return documentBody.includes(normalized) || normalized.split(/\s+/).filter(Boolean).every((part) => part.length < 4 || documentBody.includes(part));
1520
+ };
1521
+ const findings: DesignAssessmentFinding[] = [...structuralFindings];
1522
+ if (structuralPass) {
1523
+ sections.acceptanceCriteria.scenarios.forEach((scenario, index) => {
1524
+ const pass = includesCriterion(scenario.then);
1525
+ findings.push({
1526
+ type: "scenario",
1527
+ index,
1528
+ pass,
1529
+ finding: pass
1530
+ ? `Document addresses the scenario outcome: ${scenario.then}`
1531
+ : `Document does not clearly address the scenario outcome: ${scenario.then}`,
1532
+ });
1533
+ });
1534
+ sections.acceptanceCriteria.falsifiability.forEach((item, index) => {
1535
+ const pass = includesCriterion(item.condition);
1536
+ findings.push({
1537
+ type: "falsifiability",
1538
+ index,
1539
+ pass,
1540
+ finding: pass
1541
+ ? `Document addresses the falsifiability condition: ${item.condition}`
1542
+ : `Document does not clearly address the falsifiability condition: ${item.condition}`,
1543
+ });
1544
+ });
1545
+ sections.acceptanceCriteria.constraints.forEach((item, index) => {
1546
+ const pass = includesCriterion(item.text);
1547
+ findings.push({
1548
+ type: "constraint",
1549
+ index,
1550
+ pass,
1551
+ finding: pass
1552
+ ? `Document addresses the constraint: ${item.text}`
1553
+ : `Document does not clearly address the constraint: ${item.text}`,
1554
+ });
1555
+ });
1556
+ }
1557
+ const nodeTitle = node.title;
1624
1558
  const overallPass = structuralPass && findings.length > 0 && findings.every((f) => f.pass);
1625
1559
 
1626
1560
  const result: DesignAssessmentResult = { nodeId, pass: overallPass, structuralPass, findings };
@@ -598,7 +598,10 @@ export interface DirtyTreeClassificationOptions {
598
598
  volatileAllowlist?: string[];
599
599
  }
600
600
 
601
- export const DEFAULT_VOLATILE_ALLOWLIST = [".pi/memory/facts.jsonl"];
601
+ export const DEFAULT_VOLATILE_ALLOWLIST = [
602
+ ".pi/memory/facts.jsonl",
603
+ ".pi/runtime/operator-profile.json",
604
+ ];
602
605
 
603
606
  /**
604
607
  * Classify dirty-tree paths for preflight UX.
@@ -80,9 +80,9 @@ const EXECUTE_PARAMS = Type.Object({
80
80
  export type SlashCommandBridgeExecuteParams = Static<typeof EXECUTE_PARAMS>;
81
81
 
82
82
  function toArgString(args: readonly string[] | undefined): string {
83
- // Join args with spaces executors split on whitespace to extract subcommand and rest.
84
- // Individual args containing spaces are unsupported (none currently need them).
85
- return (args ?? []).join(" ");
83
+ // Preserve token boundaries for bridged execution (including args containing spaces).
84
+ // Structured executors in bridge mode can parse this JSON payload deterministically.
85
+ return JSON.stringify([...(args ?? [])]);
86
86
  }
87
87
 
88
88
  function summarize(command: string, args: readonly string[] | undefined): string {
@@ -55,6 +55,7 @@ import { DEFAULT_CONFIG, type MemoryConfig, type LifecycleMemoryCandidate } from
55
55
  import { sanitizeCompactionText, shouldInterceptCompaction } from "./compaction-policy.ts";
56
56
  import { writeJsonlIfChanged } from "./jsonl-io.ts";
57
57
  import {
58
+ computeMemoryBudgetPolicy,
58
59
  createMemoryInjectionMetrics,
59
60
  estimateTokensFromChars,
60
61
  formatMemoryInjectionMetrics,
@@ -1501,17 +1502,13 @@ export default function (pi: ExtensionAPI) {
1501
1502
  const usage = ctx.getContextUsage();
1502
1503
 
1503
1504
  // Budget: reserve space for other context (design-tree, system prompt, etc.)
1504
- // Use 15% of total context as memory budget, with a floor and ceiling.
1505
- // Estimate total tokens from current usage: tokens / (percent/100).
1506
- const usedTokens = usage?.tokens ?? 0;
1507
- const usedPercent = usage?.percent ?? 0;
1508
- const estimatedTotalTokens = usedPercent > 0
1509
- ? Math.round(usedTokens / (usedPercent / 100))
1510
- : 200_000; // safe default
1511
- const MAX_MEMORY_CHARS = Math.min(
1512
- Math.max(Math.round(estimatedTotalTokens * 0.15 * 4), 4_000), // 15% of context, min 4K chars
1513
- 16_000, // absolute ceiling
1514
- );
1505
+ // Routine turns should carry a much smaller memory payload by default.
1506
+ const budgetPolicy = computeMemoryBudgetPolicy({
1507
+ usedTokens: usage?.tokens,
1508
+ usedPercent: usage?.percent,
1509
+ userText,
1510
+ });
1511
+ const MAX_MEMORY_CHARS = budgetPolicy.maxChars;
1515
1512
 
1516
1513
  const allFacts = store.getActiveFacts(mind);
1517
1514
  const injectedIds = new Set<string>();
@@ -1578,22 +1575,24 @@ export default function (pi: ExtensionAPI) {
1578
1575
  // Ensures every section has representation even without a matching query.
1579
1576
  // This is what bulk mode got right that old semantic mode missed.
1580
1577
  const FILL_SECTIONS = ["Constraints", "Known Issues", "Patterns & Conventions", "Specs", "Recent Work"] as const;
1581
- for (const section of FILL_SECTIONS) {
1582
- if (currentChars >= MAX_MEMORY_CHARS) break;
1583
- const sectionFacts = allFacts
1584
- .filter(f => f.section === section)
1585
- .sort((a, b) => b.confidence - a.confidence)
1586
- .slice(0, 3);
1587
- for (const f of sectionFacts) {
1588
- if (!tryAdd(f)) break;
1578
+ if (budgetPolicy.includeStructuralFill) {
1579
+ for (const section of FILL_SECTIONS) {
1580
+ if (currentChars >= MAX_MEMORY_CHARS) break;
1581
+ const sectionFacts = allFacts
1582
+ .filter(f => f.section === section)
1583
+ .sort((a, b) => b.confidence - a.confidence)
1584
+ .slice(0, 2);
1585
+ for (const f of sectionFacts) {
1586
+ if (!tryAdd(f)) break;
1587
+ }
1589
1588
  }
1590
1589
  }
1591
1590
 
1592
1591
  // --- Tier 6: Recency fill — most recently reinforced not yet included ---
1593
- if (currentChars < MAX_MEMORY_CHARS) {
1592
+ if (budgetPolicy.includeStructuralFill && currentChars < MAX_MEMORY_CHARS) {
1594
1593
  const recentFacts = [...allFacts]
1595
1594
  .sort((a, b) => new Date(b.last_reinforced).getTime() - new Date(a.last_reinforced).getTime())
1596
- .slice(0, 20);
1595
+ .slice(0, 12);
1597
1596
  for (const f of recentFacts) {
1598
1597
  if (!tryAdd(f)) break;
1599
1598
  }
@@ -1605,7 +1604,7 @@ export default function (pi: ExtensionAPI) {
1605
1604
  // --- Global knowledge: semantic-gated, only when query is available ---
1606
1605
  let globalSection = "";
1607
1606
  let injectedGlobalFactCount = 0;
1608
- if (globalStore && userText.length > 10) {
1607
+ if (budgetPolicy.includeGlobalFacts && globalStore && userText.length > 10) {
1609
1608
  const globalMind = globalStore.getActiveMind() ?? "default";
1610
1609
  const globalFactCount = globalStore.countActiveFacts(globalMind);
1611
1610
  if (globalFactCount > 0) {
@@ -1633,7 +1632,7 @@ export default function (pi: ExtensionAPI) {
1633
1632
  let episodeSection = "";
1634
1633
  let injectedEpisodeCount = 0;
1635
1634
  const episodeCount = store.countEpisodes(mind);
1636
- if (episodeCount > 0) {
1635
+ if (budgetPolicy.includeEpisode && episodeCount > 0) {
1637
1636
  const recentEpisodes = store.getEpisodes(mind, 1);
1638
1637
  if (recentEpisodes.length > 0) {
1639
1638
  injectedEpisodeCount = recentEpisodes.length;
@@ -17,6 +17,38 @@ export interface MemoryInjectionMetrics {
17
17
  estimatedVsObservedDelta?: number | null;
18
18
  }
19
19
 
20
+ export interface MemoryBudgetPolicy {
21
+ maxChars: number;
22
+ includeStructuralFill: boolean;
23
+ includeGlobalFacts: boolean;
24
+ includeEpisode: boolean;
25
+ }
26
+
27
+ export function computeMemoryBudgetPolicy(input: {
28
+ usedTokens?: number | null;
29
+ usedPercent?: number | null;
30
+ userText?: string;
31
+ }): MemoryBudgetPolicy {
32
+ const usedTokens = input.usedTokens ?? 0;
33
+ const usedPercent = input.usedPercent ?? 0;
34
+ const userText = input.userText ?? "";
35
+ const estimatedTotalTokens = usedPercent > 0
36
+ ? Math.round(usedTokens / (usedPercent / 100))
37
+ : 200_000;
38
+ const maxChars = Math.min(
39
+ Math.max(Math.round(estimatedTotalTokens * 0.08 * 4), 2_000),
40
+ 8_000,
41
+ );
42
+ const trimmed = userText.trim();
43
+ const signalLength = trimmed.length;
44
+ const signalWords = trimmed.split(/\s+/).filter(Boolean).length;
45
+ const includeStructuralFill = signalLength >= 24 || signalWords >= 5;
46
+ const includeGlobalFacts = signalLength >= 48 || signalWords >= 8;
47
+ const includeEpisode = signalLength >= 64 || signalWords >= 10;
48
+
49
+ return { maxChars, includeStructuralFill, includeGlobalFacts, includeEpisode };
50
+ }
51
+
20
52
  export function estimateTokensFromChars(content: string): number {
21
53
  return Math.round(content.length / 4);
22
54
  }
@@ -0,0 +1,534 @@
1
+ {
2
+ "name": "@omegon/composition",
3
+ "version": "0.1.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "@omegon/composition",
9
+ "version": "0.1.0",
10
+ "dependencies": {
11
+ "@resvg/resvg-js": "^2.6.2",
12
+ "gifenc": "^1.0.3",
13
+ "jiti": "^2.4.2",
14
+ "react": "^18.3.1",
15
+ "react-dom": "^18.3.1",
16
+ "satori": "^0.11.2"
17
+ },
18
+ "devDependencies": {
19
+ "@types/react": "^18.3.12",
20
+ "@types/react-dom": "^18.3.1"
21
+ }
22
+ },
23
+ "node_modules/@resvg/resvg-js": {
24
+ "version": "2.6.2",
25
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js/-/resvg-js-2.6.2.tgz",
26
+ "integrity": "sha512-xBaJish5OeGmniDj9cW5PRa/PtmuVU3ziqrbr5xJj901ZDN4TosrVaNZpEiLZAxdfnhAe7uQ7QFWfjPe9d9K2Q==",
27
+ "license": "MPL-2.0",
28
+ "engines": {
29
+ "node": ">= 10"
30
+ },
31
+ "optionalDependencies": {
32
+ "@resvg/resvg-js-android-arm-eabi": "2.6.2",
33
+ "@resvg/resvg-js-android-arm64": "2.6.2",
34
+ "@resvg/resvg-js-darwin-arm64": "2.6.2",
35
+ "@resvg/resvg-js-darwin-x64": "2.6.2",
36
+ "@resvg/resvg-js-linux-arm-gnueabihf": "2.6.2",
37
+ "@resvg/resvg-js-linux-arm64-gnu": "2.6.2",
38
+ "@resvg/resvg-js-linux-arm64-musl": "2.6.2",
39
+ "@resvg/resvg-js-linux-x64-gnu": "2.6.2",
40
+ "@resvg/resvg-js-linux-x64-musl": "2.6.2",
41
+ "@resvg/resvg-js-win32-arm64-msvc": "2.6.2",
42
+ "@resvg/resvg-js-win32-ia32-msvc": "2.6.2",
43
+ "@resvg/resvg-js-win32-x64-msvc": "2.6.2"
44
+ }
45
+ },
46
+ "node_modules/@resvg/resvg-js-android-arm-eabi": {
47
+ "version": "2.6.2",
48
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-android-arm-eabi/-/resvg-js-android-arm-eabi-2.6.2.tgz",
49
+ "integrity": "sha512-FrJibrAk6v29eabIPgcTUMPXiEz8ssrAk7TXxsiZzww9UTQ1Z5KAbFJs+Z0Ez+VZTYgnE5IQJqBcoSiMebtPHA==",
50
+ "cpu": [
51
+ "arm"
52
+ ],
53
+ "license": "MPL-2.0",
54
+ "optional": true,
55
+ "os": [
56
+ "android"
57
+ ],
58
+ "engines": {
59
+ "node": ">= 10"
60
+ }
61
+ },
62
+ "node_modules/@resvg/resvg-js-android-arm64": {
63
+ "version": "2.6.2",
64
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-android-arm64/-/resvg-js-android-arm64-2.6.2.tgz",
65
+ "integrity": "sha512-VcOKezEhm2VqzXpcIJoITuvUS/fcjIw5NA/w3tjzWyzmvoCdd+QXIqy3FBGulWdClvp4g+IfUemigrkLThSjAQ==",
66
+ "cpu": [
67
+ "arm64"
68
+ ],
69
+ "license": "MPL-2.0",
70
+ "optional": true,
71
+ "os": [
72
+ "android"
73
+ ],
74
+ "engines": {
75
+ "node": ">= 10"
76
+ }
77
+ },
78
+ "node_modules/@resvg/resvg-js-darwin-arm64": {
79
+ "version": "2.6.2",
80
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-darwin-arm64/-/resvg-js-darwin-arm64-2.6.2.tgz",
81
+ "integrity": "sha512-nmok2LnAd6nLUKI16aEB9ydMC6Lidiiq2m1nEBDR1LaaP7FGs4AJ90qDraxX+CWlVuRlvNjyYJTNv8qFjtL9+A==",
82
+ "cpu": [
83
+ "arm64"
84
+ ],
85
+ "license": "MPL-2.0",
86
+ "optional": true,
87
+ "os": [
88
+ "darwin"
89
+ ],
90
+ "engines": {
91
+ "node": ">= 10"
92
+ }
93
+ },
94
+ "node_modules/@resvg/resvg-js-darwin-x64": {
95
+ "version": "2.6.2",
96
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-darwin-x64/-/resvg-js-darwin-x64-2.6.2.tgz",
97
+ "integrity": "sha512-GInyZLjgWDfsVT6+SHxQVRwNzV0AuA1uqGsOAW+0th56J7Nh6bHHKXHBWzUrihxMetcFDmQMAX1tZ1fZDYSRsw==",
98
+ "cpu": [
99
+ "x64"
100
+ ],
101
+ "license": "MPL-2.0",
102
+ "optional": true,
103
+ "os": [
104
+ "darwin"
105
+ ],
106
+ "engines": {
107
+ "node": ">= 10"
108
+ }
109
+ },
110
+ "node_modules/@resvg/resvg-js-linux-arm-gnueabihf": {
111
+ "version": "2.6.2",
112
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-arm-gnueabihf/-/resvg-js-linux-arm-gnueabihf-2.6.2.tgz",
113
+ "integrity": "sha512-YIV3u/R9zJbpqTTNwTZM5/ocWetDKGsro0SWp70eGEM9eV2MerWyBRZnQIgzU3YBnSBQ1RcxRZvY/UxwESfZIw==",
114
+ "cpu": [
115
+ "arm"
116
+ ],
117
+ "license": "MPL-2.0",
118
+ "optional": true,
119
+ "os": [
120
+ "linux"
121
+ ],
122
+ "engines": {
123
+ "node": ">= 10"
124
+ }
125
+ },
126
+ "node_modules/@resvg/resvg-js-linux-arm64-gnu": {
127
+ "version": "2.6.2",
128
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-arm64-gnu/-/resvg-js-linux-arm64-gnu-2.6.2.tgz",
129
+ "integrity": "sha512-zc2BlJSim7YR4FZDQ8OUoJg5holYzdiYMeobb9pJuGDidGL9KZUv7SbiD4E8oZogtYY42UZEap7dqkkYuA91pg==",
130
+ "cpu": [
131
+ "arm64"
132
+ ],
133
+ "license": "MPL-2.0",
134
+ "optional": true,
135
+ "os": [
136
+ "linux"
137
+ ],
138
+ "engines": {
139
+ "node": ">= 10"
140
+ }
141
+ },
142
+ "node_modules/@resvg/resvg-js-linux-arm64-musl": {
143
+ "version": "2.6.2",
144
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-arm64-musl/-/resvg-js-linux-arm64-musl-2.6.2.tgz",
145
+ "integrity": "sha512-3h3dLPWNgSsD4lQBJPb4f+kvdOSJHa5PjTYVsWHxLUzH4IFTJUAnmuWpw4KqyQ3NA5QCyhw4TWgxk3jRkQxEKg==",
146
+ "cpu": [
147
+ "arm64"
148
+ ],
149
+ "license": "MPL-2.0",
150
+ "optional": true,
151
+ "os": [
152
+ "linux"
153
+ ],
154
+ "engines": {
155
+ "node": ">= 10"
156
+ }
157
+ },
158
+ "node_modules/@resvg/resvg-js-linux-x64-gnu": {
159
+ "version": "2.6.2",
160
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-x64-gnu/-/resvg-js-linux-x64-gnu-2.6.2.tgz",
161
+ "integrity": "sha512-IVUe+ckIerA7xMZ50duAZzwf1U7khQe2E0QpUxu5MBJNao5RqC0zwV/Zm965vw6D3gGFUl7j4m+oJjubBVoftw==",
162
+ "cpu": [
163
+ "x64"
164
+ ],
165
+ "license": "MPL-2.0",
166
+ "optional": true,
167
+ "os": [
168
+ "linux"
169
+ ],
170
+ "engines": {
171
+ "node": ">= 10"
172
+ }
173
+ },
174
+ "node_modules/@resvg/resvg-js-linux-x64-musl": {
175
+ "version": "2.6.2",
176
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-x64-musl/-/resvg-js-linux-x64-musl-2.6.2.tgz",
177
+ "integrity": "sha512-UOf83vqTzoYQO9SZ0fPl2ZIFtNIz/Rr/y+7X8XRX1ZnBYsQ/tTb+cj9TE+KHOdmlTFBxhYzVkP2lRByCzqi4jQ==",
178
+ "cpu": [
179
+ "x64"
180
+ ],
181
+ "license": "MPL-2.0",
182
+ "optional": true,
183
+ "os": [
184
+ "linux"
185
+ ],
186
+ "engines": {
187
+ "node": ">= 10"
188
+ }
189
+ },
190
+ "node_modules/@resvg/resvg-js-win32-arm64-msvc": {
191
+ "version": "2.6.2",
192
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-win32-arm64-msvc/-/resvg-js-win32-arm64-msvc-2.6.2.tgz",
193
+ "integrity": "sha512-7C/RSgCa+7vqZ7qAbItfiaAWhyRSoD4l4BQAbVDqRRsRgY+S+hgS3in0Rxr7IorKUpGE69X48q6/nOAuTJQxeQ==",
194
+ "cpu": [
195
+ "arm64"
196
+ ],
197
+ "license": "MPL-2.0",
198
+ "optional": true,
199
+ "os": [
200
+ "win32"
201
+ ],
202
+ "engines": {
203
+ "node": ">= 10"
204
+ }
205
+ },
206
+ "node_modules/@resvg/resvg-js-win32-ia32-msvc": {
207
+ "version": "2.6.2",
208
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-win32-ia32-msvc/-/resvg-js-win32-ia32-msvc-2.6.2.tgz",
209
+ "integrity": "sha512-har4aPAlvjnLcil40AC77YDIk6loMawuJwFINEM7n0pZviwMkMvjb2W5ZirsNOZY4aDbo5tLx0wNMREp5Brk+w==",
210
+ "cpu": [
211
+ "ia32"
212
+ ],
213
+ "license": "MPL-2.0",
214
+ "optional": true,
215
+ "os": [
216
+ "win32"
217
+ ],
218
+ "engines": {
219
+ "node": ">= 10"
220
+ }
221
+ },
222
+ "node_modules/@resvg/resvg-js-win32-x64-msvc": {
223
+ "version": "2.6.2",
224
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-win32-x64-msvc/-/resvg-js-win32-x64-msvc-2.6.2.tgz",
225
+ "integrity": "sha512-ZXtYhtUr5SSaBrUDq7DiyjOFJqBVL/dOBN7N/qmi/pO0IgiWW/f/ue3nbvu9joWE5aAKDoIzy/CxsY0suwGosQ==",
226
+ "cpu": [
227
+ "x64"
228
+ ],
229
+ "license": "MPL-2.0",
230
+ "optional": true,
231
+ "os": [
232
+ "win32"
233
+ ],
234
+ "engines": {
235
+ "node": ">= 10"
236
+ }
237
+ },
238
+ "node_modules/@shuding/opentype.js": {
239
+ "version": "1.4.0-beta.0",
240
+ "resolved": "https://registry.npmjs.org/@shuding/opentype.js/-/opentype.js-1.4.0-beta.0.tgz",
241
+ "integrity": "sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==",
242
+ "license": "MIT",
243
+ "dependencies": {
244
+ "fflate": "^0.7.3",
245
+ "string.prototype.codepointat": "^0.2.1"
246
+ },
247
+ "bin": {
248
+ "ot": "bin/ot"
249
+ },
250
+ "engines": {
251
+ "node": ">= 8.0.0"
252
+ }
253
+ },
254
+ "node_modules/@types/prop-types": {
255
+ "version": "15.7.15",
256
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
257
+ "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
258
+ "dev": true,
259
+ "license": "MIT"
260
+ },
261
+ "node_modules/@types/react": {
262
+ "version": "18.3.28",
263
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.28.tgz",
264
+ "integrity": "sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==",
265
+ "dev": true,
266
+ "license": "MIT",
267
+ "dependencies": {
268
+ "@types/prop-types": "*",
269
+ "csstype": "^3.2.2"
270
+ }
271
+ },
272
+ "node_modules/@types/react-dom": {
273
+ "version": "18.3.7",
274
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
275
+ "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
276
+ "dev": true,
277
+ "license": "MIT",
278
+ "peerDependencies": {
279
+ "@types/react": "^18.0.0"
280
+ }
281
+ },
282
+ "node_modules/base64-js": {
283
+ "version": "0.0.8",
284
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
285
+ "integrity": "sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==",
286
+ "license": "MIT",
287
+ "engines": {
288
+ "node": ">= 0.4"
289
+ }
290
+ },
291
+ "node_modules/camelize": {
292
+ "version": "1.0.1",
293
+ "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
294
+ "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
295
+ "license": "MIT",
296
+ "funding": {
297
+ "url": "https://github.com/sponsors/ljharb"
298
+ }
299
+ },
300
+ "node_modules/color-name": {
301
+ "version": "1.1.4",
302
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
303
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
304
+ "license": "MIT"
305
+ },
306
+ "node_modules/css-background-parser": {
307
+ "version": "0.1.0",
308
+ "resolved": "https://registry.npmjs.org/css-background-parser/-/css-background-parser-0.1.0.tgz",
309
+ "integrity": "sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==",
310
+ "license": "MIT"
311
+ },
312
+ "node_modules/css-box-shadow": {
313
+ "version": "1.0.0-3",
314
+ "resolved": "https://registry.npmjs.org/css-box-shadow/-/css-box-shadow-1.0.0-3.tgz",
315
+ "integrity": "sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==",
316
+ "license": "MIT"
317
+ },
318
+ "node_modules/css-color-keywords": {
319
+ "version": "1.0.0",
320
+ "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
321
+ "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
322
+ "license": "ISC",
323
+ "engines": {
324
+ "node": ">=4"
325
+ }
326
+ },
327
+ "node_modules/css-gradient-parser": {
328
+ "version": "0.0.16",
329
+ "resolved": "https://registry.npmjs.org/css-gradient-parser/-/css-gradient-parser-0.0.16.tgz",
330
+ "integrity": "sha512-3O5QdqgFRUbXvK1x5INf1YkBz1UKSWqrd63vWsum8MNHDBYD5urm3QtxZbKU259OrEXNM26lP/MPY3d1IGkBgA==",
331
+ "license": "MIT",
332
+ "engines": {
333
+ "node": ">=16"
334
+ }
335
+ },
336
+ "node_modules/css-to-react-native": {
337
+ "version": "3.2.0",
338
+ "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
339
+ "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
340
+ "license": "MIT",
341
+ "dependencies": {
342
+ "camelize": "^1.0.0",
343
+ "css-color-keywords": "^1.0.0",
344
+ "postcss-value-parser": "^4.0.2"
345
+ }
346
+ },
347
+ "node_modules/csstype": {
348
+ "version": "3.2.3",
349
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
350
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
351
+ "dev": true,
352
+ "license": "MIT"
353
+ },
354
+ "node_modules/emoji-regex": {
355
+ "version": "10.6.0",
356
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
357
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
358
+ "license": "MIT"
359
+ },
360
+ "node_modules/escape-html": {
361
+ "version": "1.0.3",
362
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
363
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
364
+ "license": "MIT"
365
+ },
366
+ "node_modules/fflate": {
367
+ "version": "0.7.4",
368
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz",
369
+ "integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==",
370
+ "license": "MIT"
371
+ },
372
+ "node_modules/gifenc": {
373
+ "version": "1.0.3",
374
+ "resolved": "https://registry.npmjs.org/gifenc/-/gifenc-1.0.3.tgz",
375
+ "integrity": "sha512-xdr6AdrfGBcfzncONUOlXMBuc5wJDtOueE3c5rdG0oNgtINLD+f2iFZltrBRZYzACRbKr+mSVU/x98zv2u3jmw==",
376
+ "license": "MIT"
377
+ },
378
+ "node_modules/hex-rgb": {
379
+ "version": "4.3.0",
380
+ "resolved": "https://registry.npmjs.org/hex-rgb/-/hex-rgb-4.3.0.tgz",
381
+ "integrity": "sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==",
382
+ "license": "MIT",
383
+ "engines": {
384
+ "node": ">=6"
385
+ },
386
+ "funding": {
387
+ "url": "https://github.com/sponsors/sindresorhus"
388
+ }
389
+ },
390
+ "node_modules/jiti": {
391
+ "version": "2.6.1",
392
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
393
+ "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
394
+ "license": "MIT",
395
+ "bin": {
396
+ "jiti": "lib/jiti-cli.mjs"
397
+ }
398
+ },
399
+ "node_modules/js-tokens": {
400
+ "version": "4.0.0",
401
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
402
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
403
+ "license": "MIT"
404
+ },
405
+ "node_modules/linebreak": {
406
+ "version": "1.1.0",
407
+ "resolved": "https://registry.npmjs.org/linebreak/-/linebreak-1.1.0.tgz",
408
+ "integrity": "sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==",
409
+ "license": "MIT",
410
+ "dependencies": {
411
+ "base64-js": "0.0.8",
412
+ "unicode-trie": "^2.0.0"
413
+ }
414
+ },
415
+ "node_modules/loose-envify": {
416
+ "version": "1.4.0",
417
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
418
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
419
+ "license": "MIT",
420
+ "dependencies": {
421
+ "js-tokens": "^3.0.0 || ^4.0.0"
422
+ },
423
+ "bin": {
424
+ "loose-envify": "cli.js"
425
+ }
426
+ },
427
+ "node_modules/pako": {
428
+ "version": "0.2.9",
429
+ "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
430
+ "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==",
431
+ "license": "MIT"
432
+ },
433
+ "node_modules/parse-css-color": {
434
+ "version": "0.2.1",
435
+ "resolved": "https://registry.npmjs.org/parse-css-color/-/parse-css-color-0.2.1.tgz",
436
+ "integrity": "sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg==",
437
+ "license": "MIT",
438
+ "dependencies": {
439
+ "color-name": "^1.1.4",
440
+ "hex-rgb": "^4.1.0"
441
+ }
442
+ },
443
+ "node_modules/postcss-value-parser": {
444
+ "version": "4.2.0",
445
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
446
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
447
+ "license": "MIT"
448
+ },
449
+ "node_modules/react": {
450
+ "version": "18.3.1",
451
+ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
452
+ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
453
+ "license": "MIT",
454
+ "dependencies": {
455
+ "loose-envify": "^1.1.0"
456
+ },
457
+ "engines": {
458
+ "node": ">=0.10.0"
459
+ }
460
+ },
461
+ "node_modules/react-dom": {
462
+ "version": "18.3.1",
463
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
464
+ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
465
+ "license": "MIT",
466
+ "dependencies": {
467
+ "loose-envify": "^1.1.0",
468
+ "scheduler": "^0.23.2"
469
+ },
470
+ "peerDependencies": {
471
+ "react": "^18.3.1"
472
+ }
473
+ },
474
+ "node_modules/satori": {
475
+ "version": "0.11.3",
476
+ "resolved": "https://registry.npmjs.org/satori/-/satori-0.11.3.tgz",
477
+ "integrity": "sha512-Wg7sls0iYAEETzi9YYcY16QVIqXjZT06XjkwondC5CGhw1mhmgKBCub8cCmkxdl/naXXQD+m29CFgn8pwtYCnA==",
478
+ "license": "MPL-2.0",
479
+ "dependencies": {
480
+ "@shuding/opentype.js": "1.4.0-beta.0",
481
+ "css-background-parser": "^0.1.0",
482
+ "css-box-shadow": "1.0.0-3",
483
+ "css-gradient-parser": "^0.0.16",
484
+ "css-to-react-native": "^3.0.0",
485
+ "emoji-regex": "^10.2.1",
486
+ "escape-html": "^1.0.3",
487
+ "linebreak": "^1.1.0",
488
+ "parse-css-color": "^0.2.1",
489
+ "postcss-value-parser": "^4.2.0",
490
+ "yoga-wasm-web": "^0.3.3"
491
+ },
492
+ "engines": {
493
+ "node": ">=16"
494
+ }
495
+ },
496
+ "node_modules/scheduler": {
497
+ "version": "0.23.2",
498
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
499
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
500
+ "license": "MIT",
501
+ "dependencies": {
502
+ "loose-envify": "^1.1.0"
503
+ }
504
+ },
505
+ "node_modules/string.prototype.codepointat": {
506
+ "version": "0.2.1",
507
+ "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz",
508
+ "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==",
509
+ "license": "MIT"
510
+ },
511
+ "node_modules/tiny-inflate": {
512
+ "version": "1.0.3",
513
+ "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
514
+ "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==",
515
+ "license": "MIT"
516
+ },
517
+ "node_modules/unicode-trie": {
518
+ "version": "2.0.0",
519
+ "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz",
520
+ "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==",
521
+ "license": "MIT",
522
+ "dependencies": {
523
+ "pako": "^0.2.5",
524
+ "tiny-inflate": "^1.0.0"
525
+ }
526
+ },
527
+ "node_modules/yoga-wasm-web": {
528
+ "version": "0.3.3",
529
+ "resolved": "https://registry.npmjs.org/yoga-wasm-web/-/yoga-wasm-web-0.3.3.tgz",
530
+ "integrity": "sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==",
531
+ "license": "MIT"
532
+ }
533
+ }
534
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omegon",
3
- "version": "0.6.6",
3
+ "version": "0.6.7",
4
4
  "description": "Omegon — an opinionated distribution of pi (by Mario Zechner) with extensions for lifecycle management, memory, orchestration, and visualization",
5
5
  "bin": {
6
6
  "omegon": "bin/omegon.mjs",
@@ -32,6 +32,9 @@
32
32
  "url": "https://github.com/styrene-lab/omegon/issues"
33
33
  },
34
34
  "homepage": "https://github.com/styrene-lab/omegon#readme",
35
+ "engines": {
36
+ "node": ">=20.0.0"
37
+ },
35
38
  "pi": {
36
39
  "extensions": [
37
40
  "./extensions/bootstrap",
@@ -72,10 +75,10 @@
72
75
  ]
73
76
  },
74
77
  "dependencies": {
75
- "@styrene-lab/pi-coding-agent": "0.58.1-cwilson613.1",
76
- "@styrene-lab/pi-agent-core": "0.58.1",
77
- "@styrene-lab/pi-ai": "0.58.1-cwilson613.1",
78
- "@styrene-lab/pi-tui": "0.58.1-cwilson613.1",
78
+ "@styrene-lab/pi-coding-agent": "file:./vendor/pi-mono/packages/coding-agent",
79
+ "@styrene-lab/pi-agent-core": "file:./vendor/pi-mono/packages/agent",
80
+ "@styrene-lab/pi-ai": "file:./vendor/pi-mono/packages/ai",
81
+ "@styrene-lab/pi-tui": "file:./vendor/pi-mono/packages/tui",
79
82
  "@modelcontextprotocol/sdk": "^1.12.1",
80
83
  "@resvg/resvg-js": "^2.6.2",
81
84
  "@sinclair/typebox": "^0.34.48",
@@ -17,6 +17,16 @@
17
17
  #
18
18
  # Only acts during global installs (npm_config_global=true).
19
19
 
20
+ node_major="$(node -p 'process.versions.node.split(".")[0]' 2>/dev/null || echo 0)"
21
+ if [ "$node_major" -lt 20 ]; then
22
+ echo ""
23
+ echo " omegon: Unsupported Node.js runtime detected ($(node -v 2>/dev/null || echo unknown))."
24
+ echo " omegon: Omegon requires Node.js 20 or later because bundled pi-tui uses modern Unicode regex features."
25
+ echo " omegon: Upgrade Node.js to 20+ and retry the install/update."
26
+ echo ""
27
+ exit 1
28
+ fi
29
+
20
30
  if [ "$npm_config_global" != "true" ]; then
21
31
  exit 0
22
32
  fi
package/settings.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "lastChangelogVersion": "0.58.1-cwilson613.1",
3
+ "theme": "alpharius",
4
+ "defaultProvider": "anthropic",
5
+ "defaultModel": "claude-opus-4-6",
6
+ "defaultThinkingLevel": "low"
7
+ }