@exagone313/dsh-podman 0.2.0-rc.4 → 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/README.md +12 -0
- package/README.zh.md +14 -2
- package/cordis.patch.yml +58 -0
- package/dist/approval-reasons.d.ts +3 -4
- package/dist/approval-reasons.js +40 -49
- package/dist/approval-reasons.test.js +43 -15
- package/dist/approval.js +27 -10
- package/dist/approval.test.js +165 -34
- package/dist/card-route.d.ts +3 -2
- package/dist/card-route.js +103 -35
- package/dist/card-route.test.js +60 -43
- package/dist/card-test-support.js +39 -66
- package/dist/client/ContainerCard.d.ts +1 -1
- package/dist/client/ContainerCard.js +76 -70
- package/dist/client/card-protocol.d.ts +3 -3
- package/dist/client/container-card-caches.js +11 -6
- package/dist/client/container-card-controller.d.ts +13 -18
- package/dist/client/container-card-controller.js +86 -40
- package/dist/client/container-card-create-modal.d.ts +2 -2
- package/dist/client/container-card-create-modal.js +13 -5
- package/dist/client/container-card-default-env.d.ts +10 -0
- package/dist/client/container-card-default-env.js +69 -0
- package/dist/client/container-card-directory.d.ts +2 -2
- package/dist/client/container-card-directory.js +12 -4
- package/dist/client/container-card-editors.d.ts +3 -3
- package/dist/client/container-card-editors.js +104 -32
- package/dist/client/container-card-images.d.ts +4 -4
- package/dist/client/container-card-images.js +19 -6
- package/dist/client/container-card-paths.d.ts +3 -3
- package/dist/client/container-card-paths.js +18 -11
- package/dist/client/container-card-row.d.ts +10 -6
- package/dist/client/container-card-row.js +82 -13
- package/dist/client/container-card-secrets.d.ts +3 -3
- package/dist/client/container-card-secrets.js +8 -6
- package/dist/client/container-card-shared.d.ts +4 -17
- package/dist/client/container-card-shared.js +9 -25
- package/dist/client/container-card-styles.d.ts +2 -8
- package/dist/client/container-card-styles.js +14 -52
- package/dist/client/container-card-volumes.d.ts +2 -2
- package/dist/client/container-card-volumes.js +9 -5
- package/dist/client/container-card-workspace.d.ts +8 -6
- package/dist/client/container-card-workspace.js +9 -3
- package/dist/client/directory-picker.js +2 -1
- package/dist/client/index.js +13109 -2117
- package/dist/client/locales.d.ts +6 -1
- package/dist/client/locales.js +88 -38
- package/dist/client/podman-terminal-guide.d.ts +11 -0
- package/dist/client/podman-terminal-guide.js +208 -0
- package/dist/client/podman-terminal-title.d.ts +7 -0
- package/dist/client/podman-terminal-title.js +30 -0
- package/dist/client/podman-terminal.d.ts +26 -0
- package/dist/client/podman-terminal.js +412 -0
- package/dist/client/read-only-approval.d.ts +2 -2
- package/dist/client/read-only-approval.js +13 -3
- package/dist/client/slot-contract.d.ts +0 -11
- package/dist/client/terminal-preference.d.ts +26 -0
- package/dist/client/terminal-preference.js +67 -0
- package/dist/client/terminal-protocol.d.ts +85 -0
- package/dist/client/terminal-protocol.js +14 -0
- package/dist/client/terminal-tab.d.ts +60 -0
- package/dist/client/terminal-tab.js +35 -0
- package/dist/client/terminal-targets.d.ts +33 -0
- package/dist/client/terminal-targets.js +65 -0
- package/dist/client/terminal-titles.d.ts +23 -0
- package/dist/client/terminal-titles.js +52 -0
- package/dist/client/terminal-transport.d.ts +63 -0
- package/dist/client/terminal-transport.js +207 -0
- package/dist/client/tool-views.js +215 -49
- package/dist/container-env.d.ts +11 -0
- package/dist/container-env.js +96 -0
- package/dist/container-env.test.d.ts +1 -0
- package/dist/container-env.test.js +93 -0
- package/dist/containers.test.js +196 -18
- package/dist/daemons.test.js +18 -4
- package/dist/dsh-version.js +2 -1
- package/dist/env-rows.d.ts +14 -0
- package/dist/env-rows.js +52 -0
- package/dist/env-rows.test.d.ts +1 -0
- package/dist/env-rows.test.js +43 -0
- package/dist/fs-provider.d.ts +1 -0
- package/dist/fs-provider.js +26 -12
- package/dist/fs-provider.test.js +51 -10
- package/dist/generated/version.d.ts +2 -2
- package/dist/generated/version.js +2 -2
- package/dist/grpc/proto/dshctl/v1/control.proto +8 -1
- package/dist/grpc/proto/dshguest/v1/guest.proto +5 -0
- package/dist/grpc/runtime-client.d.ts +3 -1
- package/dist/grpc/runtime-client.js +90 -17
- package/dist/guest-rpc.d.ts +15 -19
- package/dist/guest-rpc.js +289 -70
- package/dist/guest-rpc.test.d.ts +1 -0
- package/dist/guest-rpc.test.js +241 -0
- package/dist/guest-terminal.d.ts +30 -0
- package/dist/guest-terminal.js +196 -0
- package/dist/images.test.js +10 -3
- package/dist/index.d.ts +11 -16
- package/dist/index.js +42 -36
- package/dist/locales.test.d.ts +1 -0
- package/dist/locales.test.js +34 -0
- package/dist/misc.test.js +38 -10
- package/dist/mount-enums.js +2 -1
- package/dist/mount-input.d.ts +2 -0
- package/dist/mount-input.js +38 -22
- package/dist/mounts.test.js +81 -11
- package/dist/naming.test.d.ts +1 -0
- package/dist/naming.test.js +28 -0
- package/dist/output-reader.js +36 -4
- package/dist/package-deps.test.d.ts +1 -0
- package/dist/package-deps.test.js +49 -0
- package/dist/paths.test.js +4 -2
- package/dist/plugin-meta.test.d.ts +1 -0
- package/dist/plugin-meta.test.js +29 -0
- package/dist/project-path.js +33 -7
- package/dist/project-path.test.js +14 -0
- package/dist/prompts.d.ts +0 -4
- package/dist/prompts.js +15 -84
- package/dist/read-only-shell.js +3 -1
- package/dist/read-only-shell.test.js +80 -25
- package/dist/runtime-client.test.d.ts +1 -0
- package/dist/runtime-client.test.js +53 -0
- package/dist/secrets.test.js +21 -6
- package/dist/settings-commands.test.js +61 -14
- package/dist/settings-create.test.js +32 -10
- package/dist/settings-default-env.test.d.ts +1 -0
- package/dist/settings-default-env.test.js +175 -0
- package/dist/settings-mounts.test.js +46 -7
- package/dist/settings-schema.d.ts +6 -11
- package/dist/settings-schema.js +4 -8
- package/dist/settings-schema.test.d.ts +1 -0
- package/dist/settings-schema.test.js +35 -0
- package/dist/settings-workspaces.test.js +36 -63
- package/dist/spill-store.d.ts +1 -0
- package/dist/spill-store.js +17 -4
- package/dist/spill-store.test.js +31 -8
- package/dist/subprocess.d.ts +4 -0
- package/dist/subprocess.js +148 -162
- package/dist/subprocess.test.js +118 -8
- package/dist/terminal-preference.test.d.ts +1 -0
- package/dist/terminal-preference.test.js +62 -0
- package/dist/terminal-route.d.ts +10 -0
- package/dist/terminal-route.js +270 -0
- package/dist/terminal-route.test.d.ts +1 -0
- package/dist/terminal-route.test.js +265 -0
- package/dist/terminal-sessions.d.ts +69 -0
- package/dist/terminal-sessions.js +252 -0
- package/dist/terminal-shells.d.ts +22 -0
- package/dist/terminal-shells.js +99 -0
- package/dist/terminal-tab.test.d.ts +1 -0
- package/dist/terminal-tab.test.js +58 -0
- package/dist/terminal-targets.test.d.ts +1 -0
- package/dist/terminal-targets.test.js +43 -0
- package/dist/terminal-titles.test.d.ts +1 -0
- package/dist/terminal-titles.test.js +36 -0
- package/dist/test-support.d.ts +35 -5
- package/dist/test-support.js +91 -29
- package/dist/tool-defs.js +19 -4
- package/dist/tool-handlers.js +80 -28
- package/dist/tool-params.js +19 -5
- package/dist/volumes.test.js +1 -1
- package/dist/workspace-binding.d.ts +18 -9
- package/dist/workspace-binding.js +244 -77
- package/dist/workspace-binding.test.js +189 -25
- package/docs/architecture.md +62 -21
- package/docs/architecture.zh.md +57 -13
- package/docs/configuration.md +61 -20
- package/docs/configuration.zh.md +53 -19
- package/docs/development-prompt.md +72 -0
- package/docs/development-prompt.zh.md +69 -0
- package/docs/development.md +141 -21
- package/docs/development.zh.md +125 -17
- package/docs/install-dsh-and-dsh-podman.md +21 -8
- package/docs/install-dsh-and-dsh-podman.zh.md +18 -8
- package/docs/uninstall.md +83 -0
- package/docs/uninstall.zh.md +79 -0
- package/docs/update.md +120 -0
- package/docs/update.zh.md +114 -0
- package/docs/usage.md +108 -61
- package/docs/usage.zh.md +76 -38
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +58 -25
- package/quadlet/dsh-podman-orchestrator.container +46 -0
- package/quadlet/dsh.container +35 -0
- package/LICENSE.pkg +0 -17103
- package/dist/preferences.d.ts +0 -6
- package/dist/preferences.js +0 -27
package/dist/client/locales.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
export declare const NS = "podman";
|
|
2
|
-
export type ContainerPluginKey = "cardTitle" | "cardDescription" | "versionMismatchMajor" | "versionMismatchMinor" | "versionsTitle" | "orchestrator" | "versionUnknown" | "dsh" | "copyVersions" | "copied" | "copyFailed" | "reload" | "
|
|
2
|
+
export type ContainerPluginKey = "cardTitle" | "cardDescription" | "versionMismatchMajor" | "versionMismatchMinor" | "versionsTitle" | "orchestrator" | "versionUnknown" | "dsh" | "copyVersions" | "copied" | "copyFailed" | "reload" | "notice" | "defaultImage" | "defaultImageHint" | "defaultEnvironment" | "defaultEnvironmentHint" | "gitIdentity" | "gitName" | "gitEmail" | "gitIdentityHint" | "applyDefaults" | "confirmApplyDefaults" | "clear" | "save" | "discard" | "workspacesTitle" | "noContainers" | "createContainer" | "containerName" | "image" | "status" | "created" | "projects" | "remove" | "removePod" | "confirmRemovePod" | "recreate" | "recreateWithImage" | "imagesTitle" | "imageId" | "imageTag" | "builtAt" | "packages" | "volumesTitle" | "createVolume" | "removeVolume" | "volumeName" | "secretsTitle" | "createSecret" | "secretName" | "secretCharset" | "selectImage" | "setSecret" | "removeSecret" | "removeImage" | "rebuildImage" | "rebuildAllImages" | "buildImage" | "build" | "buildImageTitle" | "pullImage" | "setDefaultImage" | "setDefaultImageTitle" | "baseImagesTitle" | "customImagesTitle" | "primitive" | "packageManager" | "parent" | "cancel" | "removeTag" | "env" | "secretEnv" | "envTitle" | "envKey" | "envValue" | "addEnv" | "removeEnv" | "secretLength" | "containerSecretsTitle" | "attachSecret" | "secretEnvName" | "detachSecret" | "none" | "unavailable" | "busy" | "confirmTitle" | "confirm" | "confirmRemoveContainer" | "confirmRecreate" | "confirmRemoveImage" | "confirmRebuildImage" | "confirmRebuildAllImages" | "confirmRemoveVolume" | "confirmSetSecret" | "confirmRemoveSecret" | "confirmDetachSecret" | "mountsTitle" | "addMount" | "mountKind" | "mountProject" | "mountProjectPath" | "browse" | "browseTitle" | "browseSelect" | "browseLoading" | "browseError" | "browseUnavailable" | "browseHidden" | "browseTruncated" | "browseOutsideRoot" | "mountDestination" | "pathsTitle" | "noPaths" | "editPaths" | "addPath" | "add" | "moveUp" | "moveDown" | "apply" | "dragToReorder" | "remountWaiting" | "remountApprove" | "remountReject" | "mountVolume" | "mountSecret" | "mountTmpfs" | "mountAt" | "mountMode" | "readOnly" | "readWrite" | "mountReadOnlySuffix" | "mountReadWriteSuffix" | "remountReadOnly" | "remountReadWrite" | "confirmRemountReadOnly" | "confirmRemountReadWrite" | "confirmRemoveMount" | "cachesTitle" | "noCaches" | "cacheUsage" | "cacheKeepLatest" | "confirmCacheKeepLatest" | "cacheRemoveAll" | "confirmCacheRemoveAll" | "addContainer" | "invalidContainerName" | "containerNameTaken" | "invalidName" | "invalidImageId" | "terminalSignal" | "terminalExitCode" | "terminalNoExitCode" | "terminalRunning" | "terminalFailed" | "terminalDone" | "terminalNoOutput" | "terminalCollapseAria" | "terminalExpandAria" | "terminalExpandRest" | "toolTitle_container_bash" | "toolTitle_container_exec" | "toolTitle_container_read" | "toolTitle_container_write" | "toolTitle_container_edit" | "toolTitle_container_glob" | "toolTitle_container_grep" | "toolTitle_container_list" | "toolTitle_container_start" | "toolTitle_container_recreate" | "toolTitle_container_remove" | "toolTitle_container_mount_list" | "toolTitle_container_mount_add" | "toolTitle_container_mount_remove" | "toolTitle_container_mount_update" | "toolTitle_container_path_set" | "toolTitle_container_path_add" | "toolTitle_container_path_remove" | "toolTitle_container_secret_add" | "toolTitle_container_secret_remove" | "toolTitle_image_list" | "toolTitle_image_get" | "toolTitle_image_build" | "toolTitle_image_rebuild" | "toolTitle_image_rebuild_all" | "toolTitle_image_remove" | "toolTitle_volume_list" | "toolTitle_volume_create" | "toolTitle_volume_remove" | "toolTitle_secret_list" | "toolTitle_secret_create" | "toolTitle_secret_remove" | "toolTitle_daemon_start" | "toolTitle_daemon_list" | "toolTitle_daemon_logs" | "toolTitle_daemon_restart" | "toolTitle_daemon_stop" | "terminalTabTitle" | "terminalGuideTitle" | "terminalGuideDescription" | "terminalShortcut" | "terminalShortcutNoSession" | "terminalContainer" | "terminalShell" | "terminalDefaultContainer" | "terminalStart" | "terminalConnect" | "terminalReconnect" | "terminalStatusConnecting" | "terminalStatusRunning" | "terminalStatusExited" | "terminalStatusDetached" | "terminalNoShells" | "terminalShellsFailed" | "terminalLoading";
|
|
3
|
+
/**
|
|
4
|
+
* Translate one key, interpolating `{name}` placeholders when given. Components
|
|
5
|
+
* that build dialog copy declare this so they can name their subject.
|
|
6
|
+
*/
|
|
7
|
+
export type Translate = (key: ContainerPluginKey, params?: Record<string, string>) => string;
|
|
3
8
|
export declare const en: Record<ContainerPluginKey, string>;
|
|
4
9
|
export declare const zh: Record<ContainerPluginKey, string>;
|
|
5
10
|
declare module "@deepseek-ai/dsh-client-ui-slots" {
|
package/dist/client/locales.js
CHANGED
|
@@ -15,33 +15,35 @@ export const en = {
|
|
|
15
15
|
copied: "Copied",
|
|
16
16
|
copyFailed: "Copy failed",
|
|
17
17
|
reload: "Reload this view",
|
|
18
|
-
reloading: "Reloading…",
|
|
19
18
|
notice: "Notice",
|
|
20
|
-
configTitle: "Configuration",
|
|
21
19
|
defaultImage: "Default image",
|
|
22
|
-
socketsRoot: "Sockets root",
|
|
23
|
-
projectsRoot: "Projects root",
|
|
24
20
|
defaultImageHint: "Image used when a workspace has no image of its own.",
|
|
21
|
+
defaultEnvironment: "Default environment",
|
|
22
|
+
defaultEnvironmentHint: "Seeded into a container when it is created. Edit a container's own environment and recreate it to change or remove a value for that container.",
|
|
23
|
+
gitIdentity: "Git identity",
|
|
24
|
+
gitName: "Name",
|
|
25
|
+
gitEmail: "Email",
|
|
26
|
+
gitIdentityHint: "Fills GIT_AUTHOR_NAME/EMAIL and GIT_COMMITTER_NAME/EMAIL for new containers, so commits made inside them are attributed to you.",
|
|
27
|
+
applyDefaults: "Apply default environment variables",
|
|
28
|
+
confirmApplyDefaults: "Add the default environment variables to the containers that are missing them? Matching running containers are recreated (their processes and daemons stop); existing values are kept and stopped containers are left alone.",
|
|
29
|
+
clear: "Clear",
|
|
25
30
|
save: "Save",
|
|
26
31
|
discard: "Discard",
|
|
27
32
|
workspacesTitle: "Workspaces",
|
|
28
33
|
noContainers: "This workspace has no containers yet.",
|
|
29
34
|
createContainer: "Create container",
|
|
30
|
-
containersTitle: "Containers",
|
|
31
35
|
containerName: "Container",
|
|
32
|
-
workspace: "Workspace",
|
|
33
36
|
image: "Image",
|
|
34
37
|
status: "Status",
|
|
35
38
|
created: "Created",
|
|
36
39
|
projects: "Projects",
|
|
37
40
|
remove: "Remove",
|
|
38
41
|
removePod: "Remove pod",
|
|
39
|
-
confirmRemovePod: "Remove
|
|
42
|
+
confirmRemovePod: "Remove the pod of workspace “{workspace}” and all its containers? Volume and project data is kept.",
|
|
40
43
|
recreate: "Recreate",
|
|
41
44
|
recreateWithImage: "Recreate with image",
|
|
42
45
|
imagesTitle: "Images",
|
|
43
46
|
imageId: "Image ID",
|
|
44
|
-
baseImage: "Base image",
|
|
45
47
|
imageTag: "Tag",
|
|
46
48
|
builtAt: "Built at",
|
|
47
49
|
packages: "Packages",
|
|
@@ -89,15 +91,15 @@ export const en = {
|
|
|
89
91
|
busy: "Working…",
|
|
90
92
|
confirmTitle: "Confirm action",
|
|
91
93
|
confirm: "Confirm",
|
|
92
|
-
confirmRemoveContainer: "Remove
|
|
93
|
-
confirmRecreate: "Recreate
|
|
94
|
-
confirmRemoveImage: "Remove
|
|
95
|
-
confirmRebuildImage: "Rebuild
|
|
94
|
+
confirmRemoveContainer: "Remove container “{container}” from workspace “{workspace}”?",
|
|
95
|
+
confirmRecreate: "Recreate container “{container}” in workspace “{workspace}”? Its ephemeral state is lost.",
|
|
96
|
+
confirmRemoveImage: "Remove image “{image}”? Containers using it must be recreated from another image.",
|
|
97
|
+
confirmRebuildImage: "Rebuild image “{image}” in place?",
|
|
96
98
|
confirmRebuildAllImages: "Rebuild every image in dependency order (base first)?",
|
|
97
|
-
confirmRemoveVolume: "Remove
|
|
98
|
-
confirmSetSecret: "Overwrite
|
|
99
|
-
confirmRemoveSecret: "Remove
|
|
100
|
-
confirmDetachSecret: "Detach
|
|
99
|
+
confirmRemoveVolume: "Remove volume “{volume}” and its data?",
|
|
100
|
+
confirmSetSecret: "Overwrite the value of secret “{secret}”?",
|
|
101
|
+
confirmRemoveSecret: "Remove secret “{secret}”? Containers using it must drop it first.",
|
|
102
|
+
confirmDetachSecret: "Detach secret “{secret}” from environment variable {env}?",
|
|
101
103
|
mountsTitle: "Mounts",
|
|
102
104
|
addMount: "Add mount",
|
|
103
105
|
mountKind: "Kind",
|
|
@@ -127,14 +129,18 @@ export const en = {
|
|
|
127
129
|
remountReject: "Reject",
|
|
128
130
|
mountVolume: "Volume",
|
|
129
131
|
mountSecret: "Secret",
|
|
132
|
+
mountTmpfs: "tmpfs",
|
|
133
|
+
mountAt: "at",
|
|
130
134
|
mountMode: "Mode",
|
|
131
135
|
readOnly: "Read-only",
|
|
132
136
|
readWrite: "Read-write",
|
|
137
|
+
mountReadOnlySuffix: "(ro)",
|
|
138
|
+
mountReadWriteSuffix: "(rw)",
|
|
133
139
|
remountReadOnly: "Remount as read-only",
|
|
134
140
|
remountReadWrite: "Remount as read-write",
|
|
135
|
-
confirmRemountReadOnly: "Remount
|
|
136
|
-
confirmRemountReadWrite: "Remount
|
|
137
|
-
confirmRemoveMount: "Remove
|
|
141
|
+
confirmRemountReadOnly: "Remount {mount} as read-only and recreate the container?",
|
|
142
|
+
confirmRemountReadWrite: "Remount {mount} as read-write and recreate the container?",
|
|
143
|
+
confirmRemoveMount: "Remove mount {mount} from the container and recreate it?",
|
|
138
144
|
cachesTitle: "Package caches",
|
|
139
145
|
noCaches: "No package cache is configured.",
|
|
140
146
|
cacheUsage: "{size} · {n} files",
|
|
@@ -149,6 +155,7 @@ export const en = {
|
|
|
149
155
|
invalidImageId: "Start with a letter, digit, or '_'; only letters, digits, '.', '_', '-', '/', ':' (max 128).",
|
|
150
156
|
terminalSignal: "signal {signal}",
|
|
151
157
|
terminalExitCode: "exit code {code}",
|
|
158
|
+
terminalNoExitCode: "no exit code",
|
|
152
159
|
terminalRunning: "Running",
|
|
153
160
|
terminalFailed: "Failed",
|
|
154
161
|
terminalDone: "Done",
|
|
@@ -193,6 +200,24 @@ export const en = {
|
|
|
193
200
|
toolTitle_daemon_logs: "Daemon logs",
|
|
194
201
|
toolTitle_daemon_restart: "Restart daemon",
|
|
195
202
|
toolTitle_daemon_stop: "Stop daemon",
|
|
203
|
+
terminalTabTitle: "Terminal",
|
|
204
|
+
terminalGuideTitle: "New terminal",
|
|
205
|
+
terminalGuideDescription: "Run commands in the Session workspace",
|
|
206
|
+
terminalShortcut: "New terminal",
|
|
207
|
+
terminalShortcutNoSession: "Select a session first",
|
|
208
|
+
terminalContainer: "Container",
|
|
209
|
+
terminalShell: "Shell",
|
|
210
|
+
terminalDefaultContainer: "Default container",
|
|
211
|
+
terminalStart: "Start",
|
|
212
|
+
terminalConnect: "Connect",
|
|
213
|
+
terminalReconnect: "Reconnect",
|
|
214
|
+
terminalStatusConnecting: "Connecting…",
|
|
215
|
+
terminalStatusRunning: "Connected",
|
|
216
|
+
terminalStatusExited: "Process exited ({code})",
|
|
217
|
+
terminalStatusDetached: "Detached (opened elsewhere)",
|
|
218
|
+
terminalNoShells: "No shells available",
|
|
219
|
+
terminalShellsFailed: "Could not list shells: {message}",
|
|
220
|
+
terminalLoading: "Loading…",
|
|
196
221
|
};
|
|
197
222
|
export const zh = {
|
|
198
223
|
cardTitle: "dsh-podman",
|
|
@@ -207,33 +232,35 @@ export const zh = {
|
|
|
207
232
|
copied: "已复制",
|
|
208
233
|
copyFailed: "复制失败",
|
|
209
234
|
reload: "刷新此视图",
|
|
210
|
-
reloading: "刷新中…",
|
|
211
235
|
notice: "提示",
|
|
212
|
-
configTitle: "配置",
|
|
213
236
|
defaultImage: "默认镜像",
|
|
214
|
-
socketsRoot: "套接字根目录",
|
|
215
|
-
projectsRoot: "项目根目录",
|
|
216
237
|
defaultImageHint: "工作区没有自带镜像时使用的镜像。",
|
|
238
|
+
defaultEnvironment: "默认环境变量",
|
|
239
|
+
defaultEnvironmentHint: "容器创建时注入的环境变量。编辑容器自身的环境变量后重建该容器,即可修改或移除其中的某一项。",
|
|
240
|
+
gitIdentity: "Git 身份",
|
|
241
|
+
gitName: "姓名",
|
|
242
|
+
gitEmail: "邮箱",
|
|
243
|
+
gitIdentityHint: "为新容器填入 GIT_AUTHOR_NAME/EMAIL 与 GIT_COMMITTER_NAME/EMAIL,使容器内提交的提交者信息正确。",
|
|
244
|
+
applyDefaults: "应用默认环境变量",
|
|
245
|
+
confirmApplyDefaults: "为缺少默认环境变量的容器补上这些变量?匹配的运行中容器会被重建(其进程与守护进程会停止);已有值保持不变,已停止的容器不会被处理。",
|
|
246
|
+
clear: "清除",
|
|
217
247
|
save: "保存",
|
|
218
248
|
discard: "放弃",
|
|
219
249
|
workspacesTitle: "工作区",
|
|
220
250
|
noContainers: "该工作区还没有容器。",
|
|
221
251
|
createContainer: "创建容器",
|
|
222
|
-
containersTitle: "容器",
|
|
223
252
|
containerName: "容器",
|
|
224
|
-
workspace: "工作区",
|
|
225
253
|
image: "镜像",
|
|
226
254
|
status: "状态",
|
|
227
255
|
created: "创建时间",
|
|
228
256
|
projects: "项目",
|
|
229
257
|
remove: "移除",
|
|
230
258
|
removePod: "移除 Pod",
|
|
231
|
-
confirmRemovePod: "
|
|
259
|
+
confirmRemovePod: "移除工作区“{workspace}”的 Pod 及其所有容器?卷和项目数据会保留。",
|
|
232
260
|
recreate: "重建",
|
|
233
261
|
recreateWithImage: "使用镜像重建",
|
|
234
262
|
imagesTitle: "镜像",
|
|
235
263
|
imageId: "镜像 ID",
|
|
236
|
-
baseImage: "基础镜像",
|
|
237
264
|
imageTag: "标签",
|
|
238
265
|
builtAt: "构建时间",
|
|
239
266
|
packages: "软件包",
|
|
@@ -281,15 +308,15 @@ export const zh = {
|
|
|
281
308
|
busy: "处理中…",
|
|
282
309
|
confirmTitle: "确认操作",
|
|
283
310
|
confirm: "确认",
|
|
284
|
-
confirmRemoveContainer: "
|
|
285
|
-
confirmRecreate: "
|
|
286
|
-
confirmRemoveImage: "
|
|
287
|
-
confirmRebuildImage: "
|
|
311
|
+
confirmRemoveContainer: "移除工作区“{workspace}”中的容器“{container}”?",
|
|
312
|
+
confirmRecreate: "重建工作区“{workspace}”中的容器“{container}”?其临时状态将丢失。",
|
|
313
|
+
confirmRemoveImage: "移除镜像“{image}”?使用它的容器需要用其他镜像重建。",
|
|
314
|
+
confirmRebuildImage: "就地重建镜像“{image}”?",
|
|
288
315
|
confirmRebuildAllImages: "按依赖顺序重建全部镜像(先基础镜像)?",
|
|
289
|
-
confirmRemoveVolume: "
|
|
290
|
-
confirmSetSecret: "
|
|
291
|
-
confirmRemoveSecret: "
|
|
292
|
-
confirmDetachSecret: "
|
|
316
|
+
confirmRemoveVolume: "移除卷“{volume}”及其数据?",
|
|
317
|
+
confirmSetSecret: "覆盖机密“{secret}”的值?",
|
|
318
|
+
confirmRemoveSecret: "移除机密“{secret}”?使用它的容器需先移除注入。",
|
|
319
|
+
confirmDetachSecret: "从环境变量 {env} 上移除机密“{secret}”?",
|
|
293
320
|
mountsTitle: "挂载",
|
|
294
321
|
addMount: "添加挂载",
|
|
295
322
|
mountKind: "类型",
|
|
@@ -319,14 +346,18 @@ export const zh = {
|
|
|
319
346
|
remountReject: "拒绝",
|
|
320
347
|
mountVolume: "卷",
|
|
321
348
|
mountSecret: "机密",
|
|
349
|
+
mountTmpfs: "tmpfs",
|
|
350
|
+
mountAt: "位于",
|
|
322
351
|
mountMode: "模式",
|
|
323
352
|
readOnly: "只读",
|
|
324
353
|
readWrite: "读写",
|
|
354
|
+
mountReadOnlySuffix: "(只读)",
|
|
355
|
+
mountReadWriteSuffix: "(读写)",
|
|
325
356
|
remountReadOnly: "重新挂载为只读",
|
|
326
357
|
remountReadWrite: "重新挂载为读写",
|
|
327
|
-
confirmRemountReadOnly: "
|
|
328
|
-
confirmRemountReadWrite: "
|
|
329
|
-
confirmRemoveMount: "
|
|
358
|
+
confirmRemountReadOnly: "将 {mount} 重新挂载为只读并重建容器?",
|
|
359
|
+
confirmRemountReadWrite: "将 {mount} 重新挂载为读写并重建容器?",
|
|
360
|
+
confirmRemoveMount: "从容器中移除挂载 {mount} 并重建容器?",
|
|
330
361
|
cachesTitle: "软件包缓存",
|
|
331
362
|
noCaches: "未配置软件包缓存。",
|
|
332
363
|
cacheUsage: "{size} · {n} 个文件",
|
|
@@ -341,6 +372,7 @@ export const zh = {
|
|
|
341
372
|
invalidImageId: "以字母、数字或 '_' 开头,仅可使用字母、数字、'.'、'_'、'-'、'/'、':'(最长 128 个字符)。",
|
|
342
373
|
terminalSignal: "信号 {signal}",
|
|
343
374
|
terminalExitCode: "退出码 {code}",
|
|
375
|
+
terminalNoExitCode: "无退出码",
|
|
344
376
|
terminalRunning: "运行中",
|
|
345
377
|
terminalFailed: "失败",
|
|
346
378
|
terminalDone: "已完成",
|
|
@@ -385,4 +417,22 @@ export const zh = {
|
|
|
385
417
|
toolTitle_daemon_logs: "守护进程日志",
|
|
386
418
|
toolTitle_daemon_restart: "重启守护进程",
|
|
387
419
|
toolTitle_daemon_stop: "停止守护进程",
|
|
420
|
+
terminalTabTitle: "终端",
|
|
421
|
+
terminalGuideTitle: "新建终端",
|
|
422
|
+
terminalGuideDescription: "在会话工作区运行命令",
|
|
423
|
+
terminalShortcut: "新建终端",
|
|
424
|
+
terminalShortcutNoSession: "请先选择会话",
|
|
425
|
+
terminalContainer: "容器",
|
|
426
|
+
terminalShell: "Shell",
|
|
427
|
+
terminalDefaultContainer: "默认容器",
|
|
428
|
+
terminalStart: "启动",
|
|
429
|
+
terminalConnect: "连接",
|
|
430
|
+
terminalReconnect: "重新连接",
|
|
431
|
+
terminalStatusConnecting: "正在连接…",
|
|
432
|
+
terminalStatusRunning: "已连接",
|
|
433
|
+
terminalStatusExited: "进程已退出({code})",
|
|
434
|
+
terminalStatusDetached: "已在其他位置打开",
|
|
435
|
+
terminalNoShells: "没有可用的 Shell",
|
|
436
|
+
terminalShellsFailed: "读取 Shell 失败:{message}",
|
|
437
|
+
terminalLoading: "正在加载…",
|
|
388
438
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { InjectFace, PropsLocale, PropsRuntime } from "@deepseek-ai/dsh-client-ui-slots";
|
|
2
|
+
import { type ReactNode } from "react";
|
|
3
|
+
import type { ContainerCardFace } from "./container-card-controller.js";
|
|
4
|
+
import { NS } from "./locales.js";
|
|
5
|
+
/** The card snapshot the guide reads; the tab's own actions open the terminal. */
|
|
6
|
+
export interface PodmanTerminalGuideInjected extends ContainerCardFace {
|
|
7
|
+
/** Owning session, used by the shells route and the injection contract. */
|
|
8
|
+
readonly sessionId: string;
|
|
9
|
+
}
|
|
10
|
+
export type PodmanTerminalGuideProps = PropsRuntime<"sidebar.right.tab.guide.entry"> & PropsLocale<typeof NS> & InjectFace<PodmanTerminalGuideInjected>;
|
|
11
|
+
export declare function PodmanTerminalGuide(props: PodmanTerminalGuideProps): ReactNode;
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// SPDX-FileCopyrightText: 2026 Elouan Martinet <exa@elou.world>
|
|
3
|
+
//
|
|
4
|
+
// SPDX-License-Identifier: MIT
|
|
5
|
+
// The Podman terminal's guide card: pick a container and one of the shells that
|
|
6
|
+
// container really offers, then open a new terminal tab bound to that target in
|
|
7
|
+
// the Session's own workspace. It reads the same settings-card snapshot as the
|
|
8
|
+
// tab body and never asks for a workspace, because each Session has exactly one.
|
|
9
|
+
import { Button, PluginArtworkTerminal, } from "@deepseek-ai/dsh-client-ui-primitives";
|
|
10
|
+
import { useEffect, useState } from "react";
|
|
11
|
+
import { fieldLabel, fieldSelect, hint } from "./container-card-styles.js";
|
|
12
|
+
import { ContainerField } from "./podman-terminal.js";
|
|
13
|
+
import { PODMAN_TERMINAL_KIND } from "./terminal-tab.js";
|
|
14
|
+
import { readTerminalTarget, writeTerminalTarget, } from "./terminal-preference.js";
|
|
15
|
+
import { containerOptions, validContainer, validShell, } from "./terminal-targets.js";
|
|
16
|
+
import { fetchTerminalShells, fetchTerminalTarget, } from "./terminal-transport.js";
|
|
17
|
+
export function PodmanTerminalGuide(props) {
|
|
18
|
+
const { t, sessionId } = props;
|
|
19
|
+
const { tab } = props.useTabInfo();
|
|
20
|
+
const state = props.useContainerCard((snapshot) => snapshot);
|
|
21
|
+
// The host resolves the Session's workspace and reports it when it cannot.
|
|
22
|
+
const [target, setTarget] = useState({ phase: "loading" });
|
|
23
|
+
const workspace = target.phase === "ready"
|
|
24
|
+
? target.target.workspace
|
|
25
|
+
: undefined;
|
|
26
|
+
const workspaceSlug = target.phase === "ready"
|
|
27
|
+
? target.target.workspaceSlug
|
|
28
|
+
: undefined;
|
|
29
|
+
const unknownWorkspace = target.phase === "failed";
|
|
30
|
+
const [container, setContainer] = useState(undefined);
|
|
31
|
+
const [shells, setShells] = useState({ phase: "loading" });
|
|
32
|
+
const [shell, setShell] = useState(undefined);
|
|
33
|
+
// The last target this browser started from the card, reused below while it
|
|
34
|
+
// is still valid. Read once: the card shows it, it does not track it.
|
|
35
|
+
const [stored] = useState(() => readTerminalTarget());
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
props.reload();
|
|
38
|
+
}, [props.reload]);
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
const controller = new AbortController();
|
|
41
|
+
setTarget({ phase: "loading" });
|
|
42
|
+
void fetchTerminalTarget(sessionId, controller.signal).then((resolved) => {
|
|
43
|
+
if (!controller.signal.aborted) {
|
|
44
|
+
setTarget({ phase: "ready", target: resolved });
|
|
45
|
+
}
|
|
46
|
+
}, (error) => {
|
|
47
|
+
if (controller.signal.aborted)
|
|
48
|
+
return;
|
|
49
|
+
setTarget({
|
|
50
|
+
phase: "failed",
|
|
51
|
+
message: error instanceof Error ? error.message : String(error),
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
return () => {
|
|
55
|
+
controller.abort();
|
|
56
|
+
};
|
|
57
|
+
}, [sessionId]);
|
|
58
|
+
// The empty value means the workspace's default container; the workspace
|
|
59
|
+
// row's own containerName is that container's podman name, which the
|
|
60
|
+
// orchestrator rejects, so it is never used as a target. The choice waits for
|
|
61
|
+
// the first snapshot, otherwise the empty default would pre-empt a remembered
|
|
62
|
+
// named container before the options are known.
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
if (unknownWorkspace || workspace === undefined || container !== undefined) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (state.busy)
|
|
68
|
+
return;
|
|
69
|
+
setContainer(validContainer(stored?.container, containerOptions(state.containers, workspaceSlug)));
|
|
70
|
+
}, [
|
|
71
|
+
unknownWorkspace,
|
|
72
|
+
workspace,
|
|
73
|
+
container,
|
|
74
|
+
state.busy,
|
|
75
|
+
state.containers,
|
|
76
|
+
workspaceSlug,
|
|
77
|
+
stored,
|
|
78
|
+
]);
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
if (workspace === undefined || workspace === "" || container === undefined) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const controller = new AbortController();
|
|
84
|
+
setShells({ phase: "loading" });
|
|
85
|
+
void fetchTerminalShells(workspace, container, sessionId, controller.signal).then((list) => {
|
|
86
|
+
if (controller.signal.aborted)
|
|
87
|
+
return;
|
|
88
|
+
setShells({ phase: "ready", shells: list });
|
|
89
|
+
setShell((previous) => previous ?? validShell(stored?.shell, list) ?? list[0]?.path);
|
|
90
|
+
}, (error) => {
|
|
91
|
+
if (controller.signal.aborted)
|
|
92
|
+
return;
|
|
93
|
+
setShells({
|
|
94
|
+
phase: "failed",
|
|
95
|
+
message: error instanceof Error ? error.message : String(error),
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
return () => {
|
|
99
|
+
controller.abort();
|
|
100
|
+
};
|
|
101
|
+
}, [workspace, container, sessionId]);
|
|
102
|
+
const shellList = shells.phase === "ready" ? shells.shells : [];
|
|
103
|
+
const ready = !unknownWorkspace && container !== undefined &&
|
|
104
|
+
shell !== undefined &&
|
|
105
|
+
shellList.length > 0;
|
|
106
|
+
return (_jsxs("div", { style: CARD_STYLE, "data-sidebar-right-guide-entry": props.kind, children: [_jsxs("div", { style: HEADER_STYLE, children: [_jsx("span", { style: ICON_STYLE, "aria-hidden": "true", children: _jsx(PluginArtworkTerminal, { size: 22 }) }), _jsxs("span", { style: TEXT_STYLE, children: [_jsx("span", { style: TITLE_STYLE, children: props.title }), props.description === undefined
|
|
107
|
+
? null
|
|
108
|
+
: _jsx("span", { style: DESCRIPTION_STYLE, children: props.description })] })] }), state.workspaces.length === 0
|
|
109
|
+
? (_jsx("p", { style: hint, role: "status", children: state.busy ? t("terminalLoading") : t("unavailable") }))
|
|
110
|
+
: (_jsxs(_Fragment, { children: [target.phase === "failed" && (_jsx("p", { style: hint, role: "alert", children: target.message })), _jsxs("div", { style: FIELDS_STYLE, children: [_jsx(ContainerField, { containers: state.containers, workspaceSlug: workspaceSlug, container: container, disabled: unknownWorkspace, label: t("terminalContainer"), defaultLabel: t("terminalDefaultContainer"), selectStyle: fieldSelect, onContainer: (value) => {
|
|
111
|
+
// The new container may not offer the current shell, so the
|
|
112
|
+
// shells effect re-picks one (remembered when still valid).
|
|
113
|
+
setContainer(value);
|
|
114
|
+
setShell(undefined);
|
|
115
|
+
} }), _jsx("span", { style: fieldLabel, children: t("terminalShell") }), _jsx("select", { style: fieldSelect, "aria-label": t("terminalShell"), value: shell ?? "", disabled: unknownWorkspace || shells.phase !== "ready" ||
|
|
116
|
+
shellList.length === 0, onChange: (event) => {
|
|
117
|
+
setShell(event.target.value);
|
|
118
|
+
}, children: shellList.length === 0
|
|
119
|
+
? (_jsx("option", { value: "", children: unknownWorkspace
|
|
120
|
+
? ""
|
|
121
|
+
: shells.phase === "loading"
|
|
122
|
+
? t("terminalLoading")
|
|
123
|
+
: t("terminalNoShells") }))
|
|
124
|
+
: shellList.map((entry) => (_jsx("option", { value: entry.path, children: entry.name }, entry.path))) })] }), !unknownWorkspace && shells.phase === "failed" && (_jsx("p", { style: hint, role: "alert", children: t("terminalShellsFailed", { message: shells.message }) })), !unknownWorkspace && shells.phase === "loading" && (_jsx("p", { style: hint, role: "status", children: t("terminalLoading") })), !unknownWorkspace && shells.phase === "ready" &&
|
|
125
|
+
shellList.length === 0 && (_jsx("p", { style: hint, role: "status", children: t("terminalNoShells") })), _jsx("div", { style: ACTIONS_STYLE, children: _jsx(Button, { variant: "primary", size: "sm", disabled: !ready, onClick: () => {
|
|
126
|
+
if (container === undefined || shell === undefined)
|
|
127
|
+
return;
|
|
128
|
+
writeTerminalTarget({ container, shell });
|
|
129
|
+
// Replace the guide tab in place, exactly like the built-in
|
|
130
|
+
// guide cards, instead of adding a second terminal tab.
|
|
131
|
+
tab.actions.openTab(PODMAN_TERMINAL_KIND, {
|
|
132
|
+
replaceTab: true,
|
|
133
|
+
params: { container, shell },
|
|
134
|
+
});
|
|
135
|
+
}, children: t("terminalStart") }) })] }))] }));
|
|
136
|
+
}
|
|
137
|
+
// The card mirrors the harness guide capsule skin (`GuideBody .entry`): same
|
|
138
|
+
// padding, radius token, border and background as the entries beside it, so the
|
|
139
|
+
// glyph and title line up; the column layout and the internal gaps are ours
|
|
140
|
+
// because this card carries controls rather than being one clickable capsule.
|
|
141
|
+
const CARD_STYLE = {
|
|
142
|
+
display: "flex",
|
|
143
|
+
flexDirection: "column",
|
|
144
|
+
gap: "8px",
|
|
145
|
+
boxSizing: "border-box",
|
|
146
|
+
width: "100%",
|
|
147
|
+
padding: "14px 20px",
|
|
148
|
+
border: "0.5px solid var(--dsw-alias-border-l3)",
|
|
149
|
+
borderRadius: "var(--dsl-guide-entry-radius)",
|
|
150
|
+
background: "var(--dsw-alias-bg-layer-1)",
|
|
151
|
+
};
|
|
152
|
+
const HEADER_STYLE = {
|
|
153
|
+
display: "flex",
|
|
154
|
+
alignItems: "center",
|
|
155
|
+
gap: "14px",
|
|
156
|
+
minWidth: 0,
|
|
157
|
+
};
|
|
158
|
+
const ICON_STYLE = {
|
|
159
|
+
display: "flex",
|
|
160
|
+
flex: "none",
|
|
161
|
+
alignItems: "center",
|
|
162
|
+
justifyContent: "center",
|
|
163
|
+
width: "26px",
|
|
164
|
+
height: "26px",
|
|
165
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
166
|
+
};
|
|
167
|
+
const TEXT_STYLE = {
|
|
168
|
+
display: "flex",
|
|
169
|
+
flex: 1,
|
|
170
|
+
flexDirection: "column",
|
|
171
|
+
gap: "2px",
|
|
172
|
+
minWidth: 0,
|
|
173
|
+
};
|
|
174
|
+
const TITLE_STYLE = {
|
|
175
|
+
overflow: "hidden",
|
|
176
|
+
color: "var(--dsw-alias-label-primary)",
|
|
177
|
+
fontSize: "14px",
|
|
178
|
+
lineHeight: 1.4,
|
|
179
|
+
whiteSpace: "nowrap",
|
|
180
|
+
textOverflow: "ellipsis",
|
|
181
|
+
};
|
|
182
|
+
const DESCRIPTION_STYLE = {
|
|
183
|
+
overflow: "hidden",
|
|
184
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
185
|
+
fontSize: "11px",
|
|
186
|
+
lineHeight: 1.4,
|
|
187
|
+
whiteSpace: "nowrap",
|
|
188
|
+
textOverflow: "ellipsis",
|
|
189
|
+
};
|
|
190
|
+
// A centred label/select grid: each pair is one row, so a narrow card can never
|
|
191
|
+
// wrap a label away from its control. The auto column sizes to the widest label
|
|
192
|
+
// (right-aligned by `fieldLabel`), the second is capped at the select width so
|
|
193
|
+
// both controls line up, and the pair is centred in the card.
|
|
194
|
+
const FIELDS_STYLE = {
|
|
195
|
+
display: "grid",
|
|
196
|
+
gridTemplateColumns: "auto minmax(0, 160px)",
|
|
197
|
+
gap: "8px",
|
|
198
|
+
alignItems: "center",
|
|
199
|
+
justifyContent: "center",
|
|
200
|
+
width: "100%",
|
|
201
|
+
};
|
|
202
|
+
const ACTIONS_STYLE = {
|
|
203
|
+
display: "flex",
|
|
204
|
+
flexWrap: "wrap",
|
|
205
|
+
justifyContent: "center",
|
|
206
|
+
gap: "8px",
|
|
207
|
+
alignItems: "center",
|
|
208
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { InjectFace, PropsRuntime } from "@deepseek-ai/dsh-client-ui-slots";
|
|
2
|
+
import { type ReactNode } from "react";
|
|
3
|
+
/** Session identity the session-scope title registration injects. */
|
|
4
|
+
export interface PodmanTerminalTitleInjected {
|
|
5
|
+
readonly sessionId: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function PodmanTerminalTitle(props: PropsRuntime<"sidebar.right.pane.tab.title"> & InjectFace<PodmanTerminalTitleInjected>): ReactNode;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useSyncExternalStore } from "react";
|
|
3
|
+
import { shellName } from "./terminal-targets.js";
|
|
4
|
+
import { subscribeTerminalTitles, terminalTitle } from "./terminal-titles.js";
|
|
5
|
+
export function PodmanTerminalTitle(props) {
|
|
6
|
+
const { tab } = props.useTabInfo();
|
|
7
|
+
const params = tab.navigation.params;
|
|
8
|
+
// Only the session-scope identity is available here, so the store is keyed the
|
|
9
|
+
// same way the host retains a terminal.
|
|
10
|
+
const key = `${props.sessionId}:${tab.id}`;
|
|
11
|
+
const fallback = shellName(params?.shell) ?? tab.title;
|
|
12
|
+
const title = useSyncExternalStore(subscribeTerminalTitles, () => terminalTitle(key) ?? fallback);
|
|
13
|
+
return (_jsxs("span", { style: CHIP_STYLE, children: [_jsx(TerminalGlyph, {}), _jsx("span", { style: TITLE_STYLE, children: title })] }));
|
|
14
|
+
}
|
|
15
|
+
// The built-in tab chip's 16px terminal prompt, drawn in the surrounding ink
|
|
16
|
+
// instead of the plugin artwork's fixed brand palette.
|
|
17
|
+
function TerminalGlyph() {
|
|
18
|
+
return (_jsxs("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [_jsx("path", { d: "M3 4L7 8L3 12", stroke: "currentColor" }), _jsx("path", { d: "M9 12H13", stroke: "currentColor" })] }));
|
|
19
|
+
}
|
|
20
|
+
const CHIP_STYLE = {
|
|
21
|
+
display: "inline-flex",
|
|
22
|
+
alignItems: "center",
|
|
23
|
+
gap: "4px",
|
|
24
|
+
minWidth: 0,
|
|
25
|
+
};
|
|
26
|
+
const TITLE_STYLE = {
|
|
27
|
+
overflow: "hidden",
|
|
28
|
+
whiteSpace: "nowrap",
|
|
29
|
+
textOverflow: "ellipsis",
|
|
30
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { InjectFace, PropsLocale, PropsRuntime } from "@deepseek-ai/dsh-client-ui-slots";
|
|
2
|
+
import { type ReactNode } from "react";
|
|
3
|
+
import type { ContainerView } from "./card-protocol.js";
|
|
4
|
+
import type { ContainerCardFace } from "./container-card-controller.js";
|
|
5
|
+
import { NS } from "./locales.js";
|
|
6
|
+
/** Everything the tab body is given: framework shares plus the injected card face. */
|
|
7
|
+
export interface PodmanTerminalInjected extends ContainerCardFace {
|
|
8
|
+
/** Owning session, injected by the session-scope registration. */
|
|
9
|
+
readonly sessionId: string;
|
|
10
|
+
}
|
|
11
|
+
export type PodmanTerminalProps = PropsRuntime<"sidebar.right.pane.tab"> & PropsLocale<typeof NS> & InjectFace<PodmanTerminalInjected>;
|
|
12
|
+
/** The labelled container picker shared by the body and the guide card. */
|
|
13
|
+
interface ContainerFieldProps {
|
|
14
|
+
readonly containers: readonly ContainerView[];
|
|
15
|
+
readonly workspaceSlug: string | undefined;
|
|
16
|
+
readonly container: string | undefined;
|
|
17
|
+
readonly disabled: boolean;
|
|
18
|
+
readonly label: string;
|
|
19
|
+
readonly defaultLabel: string;
|
|
20
|
+
/** Select skin; stacked cards pass a full-width variant. */
|
|
21
|
+
readonly selectStyle?: React.CSSProperties;
|
|
22
|
+
readonly onContainer: (container: string) => void;
|
|
23
|
+
}
|
|
24
|
+
export declare function ContainerField(props: ContainerFieldProps): ReactNode;
|
|
25
|
+
export declare function PodmanTerminal(props: PodmanTerminalProps): ReactNode;
|
|
26
|
+
export {};
|