@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.
Files changed (186) hide show
  1. package/README.md +12 -0
  2. package/README.zh.md +14 -2
  3. package/cordis.patch.yml +58 -0
  4. package/dist/approval-reasons.d.ts +3 -4
  5. package/dist/approval-reasons.js +40 -49
  6. package/dist/approval-reasons.test.js +43 -15
  7. package/dist/approval.js +27 -10
  8. package/dist/approval.test.js +165 -34
  9. package/dist/card-route.d.ts +3 -2
  10. package/dist/card-route.js +103 -35
  11. package/dist/card-route.test.js +60 -43
  12. package/dist/card-test-support.js +39 -66
  13. package/dist/client/ContainerCard.d.ts +1 -1
  14. package/dist/client/ContainerCard.js +76 -70
  15. package/dist/client/card-protocol.d.ts +3 -3
  16. package/dist/client/container-card-caches.js +11 -6
  17. package/dist/client/container-card-controller.d.ts +13 -18
  18. package/dist/client/container-card-controller.js +86 -40
  19. package/dist/client/container-card-create-modal.d.ts +2 -2
  20. package/dist/client/container-card-create-modal.js +13 -5
  21. package/dist/client/container-card-default-env.d.ts +10 -0
  22. package/dist/client/container-card-default-env.js +69 -0
  23. package/dist/client/container-card-directory.d.ts +2 -2
  24. package/dist/client/container-card-directory.js +12 -4
  25. package/dist/client/container-card-editors.d.ts +3 -3
  26. package/dist/client/container-card-editors.js +104 -32
  27. package/dist/client/container-card-images.d.ts +4 -4
  28. package/dist/client/container-card-images.js +19 -6
  29. package/dist/client/container-card-paths.d.ts +3 -3
  30. package/dist/client/container-card-paths.js +18 -11
  31. package/dist/client/container-card-row.d.ts +10 -6
  32. package/dist/client/container-card-row.js +82 -13
  33. package/dist/client/container-card-secrets.d.ts +3 -3
  34. package/dist/client/container-card-secrets.js +8 -6
  35. package/dist/client/container-card-shared.d.ts +4 -17
  36. package/dist/client/container-card-shared.js +9 -25
  37. package/dist/client/container-card-styles.d.ts +2 -8
  38. package/dist/client/container-card-styles.js +14 -52
  39. package/dist/client/container-card-volumes.d.ts +2 -2
  40. package/dist/client/container-card-volumes.js +9 -5
  41. package/dist/client/container-card-workspace.d.ts +8 -6
  42. package/dist/client/container-card-workspace.js +9 -3
  43. package/dist/client/directory-picker.js +2 -1
  44. package/dist/client/index.js +13109 -2117
  45. package/dist/client/locales.d.ts +6 -1
  46. package/dist/client/locales.js +88 -38
  47. package/dist/client/podman-terminal-guide.d.ts +11 -0
  48. package/dist/client/podman-terminal-guide.js +208 -0
  49. package/dist/client/podman-terminal-title.d.ts +7 -0
  50. package/dist/client/podman-terminal-title.js +30 -0
  51. package/dist/client/podman-terminal.d.ts +26 -0
  52. package/dist/client/podman-terminal.js +412 -0
  53. package/dist/client/read-only-approval.d.ts +2 -2
  54. package/dist/client/read-only-approval.js +13 -3
  55. package/dist/client/slot-contract.d.ts +0 -11
  56. package/dist/client/terminal-preference.d.ts +26 -0
  57. package/dist/client/terminal-preference.js +67 -0
  58. package/dist/client/terminal-protocol.d.ts +85 -0
  59. package/dist/client/terminal-protocol.js +14 -0
  60. package/dist/client/terminal-tab.d.ts +60 -0
  61. package/dist/client/terminal-tab.js +35 -0
  62. package/dist/client/terminal-targets.d.ts +33 -0
  63. package/dist/client/terminal-targets.js +65 -0
  64. package/dist/client/terminal-titles.d.ts +23 -0
  65. package/dist/client/terminal-titles.js +52 -0
  66. package/dist/client/terminal-transport.d.ts +63 -0
  67. package/dist/client/terminal-transport.js +207 -0
  68. package/dist/client/tool-views.js +215 -49
  69. package/dist/container-env.d.ts +11 -0
  70. package/dist/container-env.js +96 -0
  71. package/dist/container-env.test.d.ts +1 -0
  72. package/dist/container-env.test.js +93 -0
  73. package/dist/containers.test.js +196 -18
  74. package/dist/daemons.test.js +18 -4
  75. package/dist/dsh-version.js +2 -1
  76. package/dist/env-rows.d.ts +14 -0
  77. package/dist/env-rows.js +52 -0
  78. package/dist/env-rows.test.d.ts +1 -0
  79. package/dist/env-rows.test.js +43 -0
  80. package/dist/fs-provider.d.ts +1 -0
  81. package/dist/fs-provider.js +26 -12
  82. package/dist/fs-provider.test.js +51 -10
  83. package/dist/generated/version.d.ts +2 -2
  84. package/dist/generated/version.js +2 -2
  85. package/dist/grpc/proto/dshctl/v1/control.proto +8 -1
  86. package/dist/grpc/proto/dshguest/v1/guest.proto +5 -0
  87. package/dist/grpc/runtime-client.d.ts +3 -1
  88. package/dist/grpc/runtime-client.js +90 -17
  89. package/dist/guest-rpc.d.ts +15 -19
  90. package/dist/guest-rpc.js +289 -70
  91. package/dist/guest-rpc.test.d.ts +1 -0
  92. package/dist/guest-rpc.test.js +241 -0
  93. package/dist/guest-terminal.d.ts +30 -0
  94. package/dist/guest-terminal.js +196 -0
  95. package/dist/images.test.js +10 -3
  96. package/dist/index.d.ts +11 -16
  97. package/dist/index.js +42 -36
  98. package/dist/locales.test.d.ts +1 -0
  99. package/dist/locales.test.js +34 -0
  100. package/dist/misc.test.js +38 -10
  101. package/dist/mount-enums.js +2 -1
  102. package/dist/mount-input.d.ts +2 -0
  103. package/dist/mount-input.js +38 -22
  104. package/dist/mounts.test.js +81 -11
  105. package/dist/naming.test.d.ts +1 -0
  106. package/dist/naming.test.js +28 -0
  107. package/dist/output-reader.js +36 -4
  108. package/dist/package-deps.test.d.ts +1 -0
  109. package/dist/package-deps.test.js +49 -0
  110. package/dist/paths.test.js +4 -2
  111. package/dist/plugin-meta.test.d.ts +1 -0
  112. package/dist/plugin-meta.test.js +29 -0
  113. package/dist/project-path.js +33 -7
  114. package/dist/project-path.test.js +14 -0
  115. package/dist/prompts.d.ts +0 -4
  116. package/dist/prompts.js +15 -84
  117. package/dist/read-only-shell.js +3 -1
  118. package/dist/read-only-shell.test.js +80 -25
  119. package/dist/runtime-client.test.d.ts +1 -0
  120. package/dist/runtime-client.test.js +53 -0
  121. package/dist/secrets.test.js +21 -6
  122. package/dist/settings-commands.test.js +61 -14
  123. package/dist/settings-create.test.js +32 -10
  124. package/dist/settings-default-env.test.d.ts +1 -0
  125. package/dist/settings-default-env.test.js +175 -0
  126. package/dist/settings-mounts.test.js +46 -7
  127. package/dist/settings-schema.d.ts +6 -11
  128. package/dist/settings-schema.js +4 -8
  129. package/dist/settings-schema.test.d.ts +1 -0
  130. package/dist/settings-schema.test.js +35 -0
  131. package/dist/settings-workspaces.test.js +36 -63
  132. package/dist/spill-store.d.ts +1 -0
  133. package/dist/spill-store.js +17 -4
  134. package/dist/spill-store.test.js +31 -8
  135. package/dist/subprocess.d.ts +4 -0
  136. package/dist/subprocess.js +148 -162
  137. package/dist/subprocess.test.js +118 -8
  138. package/dist/terminal-preference.test.d.ts +1 -0
  139. package/dist/terminal-preference.test.js +62 -0
  140. package/dist/terminal-route.d.ts +10 -0
  141. package/dist/terminal-route.js +270 -0
  142. package/dist/terminal-route.test.d.ts +1 -0
  143. package/dist/terminal-route.test.js +265 -0
  144. package/dist/terminal-sessions.d.ts +69 -0
  145. package/dist/terminal-sessions.js +252 -0
  146. package/dist/terminal-shells.d.ts +22 -0
  147. package/dist/terminal-shells.js +99 -0
  148. package/dist/terminal-tab.test.d.ts +1 -0
  149. package/dist/terminal-tab.test.js +58 -0
  150. package/dist/terminal-targets.test.d.ts +1 -0
  151. package/dist/terminal-targets.test.js +43 -0
  152. package/dist/terminal-titles.test.d.ts +1 -0
  153. package/dist/terminal-titles.test.js +36 -0
  154. package/dist/test-support.d.ts +35 -5
  155. package/dist/test-support.js +91 -29
  156. package/dist/tool-defs.js +19 -4
  157. package/dist/tool-handlers.js +80 -28
  158. package/dist/tool-params.js +19 -5
  159. package/dist/volumes.test.js +1 -1
  160. package/dist/workspace-binding.d.ts +18 -9
  161. package/dist/workspace-binding.js +244 -77
  162. package/dist/workspace-binding.test.js +189 -25
  163. package/docs/architecture.md +62 -21
  164. package/docs/architecture.zh.md +57 -13
  165. package/docs/configuration.md +61 -20
  166. package/docs/configuration.zh.md +53 -19
  167. package/docs/development-prompt.md +72 -0
  168. package/docs/development-prompt.zh.md +69 -0
  169. package/docs/development.md +141 -21
  170. package/docs/development.zh.md +125 -17
  171. package/docs/install-dsh-and-dsh-podman.md +21 -8
  172. package/docs/install-dsh-and-dsh-podman.zh.md +18 -8
  173. package/docs/uninstall.md +83 -0
  174. package/docs/uninstall.zh.md +79 -0
  175. package/docs/update.md +120 -0
  176. package/docs/update.zh.md +114 -0
  177. package/docs/usage.md +108 -61
  178. package/docs/usage.zh.md +76 -38
  179. package/locale/en.json +6 -0
  180. package/locale/zh.json +6 -0
  181. package/package.json +58 -25
  182. package/quadlet/dsh-podman-orchestrator.container +46 -0
  183. package/quadlet/dsh.container +35 -0
  184. package/LICENSE.pkg +0 -17103
  185. package/dist/preferences.d.ts +0 -6
  186. package/dist/preferences.js +0 -27
@@ -8,34 +8,56 @@ SPDX-License-Identifier: MIT
8
8
 
9
9
  Environment variables use the `DSH_PODMAN_` prefix and are listed under the
10
10
  component that reads them (a variable read by several components appears in each
11
- of their sections). The plugin also exposes a few **UI settings** in the dsh
12
- **Settings → Plugins** card, listed separately from env vars.
11
+ of their sections). The plugin also exposes a few **UI settings** on its
12
+ **dsh-podman** page (sidebar **Plugins** panel → **Installed**), listed
13
+ separately from env vars.
13
14
 
14
15
  The plugin reads its configuration from, in order: the plugin `config` in
15
16
  cordis, then the environment variables below, then built-in defaults.
16
17
 
17
18
  ## Plugin (dsh client) — environment variables
18
19
 
19
- | Variable | Default | Description |
20
- | ------------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------ |
21
- | `DSH_PODMAN_IMAGE_PREFIX` | `localhost/dsh-podman/` | Prefix prepended to workspace image references |
22
- | `DSH_PODMAN_ORCHESTRATOR_TOKEN` | — | Shared secret authenticating control-plane gRPC calls; see [Variable details](#variable-details) |
23
- | `DSH_PODMAN_PROJECTS_ROOT` | `/projects` | Project root used to resolve session working directories into a workspace |
24
- | `DSH_PODMAN_SOCKETS_ROOT` | `/run/dsh-podman` | Socket root the plugin derives the orchestrator control socket (`orchestrator.sock`) from |
20
+ | Variable | Default | Description |
21
+ | ------------------------------- | ----------------- | ------------------------------------------------------------------------------------------------ |
22
+ | `DSH_PODMAN_ORCHESTRATOR_TOKEN` | — | Shared secret authenticating control-plane gRPC calls; see [Variable details](#variable-details) |
23
+ | `DSH_PODMAN_PROJECTS_ROOT` | `/projects` | Project root used to resolve session working directories into a workspace |
24
+ | `DSH_PODMAN_SOCKETS_ROOT` | `/run/dsh-podman` | Socket root the plugin derives the orchestrator control socket (`orchestrator.sock`) from |
25
25
 
26
- `projectsRoot` and `imagePrefix` are env-only so they match the orchestrator;
26
+ `projectsRoot` and `socketsRoot` are env-only so they match the orchestrator;
27
27
  `controlToken` comes from the plugin `config` or
28
28
  `DSH_PODMAN_ORCHESTRATOR_TOKEN`.
29
29
 
30
30
  ## Plugin (dsh client) — UI settings
31
31
 
32
- Editable in the card's **Settings → Plugins → Podman** panel (the Configuration
33
- section and the images' Set-default popup):
32
+ Editable on the **dsh-podman** page (sidebar **Plugins** panel → **Installed**;
33
+ the images' Set-default popup and the **Default environment** section):
34
34
 
35
- | Setting | Default | Description |
36
- | -------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------- |
37
- | `defaultImage` | `archlinux` | Image **short name** used for new workspaces; chosen from base and custom images via the Set-default popup |
38
- | `socketsRoot` | `DSH_PODMAN_SOCKETS_ROOT` | Socket root the plugin uses to reach the orchestrator; falls back to the env var |
35
+ | Setting | Default | Description |
36
+ | -------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
37
+ | `defaultImage` | `archlinux` | Image **short name** used for new workspaces; chosen from base and custom images via the Set-default popup |
38
+ | `uiLocale` | `""` | Plugin-managed active locale, written by the browser client so the host can render approval text in the session language (see [Approval](usage.md#approval)); not user-editable |
39
+ | `containerEnv` | `{}` | Default environment seeded into a container when it is created; see [Default environment](#default-environment) |
40
+
41
+ ### Default environment
42
+
43
+ `containerEnv` is one map of variables seeded into a container when it is
44
+ created: the default container of a new workspace and every named container. A
45
+ container's own `env` wins per key, and a recreate stores exactly the
46
+ environment it is given, so removing a value from a container's environment and
47
+ recreating it removes that value for good.
48
+
49
+ The Podman page's **Default environment** section edits it with the same
50
+ key/value rows a container uses: add or remove variables, then **Save** (or
51
+ **Discard**). **Git identity** fills `GIT_AUTHOR_NAME`, `GIT_AUTHOR_EMAIL`,
52
+ `GIT_COMMITTER_NAME` and `GIT_COMMITTER_EMAIL` from one name and one email, and
53
+ **Apply default environment variables** adds the missing values to the running
54
+ containers that lack them, recreating only those and never overwriting an
55
+ existing value; stopped containers are left for their next start. Every
56
+ workspace row offers the same action for its own containers. Reserved
57
+ `DSH_PODMAN*` keys are ignored, and the values are not secret — use `secretEnv`
58
+ for secrets (see [Secrets](usage.md#secrets)).
59
+
60
+ ## Orchestrator (`dsh-podman-orchestrator`)
39
61
 
40
62
  | Variable | Default | Description |
41
63
  | ---------------------------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
@@ -49,10 +71,10 @@ section and the images' Set-default popup):
49
71
  | `DSH_PODMAN_HOST_GUEST_AGENT_BIN` | — | Host-side guest agent binary path; bind-mounted when set; see [Variable details](#variable-details) |
50
72
  | `DSH_PODMAN_HOST_PACMAN_CACHE` | — | Host-absolute directory mounted at `/var/cache/pacman/pkg` to persist downloaded packages across pacman builds; unset disables caching |
51
73
  | `DSH_PODMAN_HOST_PROJECTS_ROOT` | `DSH_PODMAN_PROJECTS_ROOT` | Host-side projects root used as the source of bind mounts |
52
- | `DSH_PODMAN_HOST_SOCKETS_ROOT` | `DSH_PODMAN_SOCKETS_ROOT` | Host-side sockets root for guest socket bind mounts |
74
+ | `DSH_PODMAN_HOST_SOCKETS_ROOT` | required | Host-side sockets root for guest socket bind mounts; see [Variable details](#variable-details) |
53
75
  | `DSH_PODMAN_IMAGE_PREFIX` | `localhost/dsh-podman/` | Prefix prepended to built workspace image references |
54
76
  | `DSH_PODMAN_ORCHESTRATOR_PODMAN_SOCKET` | required | Podman API socket, e.g. `unix:///run/podman/podman.sock` |
55
- | `DSH_PODMAN_ORCHESTRATOR_STATE` | `/var/lib/dsh-orchestrator` | Persisted state directory |
77
+ | `DSH_PODMAN_ORCHESTRATOR_STATE` | required | Persisted state directory; see [Variable details](#variable-details) |
56
78
  | `DSH_PODMAN_ORCHESTRATOR_TOKEN` | — | Shared secret authenticating control-plane gRPC calls; see [Variable details](#variable-details) |
57
79
  | `DSH_PODMAN_PROJECTS_ROOT` | `/projects` | Project root inside every guest container |
58
80
  | `DSH_PODMAN_SECRET_PREFIX` | `dsh-podman-` | Prefix applied to managed podman secrets (see [Usage](usage.md#secrets)) |
@@ -94,8 +116,7 @@ binary. Setting it bind-mounts that binary read-only to the same in-container
94
116
  path instead of mounting the guest-agent image; it is an optional development
95
117
  fallback and takes precedence over the image mount. It is unset by default.
96
118
 
97
- If neither variable is configured, the guest container has no guest agent to
98
- run, and creating a workspace container fails.
119
+ If neither variable is configured, the orchestrator refuses to start.
99
120
 
100
121
  ### `DSH_PODMAN_GUEST_AGENT_IMAGE`, `DSH_PODMAN_GUEST_AGENT_IMAGE_AGENT_BIN`, `DSH_PODMAN_GUEST_AGENT_IMAGE_MOUNT` and `DSH_PODMAN_GUEST_AGENT_IMAGE_USE_VERSION_TAG`
101
122
 
@@ -118,6 +139,12 @@ orchestrator uses its own git version as the image tag instead of the one in
118
139
  digest reference cannot be overridden, the orchestrator fails to start when that
119
140
  variable is set alongside a digest-style `DSH_PODMAN_GUEST_AGENT_IMAGE`.
120
141
 
142
+ A container whose agent was created from a different guest-agent image than the
143
+ one currently configured is recreated the next time it is used, so upgrading the
144
+ orchestrator takes effect without recreating containers by hand. The image is
145
+ pulled only when it is absent, so a locally built development image is never
146
+ pulled over.
147
+
121
148
  ### `DSH_PODMAN_GUEST_TOKEN`
122
149
 
123
150
  Shared secret required on every guest-agent gRPC call, carried as the gRPC
@@ -137,12 +164,26 @@ orchestrator has no token set, it accepts unauthenticated control-plane calls
137
164
  (relying on the socket's file permissions instead); when a token is set,
138
165
  requests without the matching header are rejected with `Unauthenticated`.
139
166
 
167
+ ### `DSH_PODMAN_ORCHESTRATOR_STATE`
168
+
169
+ The directory the orchestrator persists its state in (workspaces, containers,
170
+ and image records). It is required, and must be an absolute path to a directory
171
+ bind-mounted into the orchestrator so the state survives a container restart:
172
+ only the deployment knows where that is. The shipped Quadlet mounts
173
+ `%h/.dsh/dsh-podman/state`. The orchestrator creates the directory if needed and
174
+ refuses to start without the variable.
175
+
140
176
  ### `DSH_PODMAN_SOCKETS_ROOT` and `DSH_PODMAN_HOST_SOCKETS_ROOT`
141
177
 
142
178
  `DSH_PODMAN_SOCKETS_ROOT` is the socket root directory shared by the
143
179
  orchestrator and the guest containers. It holds the orchestrator control socket
144
180
  (`orchestrator.sock`) and one subdirectory per workspace, where each guest agent
145
- creates its `guest.sock`.
181
+ creates its `guest.sock`. It keeps its `/run/dsh-podman` default.
182
+
183
+ `DSH_PODMAN_HOST_SOCKETS_ROOT` is required: it is the same directory as it
184
+ appears on the host, and it cannot be derived from the container path — the
185
+ shipped Quadlet mounts `%t/dsh-podman` at `/run/dsh-podman`. The orchestrator
186
+ refuses to start without it.
146
187
 
147
188
  The directory needs to be bind-mounted in the orchestrator container. Its mode
148
189
  must be `0700`: the orchestrator refuses to start when the socket root is group-
@@ -8,32 +8,50 @@ SPDX-License-Identifier: MIT
8
8
 
9
9
  环境变量使用 `DSH_PODMAN_`
10
10
  前缀,并按读取它们的组件分组列出(被多个组件读取的变量会出现在每个组件的对应章节中)。插件还在
11
- dsh 的 **设置 → 插件** 卡片中暴露了一些 **UI 设置**,与环境变量分开列出。
11
+ 侧边栏 **插件** 面板 → **已安装** 中的 **dsh-podman** 页面中暴露了一些 **UI
12
+ 设置**,与环境变量分开列出。
12
13
 
13
14
  插件按以下顺序读取其配置:先是 cordis 中的插件
14
15
  `config`,然后是下方列出的环境变量,最后是内置默认值。
15
16
 
16
17
  ## 插件(dsh 客户端)— 环境变量
17
18
 
18
- | 变量 | 默认值 | 说明 |
19
- | ------------------------------- | ----------------------- | ------------------------------------------------------------------------- |
20
- | `DSH_PODMAN_IMAGE_PREFIX` | `localhost/dsh-podman/` | 前置到工作区镜像引用上的前缀 |
21
- | `DSH_PODMAN_ORCHESTRATOR_TOKEN` | — | 用于认证控制平面 gRPC 调用的共享机密;见[变量详解](#变量详解) |
22
- | `DSH_PODMAN_PROJECTS_ROOT` | `/projects` | 用于将会话工作目录解析为工作区的项目根目录 |
23
- | `DSH_PODMAN_SOCKETS_ROOT` | `/run/dsh-podman` | 插件据此推导 orchestrator 控制套接字(`orchestrator.sock`)的套接字根目录 |
19
+ | 变量 | 默认值 | 说明 |
20
+ | ------------------------------- | ----------------- | ------------------------------------------------------------------------- |
21
+ | `DSH_PODMAN_ORCHESTRATOR_TOKEN` | — | 用于认证控制平面 gRPC 调用的共享机密;见[变量详解](#变量详解) |
22
+ | `DSH_PODMAN_PROJECTS_ROOT` | `/projects` | 用于将会话工作目录解析为工作区的项目根目录 |
23
+ | `DSH_PODMAN_SOCKETS_ROOT` | `/run/dsh-podman` | 插件据此推导 orchestrator 控制套接字(`orchestrator.sock`)的套接字根目录 |
24
24
 
25
- `projectsRoot` 和 `imagePrefix` 仅来自环境变量,以确保与 orchestrator
25
+ `projectsRoot` 与 `socketsRoot` 仅来自环境变量,以确保与 orchestrator
26
26
  一致;`controlToken` 来自插件 `config` 或 `DSH_PODMAN_ORCHESTRATOR_TOKEN`。
27
27
 
28
28
  ## 插件(dsh 客户端)— UI 设置
29
29
 
30
- 可在卡片中的 **设置 → 插件 → Podman** 面板内编辑(配置部分和镜像的 Set-default
31
- 弹窗):
30
+ 可在侧边栏 **插件** 面板 → **已安装** 的 **dsh-podman** 页面内编辑(镜像的
31
+ Set-default 弹窗和**默认环境变量**区块):
32
32
 
33
- | 设置 | 默认值 | 说明 |
34
- | -------------- | ------------------------- | --------------------------------------------------------------------------------- |
35
- | `defaultImage` | `archlinux` | 用于新工作区的镜像**短名称**;可通过 Set-default 弹窗从基础镜像和自定义镜像中选择 |
36
- | `socketsRoot` | `DSH_PODMAN_SOCKETS_ROOT` | 插件用于连接 orchestrator 的套接字根目录;回退到环境变量 |
33
+ | 设置 | 默认值 | 说明 |
34
+ | -------------- | ----------- | -------------------------------------------------------------------------------------------------------------------- |
35
+ | `defaultImage` | `archlinux` | 用于新工作区的镜像**短名称**;可通过 Set-default 弹窗从基础镜像和自定义镜像中选择 |
36
+ | `uiLocale` | `""` | 插件管理的当前语言,由浏览器客户端写入,以便主机以会话语言呈现审批文本(见[审批](usage.zh.md#审批));不可由用户编辑 |
37
+ | `containerEnv` | `{}` | 容器创建时注入的默认环境变量;见[默认环境变量](#默认环境变量) |
38
+
39
+ ### 默认环境变量
40
+
41
+ `containerEnv`
42
+ 是一个在容器创建时注入的环境变量映射:新工作区的默认容器与每个命名容器都会收到它。容器自身的
43
+ `env`
44
+ 按变量逐个优先,而重建容器时会完全采用传入的环境变量,因此在容器的环境变量里删除某一项并重建该容器,即可彻底移除它。
45
+
46
+ Podman
47
+ 页面中的**默认环境变量**区块使用与容器相同的键/值行进行编辑:增删变量后点击**保存**(或**放弃**)。**Git
48
+ 身份**用一份姓名与邮箱填入
49
+ `GIT_AUTHOR_NAME`、`GIT_AUTHOR_EMAIL`、`GIT_COMMITTER_NAME` 与
50
+ `GIT_COMMITTER_EMAIL`;**应用默认环境变量**会把缺少的变量补给尚未具备它们的运行中容器,只重建这些容器,且绝不覆盖已有值;已停止的容器留待下次启动。每个工作区行也提供同样的操作,只作用于该工作区。保留的
51
+ `DSH_PODMAN*` 键会被忽略,且这些值并非机密——机密请使用
52
+ `secretEnv`(见[机密](usage.zh.md#机密))。
53
+
54
+ ## Orchestrator(`dsh-podman-orchestrator`)
37
55
 
38
56
  | 变量 | 默认值 | 说明 |
39
57
  | ---------------------------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -47,10 +65,10 @@ dsh 的 **设置 → 插件** 卡片中暴露了一些 **UI 设置**,与环境
47
65
  | `DSH_PODMAN_HOST_GUEST_AGENT_BIN` | — | 主机侧的 guest agent 二进制路径;设置后会绑定挂载;见[变量详解](#变量详解) |
48
66
  | `DSH_PODMAN_HOST_PACMAN_CACHE` | — | 挂载在 `/var/cache/pacman/pkg` 的主机绝对路径目录,用于在 pacman 构建之间持久化已下载的软件包;未设置时禁用缓存 |
49
67
  | `DSH_PODMAN_HOST_PROJECTS_ROOT` | `DSH_PODMAN_PROJECTS_ROOT` | 用作绑定挂载源的主机侧项目根目录 |
50
- | `DSH_PODMAN_HOST_SOCKETS_ROOT` | `DSH_PODMAN_SOCKETS_ROOT` | 用于 guest 套接字绑定挂载的主机侧套接字根目录 |
68
+ | `DSH_PODMAN_HOST_SOCKETS_ROOT` | required | 用于 guest 套接字绑定挂载的主机侧套接字根目录;见[变量详解](#变量详解) |
51
69
  | `DSH_PODMAN_IMAGE_PREFIX` | `localhost/dsh-podman/` | 前置到已构建的工作区镜像引用上的前缀 |
52
70
  | `DSH_PODMAN_ORCHESTRATOR_PODMAN_SOCKET` | required | Podman API 套接字,例如 `unix:///run/podman/podman.sock` |
53
- | `DSH_PODMAN_ORCHESTRATOR_STATE` | `/var/lib/dsh-orchestrator` | 持久化状态目录 |
71
+ | `DSH_PODMAN_ORCHESTRATOR_STATE` | required | 持久化状态目录;见[变量详解](#变量详解) |
54
72
  | `DSH_PODMAN_ORCHESTRATOR_TOKEN` | — | 用于认证控制平面 gRPC 调用的共享机密;见[变量详解](#变量详解) |
55
73
  | `DSH_PODMAN_PROJECTS_ROOT` | `/projects` | 每个 guest 容器内的项目根目录 |
56
74
  | `DSH_PODMAN_SECRET_PREFIX` | `dsh-podman-` | 应用于受管 podman 机密的前缀(见[使用](usage.zh.md#机密)) |
@@ -89,8 +107,7 @@ orchestrator
89
107
  二进制在_主机上_的路径。设置它会将该二进制以只读方式绑定挂载到容器内相同路径,而不是挂载
90
108
  guest-agent 镜像;这是一个可选的开发回退方案,优先于镜像挂载。默认情况下未设置。
91
109
 
92
- 如果两个变量都未配置,guest 容器将没有可运行的 guest
93
- agent,创建工作区容器将会失败。
110
+ 如果两个变量都未配置,orchestrator 将拒绝启动。
94
111
 
95
112
  ### `DSH_PODMAN_GUEST_AGENT_IMAGE`, `DSH_PODMAN_GUEST_AGENT_IMAGE_AGENT_BIN`, `DSH_PODMAN_GUEST_AGENT_IMAGE_MOUNT` and `DSH_PODMAN_GUEST_AGENT_IMAGE_USE_VERSION_TAG`
96
113
 
@@ -111,6 +128,10 @@ guest-agent 镜像在容器创建时提供 agent:orchestrator 使用 podman
111
128
  中的标签(该标签可以完全省略)。由于摘要引用无法被覆盖,当该变量与摘要式的
112
129
  `DSH_PODMAN_GUEST_AGENT_IMAGE` 一起设置时,orchestrator 将无法启动。
113
130
 
131
+ 如果容器的 agent 来自与当前配置不同的 guest-agent
132
+ 镜像,该容器会在下次被使用时被重新创建,因此升级 orchestrator
133
+ 后无需手动重建容器即可生效。只有在镜像不存在时才会拉取,因此本地构建的开发镜像绝不会被拉取覆盖。
134
+
114
135
  ### `DSH_PODMAN_GUEST_TOKEN`
115
136
 
116
137
  每次 guest-agent gRPC 调用所需的共享机密,以 gRPC 元数据头
@@ -126,12 +147,25 @@ orchestrator 和插件必须约定的任意共享机密字符串;每个控制
126
147
  未设置令牌时,它接受未经认证的控制平面调用(转而依赖套接字的文件权限);当设置了令牌时,不带匹配头的请求会被以
127
148
  `Unauthenticated` 拒绝。
128
149
 
150
+ ### `DSH_PODMAN_ORCHESTRATOR_STATE`
151
+
152
+ orchestrator
153
+ 持久化其状态(工作区、容器和镜像记录)的目录。该变量为必填,且必须是绑定挂载到
154
+ orchestrator
155
+ 的目录的绝对路径,以便状态在容器重启后仍然保留——只有部署方知道该路径。随附的
156
+ Quadlet 会挂载 `%h/.dsh/dsh-podman/state`。orchestrator
157
+ 会在需要时创建该目录,缺少该变量时拒绝启动。
158
+
129
159
  ### `DSH_PODMAN_SOCKETS_ROOT` and `DSH_PODMAN_HOST_SOCKETS_ROOT`
130
160
 
131
161
  `DSH_PODMAN_SOCKETS_ROOT` 是 orchestrator 与 guest
132
162
  容器共享的套接字根目录。它包含 orchestrator
133
163
  控制套接字(`orchestrator.sock`)和每个工作区的一个子目录,每个 guest agent
134
- 在其中创建自己的 `guest.sock`。
164
+ 在其中创建自己的 `guest.sock`。它保留 `/run/dsh-podman` 默认值。
165
+
166
+ `DSH_PODMAN_HOST_SOCKETS_ROOT`
167
+ 为必填:它是同一目录在主机上的路径,无法从容器路径推导——随附的 Quadlet 将
168
+ `%t/dsh-podman` 挂载到 `/run/dsh-podman`。缺少该变量时 orchestrator 拒绝启动。
135
169
 
136
170
  该目录需要绑定挂载到 orchestrator 容器中。其权限模式必须是
137
171
  `0700`:当套接字根目录对组或其他用户可访问时,orchestrator
@@ -0,0 +1,72 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 Elouan Martinet <exa@elou.world>
3
+
4
+ SPDX-License-Identifier: MIT
5
+ -->
6
+
7
+ # Development container setup prompt
8
+
9
+ This page carries the prompt that builds a development image, creates the
10
+ toolchain volume and wires the workspace container to it, as described in
11
+ [Development](development.md#development-container-toolchain). Nothing it needs
12
+ exists beforehand.
13
+
14
+ Paste the block below into a dsh session attached to the workspace. It is safe
15
+ to run again: it inspects the workspace first and only creates, mounts or
16
+ changes what is missing or different. Recreating a container stops its daemons
17
+ and clears its tmpfs, so expect that whenever a change is needed.
18
+
19
+ Two steps stay manual on the host, and the prompt asks for them instead of
20
+ attempting them:
21
+
22
+ - rebuilding the dsh, orchestrator and guest-agent images (`make image`), which
23
+ needs the repository checkout and podman on the host;
24
+ - installing or editing the Quadlet units under `~/.config/containers/systemd/`,
25
+ then `systemctl --user daemon-reload` and a restart (see
26
+ [Install development builds](development.md#install-development-builds)).
27
+
28
+ ```text
29
+ Set up a development environment for this dsh-podman workspace. It must be safe
30
+ to run again: inspect the current state first, and only create, mount or change
31
+ what is missing or different, keeping whatever is already configured. Use the
32
+ container tools; never run `make` or edit files on the host.
33
+
34
+ 1. Image: build a custom image named `dsh-podman-tooling` from the `archlinux`
35
+ base with packages `go`, `nodejs-lts-jod`, `npm`, `deno`, `reuse` and
36
+ `python-chardet`, unless an image of that name already exists in this
37
+ workspace. It is a local image, not a published one; leave an existing one
38
+ alone.
39
+ 2. Volume: create the workspace volume `dsh-podman-toolchain` unless it already
40
+ exists.
41
+ 3. Container: inspect the default container's image, mounts, PATH additions and
42
+ environment. Recreate it once, only if something below is missing or
43
+ different, passing the complete merged sets so nothing existing is dropped:
44
+ - image `dsh-podman-tooling`;
45
+ - `dsh-podman-toolchain` mounted at `/opt/toolchain`, read-write, plus the
46
+ workspace project mount and every mount already there;
47
+ - PATH additions `/opt/toolchain/gopath/bin`,
48
+ `/opt/toolchain/npm-global/bin` and `/opt/toolchain/pnpm-home`, in
49
+ addition to the ones already there;
50
+ - environment `GOCACHE=/opt/toolchain/gocache`,
51
+ `GOMODCACHE=/opt/toolchain/gomodcache`, `GOPATH=/opt/toolchain/gopath`,
52
+ `npm_config_cache=/opt/toolchain/npm-cache`,
53
+ `npm_config_prefix=/opt/toolchain/npm-global`,
54
+ `PNPM_HOME=/opt/toolchain/pnpm-home`,
55
+ `DENO_DIR=/opt/toolchain/deno-dir` and
56
+ `GOENV=/opt/toolchain/home/.config/go/env`, merged with the variables
57
+ already on the container.
58
+ 4. pnpm: the volume, not the image, carries pnpm. If `pnpm --version` does not
59
+ report the version `package.json` pins in `packageManager`, install it with
60
+ `npm install -g pnpm@<that version>` and check again.
61
+ 5. Git identity: do not write a `~/.gitconfig`. If no Git identity is
62
+ configured, tell me to set it once on the Podman page (sidebar **Plugins**
63
+ panel → **Installed** → **dsh-podman**): **Default
64
+ environment → Git identity**.
65
+ 6. Verify from inside the container, without sourcing anything: `make build`,
66
+ `make vet` and `pnpm test` must succeed in the repository.
67
+ 7. Report what you created or changed, or that everything was already in place.
68
+ If a step needs the host — rebuilding the dsh, orchestrator or guest-agent
69
+ images (`make image`), or editing the Quadlet units under
70
+ `~/.config/containers/systemd/` and reloading systemd — stop and ask me
71
+ instead of trying it.
72
+ ```
@@ -0,0 +1,69 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 Elouan Martinet <exa@elou.world>
3
+
4
+ SPDX-License-Identifier: MIT
5
+ -->
6
+
7
+ # 开发容器设置提示词
8
+
9
+ 本页给出用于构建开发镜像、创建工具链卷并把工作区容器接好的提示词,参见[开发](development.zh.md#开发容器工具链)。其中没有任何东西是现成的。
10
+
11
+ 把下面的文本块粘贴到已接入该工作区的 dsh
12
+ 会话中。它可以反复运行:先检查工作区现状,只创建、挂载或修改缺失或不同的部分。重建容器会终止其守护进程并清空
13
+ tmpfs,因此在需要变更时请预期这一点。
14
+
15
+ 以下步骤仍需在宿主机上手动完成,提示词只会请求它们,而不会自行尝试:
16
+
17
+ - 重建 dsh、orchestrator 和 guest-agent
18
+ 镜像(`make image`),这需要宿主机上的仓库检出与 podman;
19
+ - 安装或编辑 `~/.config/containers/systemd/` 下的 Quadlet 单元,随后执行
20
+ `systemctl --user daemon-reload`
21
+ 并重启(见[安装开发构建](development.zh.md#安装开发构建))。
22
+
23
+ 下面的提示词与英文页保持一致,原样粘贴即可。
24
+
25
+ ```text
26
+ Set up a development environment for this dsh-podman workspace. It must be safe
27
+ to run again: inspect the current state first, and only create, mount or change
28
+ what is missing or different, keeping whatever is already configured. Use the
29
+ container tools; never run `make` or edit files on the host.
30
+
31
+ 1. Image: build a custom image named `dsh-podman-tooling` from the `archlinux`
32
+ base with packages `go`, `nodejs-lts-jod`, `npm`, `deno`, `reuse` and
33
+ `python-chardet`, unless an image of that name already exists in this
34
+ workspace. It is a local image, not a published one; leave an existing one
35
+ alone.
36
+ 2. Volume: create the workspace volume `dsh-podman-toolchain` unless it already
37
+ exists.
38
+ 3. Container: inspect the default container's image, mounts, PATH additions and
39
+ environment. Recreate it once, only if something below is missing or
40
+ different, passing the complete merged sets so nothing existing is dropped:
41
+ - image `dsh-podman-tooling`;
42
+ - `dsh-podman-toolchain` mounted at `/opt/toolchain`, read-write, plus the
43
+ workspace project mount and every mount already there;
44
+ - PATH additions `/opt/toolchain/gopath/bin`,
45
+ `/opt/toolchain/npm-global/bin` and `/opt/toolchain/pnpm-home`, in
46
+ addition to the ones already there;
47
+ - environment `GOCACHE=/opt/toolchain/gocache`,
48
+ `GOMODCACHE=/opt/toolchain/gomodcache`, `GOPATH=/opt/toolchain/gopath`,
49
+ `npm_config_cache=/opt/toolchain/npm-cache`,
50
+ `npm_config_prefix=/opt/toolchain/npm-global`,
51
+ `PNPM_HOME=/opt/toolchain/pnpm-home`,
52
+ `DENO_DIR=/opt/toolchain/deno-dir` and
53
+ `GOENV=/opt/toolchain/home/.config/go/env`, merged with the variables
54
+ already on the container.
55
+ 4. pnpm: the volume, not the image, carries pnpm. If `pnpm --version` does not
56
+ report the version `package.json` pins in `packageManager`, install it with
57
+ `npm install -g pnpm@<that version>` and check again.
58
+ 5. Git identity: do not write a `~/.gitconfig`. If no Git identity is
59
+ configured, tell me to set it once on the Podman page (sidebar **Plugins**
60
+ panel → **Installed** → **dsh-podman**): **Default
61
+ environment → Git identity**.
62
+ 6. Verify from inside the container, without sourcing anything: `make build`,
63
+ `make vet` and `pnpm test` must succeed in the repository.
64
+ 7. Report what you created or changed, or that everything was already in place.
65
+ If a step needs the host — rebuilding the dsh, orchestrator or guest-agent
66
+ images (`make image`), or editing the Quadlet units under
67
+ `~/.config/containers/systemd/` and reloading systemd — stop and ask me
68
+ instead of trying it.
69
+ ```
@@ -20,8 +20,8 @@ This page is for **contributors** building the plugin from this repository.
20
20
 
21
21
  ## Building
22
22
 
23
- Prerequisites: Go 1.27, Node ≥ 22, pnpm 12, and (for the browser half) the
24
- `@deepseek-ai/dsh-client-*` packages published on npm.
23
+ Prerequisites: Go 1.27, Node ≥ 22, pnpm 12, Deno ≥ 2.9 (formatting), and (for
24
+ the browser half) the `@deepseek-ai/dsh-client-*` packages published on npm.
25
25
 
26
26
  ```sh
27
27
  pnpm install
@@ -36,20 +36,22 @@ The `Makefile` wraps the common workflows:
36
36
  ```sh
37
37
  make build-go # build both Go binaries into bin/<os>-<arch>/
38
38
  make build # build-go + pnpm-build
39
- make vet # go vet with the build tags
39
+ make vet # gofmt -s check + go vet with the build tags
40
40
  make test-go # go test with the build tags
41
41
  make test # test-go + pnpm test (JS tests, which run against dist/)
42
- make download-licenses # generate LICENSE.pkg from the project and third-party Go licenses
43
- make image # build the orchestrator and guest-agent container images
42
+ make fmt # gofmt -s + deno fmt (TypeScript and Markdown)
43
+ make fmt-check # verify the formatting without rewriting anything
44
+ make download-licenses # generate third-party-licenses.pkg from the project and third-party Go licenses
45
+ make image # build the orchestrator, guest-agent and dsh container images
44
46
  ```
45
47
 
46
- `make image` depends on `LICENSE.pkg`: the `download-licenses` target runs the
47
- Go collector in `scripts/download-licenses`, which shells out to
48
+ `make image` depends on `third-party-licenses.pkg`: the `download-licenses`
49
+ target runs the Go collector in `scripts/download-licenses`, which shells out to
48
50
  `go-licenses save` and gathers the project's MIT license plus every third-party
49
- Go license and Apache `NOTICE` into `LICENSE.pkg`. That file is gitignored
50
- (never committed) and is baked into the orchestrator and guest-agent images at
51
- `/usr/share/licenses/dsh-podman/LICENSE`; because workspace containers mount the
52
- guest-agent image, it also rides along into every workspace container.
51
+ Go license and Apache `NOTICE` into `third-party-licenses.pkg`. That file is
52
+ gitignored (never committed) and is baked into the orchestrator and guest-agent
53
+ images at `/usr/share/licenses/dsh-podman/LICENSE`; because workspace containers
54
+ mount the guest-agent image, it also rides along into every workspace container.
53
55
 
54
56
  `pnpm test` runs `node --test dist/*.test.js`, so it requires `pnpm build` to
55
57
  have run first (the `test` target handles this).
@@ -66,6 +68,19 @@ The JS side loads the raw `.proto` files at runtime via `@grpc/proto-loader`
66
68
  (copied to `dist/grpc/proto/` at build time); no TypeScript bindings are
67
69
  generated. Optionally validate the schema with `buf lint` and `buf breaking`.
68
70
 
71
+ ## Naming
72
+
73
+ Proto field names are `lower_snake_case` (Buf's `BASIC` lint enforces it), and
74
+ the JS side reads them through proto-loader's camelCase projection, so
75
+ `secret_env` becomes `secretEnv` and `image_id` becomes `imageId`. Never spell a
76
+ proto field in its snake_case form in TypeScript: proto-loader ignores an
77
+ unknown property, so the value would be silently dropped.
78
+
79
+ Tool parameters are camelCase, except the ones that deliberately mirror the
80
+ harness's built-in tools (`file_path`, `old_string`, `new_string`,
81
+ `replace_all`). Settings are camelCase; the persisted TOML state uses snake_case
82
+ tags.
83
+
69
84
  ## Install development builds
70
85
 
71
86
  ### Build
@@ -75,17 +90,121 @@ make # builds plugin and go binaries
75
90
  make image # build images
76
91
  ```
77
92
 
78
- ### Recreate containers
93
+ ### Run the local images (Quadlet)
94
+
95
+ The shipped units pull the release images. Point them at the images built by
96
+ `make image` to run a local build as the real services; comment the original
97
+ line out so switching back is a one-line edit.
98
+
99
+ In `~/.config/containers/systemd/dsh.container`:
100
+
101
+ ```ini
102
+ #Image=ghcr.io/exagone313/dsh-podman/dsh:1
103
+ Image=localhost/dsh-podman-dsh:latest
104
+ Environment=DSH_PODMAN_PLUGIN_SOURCE=%h/project/dsh-podman
105
+ ```
106
+
107
+ The unit already mounts `%h/project` read-only, so a repository checked out
108
+ under `~/project` needs no extra `Volume=`. `npm pack` leaves the archive the
109
+ entrypoint installs next to `package.json` (see
110
+ [Install a local plugin build](#install-a-local-plugin-build)).
111
+
112
+ In `~/.config/containers/systemd/dsh-podman-orchestrator.container`:
113
+
114
+ ```ini
115
+ #Image=ghcr.io/exagone313/dsh-podman/orchestrator:1
116
+ Image=localhost/dsh-podman-orchestrator:latest
117
+ #Environment=DSH_PODMAN_GUEST_AGENT_IMAGE=ghcr.io/exagone313/dsh-podman/guest-agent
118
+ #Environment=DSH_PODMAN_GUEST_AGENT_IMAGE_USE_VERSION_TAG=true
119
+ Environment=DSH_PODMAN_GUEST_AGENT_IMAGE=localhost/dsh-podman-guest-agent:latest
120
+ ```
121
+
122
+ The release reference is version-tagged, so every release gets a distinct image
123
+ reference. The local build reuses a single `:latest` tag instead; the
124
+ orchestrator then cannot tell that the agent was rebuilt, which is what
125
+ [Update workspace containers](#update-workspace-containers) is about.
126
+
127
+ Reload systemd after editing the units:
79
128
 
80
129
  ```bash
130
+ systemctl --user daemon-reload
131
+ ```
132
+
133
+ ### Deploy a change
134
+
135
+ ```bash
136
+ make # Go binaries + the plugin bundle
137
+ make image # orchestrator, guest-agent and dsh images
138
+ npm pack # the plugin archive the dsh entrypoint installs
81
139
  systemctl --user restart dsh dsh-podman-orchestrator
82
140
  ```
83
141
 
142
+ The dsh image installs the plugin at container start, so restarting dsh is what
143
+ reinstalls the freshly packed archive; restarting the orchestrator picks up the
144
+ new orchestrator and guest-agent images.
145
+
146
+ ### Update workspace containers
147
+
148
+ The guest-agent image is mounted into each container when it is created, so a
149
+ running container keeps the agent it started with. The orchestrator recreates a
150
+ container by itself only when its guest-agent image reference differs from the
151
+ configured one — which happens with the version-tagged release reference, but
152
+ not with the local `:latest` tag. After rebuilding the guest agent, recreate the
153
+ containers yourself:
154
+
155
+ - from the Podman page (sidebar **Plugins** panel → **Installed** →
156
+ **dsh-podman**), per container: **Recreate** (same image) or **Recreate with
157
+ image**;
158
+ - with `container_recreate`, for a named container or the default one.
159
+
160
+ To rebuild a whole workspace instead, use **Remove pod** on its row (or
161
+ `RemoveWorkspace`): the pod and all its containers are removed, and the next
162
+ attach creates the pod and its default container again. Restarting the two
163
+ services never touches workspace containers, and neither action removes volumes,
164
+ secrets, or project data.
165
+
166
+ A container that still runs an agent from an older image makes dsh log
167
+ `rejected by server because of excess pings` for its guest socket. The message
168
+ is harmless (grpc-js backs off and reconnects) and disappears once the container
169
+ is recreated; the same message for `orchestrator.sock` means the orchestrator
170
+ service is still running the previous image.
171
+
172
+ ### Development container toolchain
173
+
174
+ A workspace container's root filesystem is read-only and disposable, so the
175
+ toolchain a contributor builds with needs a workspace volume. No development
176
+ image is distributed: build a custom one — the
177
+ [setup prompt](development-prompt.md) builds `dsh-podman-tooling` from the
178
+ `archlinux` base with `go`, `nodejs-lts-jod`, `npm`, `deno`, `reuse` and
179
+ `python-chardet` — and create a workspace volume for the state an image cannot
180
+ keep: the Go and npm caches, `gopath` with the `go install`ed tools, and pnpm,
181
+ which `package.json` pins to a version the Arch repositories do not carry.
182
+
183
+ The prompt mounts that volume as `dsh-podman-toolchain` at `/opt/toolchain`
184
+ (read-write) and points the container's caches at it, so commands work without
185
+ sourcing anything:
186
+
187
+ | Container setting | Value |
188
+ | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
189
+ | PATH additions | `/opt/toolchain/gopath/bin`, `/opt/toolchain/npm-global/bin`, `/opt/toolchain/pnpm-home` |
190
+ | Environment | `GOCACHE=/opt/toolchain/gocache`, `GOMODCACHE=/opt/toolchain/gomodcache`, `GOPATH=/opt/toolchain/gopath`, `npm_config_cache=/opt/toolchain/npm-cache`, `npm_config_prefix=/opt/toolchain/npm-global`, `PNPM_HOME=/opt/toolchain/pnpm-home`, `DENO_DIR=/opt/toolchain/deno-dir`, `GOENV=/opt/toolchain/home/.config/go/env` |
191
+
192
+ Set the commit identity once on the Podman page (sidebar **Plugins** panel →
193
+ **Installed** → **dsh-podman**) under
194
+ [Default environment](configuration.md#default-environment) → **Git identity**,
195
+ so containers get `GIT_AUTHOR_*`/`GIT_COMMITTER_*` without a `~/.gitconfig`.
196
+
197
+ The prompt applies all of this from inside dsh and can be pasted again to repair
198
+ a workspace. Podman stores managed volumes with `DSH_PODMAN_VOLUME_PREFIX`
199
+ prepended, so it lists the volume as `dsh-podman-dsh-podman-toolchain`.
200
+
84
201
  ### Install a local plugin build
85
202
 
86
203
  The dsh image installs the plugin itself at container start, so a development
87
- build is served by pointing that install at a bind-mounted package. Build the
88
- plugin and pack it:
204
+ build is served by pointing that install at a bind-mounted package. The Quadlet
205
+ setup above is the first form below, with the repository directory itself
206
+ (`%h/project/dsh-podman`) already visible through the unit's read-only
207
+ `%h/project` mount. Build the plugin and pack it:
89
208
 
90
209
  ```bash
91
210
  pnpm build
@@ -102,7 +221,7 @@ Environment=DSH_PODMAN_PLUGIN_SOURCE=/mnt/dsh-podman
102
221
 
103
222
  ```
104
223
  # or the archive itself
105
- Volume=/path/to/exagone313-dsh-podman-0.2.0-rc.3.tgz:/mnt/dsh-podman.tgz:ro
224
+ Volume=/path/to/exagone313-dsh-podman-x.y.z.tgz:/mnt/dsh-podman.tgz:ro
106
225
  Environment=DSH_PODMAN_PLUGIN_SOURCE=/mnt/dsh-podman.tgz
107
226
  ```
108
227
 
@@ -123,10 +242,11 @@ push runs only `release.yml`, which repeats the build, vet and tests itself:
123
242
 
124
243
  - **actions-lint** — zizmor scans the workflows for insecure practices.
125
244
  - **reuse** — REUSE license compliance.
126
- - **go** — build, vet, tests, and govulncheck (Go vulnerabilities). Unfixed
127
- findings don't fail the job; fixable ones do.
128
- - **js** — install, typecheck, build, tests, and `pnpm audit`.
129
- - **docs** — `deno fmt --check` on the Markdown.
245
+ - **go** — build, `gofmt -s` check, vet, tests, and govulncheck (Go
246
+ vulnerabilities). Unfixed findings don't fail the job; fixable ones do.
247
+ - **js** — TypeScript formatting check, install, typecheck, build, tests, and
248
+ `pnpm audit`.
249
+ - **docs** — Markdown formatting check (`deno fmt` via `make fmt-check-md`).
130
250
  - **images** — builds the orchestrator and guest-agent images (runs only after
131
251
  the test jobs pass); **dsh image** builds `Containerfile.dsh`.
132
252
  - **trivy** — filesystem vulnerability scan (unfixed ignored) and container
@@ -157,8 +277,8 @@ The tag must match `package.json`'s version — the workflow fails otherwise —
157
277
  bump both with the version script:
158
278
 
159
279
  ```sh
160
- pnpm bump-version 0.1.1 # add --dry-run to validate only
161
- git push origin master 0.1.1
280
+ pnpm bump-version x.y.z # add --dry-run to validate only
281
+ git push origin master x.y.z
162
282
  ```
163
283
 
164
284
  `scripts/bump-version.mjs` checks that the version is a semver release or