@lievclouds/dsh-cortex 0.3.1 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -186
- package/client.js +142 -153
- package/locale/en.json +6 -6
- package/locale/zh.json +6 -6
- package/package.json +106 -106
- package/src/cortex-ui/dsh/wrapper.template.js +141 -152
- package/src/cortex-ui/renderer/pages/NebulaPage.tsx +12 -10
package/locale/en.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
{
|
|
2
|
-
"meta": {
|
|
3
|
-
"title": "Cortex",
|
|
4
|
-
"description": "The original Cortex workbench inside DeepSeek Harness: vulnerability board, internal operations, memory nebula graph, assets,
|
|
5
|
-
}
|
|
6
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"title": "Cortex",
|
|
4
|
+
"description": "The original Cortex workbench inside DeepSeek Harness: vulnerability board, internal operations, memory nebula graph, assets, snapshots and retest, plus 12 native cortex_* agent tools. No MCP needed."
|
|
5
|
+
}
|
|
6
|
+
}
|
package/locale/zh.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
{
|
|
2
|
-
"meta": {
|
|
3
|
-
"title": "Cortex",
|
|
4
|
-
"description": "在 DeepSeek Harness 内使用原版 Cortex
|
|
5
|
-
}
|
|
6
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"title": "Cortex",
|
|
4
|
+
"description": "在 DeepSeek Harness 内使用原版 Cortex 工作台:漏洞看板、内网作战、记忆星云图谱、资产库、认知快照与漏洞复测;内置 12 个 cortex_* Agent 工具,无需 MCP。"
|
|
5
|
+
}
|
|
6
|
+
}
|
package/package.json
CHANGED
|
@@ -1,106 +1,106 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@lievclouds/dsh-cortex",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "Cortex workbench for DeepSeek Harness: the original Cortex UI (vulnerabilities, assets, internal operations, Memory Nebula, snapshots, retest) as a native DSH panel, plus 12 native agent tools so DSH conversations use the local Cortex SQLite without MCP.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "index.js",
|
|
7
|
-
"license": "MIT",
|
|
8
|
-
"author": {
|
|
9
|
-
"name": "Revcloudi",
|
|
10
|
-
"url": "https://github.com/Revcloudi"
|
|
11
|
-
},
|
|
12
|
-
"homepage": "https://github.com/Revcloudi/Cortex/tree/main/dsh-cortex#readme",
|
|
13
|
-
"repository": {
|
|
14
|
-
"type": "git",
|
|
15
|
-
"url": "git+https://github.com/Revcloudi/Cortex.git",
|
|
16
|
-
"directory": "dsh-cortex"
|
|
17
|
-
},
|
|
18
|
-
"bugs": {
|
|
19
|
-
"url": "https://github.com/Revcloudi/Cortex/issues"
|
|
20
|
-
},
|
|
21
|
-
"publishConfig": {
|
|
22
|
-
"access": "public"
|
|
23
|
-
},
|
|
24
|
-
"keywords": [
|
|
25
|
-
"dsh-plugin",
|
|
26
|
-
"deepseek-harness",
|
|
27
|
-
"dsh",
|
|
28
|
-
"cordis",
|
|
29
|
-
"cortex",
|
|
30
|
-
"pentest",
|
|
31
|
-
"vulnerability-management",
|
|
32
|
-
"asset-management",
|
|
33
|
-
"sqlite",
|
|
34
|
-
"nebula"
|
|
35
|
-
],
|
|
36
|
-
"exports": {
|
|
37
|
-
".": "./index.js",
|
|
38
|
-
"./client": "./client.js",
|
|
39
|
-
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
40
|
-
"./locale/*.json": "./locale/*.json",
|
|
41
|
-
"./icon": "./icon.svg",
|
|
42
|
-
"./package.json": "./package.json"
|
|
43
|
-
},
|
|
44
|
-
"files": [
|
|
45
|
-
"index.js",
|
|
46
|
-
"client.js",
|
|
47
|
-
"src",
|
|
48
|
-
"cordis.patch.yml",
|
|
49
|
-
"locale",
|
|
50
|
-
"icon.svg",
|
|
51
|
-
"README.md",
|
|
52
|
-
"LICENSE"
|
|
53
|
-
],
|
|
54
|
-
"engines": {
|
|
55
|
-
"node": ">=22.19.0"
|
|
56
|
-
},
|
|
57
|
-
"scripts": {
|
|
58
|
-
"build": "node scripts/build-host-graph.mjs && node scripts/build-cortex-ui.mjs",
|
|
59
|
-
"build:graph": "node scripts/build-host-graph.mjs",
|
|
60
|
-
"build:client": "node scripts/build-cortex-ui.mjs",
|
|
61
|
-
"smoke": "node scripts/smoke-cortex-ui.mjs",
|
|
62
|
-
"test": "node --test",
|
|
63
|
-
"test:host": "node --test \"test/host/**/*.test.mjs\"",
|
|
64
|
-
"pack:check": "npm pack --dry-run",
|
|
65
|
-
"publish:npm": "npm publish --access public"
|
|
66
|
-
},
|
|
67
|
-
"dsh": {
|
|
68
|
-
"bundle": {
|
|
69
|
-
"patch": "./cordis.patch.yml"
|
|
70
|
-
},
|
|
71
|
-
"client": {
|
|
72
|
-
"platform": "web",
|
|
73
|
-
"immediately": true,
|
|
74
|
-
"inject": [
|
|
75
|
-
"@deepseek-ai/dsh-client-ui-sidebar",
|
|
76
|
-
"@deepseek-ai/dsh-client-locale"
|
|
77
|
-
]
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
"devDependencies": {
|
|
81
|
-
"@fontsource-variable/inter": "5.3.0",
|
|
82
|
-
"@fontsource-variable/jetbrains-mono": "5.3.0",
|
|
83
|
-
"@radix-ui/react-dialog": "1.3.1",
|
|
84
|
-
"@radix-ui/react-select": "^2.4.1",
|
|
85
|
-
"@radix-ui/react-tabs": "1.2.1",
|
|
86
|
-
"@radix-ui/react-tooltip": "1.4.1",
|
|
87
|
-
"autoprefixer": "10.6.2",
|
|
88
|
-
"class-variance-authority": "0.7.1",
|
|
89
|
-
"clsx": "2.1.1",
|
|
90
|
-
"esbuild": "0.28.2",
|
|
91
|
-
"jsdom": "^31.0.0",
|
|
92
|
-
"lucide-react": "1.65.0",
|
|
93
|
-
"postcss": "8.5.32",
|
|
94
|
-
"react": "18.3.1",
|
|
95
|
-
"react-dom": "18.3.1",
|
|
96
|
-
"react-force-graph-3d": "^1.29.2",
|
|
97
|
-
"react-markdown": "^10.1.0",
|
|
98
|
-
"react-syntax-highlighter": "^16.1.2",
|
|
99
|
-
"remark-gfm": "^4.0.1",
|
|
100
|
-
"sonner": "2.0.8",
|
|
101
|
-
"tailwind-merge": "3.7.0",
|
|
102
|
-
"tailwindcss": "3.4.19",
|
|
103
|
-
"three": "^0.187.0",
|
|
104
|
-
"zod": "4.6.7"
|
|
105
|
-
}
|
|
106
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@lievclouds/dsh-cortex",
|
|
3
|
+
"version": "0.3.4",
|
|
4
|
+
"description": "Cortex workbench for DeepSeek Harness: the original Cortex UI (vulnerabilities, assets, internal operations, Memory Nebula, snapshots, retest) as a native DSH panel, plus 12 native agent tools so DSH conversations use the local Cortex SQLite without MCP.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"author": {
|
|
9
|
+
"name": "Revcloudi",
|
|
10
|
+
"url": "https://github.com/Revcloudi"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/Revcloudi/Cortex/tree/main/dsh-cortex#readme",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/Revcloudi/Cortex.git",
|
|
16
|
+
"directory": "dsh-cortex"
|
|
17
|
+
},
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/Revcloudi/Cortex/issues"
|
|
20
|
+
},
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"dsh-plugin",
|
|
26
|
+
"deepseek-harness",
|
|
27
|
+
"dsh",
|
|
28
|
+
"cordis",
|
|
29
|
+
"cortex",
|
|
30
|
+
"pentest",
|
|
31
|
+
"vulnerability-management",
|
|
32
|
+
"asset-management",
|
|
33
|
+
"sqlite",
|
|
34
|
+
"nebula"
|
|
35
|
+
],
|
|
36
|
+
"exports": {
|
|
37
|
+
".": "./index.js",
|
|
38
|
+
"./client": "./client.js",
|
|
39
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
40
|
+
"./locale/*.json": "./locale/*.json",
|
|
41
|
+
"./icon": "./icon.svg",
|
|
42
|
+
"./package.json": "./package.json"
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"index.js",
|
|
46
|
+
"client.js",
|
|
47
|
+
"src",
|
|
48
|
+
"cordis.patch.yml",
|
|
49
|
+
"locale",
|
|
50
|
+
"icon.svg",
|
|
51
|
+
"README.md",
|
|
52
|
+
"LICENSE"
|
|
53
|
+
],
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=22.19.0"
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "node scripts/build-host-graph.mjs && node scripts/build-cortex-ui.mjs",
|
|
59
|
+
"build:graph": "node scripts/build-host-graph.mjs",
|
|
60
|
+
"build:client": "node scripts/build-cortex-ui.mjs",
|
|
61
|
+
"smoke": "node scripts/smoke-cortex-ui.mjs",
|
|
62
|
+
"test": "node --test",
|
|
63
|
+
"test:host": "node --test \"test/host/**/*.test.mjs\"",
|
|
64
|
+
"pack:check": "npm pack --dry-run",
|
|
65
|
+
"publish:npm": "npm publish --access public"
|
|
66
|
+
},
|
|
67
|
+
"dsh": {
|
|
68
|
+
"bundle": {
|
|
69
|
+
"patch": "./cordis.patch.yml"
|
|
70
|
+
},
|
|
71
|
+
"client": {
|
|
72
|
+
"platform": "web",
|
|
73
|
+
"immediately": true,
|
|
74
|
+
"inject": [
|
|
75
|
+
"@deepseek-ai/dsh-client-ui-sidebar",
|
|
76
|
+
"@deepseek-ai/dsh-client-locale"
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"devDependencies": {
|
|
81
|
+
"@fontsource-variable/inter": "5.3.0",
|
|
82
|
+
"@fontsource-variable/jetbrains-mono": "5.3.0",
|
|
83
|
+
"@radix-ui/react-dialog": "1.3.1",
|
|
84
|
+
"@radix-ui/react-select": "^2.4.1",
|
|
85
|
+
"@radix-ui/react-tabs": "1.2.1",
|
|
86
|
+
"@radix-ui/react-tooltip": "1.4.1",
|
|
87
|
+
"autoprefixer": "10.6.2",
|
|
88
|
+
"class-variance-authority": "0.7.1",
|
|
89
|
+
"clsx": "2.1.1",
|
|
90
|
+
"esbuild": "0.28.2",
|
|
91
|
+
"jsdom": "^31.0.0",
|
|
92
|
+
"lucide-react": "1.65.0",
|
|
93
|
+
"postcss": "8.5.32",
|
|
94
|
+
"react": "18.3.1",
|
|
95
|
+
"react-dom": "18.3.1",
|
|
96
|
+
"react-force-graph-3d": "^1.29.2",
|
|
97
|
+
"react-markdown": "^10.1.0",
|
|
98
|
+
"react-syntax-highlighter": "^16.1.2",
|
|
99
|
+
"remark-gfm": "^4.0.1",
|
|
100
|
+
"sonner": "2.0.8",
|
|
101
|
+
"tailwind-merge": "3.7.0",
|
|
102
|
+
"tailwindcss": "3.4.19",
|
|
103
|
+
"three": "^0.187.0",
|
|
104
|
+
"zod": "4.6.7"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -1,152 +1,141 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* dsh-cortex client bundle — Cortex original UI port for DeepSeek Harness.
|
|
3
|
-
*
|
|
4
|
-
* GENERATED FILE: built by scripts/build-cortex-ui.mjs from
|
|
5
|
-
* src/cortex-ui/**. Do not edit; run `node scripts/build-cortex-ui.mjs`.
|
|
6
|
-
*
|
|
7
|
-
* The Cortex renderer (React + Tailwind) is mounted into a Shadow DOM so its
|
|
8
|
-
* stylesheet cannot leak into the DSH shell. DSH provides React 18.3.1 through
|
|
9
|
-
* the platform module table; the bundled UI shares that instance.
|
|
10
|
-
*/
|
|
11
|
-
window.__ModuleLoader__.load({
|
|
12
|
-
id: __CORTEX_PACKAGE_NAME__,
|
|
13
|
-
factory: (require) => {
|
|
14
|
-
'use strict'
|
|
15
|
-
const React = require('react')
|
|
16
|
-
globalThis.__DSH_CORTEX_REACT__ = React
|
|
17
|
-
|
|
18
|
-
const UI_CSS = __CORTEX_UI_STYLES__
|
|
19
|
-
const FONT_FACES_CSS = __CORTEX_FONT_FACES__
|
|
20
|
-
const LOGO_DATA_URL = __CORTEX_LOGO_DATA_URL__
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
try {
|
|
143
|
-
window.setTimeout(runAcceptanceProbe, 1500)
|
|
144
|
-
} catch (error) {
|
|
145
|
-
/* probe optional */
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return { name: 'dsh-cortex', inject: ['slots'], apply }
|
|
151
|
-
},
|
|
152
|
-
})
|
|
1
|
+
/**
|
|
2
|
+
* dsh-cortex client bundle — Cortex original UI port for DeepSeek Harness.
|
|
3
|
+
*
|
|
4
|
+
* GENERATED FILE: built by scripts/build-cortex-ui.mjs from
|
|
5
|
+
* src/cortex-ui/**. Do not edit; run `node scripts/build-cortex-ui.mjs`.
|
|
6
|
+
*
|
|
7
|
+
* The Cortex renderer (React + Tailwind) is mounted into a Shadow DOM so its
|
|
8
|
+
* stylesheet cannot leak into the DSH shell. DSH provides React 18.3.1 through
|
|
9
|
+
* the platform module table; the bundled UI shares that instance.
|
|
10
|
+
*/
|
|
11
|
+
window.__ModuleLoader__.load({
|
|
12
|
+
id: __CORTEX_PACKAGE_NAME__,
|
|
13
|
+
factory: (require) => {
|
|
14
|
+
'use strict'
|
|
15
|
+
const React = require('react')
|
|
16
|
+
globalThis.__DSH_CORTEX_REACT__ = React
|
|
17
|
+
|
|
18
|
+
const UI_CSS = __CORTEX_UI_STYLES__
|
|
19
|
+
const FONT_FACES_CSS = __CORTEX_FONT_FACES__
|
|
20
|
+
const LOGO_DATA_URL = __CORTEX_LOGO_DATA_URL__
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* Chromium ignores @font-face rules that live inside a Shadow DOM
|
|
24
|
+
* stylesheet, so the inlined Inter / JetBrains Mono faces are injected into
|
|
25
|
+
* document.head once (fonts are document-level and then also apply inside
|
|
26
|
+
* the shadow tree). The element is removed when the plugin unloads.
|
|
27
|
+
*/
|
|
28
|
+
let fontStyleElement = null
|
|
29
|
+
function installFontFaces() {
|
|
30
|
+
if (fontStyleElement || !FONT_FACES_CSS) return
|
|
31
|
+
const style = document.createElement('style')
|
|
32
|
+
style.setAttribute('data-dsh-cortex-fonts', '')
|
|
33
|
+
style.textContent = FONT_FACES_CSS
|
|
34
|
+
document.head.appendChild(style)
|
|
35
|
+
fontStyleElement = style
|
|
36
|
+
}
|
|
37
|
+
function uninstallFontFaces() {
|
|
38
|
+
if (!fontStyleElement) return
|
|
39
|
+
try {
|
|
40
|
+
fontStyleElement.remove()
|
|
41
|
+
} catch (error) {
|
|
42
|
+
/* ignore */
|
|
43
|
+
}
|
|
44
|
+
fontStyleElement = null
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* ---- vendored Cortex renderer (esbuild IIFE, exposes __DSH_CORTEX_UI__) ---- */
|
|
48
|
+
__CORTEX_UI_BUNDLE__
|
|
49
|
+
/* -------------------------------------------------------------------------- */
|
|
50
|
+
|
|
51
|
+
const ui = globalThis.__DSH_CORTEX_UI__
|
|
52
|
+
if (!ui || typeof ui.mount !== 'function') {
|
|
53
|
+
throw new Error('[dsh-cortex] Cortex UI bundle did not initialize')
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Original Cortex product mark (white glyph on the dark rounded square). */
|
|
57
|
+
function PanelIcon(props) {
|
|
58
|
+
const size = props && typeof props.size === 'number' ? props.size : 16
|
|
59
|
+
const inner = Math.max(8, Math.round(size * 0.56))
|
|
60
|
+
return React.createElement(
|
|
61
|
+
'span',
|
|
62
|
+
{
|
|
63
|
+
'aria-hidden': true,
|
|
64
|
+
style: {
|
|
65
|
+
display: 'flex',
|
|
66
|
+
alignItems: 'center',
|
|
67
|
+
justifyContent: 'center',
|
|
68
|
+
width: size,
|
|
69
|
+
height: size,
|
|
70
|
+
borderRadius: Math.round(size * 0.26),
|
|
71
|
+
background: 'hsl(224 18% 10%)',
|
|
72
|
+
flex: 'none',
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
React.createElement('img', {
|
|
76
|
+
src: LOGO_DATA_URL,
|
|
77
|
+
width: inner,
|
|
78
|
+
height: inner,
|
|
79
|
+
alt: '',
|
|
80
|
+
draggable: false,
|
|
81
|
+
style: { display: 'block', objectFit: 'contain' },
|
|
82
|
+
}),
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Mounts the unmodified Cortex App inside this DSH panel. */
|
|
87
|
+
function CortexPanel() {
|
|
88
|
+
const hostRef = React.useRef(null)
|
|
89
|
+
React.useEffect(() => {
|
|
90
|
+
const host = hostRef.current
|
|
91
|
+
if (!host || typeof host.attachShadow !== 'function') return undefined
|
|
92
|
+
let handle = null
|
|
93
|
+
try {
|
|
94
|
+
handle = ui.mount(host, UI_CSS)
|
|
95
|
+
} catch (error) {
|
|
96
|
+
console.error('[dsh-cortex] Cortex UI mount failed', error)
|
|
97
|
+
}
|
|
98
|
+
return () => {
|
|
99
|
+
if (!handle) return
|
|
100
|
+
try {
|
|
101
|
+
handle.destroy()
|
|
102
|
+
} catch (error) {
|
|
103
|
+
console.error('[dsh-cortex] Cortex UI unmount failed', error)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}, [])
|
|
107
|
+
return React.createElement('div', {
|
|
108
|
+
ref: hostRef,
|
|
109
|
+
style: { height: '100%', width: '100%', minHeight: 0, overflow: 'hidden' },
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function apply(ctx) {
|
|
114
|
+
try {
|
|
115
|
+
ctx.effect(() => {
|
|
116
|
+
installFontFaces()
|
|
117
|
+
return () => uninstallFontFaces()
|
|
118
|
+
}, 'dsh-cortex: document font faces')
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.error('[dsh-cortex] font-face install failed', error)
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
ctx.slots.inject('sidebar.panellist', () =>
|
|
124
|
+
ctx.slots.register(
|
|
125
|
+
{ name: 'sidebar.panellist', id: 'cortex', order: 5, label: () => 'Cortex' },
|
|
126
|
+
PanelIcon,
|
|
127
|
+
),
|
|
128
|
+
)
|
|
129
|
+
} catch (error) {
|
|
130
|
+
console.error('[dsh-cortex] sidebar.panellist registration failed', error)
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
133
|
+
ctx.slots.inject('main', () => ctx.slots.register({ name: 'main', key: 'cortex' }, CortexPanel))
|
|
134
|
+
} catch (error) {
|
|
135
|
+
console.error('[dsh-cortex] main panel registration failed', error)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return { name: 'dsh-cortex', inject: ['slots'], apply }
|
|
140
|
+
},
|
|
141
|
+
})
|
|
@@ -627,16 +627,8 @@ export function NebulaPage({ dataVersion, onOpenDetail }: NebulaPageProps) {
|
|
|
627
627
|
}
|
|
628
628
|
}, [setFullscreenModeSafe])
|
|
629
629
|
|
|
630
|
-
//
|
|
631
|
-
|
|
632
|
-
if (fullscreenMode === 'off') return undefined
|
|
633
|
-
const onKeyDown = (event: KeyboardEvent): void => {
|
|
634
|
-
if (event.key === 'Escape') leaveFullscreen()
|
|
635
|
-
}
|
|
636
|
-
window.addEventListener('keydown', onKeyDown)
|
|
637
|
-
return () => window.removeEventListener('keydown', onKeyDown)
|
|
638
|
-
}, [fullscreenMode, leaveFullscreen])
|
|
639
|
-
|
|
630
|
+
// Declared before the Escape effect below: referencing it in that effect's
|
|
631
|
+
// dependency array from a later `const` is a temporal-dead-zone ReferenceError.
|
|
640
632
|
const leaveFullscreen = useCallback((): void => {
|
|
641
633
|
const doc = document as any
|
|
642
634
|
// Always attempt the native exit even when fullscreenElement is not exposed:
|
|
@@ -650,6 +642,16 @@ export function NebulaPage({ dataVersion, onOpenDetail }: NebulaPageProps) {
|
|
|
650
642
|
setFullscreenModeSafe('off')
|
|
651
643
|
}, [setFullscreenModeSafe])
|
|
652
644
|
|
|
645
|
+
// Escape leaves either mode (native also exits itself; calling exit is safe).
|
|
646
|
+
useEffect(() => {
|
|
647
|
+
if (fullscreenMode === 'off') return undefined
|
|
648
|
+
const onKeyDown = (event: KeyboardEvent): void => {
|
|
649
|
+
if (event.key === 'Escape') leaveFullscreen()
|
|
650
|
+
}
|
|
651
|
+
window.addEventListener('keydown', onKeyDown)
|
|
652
|
+
return () => window.removeEventListener('keydown', onKeyDown)
|
|
653
|
+
}, [fullscreenMode, leaveFullscreen])
|
|
654
|
+
|
|
653
655
|
const handleToggleFullscreen = useCallback(() => {
|
|
654
656
|
const element = sectionRef.current
|
|
655
657
|
if (element === null) return
|