dsh-plugin-container 0.0.0-stage → 0.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/LICENSE +21 -0
- package/README.md +341 -2
- package/cordis.patch.yml +3 -0
- package/docs/ai-chat.png +0 -0
- package/docs/ai-new-session.png +0 -0
- package/docs/apple-container.png +0 -0
- package/docs/attach.png +0 -0
- package/docs/docker-console.png +0 -0
- package/docs/docker-overview.png +0 -0
- package/docs/docker-volumes.png +0 -0
- package/docs/image-architecture.png +0 -0
- package/docs/package-install.png +0 -0
- package/docs/provider-switch.png +0 -0
- package/docs/run-container.png +0 -0
- package/index.js +138 -0
- package/lib/client.js +3499 -0
- package/package.json +62 -4
- package/src/client/api.js +94 -0
- package/src/client/attach.jsx +133 -0
- package/src/client/components.jsx +301 -0
- package/src/client/hooks.js +161 -0
- package/src/client/i18n.js +496 -0
- package/src/client/icons.jsx +219 -0
- package/src/client/index.jsx +76 -0
- package/src/client/page.jsx +755 -0
- package/src/client/run-container.jsx +187 -0
- package/src/client/runs.js +182 -0
- package/src/client/store.js +91 -0
- package/src/client/styles.js +363 -0
- package/src/client/tabs/compose.jsx +94 -0
- package/src/client/tabs/console.jsx +211 -0
- package/src/client/tabs/containers.jsx +143 -0
- package/src/client/tabs/images.jsx +127 -0
- package/src/client/tabs/networks.jsx +91 -0
- package/src/client/tabs/overview.jsx +266 -0
- package/src/client/tabs/volumes.jsx +76 -0
- package/src/host/apple-cli.js +307 -0
- package/src/host/apple.js +471 -0
- package/src/host/attach.js +243 -0
- package/src/host/commands.js +235 -0
- package/src/host/docker-cli.js +405 -0
- package/src/host/jobs.js +245 -0
- package/src/host/parsers.js +484 -0
- package/src/host/runtime.js +285 -0
- package/src/host/service.js +832 -0
- package/src/host/tools.js +198 -0
- package/src/host/util.js +97 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/** Self-contained SVG icons; no dependency on a primitives package. */
|
|
2
|
+
|
|
3
|
+
function Svg({ size = 18, className, children, viewBox = '0 0 24 24', fill = 'none' }) {
|
|
4
|
+
return (
|
|
5
|
+
<svg
|
|
6
|
+
className={className}
|
|
7
|
+
width={size}
|
|
8
|
+
height={size}
|
|
9
|
+
viewBox={viewBox}
|
|
10
|
+
fill={fill}
|
|
11
|
+
stroke={fill === 'none' ? 'currentColor' : 'none'}
|
|
12
|
+
strokeWidth="1.6"
|
|
13
|
+
strokeLinecap="round"
|
|
14
|
+
strokeLinejoin="round"
|
|
15
|
+
aria-hidden="true"
|
|
16
|
+
focusable="false"
|
|
17
|
+
>
|
|
18
|
+
{children}
|
|
19
|
+
</svg>
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function DockerMark({ size = 24, className }) {
|
|
24
|
+
return (
|
|
25
|
+
<svg className={className} width={size} height={size} viewBox="0 0 24 24" fill="none" aria-hidden="true" focusable="false">
|
|
26
|
+
<path
|
|
27
|
+
d="M7.2 10.2h2.1v2.1H7.2zM10.1 10.2h2.1v2.1h-2.1zM13 10.2h2.1v2.1H13zM10.1 7.3h2.1v2.1h-2.1zM13 7.3h2.1v2.1H13z"
|
|
28
|
+
fill="currentColor"
|
|
29
|
+
/>
|
|
30
|
+
<path
|
|
31
|
+
d="M6 13.1h11.1c1 0 1.8-.3 2.4-.9.4.9.5 2.1-.2 3.1-.9 1.4-2.6 2.1-4.9 2.1H9.1c-2.8 0-4.9-1.5-5.7-3.9-.1-.4.1-.7.5-.7H6v.3Z"
|
|
32
|
+
fill="currentColor"
|
|
33
|
+
opacity=".9"
|
|
34
|
+
/>
|
|
35
|
+
<path d="M4.2 17.6c1.6 1.5 3.6 2.2 6.2 2.2h4.5c2.1 0 3.6-.6 4.6-1.8" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" />
|
|
36
|
+
</svg>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const IconPlay = (props) => (
|
|
41
|
+
<Svg {...props}>
|
|
42
|
+
<path d="M8 5.5v13l10-6.5L8 5.5Z" />
|
|
43
|
+
</Svg>
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
export const IconStop = (props) => (
|
|
47
|
+
<Svg {...props}>
|
|
48
|
+
<rect x="6.5" y="6.5" width="11" height="11" rx="1.5" />
|
|
49
|
+
</Svg>
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
export const IconRestart = (props) => (
|
|
53
|
+
<Svg {...props}>
|
|
54
|
+
<path d="M4.8 10.2a7.2 7.2 0 0 1 12.3-3.7l2 2" />
|
|
55
|
+
<path d="M19.4 4.2v4.6h-4.6" />
|
|
56
|
+
<path d="M19.2 13.8a7.2 7.2 0 0 1-12.3 3.7l-2-2" />
|
|
57
|
+
<path d="M4.6 19.8v-4.6h4.6" />
|
|
58
|
+
</Svg>
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
export const IconTrash = (props) => (
|
|
62
|
+
<Svg {...props}>
|
|
63
|
+
<path d="M4.5 7.2h15" />
|
|
64
|
+
<path d="M9 7.2V5.4h6v1.8" />
|
|
65
|
+
<path d="M6.5 7.2l.8 12h9.4l.8-12" />
|
|
66
|
+
<path d="M10.2 10.8v5.2M13.8 10.8v5.2" />
|
|
67
|
+
</Svg>
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
export const IconRefresh = (props) => (
|
|
71
|
+
<Svg {...props}>
|
|
72
|
+
<path d="M19.2 8.2A8 8 0 1 0 20 14" />
|
|
73
|
+
<path d="M19.6 3.8v4.8h-4.8" />
|
|
74
|
+
</Svg>
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
export const IconSearch = (props) => (
|
|
78
|
+
<Svg {...props}>
|
|
79
|
+
<circle cx="10.8" cy="10.8" r="5.8" />
|
|
80
|
+
<path d="M15.2 15.2 20 20" />
|
|
81
|
+
</Svg>
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
export const IconTerminal = (props) => (
|
|
85
|
+
<Svg {...props}>
|
|
86
|
+
<rect x="3.5" y="4.5" width="17" height="15" rx="2" />
|
|
87
|
+
<path d="m7.2 9.2 3 2.8-3 2.8M12.5 15h4" />
|
|
88
|
+
</Svg>
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
export const IconBox = (props) => (
|
|
92
|
+
<Svg {...props}>
|
|
93
|
+
<path d="m12 3.8 7.4 4.1v8.2L12 20.2l-7.4-4.1V7.9L12 3.8Z" />
|
|
94
|
+
<path d="m4.8 8 7.2 4 7.2-4M12 12v8" />
|
|
95
|
+
</Svg>
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
export const IconImage = (props) => (
|
|
99
|
+
<Svg {...props}>
|
|
100
|
+
<rect x="3.8" y="5" width="16.4" height="14" rx="2" />
|
|
101
|
+
<circle cx="9" cy="10" r="1.5" />
|
|
102
|
+
<path d="m4.8 16.4 4.4-4.1 3.2 2.9 2.8-2.4 3.8 3.6" />
|
|
103
|
+
</Svg>
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
export const IconVolume = (props) => (
|
|
107
|
+
<Svg {...props}>
|
|
108
|
+
<ellipse cx="12" cy="7" rx="6.5" ry="2.8" />
|
|
109
|
+
<path d="M5.5 7v9.6c0 1.6 2.9 2.9 6.5 2.9s6.5-1.3 6.5-2.9V7" />
|
|
110
|
+
<path d="M5.5 12c0 1.6 2.9 2.9 6.5 2.9s6.5-1.3 6.5-2.9" />
|
|
111
|
+
</Svg>
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
export const IconNetwork = (props) => (
|
|
115
|
+
<Svg {...props}>
|
|
116
|
+
<circle cx="12" cy="5.5" r="2.3" />
|
|
117
|
+
<circle cx="6" cy="17.5" r="2.3" />
|
|
118
|
+
<circle cx="18" cy="17.5" r="2.3" />
|
|
119
|
+
<path d="M10.7 7.6 7.1 15.4M13.3 7.6l3.6 7.8M8.3 17.5h7.4" />
|
|
120
|
+
</Svg>
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
export const IconCompose = (props) => (
|
|
124
|
+
<Svg {...props}>
|
|
125
|
+
<path d="M5 4.8h11.5L20 8.3v10.9H5V4.8Z" />
|
|
126
|
+
<path d="M16 4.8v4h4M8.5 12h7M8.5 15.4h5" />
|
|
127
|
+
</Svg>
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
export const IconChevronDown = (props) => (
|
|
131
|
+
<Svg {...props}>
|
|
132
|
+
<path d="m6.5 9.2 5.5 5.4 5.5-5.4" />
|
|
133
|
+
</Svg>
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
export const IconChevronRight = (props) => (
|
|
137
|
+
<Svg {...props}>
|
|
138
|
+
<path d="m9.2 6.5 5.4 5.5-5.4 5.5" />
|
|
139
|
+
</Svg>
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
export const IconCopy = (props) => (
|
|
143
|
+
<Svg {...props}>
|
|
144
|
+
<rect x="8.5" y="8.5" width="11" height="11" rx="1.8" />
|
|
145
|
+
<path d="M15.5 8.5V6.2a1.8 1.8 0 0 0-1.8-1.8H6.2a1.8 1.8 0 0 0-1.8 1.8v7.5c0 1 .8 1.8 1.8 1.8h2.3" />
|
|
146
|
+
</Svg>
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
export const IconFolder = (props) => (
|
|
150
|
+
<Svg {...props}>
|
|
151
|
+
<path d="M4 7.2a1.7 1.7 0 0 1 1.7-1.7h3.1l1.8 2h7.7A1.7 1.7 0 0 1 20 9.2v8.6a1.7 1.7 0 0 1-1.7 1.7H5.7A1.7 1.7 0 0 1 4 17.8V7.2Z" />
|
|
152
|
+
</Svg>
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
export const IconClock = (props) => (
|
|
156
|
+
<Svg {...props}>
|
|
157
|
+
<circle cx="12" cy="12" r="8" />
|
|
158
|
+
<path d="M12 7.5V12l3 1.8" />
|
|
159
|
+
</Svg>
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
export const IconCheck = (props) => (
|
|
163
|
+
<Svg {...props}>
|
|
164
|
+
<path d="m5.5 12.5 4.1 4.1 8.9-9.2" />
|
|
165
|
+
</Svg>
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
export const IconAlert = (props) => (
|
|
169
|
+
<Svg {...props}>
|
|
170
|
+
<path d="M12 4.2 21 19.4H3L12 4.2Z" />
|
|
171
|
+
<path d="M12 9.2v4.2M12 16.8v.2" />
|
|
172
|
+
</Svg>
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
export const IconInfo = (props) => (
|
|
176
|
+
<Svg {...props}>
|
|
177
|
+
<circle cx="12" cy="12" r="8.2" />
|
|
178
|
+
<path d="M12 11v5M12 8v.2" />
|
|
179
|
+
</Svg>
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
export const IconX = (props) => (
|
|
183
|
+
<Svg {...props}>
|
|
184
|
+
<path d="m6.5 6.5 11 11M17.5 6.5l-11 11" />
|
|
185
|
+
</Svg>
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
export const IconDownload = (props) => (
|
|
189
|
+
<Svg {...props}>
|
|
190
|
+
<path d="M12 4.5v10.2M7.8 10.6 12 14.8l4.2-4.2M5 18.8h14" />
|
|
191
|
+
</Svg>
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
export const IconExternal = (props) => (
|
|
195
|
+
<Svg {...props}>
|
|
196
|
+
<path d="M13.5 5H19v5.5M19 5l-7.4 7.4" />
|
|
197
|
+
<path d="M18 13.5v4.2a1.8 1.8 0 0 1-1.8 1.8H5.8A1.8 1.8 0 0 1 4 17.7V7.2a1.8 1.8 0 0 1 1.8-1.8h4.2" />
|
|
198
|
+
</Svg>
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
export const IconSparkles = (props) => (
|
|
202
|
+
<Svg {...props}>
|
|
203
|
+
<path d="M12 4.5l1.2 3.3L16.5 9l-3.3 1.2L12 13.5l-1.2-3.3L7.5 9l3.3-1.2L12 4.5Z" />
|
|
204
|
+
<path d="M18 14l.7 1.8 1.8.7-1.8.7L18 19l-.7-1.8-1.8-.7 1.8-.7L18 14Z" />
|
|
205
|
+
<path d="M6 15l.6 1.4L8 17l-1.4.6L6 19l-.6-1.4L4 17l1.4-.6L6 15Z" />
|
|
206
|
+
</Svg>
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
export const IconAttach = (props) => (
|
|
210
|
+
<Svg {...props}>
|
|
211
|
+
<path d="M9.5 14.5 14.5 9.5" />
|
|
212
|
+
<path d="M11 7.5 12.6 5.9a3.2 3.2 0 0 1 4.5 4.5L15.4 12" />
|
|
213
|
+
<path d="M13 16.5 11.4 18.1a3.2 3.2 0 0 1-4.5-4.5L8.6 12" />
|
|
214
|
+
</Svg>
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
export const IconSpinner = ({ size = 16, className }) => (
|
|
218
|
+
<span className={className === undefined ? 'dsh-docker-spinner' : `dsh-docker-spinner ${className}`} style={{ width: size, height: size }} aria-hidden="true" />
|
|
219
|
+
)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/** Client entry: register locale, main panel, and the left-sidebar Docker entry. */
|
|
2
|
+
import { createApi } from './api.js'
|
|
3
|
+
import { DockerMark } from './icons.jsx'
|
|
4
|
+
import { NS, en, zh } from './i18n.js'
|
|
5
|
+
import DockerPage from './page.jsx'
|
|
6
|
+
import { RunController } from './runs.js'
|
|
7
|
+
import { createDockerStore } from './store.js'
|
|
8
|
+
import { injectStyles } from './styles.js'
|
|
9
|
+
|
|
10
|
+
injectStyles()
|
|
11
|
+
|
|
12
|
+
export const inject = ['slots', 'layout', 'locale', 'connection', 'sessions']
|
|
13
|
+
|
|
14
|
+
/** @param {import('@deepseek-ai/cordis').Context} ctx */
|
|
15
|
+
export function apply(ctx) {
|
|
16
|
+
ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'docker: dictionaries')
|
|
17
|
+
const t = ctx.locale.bind(NS)
|
|
18
|
+
const api = createApi(ctx.connection)
|
|
19
|
+
const runs = new RunController(api)
|
|
20
|
+
const startDiagnosis = async (text) => {
|
|
21
|
+
const list = ctx.sessions.list.getSnapshot()
|
|
22
|
+
const current = Object.values(list.byId ?? {}).find((session) => (session.retainedBy?.mainView ?? 0) > 0)
|
|
23
|
+
if (current === undefined || typeof current.cwd !== 'string' || current.cwd === '') throw new Error('当前没有可用工作区,无法创建诊断会话')
|
|
24
|
+
const request = { cwd: current.cwd }
|
|
25
|
+
const preset = current.projectionValues?.agentPreset
|
|
26
|
+
if (typeof preset === 'string' && preset !== '') request.agentPreset = preset
|
|
27
|
+
const sessionId = await ctx.sessions.create(request)
|
|
28
|
+
// A Session binding is materialized when the main view retains it.
|
|
29
|
+
ctx.get('uiWorkspace')?.openSession?.(sessionId)
|
|
30
|
+
let binding = ctx.sessions.binding(sessionId)
|
|
31
|
+
for (let attempt = 0; attempt < 40 && binding === undefined; attempt += 1) {
|
|
32
|
+
await new Promise((resolve) => setTimeout(resolve, 50))
|
|
33
|
+
binding = ctx.sessions.binding(sessionId)
|
|
34
|
+
}
|
|
35
|
+
if (binding === undefined) throw new Error('新诊断会话尚未就绪')
|
|
36
|
+
const result = await binding.session.prompt([{ type: 'text', text }], 'queue')
|
|
37
|
+
if (!result.ok) throw new Error(`发送到诊断会话失败: ${result.error?.message ?? 'unknown'}`)
|
|
38
|
+
return sessionId
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const handle = createDockerStore()
|
|
42
|
+
const instance = handle.create()
|
|
43
|
+
const store = { ...handle, create: () => instance }
|
|
44
|
+
|
|
45
|
+
ctx.effect(() => () => runs.dispose(), 'docker: runs')
|
|
46
|
+
|
|
47
|
+
ctx.slots.inject('main', function* registerMain() {
|
|
48
|
+
yield ctx.slots.register(
|
|
49
|
+
{
|
|
50
|
+
name: 'main',
|
|
51
|
+
key: 'docker',
|
|
52
|
+
locale: NS,
|
|
53
|
+
store,
|
|
54
|
+
inject: () => ({ api, runs, startDiagnosis }),
|
|
55
|
+
},
|
|
56
|
+
DockerPage,
|
|
57
|
+
)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
ctx.slots.inject('sidebar.panellist', () =>
|
|
61
|
+
ctx.slots.register(
|
|
62
|
+
{
|
|
63
|
+
name: 'sidebar.panellist',
|
|
64
|
+
id: 'docker',
|
|
65
|
+
order: 20,
|
|
66
|
+
locale: NS,
|
|
67
|
+
label: () => t('panel'),
|
|
68
|
+
},
|
|
69
|
+
DockerIcon,
|
|
70
|
+
),
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function DockerIcon({ size = 18 }) {
|
|
75
|
+
return <DockerMark size={size} />
|
|
76
|
+
}
|