skynet-graph 1.2.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/CONTRIBUTING.md +22 -0
- package/LICENSE +661 -0
- package/README.md +245 -0
- package/bin/sg +20 -0
- package/concepts/README.md +23 -0
- package/concepts/_substrate/Claim/Confidence/Trusted.json +6 -0
- package/concepts/_substrate/Claim/Confidence.json +10 -0
- package/concepts/_substrate/Claim/Freshness/Stale.json +7 -0
- package/concepts/_substrate/Claim/Freshness.json +5 -0
- package/concepts/_substrate/Claim/Verification/Refuted.json +6 -0
- package/concepts/_substrate/Claim/Verification.json +6 -0
- package/concepts/_substrate/Claim.json +4 -0
- package/concepts/_substrate/Frontier/InBeam.json +6 -0
- package/concepts/_substrate/Frontier/Stuck.json +6 -0
- package/concepts/_substrate/Frontier.json +5 -0
- package/concepts/_substrate/Intake/ToTask.json +22 -0
- package/concepts/_substrate/Intake/Typed.json +10 -0
- package/concepts/_substrate/Intake.json +27 -0
- package/concepts/_substrate/Task/Answer.json +12 -0
- package/concepts/_substrate/Task/Complexity/Atomic.json +5 -0
- package/concepts/_substrate/Task/Complexity/Compound/Expansion.json +7 -0
- package/concepts/_substrate/Task/Complexity/Compound.json +6 -0
- package/concepts/_substrate/Task/Complexity.json +6 -0
- package/concepts/_substrate/Task/EvalComplexity.json +13 -0
- package/concepts/_substrate/Task/ReportUp.json +6 -0
- package/concepts/_substrate/Task/Rollup.json +10 -0
- package/concepts/_substrate/Task.json +5 -0
- package/concepts/clinical/Diagnosis/Medication.json +6 -0
- package/concepts/clinical/Diagnosis.json +15 -0
- package/concepts/clinical/Observation/LabValue/OutOfRange.json +6 -0
- package/concepts/clinical/Observation/LabValue.json +5 -0
- package/concepts/clinical/Observation.json +6 -0
- package/concepts/common/Document/pathBasket.json +6 -0
- package/concepts/common/Document.json +3 -0
- package/concepts/common/Edge/Distance.json +13 -0
- package/concepts/common/Edge/Stay/LongStay.json +8 -0
- package/concepts/common/Edge/Stay.json +8 -0
- package/concepts/common/Edge/Travel/LongTravel.json +16 -0
- package/concepts/common/Edge/Travel/ShortTravel.json +11 -0
- package/concepts/common/Edge/Travel/targetNode.json +7 -0
- package/concepts/common/Edge/Travel.json +7 -0
- package/concepts/common/Edge.json +3 -0
- package/concepts/common/Vertice.json +3 -0
- package/concepts/supply/Fulfillment.json +10 -0
- package/concepts/supply/Inventory/Reorder.json +7 -0
- package/concepts/supply/Inventory.json +5 -0
- package/concepts/supply/Procurement/SupplierConfirm.json +6 -0
- package/concepts/supply/Procurement.json +8 -0
- package/concepts/supply/Transport.json +5 -0
- package/doc/API.md +556 -0
- package/doc/CAPABILITIES.md +373 -0
- package/doc/MODELISATION.md +511 -0
- package/doc/architecture.md +267 -0
- package/doc/concept-as-graph.md +379 -0
- package/doc/concept-learning.md +168 -0
- package/doc/creative-loop-map.md +202 -0
- package/doc/original-2016-doc.md +148 -0
- package/doc/usage.md +501 -0
- package/lib/authoring/abstract.js +401 -0
- package/lib/authoring/abstraction.js +190 -0
- package/lib/authoring/adapt.js +393 -0
- package/lib/authoring/ancestry.js +216 -0
- package/lib/authoring/author.js +147 -0
- package/lib/authoring/bounded-merge.js +57 -0
- package/lib/authoring/canon.js +158 -0
- package/lib/authoring/clock.js +123 -0
- package/lib/authoring/combinator.js +92 -0
- package/lib/authoring/compete.js +76 -0
- package/lib/authoring/compose-hotspot.js +314 -0
- package/lib/authoring/compress.js +279 -0
- package/lib/authoring/concept-net.js +254 -0
- package/lib/authoring/concepts.js +66 -0
- package/lib/authoring/context-project.js +277 -0
- package/lib/authoring/contract.js +476 -0
- package/lib/authoring/corpus-pack.js +125 -0
- package/lib/authoring/cost-probe.js +86 -0
- package/lib/authoring/crystallize.js +555 -0
- package/lib/authoring/dag-decompose.js +256 -0
- package/lib/authoring/dataset-adapter.js +253 -0
- package/lib/authoring/debug-provider.js +92 -0
- package/lib/authoring/decompose.js +343 -0
- package/lib/authoring/emittability.js +236 -0
- package/lib/authoring/equilibrium.js +160 -0
- package/lib/authoring/extract.js +153 -0
- package/lib/authoring/forest.js +55 -0
- package/lib/authoring/forge-fallback.js +116 -0
- package/lib/authoring/givens.js +121 -0
- package/lib/authoring/glossary.js +177 -0
- package/lib/authoring/grammar-graph.js +191 -0
- package/lib/authoring/granularity.js +80 -0
- package/lib/authoring/graph-net.js +108 -0
- package/lib/authoring/ground.js +148 -0
- package/lib/authoring/higher-order.js +85 -0
- package/lib/authoring/hotspot.js +132 -0
- package/lib/authoring/hysteresis.js +85 -0
- package/lib/authoring/index.js +106 -0
- package/lib/authoring/lattice-morphism.js +61 -0
- package/lib/authoring/lattice-pack.js +148 -0
- package/lib/authoring/leaf-io.js +77 -0
- package/lib/authoring/library.js +156 -0
- package/lib/authoring/lifecycle.js +92 -0
- package/lib/authoring/loop.js +193 -0
- package/lib/authoring/master-loop.js +132 -0
- package/lib/authoring/mdl.js +209 -0
- package/lib/authoring/memo-stability.js +122 -0
- package/lib/authoring/method-explorer.js +138 -0
- package/lib/authoring/method-pack.js +181 -0
- package/lib/authoring/method.js +202 -0
- package/lib/authoring/mine.js +510 -0
- package/lib/authoring/mount.js +119 -0
- package/lib/authoring/negotiate.js +100 -0
- package/lib/authoring/parametric.js +139 -0
- package/lib/authoring/reaggregate.js +75 -0
- package/lib/authoring/rebalance.js +157 -0
- package/lib/authoring/recall.js +135 -0
- package/lib/authoring/registry.js +350 -0
- package/lib/authoring/relearn.js +147 -0
- package/lib/authoring/retention.js +89 -0
- package/lib/authoring/segment-proxy.js +114 -0
- package/lib/authoring/serve-leaf.js +64 -0
- package/lib/authoring/slot-aware-serve.js +77 -0
- package/lib/authoring/sound-invoke.js +59 -0
- package/lib/authoring/split-serve.js +74 -0
- package/lib/authoring/ste.js +239 -0
- package/lib/authoring/stock.js +101 -0
- package/lib/authoring/store.js +94 -0
- package/lib/authoring/supervise.js +138 -0
- package/lib/authoring/support.js +131 -0
- package/lib/authoring/task-mirror.js +51 -0
- package/lib/authoring/typed-loop.js +160 -0
- package/lib/authoring/validate.js +569 -0
- package/lib/authoring/widen.js +88 -0
- package/lib/combos/appliance.js +189 -0
- package/lib/combos/critique.js +377 -0
- package/lib/combos/defaults.js +86 -0
- package/lib/combos/durable-runner.js +115 -0
- package/lib/combos/forge.js +209 -0
- package/lib/combos/index.js +86 -0
- package/lib/combos/learning-library.js +253 -0
- package/lib/combos/mixture-serve.js +193 -0
- package/lib/combos/plan-loop.js +192 -0
- package/lib/combos/proxy-cache.js +272 -0
- package/lib/combos/self-mod.js +94 -0
- package/lib/durable/audit.js +102 -0
- package/lib/durable/checkpoint-store.js +550 -0
- package/lib/durable/fold.js +62 -0
- package/lib/durable/interpreter.js +242 -0
- package/lib/durable/xlate.js +185 -0
- package/lib/graph/Graph.js +2486 -0
- package/lib/graph/expr.js +307 -0
- package/lib/graph/index.js +26 -0
- package/lib/graph/log.js +134 -0
- package/lib/graph/objects/Concept.js +382 -0
- package/lib/graph/objects/Entity.js +503 -0
- package/lib/graph/objects/Node.js +57 -0
- package/lib/graph/objects/PathMap.js +557 -0
- package/lib/graph/objects/Segment.js +100 -0
- package/lib/graph/tasks/stabilize.js +59 -0
- package/lib/graph/tasks/taskflow.js +247 -0
- package/lib/index.js +122 -0
- package/lib/load.js +132 -0
- package/lib/providers/backends.js +117 -0
- package/lib/providers/borderline.js +129 -0
- package/lib/providers/cache.js +226 -0
- package/lib/providers/canonicalize.js +198 -0
- package/lib/providers/constat.js +107 -0
- package/lib/providers/geo.js +53 -0
- package/lib/providers/index.js +116 -0
- package/lib/providers/intake.js +263 -0
- package/lib/providers/llm-local.js +88 -0
- package/lib/providers/llm.js +236 -0
- package/lib/providers/local-host.js +197 -0
- package/lib/providers/merge-consistency.js +162 -0
- package/lib/providers/nogood.js +149 -0
- package/lib/providers/reason-loop.js +223 -0
- package/lib/providers/semiring.js +285 -0
- package/lib/providers/solver-fork.js +163 -0
- package/lib/providers/stats.js +228 -0
- package/lib/providers/verify.js +120 -0
- package/lib/runtime/index.js +135 -0
- package/lib/runtime/invoke-pool.js +92 -0
- package/lib/runtime/protocol.js +210 -0
- package/lib/runtime/transport-socket.js +77 -0
- package/lib/runtime/worker-entry.js +31 -0
- package/lib/sg/cli.js +601 -0
- package/lib/sg/log-sinks.js +214 -0
- package/lib/sg/mcp.js +395 -0
- package/lib/sg/proxy-run.js +66 -0
- package/lib/sg/serve-demo.js +185 -0
- package/lib/sg/serve.js +205 -0
- package/lib/sg/trace.js +118 -0
- package/lib/studio/protocol.js +45 -0
- package/lib/studio/public/app.js +310 -0
- package/lib/studio/public/components/ConceptEditor.js +43 -0
- package/lib/studio/public/components/ConceptTree.js +43 -0
- package/lib/studio/public/components/CorpusPanel.js +68 -0
- package/lib/studio/public/components/ForkTree.js +36 -0
- package/lib/studio/public/components/GrammarGraph.js +99 -0
- package/lib/studio/public/components/GraphCanvas.js +156 -0
- package/lib/studio/public/components/Inspector.js +48 -0
- package/lib/studio/public/components/LearningPanel.js +85 -0
- package/lib/studio/public/components/PromptConsole.js +46 -0
- package/lib/studio/public/components/ProviderTrace.js +39 -0
- package/lib/studio/public/components/SessionSplit.js +47 -0
- package/lib/studio/public/components/TilingOverlay.js +40 -0
- package/lib/studio/public/components/Timeline.js +57 -0
- package/lib/studio/public/index.html +26 -0
- package/lib/studio/public/styles.css +185 -0
- package/lib/studio/public/ws.js +58 -0
- package/lib/studio/server.js +130 -0
- package/lib/studio/session.js +397 -0
- package/lib/studio/studio.js +149 -0
- package/package.json +42 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--bg: #0f1419; --panel: #161c25; --border: #2a3340;
|
|
3
|
+
--fg: #cdd6e0; --muted: #7c8b9c; --accent: #6ea8fe;
|
|
4
|
+
--good: #3ad29f; --warn: #f5a524; --bad: #ff6b6b;
|
|
5
|
+
}
|
|
6
|
+
* { box-sizing: border-box; }
|
|
7
|
+
body { margin: 0; font: 13px/1.5 ui-sans-serif, system-ui, "Segoe UI", Roboto, sans-serif; background: var(--bg); color: var(--fg); }
|
|
8
|
+
.studio { display: flex; flex-direction: column; height: 100vh; }
|
|
9
|
+
|
|
10
|
+
.toolbar { display: flex; align-items: center; gap: 12px; padding: 8px 14px; background: var(--panel); border-bottom: 1px solid var(--border); }
|
|
11
|
+
.toolbar strong { color: var(--accent); letter-spacing: .02em; }
|
|
12
|
+
.toolbar select, .toolbar button { background: #222b36; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 4px 9px; font: inherit; }
|
|
13
|
+
.toolbar button { cursor: pointer; }
|
|
14
|
+
.toolbar button:hover:not(:disabled) { border-color: var(--accent); }
|
|
15
|
+
.toolbar button:disabled { opacity: .4; cursor: default; }
|
|
16
|
+
.toolbar .sep { width: 1px; height: 20px; background: var(--border); margin: 0 2px; }
|
|
17
|
+
.toolbar .lyt { display: flex; align-items: center; gap: 5px; color: var(--muted); font-size: 12px; }
|
|
18
|
+
.status { margin-left: auto; font-weight: 600; }
|
|
19
|
+
.status.live { color: var(--good); }
|
|
20
|
+
.status.down, .status.connecting { color: var(--warn); }
|
|
21
|
+
.rev { color: var(--muted); font-family: ui-monospace, monospace; }
|
|
22
|
+
|
|
23
|
+
.panels { flex: 1; display: flex; min-height: 0; }
|
|
24
|
+
.cy { flex: 1; min-width: 0; background: radial-gradient(circle at 50% 40%, #131a23, #0f1419); }
|
|
25
|
+
|
|
26
|
+
.inspector { width: 320px; border-left: 1px solid var(--border); padding: 12px 14px; overflow: auto; background: var(--panel); }
|
|
27
|
+
.inspector h3 { margin: 0 0 10px; color: var(--accent); font-family: ui-monospace, monospace; }
|
|
28
|
+
.inspector h4 { margin: 14px 0 6px; color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .06em; }
|
|
29
|
+
.inspector .empty { color: var(--muted); }
|
|
30
|
+
.fact { display: flex; justify-content: space-between; gap: 10px; padding: 2px 0; font-family: ui-monospace, monospace; font-size: 12px; border-bottom: 1px solid rgba(255,255,255,.04); }
|
|
31
|
+
.fact .k { color: var(--fg); }
|
|
32
|
+
.fact .v { color: var(--muted); text-align: right; word-break: break-word; }
|
|
33
|
+
.cast { margin: 6px 0; padding: 6px 8px; background: #11171f; border-left: 2px solid var(--good); border-radius: 0 4px 4px 0; }
|
|
34
|
+
.cast .cn { color: var(--good); font-family: ui-monospace, monospace; font-size: 12px; }
|
|
35
|
+
.cast .ms { color: var(--muted); }
|
|
36
|
+
.cast .why { color: var(--muted); font-family: ui-monospace, monospace; font-size: 11px; padding-left: 8px; }
|
|
37
|
+
|
|
38
|
+
.bottom { border-top: 1px solid var(--border); padding: 8px 14px; background: var(--panel); max-height: 150px; overflow: auto; }
|
|
39
|
+
.bottom h3 { margin: 0 0 6px; color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .06em; }
|
|
40
|
+
.tracerow { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
41
|
+
.tchip { font-family: ui-monospace, monospace; font-size: 11px; padding: 2px 7px; background: #11171f; border: 1px solid var(--border); border-radius: 10px; color: var(--muted); }
|
|
42
|
+
.tchip b { color: var(--good); font-weight: 600; }
|
|
43
|
+
|
|
44
|
+
/* timeline (T9) */
|
|
45
|
+
.timeline { display: flex; align-items: center; gap: 10px; padding: 6px 14px; background: #11171f; border-bottom: 1px solid var(--border); }
|
|
46
|
+
.timeline .tl-lbl { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .06em; }
|
|
47
|
+
.timeline .tl-range { flex: 1; accent-color: var(--accent); }
|
|
48
|
+
.timeline .tl-cur { color: var(--muted); font-family: ui-monospace, monospace; font-size: 12px; min-width: 96px; }
|
|
49
|
+
.timeline button { background: #222b36; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 3px 9px; cursor: pointer; font: inherit; }
|
|
50
|
+
.timeline button:hover:not(:disabled) { border-color: var(--accent); }
|
|
51
|
+
.timeline button:disabled { opacity: .4; cursor: default; }
|
|
52
|
+
|
|
53
|
+
/* diff panel (T9) */
|
|
54
|
+
.diffpanel { position: fixed; right: 16px; bottom: 16px; width: 360px; max-height: 50vh; overflow: auto; background: var(--panel); border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 8px 30px rgba(0,0,0,.5); z-index: 10; }
|
|
55
|
+
.dp-head { display: flex; justify-content: space-between; align-items: center; padding: 8px 12px; border-bottom: 1px solid var(--border); color: var(--accent); font-family: ui-monospace, monospace; }
|
|
56
|
+
.dp-head button { background: none; border: none; color: var(--muted); cursor: pointer; font-size: 14px; }
|
|
57
|
+
.dp-body { padding: 10px 12px; font-family: ui-monospace, monospace; font-size: 12px; }
|
|
58
|
+
.dp-sec { margin: 4px 0; }
|
|
59
|
+
.dp-sec.added { color: var(--good); }
|
|
60
|
+
.dp-sec.removed { color: var(--bad); }
|
|
61
|
+
.dp-sec.changed { color: var(--warn); }
|
|
62
|
+
.dp-chg { color: var(--muted); padding-left: 12px; }
|
|
63
|
+
|
|
64
|
+
/* concept tree (T10) */
|
|
65
|
+
.concepts { width: 220px; border-right: 1px solid var(--border); padding: 10px 0; overflow: auto; background: var(--panel); flex-shrink: 0; }
|
|
66
|
+
.concepts h3 { margin: 0 0 8px 14px; color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .06em; }
|
|
67
|
+
.concepts .empty { color: var(--muted); padding: 0 14px; }
|
|
68
|
+
.cset { margin-bottom: 8px; }
|
|
69
|
+
.csetname { color: var(--accent); font-family: ui-monospace, monospace; font-size: 11px; padding: 2px 14px; opacity: .8; }
|
|
70
|
+
.cname { display: block; padding: 2px 14px; font-family: ui-monospace, monospace; font-size: 12px; color: var(--fg); cursor: pointer; }
|
|
71
|
+
.cname:hover { background: #11171f; color: var(--accent); }
|
|
72
|
+
|
|
73
|
+
/* concept editor modal (T10) */
|
|
74
|
+
.editor-modal { position: fixed; inset: 0; background: rgba(0,0,0,.5); display: flex; align-items: center; justify-content: center; z-index: 20; }
|
|
75
|
+
.em-box { width: 560px; max-width: 92vw; background: var(--panel); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 12px 40px rgba(0,0,0,.6); display: flex; flex-direction: column; }
|
|
76
|
+
.em-head { display: flex; justify-content: space-between; align-items: center; padding: 10px 14px; border-bottom: 1px solid var(--border); color: var(--fg); }
|
|
77
|
+
.em-head b { color: var(--accent); font-family: ui-monospace, monospace; }
|
|
78
|
+
.em-head button { background: none; border: none; color: var(--muted); cursor: pointer; font-size: 15px; }
|
|
79
|
+
.em-text { margin: 12px 14px 0; height: 320px; background: #0d1218; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 10px; font-family: ui-monospace, monospace; font-size: 12px; resize: vertical; }
|
|
80
|
+
.em-validation { margin: 8px 14px 0; font-family: ui-monospace, monospace; font-size: 12px; }
|
|
81
|
+
.em-validation.ok { color: var(--good); }
|
|
82
|
+
.em-validation.bad { color: var(--bad); }
|
|
83
|
+
.em-warn { color: var(--warn); margin-top: 4px; }
|
|
84
|
+
.em-actions { display: flex; gap: 8px; justify-content: flex-end; padding: 12px 14px; }
|
|
85
|
+
.em-actions button { background: #222b36; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 5px 12px; cursor: pointer; font: inherit; }
|
|
86
|
+
.em-actions button.primary { background: var(--accent); color: #0b1017; border-color: var(--accent); font-weight: 600; }
|
|
87
|
+
.em-actions button.danger { background: #3a1f24; color: #ff9a9a; border-color: #6b2b33; margin-right: auto; }
|
|
88
|
+
.em-actions button:disabled { opacity: .4; cursor: default; }
|
|
89
|
+
|
|
90
|
+
/* fork tree (T11) — footer becomes a row: trace | forks */
|
|
91
|
+
.bottom { display: flex; padding: 0; }
|
|
92
|
+
.trace-wrap { flex: 1; min-width: 0; padding: 8px 14px; overflow: auto; }
|
|
93
|
+
.forks { width: 240px; border-left: 1px solid var(--border); padding: 8px 12px; overflow: auto; flex-shrink: 0; }
|
|
94
|
+
.fk-head { display: flex; justify-content: space-between; align-items: center; color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .06em; margin-bottom: 6px; }
|
|
95
|
+
.fk-head button { background: #222b36; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 2px 8px; cursor: pointer; font-size: 11px; text-transform: none; letter-spacing: 0; }
|
|
96
|
+
.fk-head button:hover { border-color: var(--accent); }
|
|
97
|
+
.fk-item { display: flex; justify-content: space-between; align-items: center; padding: 2px 0; }
|
|
98
|
+
.fk-item.active .fk-id { color: var(--accent); font-weight: 600; }
|
|
99
|
+
.fk-id { font-family: ui-monospace, monospace; font-size: 12px; color: var(--fg); cursor: pointer; }
|
|
100
|
+
.fk-id:hover { color: var(--accent); }
|
|
101
|
+
.fk-merge { background: none; border: 1px solid var(--border); color: var(--muted); border-radius: 6px; padding: 1px 7px; cursor: pointer; font-size: 11px; }
|
|
102
|
+
.fk-merge:hover { border-color: var(--good); color: var(--good); }
|
|
103
|
+
|
|
104
|
+
/* prompt console (T12) */
|
|
105
|
+
.prompt { border-top: 1px solid var(--border); background: var(--panel); }
|
|
106
|
+
.pr-out { max-height: 180px; overflow: auto; padding: 8px 14px; font-family: ui-monospace, monospace; font-size: 12px; border-bottom: 1px solid var(--border); }
|
|
107
|
+
.pr-err { color: var(--bad); }
|
|
108
|
+
.pr-step { color: var(--muted); padding: 1px 0; }
|
|
109
|
+
.pr-step.pr-eval { color: var(--accent); }
|
|
110
|
+
.pr-step.pr-expand { color: var(--warn); }
|
|
111
|
+
.pr-step.pr-answer { color: var(--good); }
|
|
112
|
+
.pr-step.pr-rollup { color: #c792ea; }
|
|
113
|
+
.pr-answer { margin-top: 8px; color: var(--fg); }
|
|
114
|
+
.pr-answer b { color: var(--good); display: block; margin-bottom: 4px; }
|
|
115
|
+
.pr-bar { display: flex; gap: 8px; padding: 8px 14px; }
|
|
116
|
+
.pr-bar input { flex: 1; background: #0d1218; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 6px 10px; font: inherit; }
|
|
117
|
+
.pr-bar input:focus { outline: none; border-color: var(--accent); }
|
|
118
|
+
.pr-bar button { background: var(--accent); color: #0b1017; border: none; border-radius: 6px; padding: 6px 16px; font-weight: 600; cursor: pointer; }
|
|
119
|
+
.pr-bar button:disabled { opacity: .4; cursor: default; }
|
|
120
|
+
|
|
121
|
+
/* --- grammar workbench + corpus exchange --- */
|
|
122
|
+
.viewtoggle { display: inline-flex; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }
|
|
123
|
+
.viewtoggle button { background: transparent; color: var(--muted); border: none; padding: 4px 12px; cursor: pointer; font: inherit; }
|
|
124
|
+
.viewtoggle button.on { background: var(--accent); color: #0b1017; font-weight: 600; }
|
|
125
|
+
.grammar-cy { flex: 1; min-width: 0; background: #0b1017; }
|
|
126
|
+
.corpus-panel { width: 280px; overflow: auto; padding: 10px; border-left: 1px solid var(--border); font-size: 12px; }
|
|
127
|
+
.cp-actions { display: flex; gap: 6px; margin-bottom: 10px; }
|
|
128
|
+
.cp-actions button { flex: 1; background: var(--panel); color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 6px; cursor: pointer; }
|
|
129
|
+
.cp-legend { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
|
|
130
|
+
.cp-legend .lg { font-size: 10px; padding: 1px 6px; border-radius: 4px; }
|
|
131
|
+
.lg-w { background: #14392e; color: var(--good); } .lg-rp { background: #16294a; color: var(--accent); }
|
|
132
|
+
.lg-rn { background: #3a1620; color: var(--bad); } .lg-sep { background: #3a2a12; color: var(--warn); }
|
|
133
|
+
.cp-manifest .cp-row { padding: 2px 0; color: var(--muted); }
|
|
134
|
+
.cp-manifest b { color: var(--fg); } .cp-v { color: var(--accent); }
|
|
135
|
+
.cp-prov, .cp-alpha { color: var(--fg); }
|
|
136
|
+
.cp-prov { background: var(--panel); border-radius: 4px; padding: 0 5px; margin-right: 4px; }
|
|
137
|
+
.cp-cross, .cp-coll { margin-top: 10px; }
|
|
138
|
+
.cp-cross h4, .cp-coll h4 { margin: 0 0 4px; font-size: 11px; color: var(--muted); }
|
|
139
|
+
.cp-coll h4 { color: var(--warn); }
|
|
140
|
+
.cp-link, .cp-clash { padding: 1px 0; color: var(--muted); } .cp-link b, .cp-clash b { color: var(--fg); }
|
|
141
|
+
.ptrace { flex: 1; min-width: 180px; max-width: 360px; overflow: hidden; display: flex; flex-direction: column; }
|
|
142
|
+
.pt-head { font-size: 11px; color: var(--muted); display: flex; justify-content: space-between; padding: 2px 0; }
|
|
143
|
+
.pt-refresh { background: transparent; border: none; color: var(--muted); cursor: pointer; }
|
|
144
|
+
.pt-rows { overflow: auto; font-family: ui-monospace, monospace; font-size: 10px; }
|
|
145
|
+
.pt-empty { color: var(--muted); opacity: .6; }
|
|
146
|
+
.pt-row { padding: 1px 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
147
|
+
.pt-lvl { color: var(--muted); margin-right: 4px; } .pt-concept { color: var(--accent); } .pt-target { color: var(--good); }
|
|
148
|
+
.pt-aid { color: var(--muted); opacity: .6; margin-left: 4px; }
|
|
149
|
+
.split-modal { position: fixed; inset: 0; background: rgba(0,0,0,.6); display: flex; align-items: center; justify-content: center; z-index: 50; }
|
|
150
|
+
.split-box { background: var(--panel); border: 1px solid var(--border); border-radius: 8px; width: 88vw; height: 80vh; display: flex; flex-direction: column; }
|
|
151
|
+
.split-head { display: flex; justify-content: space-between; align-items: center; padding: 8px 12px; border-bottom: 1px solid var(--border); }
|
|
152
|
+
.split-head button { background: var(--panel); color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 4px 12px; cursor: pointer; }
|
|
153
|
+
.split-canvases { flex: 1; display: flex; min-height: 0; }
|
|
154
|
+
.split-pane { flex: 1; display: flex; flex-direction: column; min-width: 0; border-right: 1px solid var(--border); }
|
|
155
|
+
.split-label { font-size: 11px; color: var(--muted); padding: 4px 8px; }
|
|
156
|
+
.split-merge { display: flex; justify-content: space-between; align-items: center; padding: 8px 12px; border-top: 1px solid var(--border); }
|
|
157
|
+
.split-prev { font-size: 12px; color: var(--muted); }
|
|
158
|
+
.split-do { background: var(--accent); color: #0b1017; border: none; border-radius: 6px; padding: 6px 16px; font-weight: 600; cursor: pointer; }
|
|
159
|
+
|
|
160
|
+
/* --- learning panel (typed lattice registry — track 4) --- */
|
|
161
|
+
.learning { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 10px; padding: 12px 16px; overflow: auto; background: var(--panel); }
|
|
162
|
+
.lp-head { font-weight: 600; }
|
|
163
|
+
.lp-ver { color: var(--muted); font-size: 11px; margin-left: 8px; }
|
|
164
|
+
.lp-block { padding: 10px 12px; background: #11171f; border: 1px solid var(--border); border-radius: 8px; }
|
|
165
|
+
.lp-grow { flex: 1; min-height: 0; display: flex; flex-direction: column; }
|
|
166
|
+
.lp-title { font-size: 12px; margin-bottom: 8px; }
|
|
167
|
+
.lp-note { color: var(--muted); font-weight: 400; font-size: 11px; }
|
|
168
|
+
.lp-row { display: flex; gap: 8px; align-items: center; }
|
|
169
|
+
.lp-row input, .lp-row select { background: #222b36; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 4px 8px; font: inherit; }
|
|
170
|
+
.lp-row input.lp-enum { flex: 1; }
|
|
171
|
+
.lp-row button { background: #222b36; color: var(--fg); border: 1px solid var(--border); border-radius: 6px; padding: 4px 10px; cursor: pointer; font: inherit; }
|
|
172
|
+
.lp-row button:disabled { opacity: .4; cursor: default; }
|
|
173
|
+
.lp-keys { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 6px; }
|
|
174
|
+
.lp-kchip { font-family: ui-monospace, monospace; font-size: 11px; padding: 2px 8px; background: #0f1419; border: 1px solid var(--border); border-radius: 10px; color: var(--muted); }
|
|
175
|
+
.lp-verdict { margin-top: 8px; font-family: ui-monospace, monospace; font-size: 12px; padding: 5px 8px; border-radius: 6px; }
|
|
176
|
+
.lp-verdict.ok { background: rgba(70, 180, 110, .12); border-left: 2px solid var(--good, #4b6); }
|
|
177
|
+
.lp-verdict.ko { background: rgba(220, 90, 90, .12); border-left: 2px solid #d55; }
|
|
178
|
+
.lp-rings { flex: 1; overflow: auto; display: flex; flex-direction: column; gap: 4px; }
|
|
179
|
+
.lp-ring { display: flex; gap: 8px; align-items: center; font-family: ui-monospace, monospace; font-size: 12px; padding: 3px 8px; background: #0f1419; border: 1px solid var(--border); border-radius: 6px; }
|
|
180
|
+
.lp-rkey { color: var(--muted); }
|
|
181
|
+
.lp-ralias { font-weight: 600; }
|
|
182
|
+
.lp-rvia { color: var(--muted); font-size: 11px; margin-left: auto; }
|
|
183
|
+
.lp-retract { background: none; border: none; color: var(--muted); cursor: pointer; font-size: 13px; }
|
|
184
|
+
.lp-retract:hover { color: #d55; }
|
|
185
|
+
.lp-empty { color: var(--muted); font-size: 12px; }
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Nathanael Braun
|
|
3
|
+
* @author : Nathanael BRAUN <pp9ping@gmail.com>
|
|
4
|
+
*
|
|
5
|
+
* This program is free software: you can redistribute it and/or modify
|
|
6
|
+
* it under the terms of the GNU Affero General Public License as published by
|
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
* (at your option) any later version.
|
|
9
|
+
*
|
|
10
|
+
* This program is distributed in the hope that it will be useful,
|
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
* GNU Affero General Public License for more details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
16
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
// Tiny studio ws client: request/response correlated by id, plus event push.
|
|
19
|
+
// Auto-reconnects; queues calls issued before the socket is open.
|
|
20
|
+
export function connect( url, onEvent ) {
|
|
21
|
+
let ws, nextId = 0;
|
|
22
|
+
const pending = new Map();
|
|
23
|
+
const queue = [];
|
|
24
|
+
let statusCb = () => {};
|
|
25
|
+
|
|
26
|
+
function setStatus( s ) { statusCb(s); }
|
|
27
|
+
|
|
28
|
+
function open() {
|
|
29
|
+
ws = new WebSocket(url);
|
|
30
|
+
ws.onopen = () => { setStatus('live'); while ( queue.length ) ws.send(queue.shift()); };
|
|
31
|
+
ws.onclose = () => { setStatus('down'); setTimeout(open, 1000); };
|
|
32
|
+
ws.onerror = () => { try { ws.close(); } catch ( e ) {} };
|
|
33
|
+
ws.onmessage = ( ev ) => {
|
|
34
|
+
let m; try { m = JSON.parse(ev.data); } catch ( e ) { return; }
|
|
35
|
+
if ( m.id != null && pending.has(m.id) ) {
|
|
36
|
+
const { resolve, reject } = pending.get(m.id);
|
|
37
|
+
pending.delete(m.id);
|
|
38
|
+
m.ok ? resolve(m.result) : reject(new Error(m.error));
|
|
39
|
+
} else if ( m.type ) {
|
|
40
|
+
onEvent(m);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
open();
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
onStatus( cb ) { statusCb = cb; },
|
|
48
|
+
call( op, args, sessionId ) {
|
|
49
|
+
const id = 'r' + (++nextId);
|
|
50
|
+
const payload = JSON.stringify({ id, op, args: args || {}, sessionId });
|
|
51
|
+
return new Promise(( resolve, reject ) => {
|
|
52
|
+
pending.set(id, { resolve, reject });
|
|
53
|
+
if ( ws && ws.readyState === WebSocket.OPEN ) ws.send(payload);
|
|
54
|
+
else queue.push(payload);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Nathanael Braun
|
|
3
|
+
* @author : Nathanael BRAUN <pp9ping@gmail.com>
|
|
4
|
+
*
|
|
5
|
+
* This program is free software: you can redistribute it and/or modify
|
|
6
|
+
* it under the terms of the GNU Affero General Public License as published by
|
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
* (at your option) any later version.
|
|
9
|
+
*
|
|
10
|
+
* This program is distributed in the hope that it will be useful,
|
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
* GNU Affero General Public License for more details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
16
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
'use strict';
|
|
19
|
+
/**
|
|
20
|
+
* The studio server: serves the static frontend (lib/studio/public) over http and
|
|
21
|
+
* bridges a WebSocket to the Studio (ops in, events out). Thin — all logic lives in
|
|
22
|
+
* studio.js / session.js.
|
|
23
|
+
*
|
|
24
|
+
* const { createServer } = require('skynet-graph/lib/studio/server');
|
|
25
|
+
* const srv = createServer({ Graph: require('skynet-graph'), root: './' , ask });
|
|
26
|
+
* srv.listen(4848, () => console.log('sg studio on http://localhost:4848'));
|
|
27
|
+
*/
|
|
28
|
+
const http = require('http');
|
|
29
|
+
const fs = require('fs');
|
|
30
|
+
const path = require('path');
|
|
31
|
+
const { WebSocketServer } = require('ws');
|
|
32
|
+
const Studio = require('./studio.js');
|
|
33
|
+
const { OPS } = require('./protocol.js');
|
|
34
|
+
|
|
35
|
+
const PUBLIC = path.join(__dirname, 'public');
|
|
36
|
+
const MIME = {
|
|
37
|
+
'.html': 'text/html', '.js': 'text/javascript', '.css': 'text/css',
|
|
38
|
+
'.json': 'application/json', '.svg': 'image/svg+xml', '.map': 'application/json'
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// route an op to a studio-level or session-level method
|
|
42
|
+
function dispatch( studio, sessionId, op, args ) {
|
|
43
|
+
switch ( op ) {
|
|
44
|
+
case 'listCorpora': return studio.listCorpora();
|
|
45
|
+
case 'loadCorpus': return studio.loadCorpus(args);
|
|
46
|
+
case 'fork': return studio.fork(sessionId || 'root', args);
|
|
47
|
+
case 'merge': return studio.merge(args.childId, args.targetId, args.project);
|
|
48
|
+
case 'selectSession': { const ok = !!studio.getSession(args.sessionId); if ( ok ) studio.setActive(args.sessionId); return { ok }; }
|
|
49
|
+
case 'importCorpus': return studio.importCorpus(args.bundle, args.opts || {});
|
|
50
|
+
}
|
|
51
|
+
const s = studio.getSession(sessionId || 'root');
|
|
52
|
+
if ( !s ) throw new Error('no such session: ' + sessionId);
|
|
53
|
+
switch ( op ) {
|
|
54
|
+
case 'reset': s._destroy(); return { ok: true };
|
|
55
|
+
case 'mutate': return s.mutate(args.template, args.targetId);
|
|
56
|
+
case 'run': return s.run();
|
|
57
|
+
case 'state': return s.state();
|
|
58
|
+
case 'conceptTree': return s.conceptTree();
|
|
59
|
+
case 'grammarGraph': return s.grammarGraph();
|
|
60
|
+
case 'corpusManifest': return s.corpusManifest(args.meta);
|
|
61
|
+
case 'exportCorpus': return s.exportCorpus(args.meta);
|
|
62
|
+
case 'providerTrace': return s.providerTrace(args.n, args.filter);
|
|
63
|
+
case 'mergePreview': return s.mergePreview(args.template, args.opts);
|
|
64
|
+
case 'getConcept': return s.getConcept(args.nameOrId);
|
|
65
|
+
case 'validateConcept': return s.validateConcept(args.schema);
|
|
66
|
+
case 'patchConcept': return s.patchConcept(args.nameOrId, args.updates);
|
|
67
|
+
case 'addConcept': return s.addConcept(args.parentNameOrId, args.schema);
|
|
68
|
+
case 'deleteConcept': return s.deleteConcept(args.nameOrId);
|
|
69
|
+
case 'registry': return s.registry();
|
|
70
|
+
case 'declareKey': return s.declareKey(args);
|
|
71
|
+
case 'proposeAlias': return s.proposeAlias(args);
|
|
72
|
+
case 'retractAlias': return s.retractAlias(args);
|
|
73
|
+
case 'creditAlias': return s.creditAlias(args);
|
|
74
|
+
case 'exportLattice': return s.exportLattice(args.meta);
|
|
75
|
+
case 'importLattice': return s.importLattice(args);
|
|
76
|
+
case 'revisions': return s.revisions();
|
|
77
|
+
case 'snapshot': return s.snapshot(args.rev);
|
|
78
|
+
case 'rollback': return s.rollback(args.rev);
|
|
79
|
+
case 'diff': return s.diff(args.a, args.b);
|
|
80
|
+
case 'prompt':
|
|
81
|
+
if ( typeof s.prompt !== 'function' ) throw new Error('prompt not available (no LLM backend wired)');
|
|
82
|
+
return s.prompt(args.text, args.opts);
|
|
83
|
+
}
|
|
84
|
+
throw new Error('unhandled op: ' + op);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function serveStatic( req, res ) {
|
|
88
|
+
let urlPath = decodeURIComponent((req.url || '/').split('?')[0]);
|
|
89
|
+
if ( urlPath === '/favicon.ico' ) { res.writeHead(204); return res.end(); }
|
|
90
|
+
if ( urlPath === '/' ) urlPath = '/index.html';
|
|
91
|
+
const filePath = path.normalize(path.join(PUBLIC, urlPath));
|
|
92
|
+
if ( !filePath.startsWith(PUBLIC) ) { res.writeHead(403); return res.end('forbidden'); }
|
|
93
|
+
fs.readFile(filePath, ( err, buf ) => {
|
|
94
|
+
if ( err ) { res.writeHead(404); return res.end('not found'); }
|
|
95
|
+
res.writeHead(200, { 'Content-Type': MIME[path.extname(filePath)] || 'application/octet-stream' });
|
|
96
|
+
res.end(buf);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function createServer( { Graph, ask, root, logger } = {} ) {
|
|
101
|
+
const studio = new Studio({ Graph, ask, root, logger });
|
|
102
|
+
const httpServer = http.createServer(serveStatic);
|
|
103
|
+
const wss = new WebSocketServer({ server: httpServer });
|
|
104
|
+
|
|
105
|
+
wss.on('connection', ( ws ) => {
|
|
106
|
+
const onEvent = ( e ) => { if ( ws.readyState === ws.OPEN ) ws.send(JSON.stringify(e)); };
|
|
107
|
+
studio.on('event', onEvent);
|
|
108
|
+
ws.on('close', () => studio.off('event', onEvent));
|
|
109
|
+
ws.on('message', async ( data ) => {
|
|
110
|
+
let msg;
|
|
111
|
+
try { msg = JSON.parse(data.toString()); } catch ( e ) { return; }
|
|
112
|
+
const { id, sessionId, op, args } = msg;
|
|
113
|
+
try {
|
|
114
|
+
if ( !OPS.includes(op) ) throw new Error('unknown op: ' + op);
|
|
115
|
+
const result = await dispatch(studio, sessionId, op, args || {});
|
|
116
|
+
ws.send(JSON.stringify({ id, ok: true, result }));
|
|
117
|
+
} catch ( e ) {
|
|
118
|
+
ws.send(JSON.stringify({ id, ok: false, error: e.message }));
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
httpServer, studio,
|
|
125
|
+
listen( port, cb ) { httpServer.listen(port, cb); return this; },
|
|
126
|
+
close( cb ) { wss.close(); httpServer.close(cb); }
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
module.exports = { createServer };
|