@hongmaple0820/scale-engine 0.50.1 → 0.50.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.en.md +2 -2
  2. package/README.md +2 -2
  3. package/dist/api/http.js +3 -1
  4. package/dist/api/http.js.map +1 -1
  5. package/dist/cli/cortexCommands.d.ts +16 -0
  6. package/dist/cli/cortexCommands.js +47 -4
  7. package/dist/cli/cortexCommands.js.map +1 -1
  8. package/dist/cortex/InstinctStore.d.ts +13 -1
  9. package/dist/cortex/InstinctStore.js +90 -11
  10. package/dist/cortex/InstinctStore.js.map +1 -1
  11. package/dist/cortex/SessionInjector.js +39 -2
  12. package/dist/cortex/SessionInjector.js.map +1 -1
  13. package/dist/dashboard/DashboardServer.d.ts +158 -0
  14. package/dist/dashboard/DashboardServer.js +753 -13
  15. package/dist/dashboard/DashboardServer.js.map +1 -1
  16. package/dist/dashboard/spa/assets/index-VYBCLBje.js +11 -0
  17. package/dist/dashboard/spa/assets/index-VhwY_ac1.css +1 -0
  18. package/dist/dashboard/spa/assets/naive-ui-BQy2AJkt.js +3340 -0
  19. package/dist/dashboard/spa/assets/vendor-BPU6aOYA.js +3 -0
  20. package/dist/dashboard/spa/assets/vue-CQQMb5Wi.js +17 -0
  21. package/dist/dashboard/spa/index.html +15 -462
  22. package/dist/memory/MemoryFabric.d.ts +13 -1
  23. package/dist/memory/MemoryFabric.js +60 -0
  24. package/dist/memory/MemoryFabric.js.map +1 -1
  25. package/dist/version.d.ts +1 -1
  26. package/dist/version.js +1 -1
  27. package/docs/workflow/ASSESSMENT_INDEX.md +326 -0
  28. package/docs/workflow/COMPARATIVE_ANALYSIS.md +422 -0
  29. package/docs/workflow/EXECUTIVE_SUMMARY.md +310 -0
  30. package/docs/workflow/IMPROVEMENT_CHECKLIST.md +518 -0
  31. package/docs/workflow/IMPROVEMENT_ROADMAP.md +707 -0
  32. package/docs/workflow/README.md +8 -0
  33. package/package.json +6 -2
  34. package/dist/dashboard/spa/app.js +0 -515
  35. package/dist/dashboard/spa/components/DataTable.js +0 -53
  36. package/dist/dashboard/spa/components/EventStream.js +0 -66
  37. package/dist/dashboard/spa/components/LoadingState.js +0 -39
  38. package/dist/dashboard/spa/components/MetricCard.js +0 -30
  39. package/dist/dashboard/spa/components/Panel.js +0 -27
  40. package/dist/dashboard/spa/components/StatusBadge.js +0 -51
  41. package/dist/dashboard/spa/i18n.js +0 -767
  42. package/dist/dashboard/spa/pages/costs.js +0 -522
  43. package/dist/dashboard/spa/pages/documents.js +0 -540
  44. package/dist/dashboard/spa/pages/knowledge.js +0 -457
  45. package/dist/dashboard/spa/pages/monitoring.js +0 -361
  46. package/dist/dashboard/spa/pages/overview.js +0 -301
  47. package/dist/dashboard/spa/pages/topology-renderers.js +0 -251
  48. package/dist/dashboard/spa/pages/topology.js +0 -370
  49. package/dist/dashboard/spa/pages/workflow-renderers.js +0 -239
  50. package/dist/dashboard/spa/pages/workflow.js +0 -217
@@ -1,463 +1,16 @@
1
- <!DOCTYPE html>
2
- <html lang="en" data-theme="dark">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>SCALE Engine Dashboard</title>
7
- <style>
8
- :root {
9
- --bg-0: #0a0a0a; --bg-1: #111111; --bg-2: #191919; --bg-3: #222222;
10
- --border: #2a2a2a; --border-hover: #3a3a3a;
11
- --text-0: #ededed; --text-1: #a1a1a1; --text-2: #666666;
12
- --accent: #00dc82; --accent-dim: rgba(0,220,130,0.15); --accent-hover: #00f090;
13
- --danger: #ff4444; --warning: #ffaa00; --info: #5588ff;
14
- --radius: 8px; --radius-lg: 12px;
15
- --shadow: 0 1px 3px rgba(0,0,0,0.3);
16
- --transition: 150ms ease;
17
- --sidebar-w: 240px;
18
- --header-h: 56px;
19
- }
20
- [data-theme="light"] {
21
- --bg-0: #ffffff; --bg-1: #fafafa; --bg-2: #f5f5f5; --bg-3: #eeeeee;
22
- --border: #e0e0e0; --border-hover: #cccccc;
23
- --text-0: #111111; --text-1: #555555; --text-2: #999999;
24
- --accent: #00b868; --accent-dim: rgba(0,184,104,0.1); --accent-hover: #00a058;
25
- --shadow: 0 1px 3px rgba(0,0,0,0.08);
26
- }
27
- * { box-sizing: border-box; margin: 0; padding: 0; }
28
- body {
29
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Inter', sans-serif;
30
- background: var(--bg-0); color: var(--text-0);
31
- display: flex; min-height: 100vh;
32
- -webkit-font-smoothing: antialiased;
33
- }
34
- a { color: var(--accent); text-decoration: none; }
35
- a:hover { color: var(--accent-hover); }
36
- button { font-family: inherit; cursor: pointer; }
37
-
38
- /* ── Sidebar ──────────────────────────────────────────────────── */
39
- .sidebar {
40
- width: var(--sidebar-w); min-width: var(--sidebar-w);
41
- background: var(--bg-1); border-right: 1px solid var(--border);
42
- display: flex; flex-direction: column;
43
- position: fixed; top: 0; left: 0; bottom: 0;
44
- z-index: 100;
45
- }
46
- .sidebar-brand {
47
- padding: 16px 20px; display: flex; align-items: center; gap: 10px;
48
- border-bottom: 1px solid var(--border);
49
- font-weight: 600; font-size: 15px;
50
- }
51
- .sidebar-brand .logo {
52
- width: 28px; height: 28px; background: var(--accent);
53
- border-radius: 6px; display: flex; align-items: center; justify-content: center;
54
- color: #000; font-weight: 700; font-size: 14px;
55
- }
56
- .sidebar-nav { flex: 1; padding: 12px 8px; overflow-y: auto; }
57
- .nav-section { padding: 8px 12px 4px; font-size: 11px; color: var(--text-2); text-transform: uppercase; letter-spacing: 0.5px; }
58
- .nav-item {
59
- display: flex; align-items: center; gap: 10px;
60
- padding: 8px 12px; border-radius: var(--radius);
61
- color: var(--text-1); font-size: 14px; transition: all var(--transition);
62
- cursor: pointer; user-select: none;
63
- }
64
- .nav-item:hover { background: var(--bg-3); color: var(--text-0); }
65
- .nav-item.active { background: var(--accent-dim); color: var(--accent); }
66
- .nav-item .icon { width: 18px; text-align: center; font-size: 15px; }
67
- .nav-item .badge {
68
- margin-left: auto; background: var(--accent); color: #000;
69
- padding: 1px 6px; border-radius: 10px; font-size: 11px; font-weight: 600;
70
- }
71
- .sidebar-footer {
72
- padding: 12px 16px; border-top: 1px solid var(--border);
73
- display: flex; align-items: center; justify-content: space-between;
74
- }
75
- .footer-controls { display: flex; align-items: center; gap: 6px; }
76
- .theme-toggle, .lang-toggle {
77
- background: var(--bg-3); border: 1px solid var(--border);
78
- color: var(--text-1); padding: 6px 10px; border-radius: var(--radius);
79
- font-size: 13px; transition: all var(--transition);
80
- }
81
- .theme-toggle:hover, .lang-toggle:hover { border-color: var(--border-hover); color: var(--text-0); }
82
- .sse-status { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-2); }
83
- .sse-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--danger); }
84
- .sse-dot.connected { background: var(--accent); }
85
-
86
- /* ── Main Content ─────────────────────────────────────────────── */
87
- .main { flex: 1; margin-left: var(--sidebar-w); display: flex; flex-direction: column; min-height: 100vh; }
88
- .header {
89
- height: var(--header-h); padding: 0 24px;
90
- display: flex; align-items: center; justify-content: space-between;
91
- border-bottom: 1px solid var(--border); background: var(--bg-1);
92
- position: sticky; top: 0; z-index: 50;
93
- }
94
- .header-title { font-size: 18px; font-weight: 600; }
95
- .header-actions { display: flex; align-items: center; gap: 12px; }
96
- .search-box {
97
- background: var(--bg-2); border: 1px solid var(--border);
98
- color: var(--text-0); padding: 7px 12px; border-radius: var(--radius);
99
- font-size: 13px; width: 220px; transition: all var(--transition);
100
- }
101
- .search-box:focus { outline: none; border-color: var(--accent); }
102
- .search-box::placeholder { color: var(--text-2); }
103
- .content { flex: 1; padding: 24px; overflow-y: auto; }
104
- .page-toolbar {
105
- display: flex; gap: 12px; margin-bottom: 16px; align-items: center; flex-wrap: wrap;
106
- }
107
- .toolbar-spacer { flex: 1; min-width: 12px; }
108
- .data-note {
109
- display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: center;
110
- padding: 10px 12px; margin-bottom: 16px; border: 1px solid var(--border);
111
- border-radius: var(--radius); background: var(--bg-1); color: var(--text-1);
112
- font-size: 12px; line-height: 1.5;
113
- }
114
- .data-note strong { color: var(--text-0); font-weight: 600; }
115
- .action-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
116
- .field-label { display: inline-flex; gap: 8px; align-items: center; color: var(--text-1); font-size: 12px; }
117
- .field-label input[type="checkbox"] { accent-color: var(--accent); }
118
- .section-copy { color: var(--text-2); font-size: 12px; line-height: 1.6; }
119
- .auto-refresh-control {
120
- padding: 6px 10px; border: 1px solid var(--border); border-radius: var(--radius);
121
- background: var(--bg-1);
122
- }
123
-
124
- /* ── Cards & Widgets ──────────────────────────────────────────── */
125
- .metrics-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; margin-bottom: 24px; }
126
- .metric-card {
127
- background: var(--bg-1); border: 1px solid var(--border);
128
- border-radius: var(--radius-lg); padding: 20px;
129
- transition: border-color var(--transition);
130
- }
131
- .metric-card:hover { border-color: var(--border-hover); }
132
- .metric-label { font-size: 13px; color: var(--text-1); margin-bottom: 8px; }
133
- .metric-value { font-size: 28px; font-weight: 700; color: var(--text-0); }
134
- .metric-value.accent { color: var(--accent); }
135
- .metric-change { font-size: 12px; margin-top: 4px; }
136
- .metric-change.up { color: var(--accent); }
137
- .metric-change.down { color: var(--danger); }
138
-
139
- .chart-container {
140
- background: var(--bg-1); border: 1px solid var(--border);
141
- border-radius: var(--radius-lg); padding: 20px; margin-bottom: 24px;
142
- }
143
- .chart-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; }
144
- .chart-title { font-size: 15px; font-weight: 600; }
145
- .chart-area { width: 100%; height: 300px; }
146
-
147
- .panel {
148
- background: var(--bg-1); border: 1px solid var(--border);
149
- border-radius: var(--radius-lg); padding: 20px; margin-bottom: 24px;
150
- }
151
- .panel-title { font-size: 15px; font-weight: 600; margin-bottom: 16px; display: flex; align-items: center; gap: 8px; }
152
- .panel-title .count { color: var(--text-2); font-weight: 400; font-size: 13px; }
153
-
154
- /* ── Status Badges ────────────────────────────────────────────── */
155
- .badge-status {
156
- display: inline-block; padding: 2px 8px; border-radius: 4px;
157
- font-size: 12px; font-weight: 500;
158
- }
159
- .badge-DRAFT { background: #333; color: #999; }
160
- .badge-REVIEWING { background: rgba(255,170,0,0.15); color: #ffaa00; }
161
- .badge-FROZEN { background: rgba(85,136,255,0.15); color: #5588ff; }
162
- .badge-COMPLETED { background: rgba(0,220,130,0.15); color: #00dc82; }
163
- .badge-BLOCKED { background: rgba(255,68,68,0.15); color: #ff4444; }
164
- .badge-IN_PROGRESS { background: rgba(255,170,0,0.15); color: #ffaa00; }
165
- .badge-DONE { background: rgba(0,220,130,0.15); color: #00dc82; }
166
- .badge-PROPOSED { background: rgba(85,136,255,0.15); color: #5588ff; }
167
- .badge-APPROVED { background: rgba(0,220,130,0.15); color: #00dc82; }
168
- .badge-REJECTED { background: rgba(255,68,68,0.15); color: #ff4444; }
169
-
170
- .severity-badge { display: inline-block; padding: 2px 6px; border-radius: 3px; font-size: 11px; font-weight: 500; }
171
- .severity-low { background: rgba(0,220,130,0.15); color: #00dc82; }
172
- .severity-medium { background: rgba(255,170,0,0.15); color: #ffaa00; }
173
- .severity-high { background: rgba(255,68,68,0.15); color: #ff4444; }
174
- .severity-critical { background: rgba(255,0,0,0.2); color: #ff2222; }
175
-
176
- /* ── Tables ───────────────────────────────────────────────────── */
177
- .data-table { width: 100%; border-collapse: collapse; }
178
- .data-table th { text-align: left; padding: 8px 12px; font-size: 12px; color: var(--text-2); font-weight: 500; border-bottom: 1px solid var(--border); }
179
- .data-table td { padding: 10px 12px; font-size: 13px; border-bottom: 1px solid var(--bg-3); }
180
- .data-table tr:hover td { background: var(--bg-2); }
181
-
182
- /* ── Event Stream ─────────────────────────────────────────────── */
183
- .event-stream { max-height: 400px; overflow-y: auto; }
184
- .event-item {
185
- display: flex; align-items: center; gap: 12px;
186
- padding: 8px 0; border-bottom: 1px solid var(--bg-3);
187
- font-size: 13px;
188
- }
189
- .event-type {
190
- background: var(--accent-dim); color: var(--accent);
191
- padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 500;
192
- white-space: nowrap;
193
- }
194
- .event-time { color: var(--text-2); font-size: 12px; white-space: nowrap; }
195
-
196
- /* ── Artifact Cards ───────────────────────────────────────────── */
197
- .artifact-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16px; }
198
- .artifact-card {
199
- background: var(--bg-1); border: 1px solid var(--border);
200
- border-radius: var(--radius-lg); padding: 16px;
201
- transition: border-color var(--transition);
202
- }
203
- .artifact-card:hover { border-color: var(--border-hover); }
204
- .artifact-card-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 12px; }
205
- .artifact-card-title { font-size: 14px; font-weight: 600; }
206
- .artifact-card-meta { font-size: 12px; color: var(--text-2); margin-bottom: 12px; }
207
- .artifact-gates { display: flex; flex-wrap: wrap; gap: 6px; }
208
- .gate-pill {
209
- padding: 2px 8px; border-radius: 4px; font-size: 11px;
210
- background: var(--bg-3); color: var(--text-1);
211
- }
212
- .gate-pill.passed { background: rgba(0,220,130,0.15); color: #00dc82; }
213
- .gate-pill.failed { background: rgba(255,68,68,0.15); color: #ff4444; }
214
-
215
- /* ── Document Viewer ──────────────────────────────────────────── */
216
- .doc-layout {
217
- display: grid; grid-template-columns: 260px 1fr; gap: 24px;
218
- min-height: calc(100vh - var(--header-h) - 96px); align-items: start;
219
- }
220
- .doc-tree {
221
- background: var(--bg-1); border: 1px solid var(--border);
222
- border-radius: var(--radius-lg); padding: 16px; overflow-y: auto;
223
- position: sticky; top: 0; max-height: calc(100vh - var(--header-h) - 96px);
224
- }
225
- .doc-tree-item {
226
- padding: 6px 8px; border-radius: var(--radius); font-size: 13px;
227
- cursor: pointer; color: var(--text-1); transition: all var(--transition);
228
- }
229
- .doc-tree-item:hover { background: var(--bg-3); color: var(--text-0); }
230
- .doc-tree-item.active { background: var(--accent-dim); color: var(--accent); }
231
- .doc-tree-folder { font-weight: 600; color: var(--text-0); padding: 8px 8px 4px; font-size: 12px; text-transform: uppercase; }
232
- .doc-renderer {
233
- background: var(--bg-1); border: 1px solid var(--border);
234
- border-radius: var(--radius-lg); padding: 24px; overflow-y: auto;
235
- min-height: calc(100vh - var(--header-h) - 96px);
236
- }
237
- .doc-renderer iframe { width: 100%; height: 100%; border: none; min-height: 600px; }
238
- .prototype-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 14px; }
239
- .prototype-card {
240
- border: 1px solid var(--border); border-radius: var(--radius-lg);
241
- background: var(--bg-2); overflow: hidden;
242
- }
243
- .prototype-preview {
244
- height: 150px; border-bottom: 1px solid var(--border); background: var(--bg-0); overflow: hidden;
245
- }
246
- .prototype-preview iframe {
247
- width: 100%; height: 300px; transform: scale(0.5); transform-origin: top left;
248
- border: 0; pointer-events: none; background: white;
249
- }
250
- .prototype-body { padding: 12px; display: flex; flex-direction: column; gap: 10px; }
251
- .prototype-title { font-size: 13px; font-weight: 600; color: var(--text-0); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
252
- .prototype-meta { color: var(--text-2); font-size: 12px; }
253
- .review-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; margin-bottom: 12px; }
254
- .review-item { border: 1px solid var(--border); border-radius: var(--radius); padding: 12px; background: var(--bg-2); }
255
- .review-count { font-size: 22px; font-weight: 700; color: var(--text-0); }
256
- .review-label { font-size: 12px; color: var(--text-2); margin-top: 4px; }
257
-
258
- /* ── Utilities ────────────────────────────────────────────────── */
259
- .flex { display: flex; }
260
- .flex-col { flex-direction: column; }
261
- .gap-16 { gap: 16px; }
262
- .gap-24 { gap: 24px; }
263
- .mb-24 { margin-bottom: 24px; }
264
- .text-muted { color: var(--text-2); }
265
- .text-sm { font-size: 13px; }
266
- .grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
267
- .grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 24px; }
268
- .loading-placeholder {
269
- background: var(--bg-2); border-radius: var(--radius);
270
- height: 200px; display: flex; align-items: center; justify-content: center;
271
- color: var(--text-2); font-size: 14px;
272
- }
273
- .empty-state {
274
- text-align: center; padding: 48px 24px; color: var(--text-2);
275
- }
276
- .empty-state .icon { font-size: 32px; margin-bottom: 12px; }
277
- .tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 16px; }
278
- .tab {
279
- padding: 8px 16px; font-size: 13px; color: var(--text-1);
280
- cursor: pointer; border-bottom: 2px solid transparent;
281
- transition: all var(--transition);
282
- }
283
- .tab:hover { color: var(--text-0); }
284
- .tab.active { color: var(--accent); border-bottom-color: var(--accent); }
285
-
286
- /* ── Markdown Body ────────────────────────────────────────────── */
287
- .markdown-body h1, .markdown-body h2, .markdown-body h3 { color: var(--text-0); }
288
- .markdown-body a { color: var(--accent); }
289
- .markdown-body code { background: var(--bg-2); padding: 2px 5px; border-radius: 3px; font-size: 12px; }
290
- .markdown-body pre { background: var(--bg-2); padding: 12px; border-radius: var(--radius); overflow-x: auto; }
291
- .markdown-body blockquote { border-left: 3px solid var(--accent); padding-left: 12px; color: var(--text-1); margin: 12px 0; }
292
- .markdown-body table { border-collapse: collapse; width: 100%; margin: 12px 0; }
293
- .markdown-body th, .markdown-body td { border: 1px solid var(--border); padding: 6px 10px; text-align: left; }
294
- .markdown-body th { background: var(--bg-2); font-weight: 600; }
295
- .markdown-body img { max-width: 100%; border-radius: var(--radius); }
296
-
297
- /* ── Doc Favorites ────────────────────────────────────────────── */
298
- .doc-fav-btn:hover { color: #ffaa00 !important; transform: scale(1.2); }
299
- .doc-fav-btn { transition: all var(--transition); display: inline-flex; }
300
-
301
- /* ── Topology Legend Items ─────────────────────────────────────── */
302
- .topo-legend-item:hover, .topo-kind-item:hover, .topo-domain-item:hover {
303
- background: var(--bg-3);
304
- }
305
-
306
- /* ── Scrollbar ────────────────────────────────────────────────── */
307
- ::-webkit-scrollbar { width: 6px; height: 6px; }
308
- ::-webkit-scrollbar-track { background: transparent; }
309
- ::-webkit-scrollbar-thumb { background: var(--bg-3); border-radius: 3px; }
310
- ::-webkit-scrollbar-thumb:hover { background: var(--border-hover); }
311
-
312
- /* ── Topology ─────────────────────────────────────────────────── */
313
- #topology-cy { width: 100%; height: calc(100vh - var(--header-h) - 48px); background: var(--bg-0); border-radius: var(--radius-lg); }
314
- .topology-controls { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
315
- .topo-btn {
316
- padding: 6px 12px; border-radius: var(--radius);
317
- background: var(--bg-2); border: 1px solid var(--border);
318
- color: var(--text-1); font-size: 12px; transition: all var(--transition);
319
- cursor: pointer;
320
- }
321
- .topo-btn:hover, .topo-btn.active { background: var(--accent-dim); color: var(--accent); border-color: var(--accent); }
322
- .topo-btn:focus-visible, .tab:focus-visible, .nav-item:focus-visible, .doc-tree-item:focus-visible {
323
- outline: 2px solid var(--accent); outline-offset: 2px;
324
- }
325
-
326
- /* ── Components ──────────────────────────────────────────────── */
327
- .badge {
328
- display: inline-block; padding: 2px 8px; border-radius: 10px;
329
- font-size: 11px; font-weight: 500; line-height: 1.4;
330
- }
331
- .badge-accent { background: var(--accent-dim); color: var(--accent); }
332
- .badge-success { background: rgba(0,220,130,0.15); color: #00dc82; }
333
- .badge-warning { background: rgba(255,170,0,0.15); color: #ffaa00; }
334
- .badge-danger { background: rgba(255,68,68,0.15); color: #ff4444; }
335
- .badge-info { background: rgba(85,136,255,0.15); color: #5588ff; }
336
- .badge-muted { background: var(--bg-3); color: var(--text-2); }
337
-
338
- .data-table { width: 100%; border-collapse: collapse; font-size: 13px; }
339
- .data-table th {
340
- text-align: left; padding: 8px 12px; font-weight: 500; font-size: 11px;
341
- color: var(--text-2); text-transform: uppercase; letter-spacing: 0.5px;
342
- border-bottom: 1px solid var(--border);
343
- }
344
- .data-table td { padding: 8px 12px; border-bottom: 1px solid var(--border); }
345
- .data-table tr:hover td { background: var(--bg-2); }
346
- .table-wrap { overflow-x: auto; }
347
-
348
- .loading-state, .empty-state {
349
- display: flex; flex-direction: column; align-items: center; justify-content: center;
350
- padding: 48px 24px; gap: 12px;
351
- }
352
- .loading-spinner {
353
- width: 24px; height: 24px; border: 2px solid var(--border);
354
- border-top-color: var(--accent); border-radius: 50%;
355
- animation: spin 0.6s linear infinite;
356
- }
357
- @keyframes spin { to { transform: rotate(360deg); } }
358
- .empty-icon { font-size: 32px; opacity: 0.5; }
359
- .empty-title { font-size: 14px; font-weight: 500; }
360
- .empty-desc { font-size: 12px; }
361
-
362
- .metric-icon { font-size: 20px; margin-bottom: 4px; }
363
-
364
- .event-icon { font-size: 14px; width: 20px; text-align: center; }
365
- .event-icon.accent { color: var(--accent); }
366
- .event-icon.danger { color: var(--danger); }
367
- .event-icon.warning { color: var(--warning); }
368
- .event-icon.info { color: var(--info); }
369
- .event-icon.success { color: var(--accent); }
370
- .event-type { font-size: 12px; font-weight: 500; }
371
- .event-time { font-size: 11px; color: var(--text-2); margin-left: auto; }
372
-
373
- /* ── Responsive ───────────────────────────────────────────────── */
374
- @media (max-width: 768px) {
375
- .sidebar { transform: translateX(-100%); }
376
- .main { margin-left: 0; }
377
- .grid-2, .grid-3 { grid-template-columns: 1fr; }
378
- .doc-layout { grid-template-columns: 1fr; }
379
- .doc-tree { position: static; max-height: 320px; }
380
- .page-toolbar { align-items: stretch; }
381
- .page-toolbar .search-box { width: 100%; max-width: none !important; }
382
- .toolbar-spacer { display: none; }
383
- }
384
- </style>
385
- </head>
386
- <body>
387
- <!-- Sidebar -->
388
- <nav class="sidebar">
389
- <div class="sidebar-brand">
390
- <div class="logo">S</div>
391
- <span>SCALE Engine</span>
392
- </div>
393
- <div class="sidebar-nav">
394
- <div class="nav-section" data-i18n="nav.dashboard">Dashboard</div>
395
- <div class="nav-item active" data-page="overview">
396
- <span class="icon">&#9632;</span> <span data-i18n="nav.overview">Overview</span>
397
- </div>
398
- <div class="nav-item" data-page="workflow">
399
- <span class="icon">&#9654;</span> <span data-i18n="nav.workflow">Workflow</span>
400
- </div>
401
- <div class="nav-item" data-page="topology">
402
- <span class="icon">&#9670;</span> <span data-i18n="nav.topology">Topology</span>
403
- </div>
404
- <div class="nav-section" data-i18n="nav.operations">Operations</div>
405
- <div class="nav-item" data-page="monitoring">
406
- <span class="icon">&#9673;</span> <span data-i18n="nav.monitoring">Monitoring</span>
407
- </div>
408
- <div class="nav-item" data-page="costs">
409
- <span class="icon">&#9660;</span> <span data-i18n="nav.costs">Costs</span>
410
- </div>
411
- <div class="nav-section" data-i18n="nav.content">Content</div>
412
- <div class="nav-item" data-page="documents">
413
- <span class="icon">&#9776;</span> <span data-i18n="nav.documents">Documents</span>
414
- </div>
415
- <div class="nav-item" data-page="knowledge">
416
- <span class="icon">&#9678;</span> <span data-i18n="nav.knowledge">Knowledge</span>
417
- </div>
418
- </div>
419
- <div class="sidebar-footer">
420
- <div class="sse-status">
421
- <div class="sse-dot" id="sse-dot"></div>
422
- <span id="sse-label" data-i18n="sse.disconnected">Disconnected</span>
423
- </div>
424
- <div class="footer-controls">
425
- <button class="lang-toggle" id="lang-toggle" title="Switch language">EN</button>
426
- <button class="theme-toggle" id="theme-toggle" title="Toggle theme">&#9790;</button>
427
- </div>
428
- </div>
429
- </nav>
430
-
431
- <!-- Main Content -->
432
- <div class="main">
433
- <header class="header">
434
- <h1 class="header-title" id="page-title">Overview</h1>
435
- <div class="header-actions">
436
- <input type="text" class="search-box" placeholder="Search..." id="global-search" data-i18n-placeholder="header.search">
437
- </div>
438
- </header>
439
- <div class="content" id="app"></div>
440
- </div>
441
-
442
- <!-- Scripts -->
443
- <script src="https://cdn.jsdelivr.net/npm/echarts@5.6.0/dist/echarts.min.js"></script>
444
- <script src="/spa/i18n.js"></script>
445
- <script src="/spa/app.js"></script>
446
- <script src="/spa/components/MetricCard.js"></script>
447
- <script src="/spa/components/Panel.js"></script>
448
- <script src="/spa/components/StatusBadge.js"></script>
449
- <script src="/spa/components/DataTable.js"></script>
450
- <script src="/spa/components/EventStream.js"></script>
451
- <script src="/spa/components/LoadingState.js"></script>
452
- <script src="/spa/pages/overview.js"></script>
453
- <script src="/spa/pages/workflow-renderers.js"></script>
454
- <script src="/spa/pages/workflow.js"></script>
455
- <script src="/spa/pages/monitoring.js"></script>
456
- <script src="/spa/pages/costs.js"></script>
457
- <script src="/spa/pages/documents.js"></script>
458
- <script src="/spa/pages/knowledge.js"></script>
459
- <script src="/spa/pages/topology-renderers.js"></script>
460
- <script src="/spa/pages/topology.js"></script>
461
- <script>window.Dashboard?.navigate(location.hash.slice(1) || 'overview')</script>
462
- </body>
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>SCALE Engine Dashboard</title>
7
+ <script type="module" crossorigin src="/assets/index-VYBCLBje.js"></script>
8
+ <link rel="modulepreload" crossorigin href="/assets/vue-CQQMb5Wi.js">
9
+ <link rel="modulepreload" crossorigin href="/assets/vendor-BPU6aOYA.js">
10
+ <link rel="modulepreload" crossorigin href="/assets/naive-ui-BQy2AJkt.js">
11
+ <link rel="stylesheet" crossorigin href="/assets/index-VhwY_ac1.css">
12
+ </head>
13
+ <body>
14
+ <div id="app"></div>
15
+ </body>
463
16
  </html>
@@ -53,7 +53,7 @@ export interface ContextPack {
53
53
  sections: ContextPackSection[];
54
54
  omittedSections: ContextPackOmittedSection[];
55
55
  }
56
- export type ContextPackItem = RuntimeEvidenceContextItem | RuntimeSessionContextItem | ProviderMemoryContextItem | KnowledgeContextItem | GraphContextItem;
56
+ export type ContextPackItem = RuntimeEvidenceContextItem | RuntimeSessionContextItem | CortexInstinctContextItem | ProviderMemoryContextItem | KnowledgeContextItem | GraphContextItem;
57
57
  export interface RuntimeEvidenceContextItem {
58
58
  type: 'runtime-evidence';
59
59
  id: string;
@@ -75,6 +75,17 @@ export interface RuntimeSessionContextItem {
75
75
  message?: string;
76
76
  createdAt: string;
77
77
  }
78
+ export interface CortexInstinctContextItem {
79
+ type: 'cortex-instinct';
80
+ id: string;
81
+ domain: string;
82
+ trigger: string;
83
+ confidence: number;
84
+ observations: number;
85
+ hitRate: number;
86
+ action: string;
87
+ evidence: string[];
88
+ }
78
89
  export interface ProviderMemoryContextItem {
79
90
  type: 'provider-memory';
80
91
  provider: string;
@@ -112,6 +123,7 @@ export declare class MemoryFabric {
112
123
  createContextPack(input: ContextPackInput): Promise<ContextPack>;
113
124
  private runtimeEvidenceSection;
114
125
  private sessionEventsSection;
126
+ private cortexInstinctSection;
115
127
  private knowledgeSection;
116
128
  private providerMemorySection;
117
129
  private graphSection;
@@ -3,6 +3,7 @@ import { isAbsolute, join, relative, resolve } from 'node:path';
3
3
  import { resolveRuntimeEvidenceFailures, RuntimeEvidenceLedger, } from '../runtime/RuntimeEvidenceLedger.js';
4
4
  import { SessionLedger } from '../runtime/SessionLedger.js';
5
5
  import { redactEvidenceText } from '../tools/ToolEvidenceStore.js';
6
+ import { InstinctStore } from '../cortex/InstinctStore.js';
6
7
  import { recallMemoryProviders } from './MemoryProviders.js';
7
8
  const DEFAULT_BUDGET_TOKENS = 4_000;
8
9
  const DEFAULT_KNOWLEDGE_TOP_K = 5;
@@ -38,6 +39,7 @@ export class MemoryFabric {
38
39
  const drafts = [
39
40
  this.runtimeEvidenceSection(task),
40
41
  this.sessionEventsSection(task),
42
+ this.cortexInstinctSection(),
41
43
  await this.providerMemorySection(task, input.knowledgeTopK ?? DEFAULT_KNOWLEDGE_TOP_K),
42
44
  await this.knowledgeSection(task, input.knowledgeTopK ?? DEFAULT_KNOWLEDGE_TOP_K),
43
45
  this.graphSection(),
@@ -102,6 +104,21 @@ export class MemoryFabric {
102
104
  items: events.map(toSessionEventItem),
103
105
  };
104
106
  }
107
+ cortexInstinctSection() {
108
+ const store = new InstinctStore(join(this.scaleRoot, 'instincts'), { createDirs: false });
109
+ const instincts = store.getInjectionInstincts(undefined, {
110
+ allowModerateFallback: true,
111
+ fallbackMinConfidence: 0.5,
112
+ fallbackMinObservations: 3,
113
+ fallbackLimit: 3,
114
+ });
115
+ return {
116
+ id: 'cortex-instincts',
117
+ title: 'Cortex Learned Instincts',
118
+ priority: 75,
119
+ items: instincts.map(toCortexInstinctItem),
120
+ };
121
+ }
105
122
  async knowledgeSection(task, topK) {
106
123
  if (!this.knowledgeBase) {
107
124
  return { id: 'knowledge', title: 'Knowledge Recall', priority: 60, items: [] };
@@ -265,6 +282,19 @@ function toSessionEventItem(event) {
265
282
  createdAt: event.createdAt,
266
283
  };
267
284
  }
285
+ function toCortexInstinctItem(instinct) {
286
+ return {
287
+ type: 'cortex-instinct',
288
+ id: instinct.id,
289
+ domain: instinct.domain,
290
+ trigger: instinct.trigger,
291
+ confidence: instinct.confidence,
292
+ observations: instinct.observations,
293
+ hitRate: Math.max(0, Math.min(1, instinct.hitRate)),
294
+ action: summarizeInstinctAction(instinct.action, instinct.trigger),
295
+ evidence: instinct.evidence.slice(0, 3),
296
+ };
297
+ }
268
298
  function toProviderMemoryItem(item) {
269
299
  return {
270
300
  type: 'provider-memory',
@@ -283,12 +313,42 @@ function renderItemSummary(item) {
283
313
  return `[${item.status}] ${item.title}: ${item.summary}`;
284
314
  if (item.type === 'session-event')
285
315
  return `${item.eventType}${item.phase ? `/${item.phase}` : ''}: ${item.message ?? item.createdAt}`;
316
+ if (item.type === 'cortex-instinct')
317
+ return `${item.domain}/${item.id}: ${item.action} (${item.confidence.toFixed(2)})`;
286
318
  if (item.type === 'provider-memory')
287
319
  return `${item.provider}/${item.id}: ${item.title} (${item.confidence.toFixed(2)})`;
288
320
  if (item.type === 'knowledge')
289
321
  return `${item.title} (${item.tags.join(', ') || 'no tags'})`;
290
322
  return `${item.kind}: ${item.path}`;
291
323
  }
324
+ function summarizeInstinctAction(action, fallback) {
325
+ const lines = action
326
+ .replace(/\r\n/g, '\n')
327
+ .split('\n')
328
+ .map(line => line.trim());
329
+ const preferred = firstLineAfterHeading(lines, ['Recommended Action', 'Action', 'Known Resolutions']);
330
+ const summary = preferred ?? lines.find(line => line &&
331
+ !/^#{1,6}\s+/.test(line) &&
332
+ !/^[-*_`>]+$/.test(line) &&
333
+ !/^## Evidence$/i.test(line)) ?? fallback;
334
+ return truncate(summary.replace(/^[-*]\s+/, '').replace(/^#+\s+/, '').replace(/\s+/g, ' ').trim(), 180);
335
+ }
336
+ function firstLineAfterHeading(lines, headings) {
337
+ const normalizedHeadings = headings.map(heading => heading.toLowerCase());
338
+ for (let index = 0; index < lines.length; index++) {
339
+ const match = lines[index]?.match(/^#{1,6}\s+(.+)$/);
340
+ if (!match || !normalizedHeadings.includes(match[1].trim().toLowerCase()))
341
+ continue;
342
+ for (const candidate of lines.slice(index + 1)) {
343
+ if (!candidate)
344
+ continue;
345
+ if (/^#{1,6}\s+/.test(candidate))
346
+ break;
347
+ return candidate;
348
+ }
349
+ }
350
+ return undefined;
351
+ }
292
352
  function estimateTokens(text) {
293
353
  return Math.max(1, Math.ceil(text.length / 4));
294
354
  }