@a-company/paradigm 3.21.0 → 3.22.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.
- package/dist/graph-BFZXFAFL.js +160 -0
- package/dist/graph-server-BPKQYSQK.js +188 -0
- package/dist/index.js +8 -0
- package/dist/mcp.js +260 -16
- package/graph-ui/dist/assets/index-BJ499n6C.css +1 -0
- package/graph-ui/dist/assets/index-EP5AoOxo.js +63 -0
- package/graph-ui/dist/index.html +13 -0
- package/package.json +4 -2
package/dist/mcp.js
CHANGED
|
@@ -2026,7 +2026,7 @@ function registerResources(server, getContext2) {
|
|
|
2026
2026
|
|
|
2027
2027
|
// ../paradigm-mcp/src/tools/index.ts
|
|
2028
2028
|
import * as os3 from "os";
|
|
2029
|
-
import * as
|
|
2029
|
+
import * as path26 from "path";
|
|
2030
2030
|
import {
|
|
2031
2031
|
ListToolsRequestSchema,
|
|
2032
2032
|
CallToolRequestSchema
|
|
@@ -2790,7 +2790,7 @@ function navigateExplore(config, target, rootDir) {
|
|
|
2790
2790
|
}
|
|
2791
2791
|
if (result.paths.length === 0) {
|
|
2792
2792
|
const areaSymbols = Object.entries(config.symbols).filter(
|
|
2793
|
-
([sym,
|
|
2793
|
+
([sym, path27]) => sym.toLowerCase().includes(targetLower) || path27.toLowerCase().includes(targetLower)
|
|
2794
2794
|
).slice(0, 10);
|
|
2795
2795
|
result.paths = [...new Set(areaSymbols.map(([, p]) => p))];
|
|
2796
2796
|
result.symbols = areaSymbols.map(([s]) => s);
|
|
@@ -11288,8 +11288,8 @@ function generateRunId() {
|
|
|
11288
11288
|
var TEMPLATE_REGEX = /\{\{([^}]+)\}\}/g;
|
|
11289
11289
|
function interpolate(value, scope) {
|
|
11290
11290
|
if (typeof value === "string") {
|
|
11291
|
-
return value.replace(TEMPLATE_REGEX, (_match,
|
|
11292
|
-
const resolved = resolvePath(
|
|
11291
|
+
return value.replace(TEMPLATE_REGEX, (_match, path27) => {
|
|
11292
|
+
const resolved = resolvePath(path27.trim(), scope);
|
|
11293
11293
|
return resolved !== void 0 ? String(resolved) : _match;
|
|
11294
11294
|
});
|
|
11295
11295
|
}
|
|
@@ -11322,8 +11322,8 @@ function resolvePath(dotPath, scope) {
|
|
|
11322
11322
|
return void 0;
|
|
11323
11323
|
}
|
|
11324
11324
|
}
|
|
11325
|
-
function deepGet(obj,
|
|
11326
|
-
const parts =
|
|
11325
|
+
function deepGet(obj, path27) {
|
|
11326
|
+
const parts = path27.split(/[.\[\]]+/).filter(Boolean);
|
|
11327
11327
|
let current = obj;
|
|
11328
11328
|
for (const part of parts) {
|
|
11329
11329
|
if (current == null || typeof current !== "object") return void 0;
|
|
@@ -11559,11 +11559,11 @@ async function runPersonaObject(rootDir, persona, options) {
|
|
|
11559
11559
|
}
|
|
11560
11560
|
async function runChain(rootDir, chainId, options) {
|
|
11561
11561
|
const start = Date.now();
|
|
11562
|
-
const
|
|
11563
|
-
const
|
|
11562
|
+
const fs23 = await import("fs");
|
|
11563
|
+
const path27 = await import("path");
|
|
11564
11564
|
const yaml14 = await import("js-yaml");
|
|
11565
|
-
const chainPath =
|
|
11566
|
-
if (!
|
|
11565
|
+
const chainPath = path27.join(rootDir, ".paradigm", "personas", "chains", `${chainId}.yaml`);
|
|
11566
|
+
if (!fs23.existsSync(chainPath)) {
|
|
11567
11567
|
return {
|
|
11568
11568
|
chain_id: chainId,
|
|
11569
11569
|
status: "error",
|
|
@@ -11572,7 +11572,7 @@ async function runChain(rootDir, chainId, options) {
|
|
|
11572
11572
|
duration_ms: Date.now() - start
|
|
11573
11573
|
};
|
|
11574
11574
|
}
|
|
11575
|
-
const chain = yaml14.load(
|
|
11575
|
+
const chain = yaml14.load(fs23.readFileSync(chainPath, "utf8"));
|
|
11576
11576
|
let permutation;
|
|
11577
11577
|
if (options.permutation && chain.permutations) {
|
|
11578
11578
|
permutation = chain.permutations.find((p) => p.id === options.permutation);
|
|
@@ -11676,8 +11676,8 @@ function validateInterpolation(persona) {
|
|
|
11676
11676
|
const serialized = JSON.stringify(step);
|
|
11677
11677
|
const templates = serialized.match(TEMPLATE_REGEX) || [];
|
|
11678
11678
|
for (const template of templates) {
|
|
11679
|
-
const
|
|
11680
|
-
const [namespace, ...rest] =
|
|
11679
|
+
const path27 = template.replace("{{", "").replace("}}", "").trim();
|
|
11680
|
+
const [namespace, ...rest] = path27.split(".");
|
|
11681
11681
|
const key = rest.join(".");
|
|
11682
11682
|
switch (namespace) {
|
|
11683
11683
|
case "fixtures":
|
|
@@ -12689,8 +12689,241 @@ function summarizeStep(step) {
|
|
|
12689
12689
|
return result;
|
|
12690
12690
|
}
|
|
12691
12691
|
|
|
12692
|
-
// ../paradigm-mcp/src/tools/
|
|
12692
|
+
// ../paradigm-mcp/src/tools/graph.ts
|
|
12693
|
+
import * as fs22 from "fs";
|
|
12693
12694
|
import * as path24 from "path";
|
|
12695
|
+
var CATEGORY_PREFIXES = {
|
|
12696
|
+
component: "#",
|
|
12697
|
+
flow: "$",
|
|
12698
|
+
gate: "^",
|
|
12699
|
+
signal: "!",
|
|
12700
|
+
aspect: "~"
|
|
12701
|
+
};
|
|
12702
|
+
var NODE_WIDTH = 200;
|
|
12703
|
+
var NODE_HEIGHT = 60;
|
|
12704
|
+
var NODE_GAP = 20;
|
|
12705
|
+
var GROUP_PADDING = 40;
|
|
12706
|
+
var GROUP_HEADER = 50;
|
|
12707
|
+
var GROUP_GAP = 60;
|
|
12708
|
+
function getGraphToolsList() {
|
|
12709
|
+
return [
|
|
12710
|
+
{
|
|
12711
|
+
name: "paradigm_graph_generate",
|
|
12712
|
+
description: "Generate a GraphState JSON document for the Paradigm Symbol Graph UI. Accepts optional symbols (filter), groups (clustering), and links (edges between groups). Returns valid GraphState ready to load. ~200 tokens.",
|
|
12713
|
+
inputSchema: {
|
|
12714
|
+
type: "object",
|
|
12715
|
+
properties: {
|
|
12716
|
+
symbols: {
|
|
12717
|
+
type: "array",
|
|
12718
|
+
items: { type: "string" },
|
|
12719
|
+
description: 'Symbol names to include (e.g. ["#auth-middleware", "^authenticated"]). Omit to include all from scan-index.'
|
|
12720
|
+
},
|
|
12721
|
+
groups: {
|
|
12722
|
+
type: "array",
|
|
12723
|
+
items: {
|
|
12724
|
+
type: "object",
|
|
12725
|
+
properties: {
|
|
12726
|
+
label: { type: "string", description: "Group display label" },
|
|
12727
|
+
symbols: {
|
|
12728
|
+
type: "array",
|
|
12729
|
+
items: { type: "string" },
|
|
12730
|
+
description: "Symbol names belonging to this group"
|
|
12731
|
+
}
|
|
12732
|
+
},
|
|
12733
|
+
required: ["label", "symbols"]
|
|
12734
|
+
},
|
|
12735
|
+
description: "Optional groupings of symbols."
|
|
12736
|
+
},
|
|
12737
|
+
links: {
|
|
12738
|
+
type: "array",
|
|
12739
|
+
items: {
|
|
12740
|
+
type: "object",
|
|
12741
|
+
properties: {
|
|
12742
|
+
source: { type: "string", description: "Source group label" },
|
|
12743
|
+
target: { type: "string", description: "Target group label" },
|
|
12744
|
+
label: { type: "string", description: "Edge label" }
|
|
12745
|
+
},
|
|
12746
|
+
required: ["source", "target"]
|
|
12747
|
+
},
|
|
12748
|
+
description: "Edges between groups (by label name)."
|
|
12749
|
+
},
|
|
12750
|
+
name: {
|
|
12751
|
+
type: "string",
|
|
12752
|
+
description: 'Graph name (default: "Generated Graph").'
|
|
12753
|
+
}
|
|
12754
|
+
}
|
|
12755
|
+
},
|
|
12756
|
+
annotations: {
|
|
12757
|
+
readOnlyHint: true,
|
|
12758
|
+
destructiveHint: false
|
|
12759
|
+
}
|
|
12760
|
+
}
|
|
12761
|
+
];
|
|
12762
|
+
}
|
|
12763
|
+
async function handleGraphTool(name, args, ctx) {
|
|
12764
|
+
if (name !== "paradigm_graph_generate") {
|
|
12765
|
+
return { handled: false, text: "" };
|
|
12766
|
+
}
|
|
12767
|
+
try {
|
|
12768
|
+
const result = buildGraphState(
|
|
12769
|
+
ctx.rootDir,
|
|
12770
|
+
args.symbols,
|
|
12771
|
+
args.groups,
|
|
12772
|
+
args.links,
|
|
12773
|
+
args.name || "Generated Graph"
|
|
12774
|
+
);
|
|
12775
|
+
const text = JSON.stringify(result, null, 2);
|
|
12776
|
+
trackToolCall(text.length, name);
|
|
12777
|
+
return { handled: true, text };
|
|
12778
|
+
} catch (err2) {
|
|
12779
|
+
const text = JSON.stringify({ error: err2.message }, null, 2);
|
|
12780
|
+
trackToolCall(text.length, name);
|
|
12781
|
+
return { handled: true, text };
|
|
12782
|
+
}
|
|
12783
|
+
}
|
|
12784
|
+
var SCAN_CATEGORY_MAP = {
|
|
12785
|
+
components: "component",
|
|
12786
|
+
flows: "flow",
|
|
12787
|
+
gates: "gate",
|
|
12788
|
+
signals: "signal",
|
|
12789
|
+
aspects: "aspect"
|
|
12790
|
+
};
|
|
12791
|
+
function loadScanIndex(rootDir) {
|
|
12792
|
+
const indexPath = path24.join(rootDir, ".paradigm", "scan-index.json");
|
|
12793
|
+
if (!fs22.existsSync(indexPath)) return [];
|
|
12794
|
+
const raw = JSON.parse(fs22.readFileSync(indexPath, "utf8"));
|
|
12795
|
+
const symbols = [];
|
|
12796
|
+
for (const [sectionKey, categoryName] of Object.entries(SCAN_CATEGORY_MAP)) {
|
|
12797
|
+
const section = raw[sectionKey];
|
|
12798
|
+
if (!section || typeof section !== "object") continue;
|
|
12799
|
+
for (const [id, sym] of Object.entries(section)) {
|
|
12800
|
+
const s = sym;
|
|
12801
|
+
symbols.push({
|
|
12802
|
+
id,
|
|
12803
|
+
name: id,
|
|
12804
|
+
category: categoryName,
|
|
12805
|
+
prefix: CATEGORY_PREFIXES[categoryName] || "#",
|
|
12806
|
+
description: s.description,
|
|
12807
|
+
path: s.path,
|
|
12808
|
+
tags: s.tags
|
|
12809
|
+
});
|
|
12810
|
+
}
|
|
12811
|
+
}
|
|
12812
|
+
return symbols;
|
|
12813
|
+
}
|
|
12814
|
+
function resolveSymbol(name, allSymbols) {
|
|
12815
|
+
const stripped = name.replace(/^[#$^!~]/, "");
|
|
12816
|
+
return allSymbols.find(
|
|
12817
|
+
(s) => s.id === stripped || s.name === stripped || s.id === name || s.name === name
|
|
12818
|
+
);
|
|
12819
|
+
}
|
|
12820
|
+
function buildGraphState(rootDir, symbolFilter, groups, links, graphName = "Generated Graph") {
|
|
12821
|
+
const allSymbols = loadScanIndex(rootDir);
|
|
12822
|
+
let included;
|
|
12823
|
+
if (symbolFilter && symbolFilter.length > 0) {
|
|
12824
|
+
included = symbolFilter.map((name) => resolveSymbol(name, allSymbols)).filter(Boolean);
|
|
12825
|
+
} else {
|
|
12826
|
+
included = allSymbols;
|
|
12827
|
+
}
|
|
12828
|
+
const nodes = [];
|
|
12829
|
+
const edges = [];
|
|
12830
|
+
const groupIdMap = /* @__PURE__ */ new Map();
|
|
12831
|
+
const assignedSymbols = /* @__PURE__ */ new Set();
|
|
12832
|
+
let nextGroupX = 0;
|
|
12833
|
+
if (groups && groups.length > 0) {
|
|
12834
|
+
for (const group of groups) {
|
|
12835
|
+
const groupId = `group-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
12836
|
+
groupIdMap.set(group.label, groupId);
|
|
12837
|
+
const memberSymbols = group.symbols.map((name) => resolveSymbol(name, included)).filter(Boolean);
|
|
12838
|
+
const cols = Math.ceil(Math.sqrt(memberSymbols.length));
|
|
12839
|
+
const rows = Math.ceil(memberSymbols.length / cols);
|
|
12840
|
+
for (let i = 0; i < memberSymbols.length; i++) {
|
|
12841
|
+
const sym = memberSymbols[i];
|
|
12842
|
+
const col = i % cols;
|
|
12843
|
+
const row = Math.floor(i / cols);
|
|
12844
|
+
const prefix = CATEGORY_PREFIXES[sym.category] || "#";
|
|
12845
|
+
nodes.push({
|
|
12846
|
+
id: `sym-${sym.id}`,
|
|
12847
|
+
type: "symbolNode",
|
|
12848
|
+
position: {
|
|
12849
|
+
x: GROUP_PADDING + col * (NODE_WIDTH + NODE_GAP),
|
|
12850
|
+
y: GROUP_HEADER + GROUP_PADDING + row * (NODE_HEIGHT + NODE_GAP)
|
|
12851
|
+
},
|
|
12852
|
+
parentId: groupId,
|
|
12853
|
+
data: {
|
|
12854
|
+
type: "symbol",
|
|
12855
|
+
symbol: sym,
|
|
12856
|
+
label: `${prefix}${sym.name}`
|
|
12857
|
+
}
|
|
12858
|
+
});
|
|
12859
|
+
assignedSymbols.add(sym.id);
|
|
12860
|
+
}
|
|
12861
|
+
const cols2 = Math.max(cols, 1);
|
|
12862
|
+
const rows2 = Math.max(rows, 1);
|
|
12863
|
+
const groupWidth = GROUP_PADDING * 2 + cols2 * NODE_WIDTH + (cols2 - 1) * NODE_GAP;
|
|
12864
|
+
const groupHeight = GROUP_HEADER + GROUP_PADDING * 2 + rows2 * NODE_HEIGHT + (rows2 - 1) * NODE_GAP;
|
|
12865
|
+
nodes.unshift({
|
|
12866
|
+
id: groupId,
|
|
12867
|
+
type: "groupNode",
|
|
12868
|
+
position: { x: nextGroupX, y: 0 },
|
|
12869
|
+
style: { width: groupWidth, height: groupHeight },
|
|
12870
|
+
data: { type: "group", label: group.label }
|
|
12871
|
+
});
|
|
12872
|
+
nextGroupX += groupWidth + GROUP_GAP;
|
|
12873
|
+
}
|
|
12874
|
+
}
|
|
12875
|
+
const ungrouped = included.filter((s) => !assignedSymbols.has(s.id));
|
|
12876
|
+
if (ungrouped.length > 0) {
|
|
12877
|
+
const startY = groups && groups.length > 0 ? 400 : 0;
|
|
12878
|
+
const cols = Math.ceil(Math.sqrt(ungrouped.length));
|
|
12879
|
+
for (let i = 0; i < ungrouped.length; i++) {
|
|
12880
|
+
const sym = ungrouped[i];
|
|
12881
|
+
const col = i % cols;
|
|
12882
|
+
const row = Math.floor(i / cols);
|
|
12883
|
+
const prefix = CATEGORY_PREFIXES[sym.category] || "#";
|
|
12884
|
+
nodes.push({
|
|
12885
|
+
id: `sym-${sym.id}`,
|
|
12886
|
+
type: "symbolNode",
|
|
12887
|
+
position: {
|
|
12888
|
+
x: col * (NODE_WIDTH + NODE_GAP),
|
|
12889
|
+
y: startY + row * (NODE_HEIGHT + NODE_GAP)
|
|
12890
|
+
},
|
|
12891
|
+
data: {
|
|
12892
|
+
type: "symbol",
|
|
12893
|
+
symbol: sym,
|
|
12894
|
+
label: `${prefix}${sym.name}`
|
|
12895
|
+
}
|
|
12896
|
+
});
|
|
12897
|
+
}
|
|
12898
|
+
}
|
|
12899
|
+
if (links && links.length > 0) {
|
|
12900
|
+
for (const link of links) {
|
|
12901
|
+
const sourceId = groupIdMap.get(link.source);
|
|
12902
|
+
const targetId = groupIdMap.get(link.target);
|
|
12903
|
+
if (sourceId && targetId) {
|
|
12904
|
+
edges.push({
|
|
12905
|
+
id: `e-${sourceId}-${targetId}`,
|
|
12906
|
+
source: sourceId,
|
|
12907
|
+
target: targetId,
|
|
12908
|
+
type: "default",
|
|
12909
|
+
label: link.label,
|
|
12910
|
+
data: { label: link.label }
|
|
12911
|
+
});
|
|
12912
|
+
}
|
|
12913
|
+
}
|
|
12914
|
+
}
|
|
12915
|
+
return {
|
|
12916
|
+
version: "1.0",
|
|
12917
|
+
name: graphName,
|
|
12918
|
+
projectId: path24.basename(rootDir),
|
|
12919
|
+
lastModified: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12920
|
+
nodes,
|
|
12921
|
+
edges
|
|
12922
|
+
};
|
|
12923
|
+
}
|
|
12924
|
+
|
|
12925
|
+
// ../paradigm-mcp/src/tools/fallback-grep.ts
|
|
12926
|
+
import * as path25 from "path";
|
|
12694
12927
|
import { execSync as execSync5 } from "child_process";
|
|
12695
12928
|
function grepForReferences(rootDir, symbol, options = {}) {
|
|
12696
12929
|
const { maxResults = 20 } = options;
|
|
@@ -12719,7 +12952,7 @@ function grepForReferences(rootDir, symbol, options = {}) {
|
|
|
12719
12952
|
const match = line.match(/^(.+?):(\d+):(.*)$/);
|
|
12720
12953
|
if (match) {
|
|
12721
12954
|
const [, filePath, lineNum, content] = match;
|
|
12722
|
-
const relativePath =
|
|
12955
|
+
const relativePath = path25.relative(rootDir, filePath);
|
|
12723
12956
|
let context2 = "unknown";
|
|
12724
12957
|
if (relativePath.includes(".purpose") || relativePath.includes("portal.yaml")) {
|
|
12725
12958
|
context2 = "purpose";
|
|
@@ -12982,6 +13215,8 @@ function registerTools(server, getContext2, reloadContext2) {
|
|
|
12982
13215
|
...getPersonaToolsList(),
|
|
12983
13216
|
// Protocol tools
|
|
12984
13217
|
...getProtocolsToolsList(),
|
|
13218
|
+
// Graph generation tool
|
|
13219
|
+
...getGraphToolsList(),
|
|
12985
13220
|
// Plugin update check
|
|
12986
13221
|
{
|
|
12987
13222
|
name: "paradigm_plugin_check",
|
|
@@ -13615,7 +13850,7 @@ Update command:
|
|
|
13615
13850
|
const { rebuildStaticFiles: rebuildStaticFiles2 } = await import("./reindex-CMZARW5K.js");
|
|
13616
13851
|
const memberResults = [];
|
|
13617
13852
|
for (const member of ctx.workspace.config.members) {
|
|
13618
|
-
const memberAbsPath =
|
|
13853
|
+
const memberAbsPath = path26.resolve(path26.dirname(ctx.workspace.workspacePath), member.path);
|
|
13619
13854
|
try {
|
|
13620
13855
|
const result = await rebuildStaticFiles2(memberAbsPath);
|
|
13621
13856
|
memberResults.push({
|
|
@@ -13804,6 +14039,15 @@ Update command:
|
|
|
13804
14039
|
};
|
|
13805
14040
|
}
|
|
13806
14041
|
}
|
|
14042
|
+
if (name === "paradigm_graph_generate") {
|
|
14043
|
+
const result = await handleGraphTool(name, args, ctx);
|
|
14044
|
+
if (result.handled) {
|
|
14045
|
+
trackToolCall(result.text.length, name);
|
|
14046
|
+
return {
|
|
14047
|
+
content: [{ type: "text", text: result.text }]
|
|
14048
|
+
};
|
|
14049
|
+
}
|
|
14050
|
+
}
|
|
13807
14051
|
if (name === "paradigm_reindex") {
|
|
13808
14052
|
const reload = reloadContext2 || (async () => {
|
|
13809
14053
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.react-flow{direction:ltr;--xy-edge-stroke-default: #b1b1b7;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #555;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(255, 255, 255, .5);--xy-minimap-background-color-default: #fff;--xy-minimap-mask-background-color-default: rgba(240, 240, 240, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #e2e2e2;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: transparent;--xy-background-pattern-dots-color-default: #91919a;--xy-background-pattern-lines-color-default: #eee;--xy-background-pattern-cross-color-default: #e2e2e2;background-color:var(--xy-background-color, var(--xy-background-color-default));--xy-node-color-default: inherit;--xy-node-border-default: 1px solid #1a192b;--xy-node-background-color-default: #fff;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(0, 0, 0, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #1a192b;--xy-node-border-radius-default: 3px;--xy-handle-background-color-default: #1a192b;--xy-handle-border-color-default: #fff;--xy-selection-background-color-default: rgba(0, 89, 220, .08);--xy-selection-border-default: 1px dotted rgba(0, 89, 220, .8);--xy-controls-button-background-color-default: #fefefe;--xy-controls-button-background-color-hover-default: #f4f4f4;--xy-controls-button-color-default: inherit;--xy-controls-button-color-hover-default: inherit;--xy-controls-button-border-color-default: #eee;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #ffffff;--xy-edge-label-color-default: inherit;--xy-resize-background-color-default: #3367d9}.react-flow.dark{--xy-edge-stroke-default: #3e3e3e;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #727272;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(150, 150, 150, .25);--xy-minimap-background-color-default: #141414;--xy-minimap-mask-background-color-default: rgba(60, 60, 60, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #2b2b2b;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: #141414;--xy-background-pattern-dots-color-default: #777;--xy-background-pattern-lines-color-default: #777;--xy-background-pattern-cross-color-default: #777;--xy-node-color-default: #f8f8f8;--xy-node-border-default: 1px solid #3c3c3c;--xy-node-background-color-default: #1e1e1e;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(255, 255, 255, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #999;--xy-handle-background-color-default: #bebebe;--xy-handle-border-color-default: #1e1e1e;--xy-selection-background-color-default: rgba(200, 200, 220, .08);--xy-selection-border-default: 1px dotted rgba(200, 200, 220, .8);--xy-controls-button-background-color-default: #2b2b2b;--xy-controls-button-background-color-hover-default: #3e3e3e;--xy-controls-button-color-default: #f8f8f8;--xy-controls-button-color-hover-default: #fff;--xy-controls-button-border-color-default: #5b5b5b;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #141414;--xy-edge-label-color-default: #f8f8f8}.react-flow__background{background-color:var(--xy-background-color-props, var(--xy-background-color, var(--xy-background-color-default)));pointer-events:none;z-index:-1}.react-flow__container{position:absolute;width:100%;height:100%;top:0;left:0}.react-flow__pane{z-index:1}.react-flow__pane.draggable{cursor:grab}.react-flow__pane.dragging{cursor:grabbing}.react-flow__pane.selection{cursor:pointer}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow__edge-path{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default));stroke-width:var(--xy-edge-stroke-width, var(--xy-edge-stroke-width-default));fill:none}.react-flow__connection-path{stroke:var(--xy-connectionline-stroke, var(--xy-connectionline-stroke-default));stroke-width:var(--xy-connectionline-stroke-width, var(--xy-connectionline-stroke-width-default));fill:none}.react-flow .react-flow__edges{position:absolute}.react-flow .react-flow__edges svg{overflow:visible;position:absolute;pointer-events:none}.react-flow__edge{pointer-events:visibleStroke}.react-flow__edge.selectable{cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;animation:dashdraw .5s linear infinite}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge.selectable:focus .react-flow__edge-path,.react-flow__edge.selectable:focus-visible .react-flow__edge-path{stroke:var(--xy-edge-stroke-selected, var(--xy-edge-stroke-selected-default))}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__arrowhead polyline{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__arrowhead polyline.arrowclosed{fill:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:dashdraw .5s linear infinite}svg.react-flow__connectionline{z-index:1001;overflow:visible;position:absolute}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:default}.react-flow__node.selectable{cursor:pointer}.react-flow__node.draggable{cursor:grab;pointer-events:all}.react-flow__node.draggable.dragging{cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:left top;pointer-events:none}.react-flow__nodesselection-rect{position:absolute;pointer-events:all;cursor:grab}.react-flow__handle{position:absolute;pointer-events:none;min-width:5px;min-height:5px;width:6px;height:6px;background-color:var(--xy-handle-background-color, var(--xy-handle-background-color-default));border:1px solid var(--xy-handle-border-color, var(--xy-handle-border-color-default));border-radius:100%}.react-flow__handle.connectingfrom{pointer-events:all}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;left:50%;bottom:0;transform:translate(-50%,50%)}.react-flow__handle-top{top:0;left:50%;transform:translate(-50%,-50%)}.react-flow__handle-left{top:50%;left:0;transform:translate(-50%,-50%)}.react-flow__handle-right{top:50%;right:0;transform:translate(50%,-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__pane.selection .react-flow__panel{pointer-events:none}.react-flow__panel{position:absolute;z-index:5;margin:15px}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.top.center,.react-flow__panel.bottom.center{left:50%;transform:translate(-15px) translate(-50%)}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.left.center,.react-flow__panel.right.center{top:50%;transform:translateY(-15px) translateY(-50%)}.react-flow__attribution{font-size:10px;background:var(--xy-attribution-background-color, var(--xy-attribution-background-color-default));padding:2px 3px;margin:0}.react-flow__attribution a{text-decoration:none;color:#999}@keyframes dashdraw{0%{stroke-dashoffset:10}}.react-flow__edgelabel-renderer{position:absolute;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;left:0;top:0}.react-flow__viewport-portal{position:absolute;width:100%;height:100%;left:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__minimap{background:var( --xy-minimap-background-color-props, var(--xy-minimap-background-color, var(--xy-minimap-background-color-default)) )}.react-flow__minimap-svg{display:block}.react-flow__minimap-mask{fill:var( --xy-minimap-mask-background-color-props, var(--xy-minimap-mask-background-color, var(--xy-minimap-mask-background-color-default)) );stroke:var( --xy-minimap-mask-stroke-color-props, var(--xy-minimap-mask-stroke-color, var(--xy-minimap-mask-stroke-color-default)) );stroke-width:var( --xy-minimap-mask-stroke-width-props, var(--xy-minimap-mask-stroke-width, var(--xy-minimap-mask-stroke-width-default)) )}.react-flow__minimap-node{fill:var( --xy-minimap-node-background-color-props, var(--xy-minimap-node-background-color, var(--xy-minimap-node-background-color-default)) );stroke:var( --xy-minimap-node-stroke-color-props, var(--xy-minimap-node-stroke-color, var(--xy-minimap-node-stroke-color-default)) );stroke-width:var( --xy-minimap-node-stroke-width-props, var(--xy-minimap-node-stroke-width, var(--xy-minimap-node-stroke-width-default)) )}.react-flow__background-pattern.dots{fill:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-dots-color-default)) )}.react-flow__background-pattern.lines{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-lines-color-default)) )}.react-flow__background-pattern.cross{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-cross-color-default)) )}.react-flow__controls{display:flex;flex-direction:column;box-shadow:var(--xy-controls-box-shadow, var(--xy-controls-box-shadow-default))}.react-flow__controls.horizontal{flex-direction:row}.react-flow__controls-button{display:flex;justify-content:center;align-items:center;height:26px;width:26px;padding:4px;border:none;background:var(--xy-controls-button-background-color, var(--xy-controls-button-background-color-default));border-bottom:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) );color:var( --xy-controls-button-color-props, var(--xy-controls-button-color, var(--xy-controls-button-color-default)) );cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__controls-button svg{width:100%;max-width:12px;max-height:12px;fill:currentColor}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-input,.react-flow__node-default,.react-flow__node-output,.react-flow__node-group{padding:10px;border-radius:var(--xy-node-border-radius, var(--xy-node-border-radius-default));width:150px;font-size:12px;color:var(--xy-node-color, var(--xy-node-color-default));text-align:center;border:var(--xy-node-border, var(--xy-node-border-default));background-color:var(--xy-node-background-color, var(--xy-node-background-color-default))}.react-flow__node-input.selectable:hover,.react-flow__node-default.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:var(--xy-node-boxshadow-hover, var(--xy-node-boxshadow-hover-default))}.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:var(--xy-node-boxshadow-selected, var(--xy-node-boxshadow-selected-default))}.react-flow__node-group{background-color:var(--xy-node-group-background-color, var(--xy-node-group-background-color-default))}.react-flow__nodesselection-rect,.react-flow__selection{background:var(--xy-selection-background-color, var(--xy-selection-background-color-default));border:var(--xy-selection-border, var(--xy-selection-border-default))}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls-button:hover{background:var( --xy-controls-button-background-color-hover-props, var(--xy-controls-button-background-color-hover, var(--xy-controls-button-background-color-hover-default)) );color:var( --xy-controls-button-color-hover-props, var(--xy-controls-button-color-hover, var(--xy-controls-button-color-hover-default)) )}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__controls-button:last-child{border-bottom:none}.react-flow__controls.horizontal .react-flow__controls-button{border-bottom:none;border-right:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) )}.react-flow__controls.horizontal .react-flow__controls-button:last-child{border-right:none}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{width:5px;height:5px;border:1px solid #fff;border-radius:1px;background-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));translate:-50% -50%}.react-flow__resize-control.handle.left{left:0;top:50%}.react-flow__resize-control.handle.right{left:100%;top:50%}.react-flow__resize-control.handle.top{left:50%;top:0}.react-flow__resize-control.handle.bottom{left:50%;top:100%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));border-width:0;border-style:solid}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;transform:translate(-50%);top:0;height:100%}.react-flow__resize-control.line.left{left:0;border-left-width:1px}.react-flow__resize-control.line.right{left:100%;border-right-width:1px}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{height:1px;transform:translateY(-50%);left:0;width:100%}.react-flow__resize-control.line.top{top:0;border-top-width:1px}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.react-flow__edge-textbg{fill:var(--xy-edge-label-background-color, var(--xy-edge-label-background-color-default))}.react-flow__edge-text{fill:var(--xy-edge-label-color, var(--xy-edge-label-color-default))}:root{--bg-base: #0a0a0f;--bg-panel: #0f172a;--bg-surface: #1e293b;--bg-hover: #334155;--text-primary: #e2e8f0;--text-secondary: #94a3b8;--text-muted: #64748b;--border: #1e293b;--border-focus: #475569;--color-component: #86efac;--color-flow: #fbbf24;--color-gate: #f87171;--color-signal: #fde047;--color-aspect: #a78bfa}*{margin:0;padding:0;box-sizing:border-box}body{background:var(--bg-base);color:var(--text-primary);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;overflow:hidden}.app{display:flex;height:100vh;width:100vw}.app__main{flex:1;display:flex;flex-direction:column;min-width:0}.symbol-panel{width:280px;min-width:280px;background:var(--bg-panel);border-right:1px solid var(--border);display:flex;flex-direction:column;overflow:hidden}.symbol-panel__header{display:flex;align-items:center;justify-content:space-between;padding:16px;border-bottom:1px solid var(--border)}.symbol-panel__header h2{font-size:14px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--text-secondary)}.symbol-panel__count{font-size:12px;background:var(--bg-surface);color:var(--text-muted);padding:2px 8px;border-radius:10px}.symbol-panel__search{margin:12px 16px;padding:8px 12px;background:var(--bg-surface);border:1px solid var(--border);border-radius:6px;color:var(--text-primary);font-size:13px;outline:none;transition:border-color .15s}.symbol-panel__search:focus{border-color:var(--border-focus)}.symbol-panel__search::placeholder{color:var(--text-muted)}.symbol-panel__list{flex:1;overflow-y:auto;padding:0 8px 16px}.symbol-panel__section{margin-top:4px}.symbol-panel__section-header{display:flex;align-items:center;gap:6px;width:100%;padding:6px 8px;background:none;border:none;font-size:12px;font-weight:600;cursor:pointer;text-transform:uppercase;letter-spacing:.05em}.symbol-panel__section-arrow{font-size:10px;width:12px}.symbol-panel__section-count{margin-left:auto;font-size:11px;opacity:.5;font-weight:400}.symbol-panel__section-items{padding:2px 0}.symbol-panel__item{display:flex;flex-direction:column;gap:2px;padding:6px 8px 6px 12px;margin:1px 0;border-left:2px solid transparent;border-radius:4px;cursor:grab;transition:background .1s}.symbol-panel__item:hover{background:var(--bg-surface)}.symbol-panel__item:active{cursor:grabbing}.symbol-panel__item-name{font-size:13px;font-weight:500;font-family:SF Mono,Fira Code,monospace}.symbol-panel__item-desc{font-size:11px;color:var(--text-muted);line-height:1.3}.toolbar{display:flex;align-items:center;gap:8px;padding:8px 16px;background:var(--bg-panel);border-bottom:1px solid var(--border)}.toolbar__name{background:transparent;border:1px solid transparent;color:var(--text-primary);font-size:14px;font-weight:600;padding:4px 8px;border-radius:4px;width:200px;outline:none;transition:border-color .15s}.toolbar__name:hover,.toolbar__name:focus{border-color:var(--border-focus)}.toolbar__actions{display:flex;align-items:center;gap:6px;margin-left:auto}.toolbar__btn{padding:6px 12px;background:var(--bg-surface);border:1px solid var(--border);color:var(--text-secondary);font-size:12px;font-weight:500;border-radius:6px;cursor:pointer;transition:all .15s}.toolbar__btn:hover{background:var(--bg-hover);color:var(--text-primary)}.toolbar__btn--primary{background:#1d4ed8;border-color:#2563eb;color:#fff}.toolbar__btn--primary:hover{background:#2563eb}.toolbar__divider{width:1px;height:20px;background:var(--border);margin:0 4px}.canvas-wrapper{flex:1;position:relative}.paradigm-flow{background:var(--bg-base)!important}.react-flow__controls{background:var(--bg-panel)!important;border:1px solid var(--border)!important;border-radius:8px!important;overflow:hidden}.react-flow__controls-button{background:var(--bg-panel)!important;border-bottom:1px solid var(--border)!important;fill:var(--text-secondary)!important}.react-flow__controls-button:hover{background:var(--bg-surface)!important}.react-flow__minimap{border:1px solid var(--border)!important;border-radius:8px!important;overflow:hidden}.react-flow__edge-path{stroke:var(--text-muted)!important;stroke-width:2}.react-flow__edge.selected .react-flow__edge-path{stroke:var(--text-primary)!important}.react-flow__edge-text{fill:var(--text-secondary)!important;font-size:11px}.react-flow__edge-textbg{fill:var(--bg-panel)!important}.symbol-node{background:var(--bg-panel);border:1px solid var(--border);border-left:3px solid var(--color-component);border-radius:8px;padding:8px 12px;min-width:160px;max-width:240px;transition:border-color .15s}.symbol-node:hover{border-color:var(--border-focus)}.symbol-node__name{font-size:13px;font-weight:600;font-family:SF Mono,Fira Code,monospace;line-height:1.4}.symbol-node__desc{font-size:11px;color:var(--text-muted);line-height:1.3;margin-top:2px}.group-node{background:#1e293b80;border:2px dashed var(--border-focus);border-radius:12px;width:100%;height:100%;position:relative}.group-node__header{padding:8px 16px;border-bottom:1px solid var(--border);border-radius:12px 12px 0 0;background:#0f172acc;cursor:default}.group-node__label{font-size:13px;font-weight:600;color:var(--text-primary)}.group-node__input{background:var(--bg-surface);border:1px solid var(--border-focus);color:var(--text-primary);font-size:13px;font-weight:600;padding:2px 8px;border-radius:4px;outline:none;width:100%}.group-node__resizer-line{border-color:var(--color-component)!important}.group-node__resizer-handle{background:var(--color-component)!important;width:8px!important;height:8px!important;border-radius:2px!important}.group-handle{width:10px!important;height:10px!important;background:var(--bg-hover)!important;border:2px solid var(--text-muted)!important}.export-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#0009;display:flex;align-items:center;justify-content:center;z-index:100}.export-dialog{background:var(--bg-panel);border:1px solid var(--border);border-radius:12px;width:640px;max-width:90vw;max-height:80vh;display:flex;flex-direction:column}.export-dialog__header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--border)}.export-dialog__header h3{font-size:16px;font-weight:600}.export-dialog__close{background:none;border:none;color:var(--text-muted);font-size:24px;cursor:pointer;line-height:1;padding:0 4px}.export-dialog__close:hover{color:var(--text-primary)}.export-dialog__content{flex:1;margin:16px 20px;padding:12px;background:var(--bg-base);border:1px solid var(--border);border-radius:8px;color:var(--text-primary);font-size:13px;font-family:SF Mono,Fira Code,monospace;resize:none;outline:none;overflow-y:auto}.export-dialog__actions{display:flex;gap:8px;padding:16px 20px;border-top:1px solid var(--border);justify-content:flex-end}.load-dialog{width:520px}.load-dialog__body{padding:16px 20px;display:flex;flex-direction:column;gap:12px}.load-dialog__section{display:flex;flex-direction:column;gap:8px}.load-dialog__label{font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--text-secondary)}.load-dialog__divider{display:flex;align-items:center;gap:12px;color:var(--text-muted);font-size:12px}.load-dialog__divider:before,.load-dialog__divider:after{content:"";flex:1;height:1px;background:var(--border)}.load-dialog__status{font-size:12px;padding:8px 12px;border-radius:6px}.load-dialog__status--error{background:#f871711a;color:#f87171;border:1px solid rgba(248,113,113,.2)}.load-dialog__status--success{background:#86efac1a;color:#86efac;border:1px solid rgba(134,239,172,.2)}::-webkit-scrollbar{width:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--bg-hover);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:var(--text-muted)}
|