@h-ai/cli 1.0.0-beta.3 → 1.0.0-beta.5

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.en.md CHANGED
@@ -125,7 +125,7 @@ Configure `hai.json.deploy.provider.expose.https` or private environment overrid
125
125
 
126
126
  Default/custom middleware configuration preserves all effective settings for the same backend, including `publicEndpoint`, pool and operation log options absent from the form. Managed services replace connection selectors and credentials. Restore fields already lost from old parent JSON before rebuilding; see [middleware settings](../deploy/README.en.md#configure-only-the-middleware-the-application-needs).
127
127
 
128
- Node backends (Serv / SvelteKit SSR) reread the release `.env.runtime` on every start by default. Edit it, then run `docker restart <container>` or `podman restart <container>`; no image rebuild or extra override is needed. Existing deployments need one deployment with the new CLI. Removed settings do not survive through stale Compose injection. Managed connections in `middleware.env` retain precedence; private proxy identity and Node startup options remain deployment settings. Static Web, middleware, ports/mounts and Nginx limits keep their existing update flow. Back up manual edits and copy permanent changes into the source environment; the next backend deployment regenerates the file.
128
+ Node backends (Serv / SvelteKit SSR) reread the release `.env.runtime` on every start by default. Edit it, then run `docker restart <container>` or `podman restart <container>`; no image rebuild or extra override is needed. Existing deployments need one deployment with the new CLI. Removed settings do not survive through stale Compose injection. Managed connections in `middleware.env` retain precedence; private proxy identity and Node startup options remain deployment settings. Static Web, middleware, ports/mounts, and Nginx routes and limits keep their existing update flow. Gateway path, port or mount changes require a full deployment. Back up manual edits and copy permanent changes into the source environment; the next backend deployment regenerates the file.
129
129
 
130
130
  Image builds run at most two images concurrently by default; use `--concurrency 1` to reduce resource use. Dependency installation precedes source copies, and each side copies only its required source. Runtime images omit application declaration files, source maps and README files. Packaging validates and reuses middleware archives by image content ID and hashes application archives while copying. Delivery defaults to `.tar.gz`; explicit `--output release.tar` keeps an uncompressed archive. README is only outside the archive. Successful deployment removes its incoming upload/extraction, retains recovery configuration in releases, and keeps images in the container engine.
131
131
 
@@ -186,7 +186,7 @@ The [fullstack security configuration guide template](templates/apps/fullstack/d
186
186
 
187
187
  ### Feedback and offline analysis
188
188
 
189
- A new `hai create my-app --type fullstack --frontends web --defaults` includes feedback by default; API projects require `--features feedback`. Members and business operators can submit reports. Only business_operator sees the review menu and can read, process, reopen or export reports. Database, storage, reach and authentication dependencies are included. The generated app provides intake, paginated review and server contracts. Production uses shared DB and private S3. Notifications independently select disabled/console/reach; console defaults to metadata only. Select consoleContent: summary explicitly for summaries, or configure Reach providers and recipients for actual delivery.
189
+ A new `hai create my-app --type fullstack --frontends web --defaults` includes feedback by default; API projects also include it without additional options. Members and business operators can submit reports. Only `business_operator` sees the review menu and can read, process, reopen or export reports. Database, storage, reach and authentication dependencies are included. Fullstack provides intake, paginated review and server contracts; API projects provide the server contracts. Production uses shared DB and private S3. Notifications independently select `disabled`, `console` or `reach`; `console` defaults to `metadata` only. Select `consoleContent: summary` explicitly for summaries, or configure Reach providers and recipients for actual delivery.
190
190
 
191
191
  Register collectEvidence through feedback.init(config, { collectEvidence }) to await business text or archives. _feedback.yml includes businessCollectionTimeoutMs and webhookUrl/webhookSecret/webhookTimeoutMs. Webhook delivery retries durably and exposes status and administrator retry in details. Keep secrets in private server environment settings; see [feedback examples](../feedback/README.en.md).
192
192
 
package/README.ja.md CHANGED
@@ -125,7 +125,7 @@ admin・website・h5 作成時に crypto を選ぶと `_kit.yml` の transport
125
125
 
126
126
  既定/カスタム設定は同じバックエンドの全有効項目を保持し、フォームにない `publicEndpoint`、接続プール、操作ログも引き継ぎます。自前/クラウド構成は接続と認証を更新します。旧親 JSON から消えた項目は復元後に再梱包してください。[ミドルウェア設定](../deploy/README.ja.md#本当に必要なミドルウェアだけを設定する)を参照してください。
127
127
 
128
- Node バックエンド(Serv / SvelteKit SSR)は起動ごとに配布先の `.env.runtime` を既定で読み直します。編集後に `docker restart <コンテナー>` または `podman restart <コンテナー>` を実行し、イメージ再構築や追加 override は不要です。既存配置は新 CLI で一度デプロイしてください。削除した設定を旧 Compose 環境から復活させず、管理接続の `middleware.env` を優先します。私有プロキシ識別と Node 起動引数は配置設定のままです。静的 Web・ミドルウェア・ポート/マウント・Nginx 制限は従来手順で更新します。手動変更をバックアップし、継続する値は元の環境にも反映してください。次のバックエンド配置時に再生成されます。
128
+ Node バックエンド(Serv / SvelteKit SSR)は起動ごとに配布先の `.env.runtime` を既定で読み直します。編集後に `docker restart <コンテナー>` または `podman restart <コンテナー>` を実行し、イメージ再構築や追加 override は不要です。既存配置は新 CLI で一度デプロイしてください。削除した設定を旧 Compose 環境から復活させず、管理接続の `middleware.env` を優先します。私有プロキシ識別と Node 起動引数は配置設定のままです。静的 Web・ミドルウェア・ポート/マウント・Nginx の経路と制限は従来手順で更新します。ゲートウェイの経路、ポート、マウントの変更は全量デプロイを行います。手動変更をバックアップし、継続する値は元の環境にも反映してください。次のバックエンド配置時に再生成されます。
129
129
 
130
130
  イメージは既定で最大 2 件を並列構築し、`--concurrency 1` で資源使用量を抑えます。ソースの前に依存をインストールし、各端で必要なソースだけをコピーします。実行イメージからアプリの型宣言・source map・README を除去します。ミドルウェアのアーカイブはイメージ内容 ID で検証・再利用し、コピーと同時にハッシュを計算します。配布の既定は `.tar.gz`、明示的な `--output release.tar` は非圧縮です。README は外側だけに保持します。成功後に今回の incoming アップロードと展開先を削除し、release に復旧設定、エンジンにイメージを保持します。
131
131
 
@@ -188,7 +188,7 @@ fullstack 例はアプリ設定で `admin`、`audit_admin`、`config_admin`、`b
188
188
 
189
189
  feedback.init(config, { collectEvidence }) で業務の本文・ZIP を非同期収集できます。_feedback.yml は businessCollectionTimeoutMs と webhookUrl/webhookSecret/webhookTimeoutMs を提供します。Webhook は永続再試行と詳細画面での状態確認・再試行に対応し、秘密はサーバー非公開環境に保存します。[feedback の例](../feedback/README.ja.md) を参照してください。
190
190
 
191
- `hai create my-app --type fullstack --frontends web --defaults` は問題報告を既定で有効にし、API 工程では `--features feedback` を指定します。一般会員と業務操作員が報告でき、管理メニューの表示と閲覧・処理・再開・エクスポートは business_operator に限定します。DB・ストレージ・通知・認証の依存を補い、収集、ページ一覧とサーバーAPIを生成します。本番では共有 DB と非公開 S3 を使用します。通知は disabled/console/reach を独立に選び、console の既定は metadata のみです。要約は consoleContent: summary を明示し、実送信が必要な場合に Reach 通路と受信者を設定します。
191
+ `hai create my-app --type fullstack --frontends web --defaults` は問題報告を既定で有効にし、API 工程にも追加引数なしで feedback を含めます。一般会員と業務操作員が報告でき、管理メニューの表示と閲覧・処理・再開・エクスポートは `business_operator` に限定します。DB・ストレージ・通知・認証の依存を補い、Fullstack では収集、ページ一覧とサーバー API、API 工程ではサーバー API を生成します。本番では共有 DB と非公開 S3 を使用します。通知は `disabled`、`console`、`reach` を独立に選び、`console` の既定は `metadata` のみです。要約は `consoleContent: summary` を明示し、実送信が必要な場合に Reach 通路と受信者を設定します。
192
192
 
193
193
  `hai feedback summary <bundle.zip>`、`inspect`、`evidence --request-id <ID> --page 1 --page-size 20`、`view` で本番へ接続せず分析できます。表示はloopbackのみで待機し、Ctrl+Cで閉じます。
194
194
 
package/README.md CHANGED
@@ -125,7 +125,7 @@ CLI 消息支持中文、英文和日文,优先使用 `HAI_CORE_DEFAULTLOCALE`
125
125
 
126
126
  部署向导的默认/自定义模式保留同后端完整配置,包括未出现在表单中的 `publicEndpoint`、连接池及操作日志;自建或云开通只重新定稿连接与认证。旧版已保存的缺字段父 JSON 需先补回再打包,见[中间件配置说明](../deploy/README.md#按应用真正需要的中间件处理)。
127
127
 
128
- Node 后端(Serv / SvelteKit SSR)默认在每次启动时重读发布目录的 `.env.runtime`,修改后 `docker restart <容器名>` 或 `podman restart <容器名>` 即可,无需重建镜像或额外 override。旧部署先用新版 CLI 发布一次。删除的字段不会从旧 Compose 注入中复活;服务器托管连接的 `middleware.env` 保持原有更高优先级,私有代理标记和 Node 启动参数仍由部署装配管理。静态 Web、中间件、端口/挂载和 Nginx 限额不在该重载范围。手工修改需备份;下一次后端发布会从工程环境重新生成,需要长期保留的配置同步回源环境。
128
+ Node 后端(Serv / SvelteKit SSR)默认在每次启动时重读发布目录的 `.env.runtime`,修改后 `docker restart <容器名>` 或 `podman restart <容器名>` 即可,无需重建镜像或额外 override。旧部署先用新版 CLI 发布一次。删除的字段不会从旧 Compose 注入中复活;服务器托管连接的 `middleware.env` 保持原有更高优先级,私有代理标记和 Node 启动参数仍由部署装配管理。静态 Web、中间件、端口/挂载、Nginx 路由与限额不在该重载范围;改变网关路径、端口或挂载时使用全量部署。手工修改需备份;下一次后端发布会从工程环境重新生成,需要长期保留的配置同步回源环境。
129
129
 
130
130
  镜像默认最多并行两项,`--concurrency 1` 可降低资源占用。Dockerfile 在复制源码前安装依赖;前后端仅复制各自必要源码,复用安装层和驱动缓存。运行镜像移除应用自身的声明文件、源码映射和说明文件。打包按镜像内容 ID 复用并校验中间件归档,复制应用镜像时同时计算摘要。默认交付压缩为 `.tar.gz`,显式 `--output release.tar` 可保留未压缩格式;README 仅保留外层一份。成功部署后清理本次 incoming 上传和解包目录,release 保留恢复配置和状态,镜像由容器引擎保存。
131
131
 
@@ -186,7 +186,7 @@ fullstack 的逐项开关、默认值、启用前提与使用影响见[配置化
186
186
 
187
187
  ### 问题反馈与离线分析
188
188
 
189
- 使用 `hai create my-app --type fullstack --frontends web --defaults` 默认启用反馈;API 工程需显式选择 `--features feedback`。普通成员及业务操作员可提交反馈,business_operator 才显示管理菜单并能查看、处理、撤销和导出;自动补齐数据库、存储、触达与认证依赖。生成收集入口、分页管理页和服务端接口。生产使用共享 DB 和私有 S3;通知独立选择 disabled/console/reach,默认 console 只输出 metadata。需要摘要时显式设 consoleContent: summary,需要实际发送时再配置 Reach 通道与收件人。
189
+ 使用 `hai create my-app --type fullstack --frontends web --defaults` 默认启用反馈;API 工程也默认包含反馈,无需额外参数。普通成员及业务操作员可提交反馈,`business_operator` 才显示管理菜单并能查看、处理、撤销和导出;自动补齐数据库、存储、触达与认证依赖。Fullstack 生成收集入口、分页管理页和服务端接口;API 工程生成服务端接口。生产使用共享 DB 和私有 S3;通知独立选择 `disabled`、`console` 或 `reach`,默认 `console` 只输出 `metadata`。需要摘要时显式设 `consoleContent: summary`,需要实际发送时再配置 Reach 通道与收件人。
190
190
 
191
191
  业务扩展在 feedback.init(config, { collectEvidence }) 中 await 文本/ZIP 等材料;_feedback.yml 提供 businessCollectionTimeoutMs、webhookUrl/webhookSecret/webhookTimeoutMs。Webhook 独立持久重试,详情可查看状态并重试;密钥仅放服务端私有环境。见 [feedback 配置与示例](../feedback/README.md)。
192
192
 
@@ -22671,7 +22671,13 @@ var en_US_default = {
22671
22671
  deploy_projectNameOverrideRemoved: "Deployment identity comes from the root package.json.name; remove the obsolete projectName override.",
22672
22672
  deploy_requestAccessInvalid: "Invalid request access policy ({field}). Check fields, IP addresses, timezones and time windows. For a file reference, use readable YAML no larger than 1 MiB. Fix the configuration and create a new bundle.",
22673
22673
  deploy_httpsPortsInvalid: "HTTP and HTTPS ports must differ; Let\u2019s Encrypt HTTP-01 requires host port 80.",
22674
- deploy_httpsCertificateInvalid: "Invalid HTTPS certificate. Check readable PEM files, matching unencrypted private key, validity dates and domain, then repackage."
22674
+ deploy_httpsCertificateInvalid: "Invalid HTTPS certificate. Check readable PEM files, matching unencrypted private key, validity dates and domain, then repackage.",
22675
+ deploy_bundleRuntime: "Runtime configuration and activation:\nThis release record: {directory}/releases/{deploymentId}\nNode backends read the file mounted at /run/hai/.env.runtime. Incremental deployments may retain an older record; current alone does not identify it. Inspect Source with docker inspect --format '{{json .Mounts}}' <container>.\nFor ordinary backend settings: back up, edit that file, run docker restart <container> (or Podman), then verify health and affected business flows. HAI parents override children; managed connections in middleware.env take precedence.\nStatic Web/middleware settings injected by Compose env_file require container recreation. Ports, mounts, Nginx routes/limits and HTTPS layout require a new full deployment bundle. Changing the website base also requires rebuilding artifacts.\nCopy permanent edits back to the packaging source environment; the next release regenerates these files.",
22676
+ deploy_bundleHttpOnly: "HTTPS: disabled. This bundle exposes HTTP port {port}, contains no certificate attachment and will not request a certificate on the server.",
22677
+ deploy_bundleHttps: "HTTPS: enabled, https://{domain}:{port}; mode {mode}.\nServer certificate: {certificates}/fullchain.pem; private key: {certificates}/privkey.pem. Mounted read-only at /etc/nginx/tls/.\nEdit expose.https in HAI_DEPLOY_PROVIDER in the packaging environment .env.{environment}.local, or the unshadowed hai.json.deploy.provider.expose.https. Enable/disable, mode, domain or port changes require a new full bundle; editing .env.runtime and restarting does not issue a certificate for a new domain.",
22678
+ deploy_bundleAcme: "Persistent Certbot state: {state}; current certificate entry: {state}/live/{domain}. Packaging does not contact the CA; issuance runs during server deployment, followed by automatic renewal. Public port 80 and root /.well-known/acme-challenge/ must remain reachable independently of the business context path.",
22679
+ deploy_bundleAccounts: "Initial account variables (names and sources only; passwords omitted):\n{sources}\nApplications with matching bootstrap logic use HAI_CONFIG_ADMIN_PASSWORD to create the config_admin configuration administrator. HAI_ADMIN_DEFAULT_PASSWORD, HAI_AUDIT_ADMIN_PASSWORD and HAI_BUSINESS_OPERATOR_PASSWORD belong to the other template roles.\nFullstack creation generates independent initial passwords per environment. Packaging reads the selected environment and process overrides; server deployment does not generate new application account passwords. Startup creates missing configured accounts; changing variables does not reset existing passwords or restore old roles. Custom applications without this bootstrap follow their own implementation.",
22680
+ deploy_bundleDirectories: "Server directory guide (root {directory}):\nincoming/: uploaded archive and .contents extraction; this upload is removed after success, retained after failure or unknown execution for diagnosis.\nreleases/{deploymentId}/: runtime files and recovery records. images/ is not copied here; images live in the container engine and database/object data in volumes.\ncompose.json defines services; compose-entry.json, proxy-entry.json and compose-files combine full/incremental releases and proxy overrides.\n.env.runtime, middleware.env, middleware-runtime.env and runtime-env.mjs load application/middleware environments; web.conf is the proxy and request-access.yml the verified policy snapshot.\nmanifest.json, image-list, services, dependencies, layout, web-base-path, storage-routing and health-paths record artifacts and probes. apply.sh and resolve-*.sh apply and validate state; SHA256SUMS verifies delivery content.\nmanaged-* and state-backends describe bundle credential candidates and volume/backend bindings. Root managed-secrets.env holds long-lived server credentials; persistent-backends is the backend ledger. Back them up together with data volumes.\ncurrent is a text file containing the last locally successful server release ID. Inspect result-{deploymentId}.json stage/exitCode/recoveryStatus and steps-{deploymentId}.jsonl; a release directory alone does not prove success.\nActive containers and incremental composition may reference older releases. Check every active mount and compose-files before cleanup; retaining only current is insufficient."
22675
22681
  };
22676
22682
 
22677
22683
  // ../deploy/messages/ja-JP.json
@@ -22781,7 +22787,13 @@ var ja_JP_default = {
22781
22787
  deploy_projectNameOverrideRemoved: "\u30C7\u30D7\u30ED\u30A4\u8B58\u5225\u540D\u306F\u5DE5\u7A0B\u30EB\u30FC\u30C8\u306E package.json.name \u304B\u3089\u53D6\u5F97\u3057\u307E\u3059\u3002\u65E7 projectName \u4E0A\u66F8\u304D\u5F15\u6570\u3092\u524A\u9664\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
22782
22788
  deploy_requestAccessInvalid: "\u30EA\u30AF\u30A8\u30B9\u30C8\u30A2\u30AF\u30BB\u30B9\u8A2D\u5B9A\uFF08{field}\uFF09\u304C\u7121\u52B9\u3067\u3059\u3002\u30D5\u30A3\u30FC\u30EB\u30C9\u3001IP\u3001\u30BF\u30A4\u30E0\u30BE\u30FC\u30F3\u3001\u6642\u9593\u5E2F\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u30D5\u30A1\u30A4\u30EB\u306F\u8AAD\u307F\u53D6\u308A\u53EF\u80FD\u306A 1 MiB \u4EE5\u4E0B\u306E YAML \u3092\u6307\u5B9A\u3057\u3001\u4FEE\u6B63\u5F8C\u306B\u518D\u30D1\u30C3\u30B1\u30FC\u30B8\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
22783
22789
  deploy_httpsPortsInvalid: "HTTP \u3068 HTTPS \u306E\u30DD\u30FC\u30C8\u306F\u7570\u306A\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002Let\u2019s Encrypt HTTP-01 \u306B\u306F\u30DB\u30B9\u30C8\u306E\u30DD\u30FC\u30C8 80 \u304C\u5FC5\u8981\u3067\u3059\u3002",
22784
- deploy_httpsCertificateInvalid: "HTTPS \u8A3C\u660E\u66F8\u304C\u7121\u52B9\u3067\u3059\u3002PEM \u30D5\u30A1\u30A4\u30EB\u3001\u6697\u53F7\u5316\u3055\u308C\u3066\u3044\u306A\u3044\u79D8\u5BC6\u9375\u3068\u306E\u4E00\u81F4\u3001\u6709\u52B9\u671F\u9593\u3001\u30C9\u30E1\u30A4\u30F3\u3092\u78BA\u8A8D\u3057\u3001\u518D\u4F5C\u6210\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
22790
+ deploy_httpsCertificateInvalid: "HTTPS \u8A3C\u660E\u66F8\u304C\u7121\u52B9\u3067\u3059\u3002PEM \u30D5\u30A1\u30A4\u30EB\u3001\u6697\u53F7\u5316\u3055\u308C\u3066\u3044\u306A\u3044\u79D8\u5BC6\u9375\u3068\u306E\u4E00\u81F4\u3001\u6709\u52B9\u671F\u9593\u3001\u30C9\u30E1\u30A4\u30F3\u3092\u78BA\u8A8D\u3057\u3001\u518D\u4F5C\u6210\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
22791
+ deploy_bundleRuntime: "\u5B9F\u884C\u8A2D\u5B9A\u306E\u5909\u66F4\u3068\u53CD\u6620\uFF1A\n\u4ECA\u56DE\u306E\u914D\u5099\u8A18\u9332\uFF1A{directory}/releases/{deploymentId}\nNode \u30D0\u30C3\u30AF\u30A8\u30F3\u30C9\u306F /run/hai/.env.runtime \u306B\u5B9F\u969B\u306B\u30DE\u30A6\u30F3\u30C8\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u3092\u8AAD\u307F\u307E\u3059\u3002\u5DEE\u5206\u914D\u5099\u3067\u306F\u53E4\u3044\u8A18\u9332\u3092\u53C2\u7167\u3059\u308B\u305F\u3081 current \u3060\u3051\u3067\u306F\u5224\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002docker inspect --format '{{json .Mounts}}' <\u30B3\u30F3\u30C6\u30CA\u540D> \u306E Source \u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n\u901A\u5E38\u306E\u30D0\u30C3\u30AF\u30A8\u30F3\u30C9\u8A2D\u5B9A\u306F\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u5F8C\u306B\u7DE8\u96C6\u3057\u3001docker restart <\u30B3\u30F3\u30C6\u30CA\u540D>\uFF08Podman \u3082\u540C\u69D8\uFF09\u3067\u53CD\u6620\u3057\u3066\u30D8\u30EB\u30B9\u3068\u696D\u52D9\u3092\u78BA\u8A8D\u3057\u307E\u3059\u3002HAI \u89AA\u8A2D\u5B9A\u3068 middleware.env \u306E\u7BA1\u7406\u63A5\u7D9A\u304C\u512A\u5148\u3057\u307E\u3059\u3002\nCompose env_file \u306E\u9759\u7684 Web\u30FB\u30DF\u30C9\u30EB\u30A6\u30A7\u30A2\u8A2D\u5B9A\u306F\u30B3\u30F3\u30C6\u30CA\u518D\u4F5C\u6210\u3001\u30DD\u30FC\u30C8\u30FB\u30DE\u30A6\u30F3\u30C8\u30FBNginx \u7D4C\u8DEF/\u4E0A\u9650\u30FBHTTPS \u69CB\u6210\u306F\u65B0\u3057\u3044\u5168\u91CF\u914D\u5099\u304C\u5FC5\u8981\u3067\u3059\u3002\u30B5\u30A4\u30C8 base \u306E\u5909\u66F4\u306F\u5236\u54C1\u3082\u518D\u69CB\u7BC9\u3057\u307E\u3059\u3002\n\u6052\u4E45\u7684\u306A\u5909\u66F4\u306F\u5143\u306E\u74B0\u5883\u3078\u623B\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u6B21\u56DE\u914D\u5099\u3067\u30D5\u30A1\u30A4\u30EB\u304C\u518D\u751F\u6210\u3055\u308C\u307E\u3059\u3002",
22792
+ deploy_bundleHttpOnly: "HTTPS\uFF1A\u7121\u52B9\u3002HTTP \u30DD\u30FC\u30C8 {port} \u306E\u307F\u3092\u516C\u958B\u3057\u3001\u8A3C\u660E\u66F8\u306F\u540C\u68B1\u305B\u305A\u3001\u30B5\u30FC\u30D0\u30FC\u3067\u3082\u7533\u8ACB\u3057\u307E\u305B\u3093\u3002",
22793
+ deploy_bundleHttps: "HTTPS\uFF1A\u6709\u52B9\u3001https://{domain}:{port}\u3001\u30E2\u30FC\u30C9 {mode}\u3002\n\u30B5\u30FC\u30D0\u30FC\u8A3C\u660E\u66F8\uFF1A{certificates}/fullchain.pem\u3001\u79D8\u5BC6\u9375\uFF1A{certificates}/privkey.pem\u3002\u30B3\u30F3\u30C6\u30CA\u306E /etc/nginx/tls/ \u306B\u8AAD\u307F\u53D6\u308A\u5C02\u7528\u3067\u30DE\u30A6\u30F3\u30C8\u3057\u307E\u3059\u3002\n\u914D\u5E03\u5143 .env.{environment}.local \u306E HAI_DEPLOY_PROVIDER \u5185 expose.https\u3001\u307E\u305F\u306F\u4E0A\u66F8\u304D\u3055\u308C\u3066\u3044\u306A\u3044 hai.json.deploy.provider.expose.https \u3092\u7DE8\u96C6\u3057\u307E\u3059\u3002\u6709\u52B9/\u7121\u52B9\u3001\u30E2\u30FC\u30C9\u3001\u30C9\u30E1\u30A4\u30F3\u3001\u30DD\u30FC\u30C8\u5909\u66F4\u306F\u65B0\u3057\u3044\u5168\u91CF\u914D\u5099\u304C\u5FC5\u8981\u3067\u3059\u3002.env.runtime \u306E\u7DE8\u96C6\u3068\u518D\u8D77\u52D5\u3067\u306F\u65B0\u30C9\u30E1\u30A4\u30F3\u306E\u8A3C\u660E\u66F8\u3092\u7533\u8ACB\u3057\u307E\u305B\u3093\u3002",
22794
+ deploy_bundleAcme: "Certbot \u6C38\u7D9A\u72B6\u614B\uFF1A{state}\u3001\u73FE\u5728\u306E\u8A3C\u660E\u66F8\u5165\u53E3\uFF1A{state}/live/{domain}\u3002\u30D1\u30C3\u30B1\u30FC\u30B8\u6642\u306F CA \u306B\u63A5\u7D9A\u305B\u305A\u3001\u30B5\u30FC\u30D0\u30FC\u914D\u5099\u6642\u306B\u7533\u8ACB\u3057\u3001\u305D\u306E\u5F8C\u81EA\u52D5\u66F4\u65B0\u3057\u307E\u3059\u3002\u516C\u958B\u30DD\u30FC\u30C8 80 \u3068\u30EB\u30FC\u30C8 /.well-known/acme-challenge/ \u306F\u696D\u52D9 context path \u3068\u5225\u306B\u5230\u9054\u53EF\u80FD\u306B\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
22795
+ deploy_bundleAccounts: "\u521D\u671F\u30A2\u30AB\u30A6\u30F3\u30C8\u5909\u6570\uFF08\u540D\u524D\u3068\u53D6\u5F97\u5143\u306E\u307F\u3001\u30D1\u30B9\u30EF\u30FC\u30C9\u975E\u8868\u793A\uFF09\uFF1A\n{sources}\n\u5BFE\u5FDC\u3059\u308B\u521D\u671F\u5316\u3092\u6301\u3064\u30A2\u30D7\u30EA\u3067\u306F HAI_CONFIG_ADMIN_PASSWORD \u304C config_admin \u8A2D\u5B9A\u7BA1\u7406\u8005\u3092\u4F5C\u6210\u3057\u307E\u3059\u3002HAI_ADMIN_DEFAULT_PASSWORD\u3001HAI_AUDIT_ADMIN_PASSWORD\u3001HAI_BUSINESS_OPERATOR_PASSWORD \u306F\u4ED6\u306E\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u5F79\u5272\u306B\u5BFE\u5FDC\u3057\u307E\u3059\u3002\nFullstack \u4F5C\u6210\u6642\u306B\u74B0\u5883\u3054\u3068\u306E\u72EC\u7ACB\u521D\u671F\u30D1\u30B9\u30EF\u30FC\u30C9\u3092\u751F\u6210\u3057\u3001\u914D\u5E03\u6642\u306F\u9078\u629E\u74B0\u5883\u3068\u30D7\u30ED\u30BB\u30B9\u4E0A\u66F8\u304D\u3092\u8AAD\u307F\u307E\u3059\u3002\u30B5\u30FC\u30D0\u30FC\u914D\u5099\u3067\u65B0\u305F\u306B\u751F\u6210\u3057\u307E\u305B\u3093\u3002\u8A2D\u5B9A\u304C\u3042\u308B\u672A\u4F5C\u6210\u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u8D77\u52D5\u6642\u306B\u4F5C\u308A\u3001\u65E2\u5B58\u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u3084\u5909\u66F4\u5F8C\u306E\u5F79\u5272\u306F\u5909\u6570\u5909\u66F4\u3067\u623B\u3057\u307E\u305B\u3093\u3002\u72EC\u81EA\u30A2\u30D7\u30EA\u306F\u5B9F\u88C5\u306B\u5F93\u3044\u307E\u3059\u3002",
22796
+ deploy_bundleDirectories: "\u30B5\u30FC\u30D0\u30FC\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\uFF08\u30EB\u30FC\u30C8 {directory}\uFF09\uFF1A\nincoming/\uFF1A\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3068 .contents \u5C55\u958B\u5148\u3002\u6210\u529F\u6642\u306B\u4ECA\u56DE\u5206\u3092\u524A\u9664\u3057\u3001\u5931\u6557\u30FB\u5B9F\u884C\u4E0D\u660E\u6642\u306F\u8ABF\u67FB\u7528\u306B\u4FDD\u6301\u3057\u307E\u3059\u3002\nreleases/{deploymentId}/\uFF1A\u5B9F\u884C\u30D5\u30A1\u30A4\u30EB\u3068\u5FA9\u65E7\u8A18\u9332\u3002images/ \u306F\u30B3\u30D4\u30FC\u305B\u305A\u30A4\u30E1\u30FC\u30B8\u306F\u30B3\u30F3\u30C6\u30CA\u30A8\u30F3\u30B8\u30F3\u3001DB\u30FB\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u30C7\u30FC\u30BF\u306F\u30DC\u30EA\u30E5\u30FC\u30E0\u306B\u4FDD\u5B58\u3057\u307E\u3059\u3002\ncompose.json \u306F\u30B5\u30FC\u30D3\u30B9\u5B9A\u7FA9\u3001compose-entry.json\u30FBproxy-entry.json\u30FBcompose-files \u306F\u5168\u91CF/\u5DEE\u5206\u3068\u30D7\u30ED\u30AD\u30B7\u4E0A\u66F8\u304D\u306E\u7D44\u5408\u305B\u3067\u3059\u3002\n.env.runtime\u30FBmiddleware.env\u30FBmiddleware-runtime.env\u30FBruntime-env.mjs \u306F\u74B0\u5883\u3001web.conf \u306F\u30D7\u30ED\u30AD\u30B7\u3001request-access.yml \u306F\u691C\u8A3C\u6E08\u307F\u30DD\u30EA\u30B7\u30FC\u3067\u3059\u3002\nmanifest.json\u30FBimage-list\u30FBservices\u30FBdependencies\u30FBlayout\u30FBweb-base-path\u30FBstorage-routing\u30FBhealth-paths \u306F\u5236\u54C1/\u4F9D\u5B58/\u30D7\u30ED\u30FC\u30D6\u3001apply.sh\u30FBresolve-*.sh \u306F\u914D\u5099\u3068\u72B6\u614B\u691C\u8A3C\u3001SHA256SUMS \u306F\u914D\u5E03\u6574\u5408\u6027\u7528\u3067\u3059\u3002\nmanaged-*\u30FBstate-backends \u306F\u5019\u88DC\u8CC7\u683C\u60C5\u5831\u3068\u30DC\u30EA\u30E5\u30FC\u30E0/\u30D0\u30C3\u30AF\u30A8\u30F3\u30C9\u306E\u5BFE\u5FDC\u3067\u3059\u3002\u30EB\u30FC\u30C8 managed-secrets.env \u306F\u6C38\u7D9A\u8CC7\u683C\u60C5\u5831\u3001persistent-backends \u306F\u53F0\u5E33\u3067\u3001\u30C7\u30FC\u30BF\u30DC\u30EA\u30E5\u30FC\u30E0\u3068\u4E00\u7DD2\u306B\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u3057\u307E\u3059\u3002\ncurrent \u306F\u6700\u5F8C\u306B\u30B5\u30FC\u30D0\u30FC\u5185\u3067\u6210\u529F\u3057\u305F ID \u306E\u30C6\u30AD\u30B9\u30C8\u30D5\u30A1\u30A4\u30EB\u3067\u3059\u3002result-{deploymentId}.json \u306E stage/exitCode/recoveryStatus \u3068 steps-{deploymentId}.jsonl \u3092\u78BA\u8A8D\u3057\u3001release \u306E\u5B58\u5728\u3060\u3051\u3067\u6210\u529F\u3068\u5224\u65AD\u3057\u307E\u305B\u3093\u3002\n\u5DEE\u5206\u69CB\u6210\u3068\u5B9F\u884C\u30B3\u30F3\u30C6\u30CA\u306F\u53E4\u3044 release \u3092\u53C2\u7167\u3067\u304D\u307E\u3059\u3002\u6574\u7406\u524D\u306B\u5168 Mounts \u3068 compose-files \u3092\u78BA\u8A8D\u3057\u3001current \u4EE5\u5916\u3092\u4E00\u5F8B\u524A\u9664\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002"
22785
22797
  };
22786
22798
 
22787
22799
  // ../deploy/messages/zh-CN.json
@@ -22891,7 +22903,13 @@ var zh_CN_default2 = {
22891
22903
  deploy_projectNameOverrideRemoved: "\u90E8\u7F72\u9879\u76EE\u540D\u7EDF\u4E00\u6765\u81EA\u5DE5\u7A0B\u6839 package.json.name\uFF1B\u8BF7\u79FB\u9664\u65E7 projectName \u8986\u76D6\u53C2\u6570\u3002",
22892
22904
  deploy_requestAccessInvalid: "\u8BF7\u6C42\u8BBF\u95EE\u7B56\u7565\u914D\u7F6E\u65E0\u6548\uFF08{field}\uFF09\u3002\u8BF7\u68C0\u67E5\u5B57\u6BB5\u3001IP\u3001\u65F6\u533A\u53CA\u65F6\u95F4\u7A97\u53E3\uFF1B\u5982\u5F15\u7528\u6587\u4EF6\uFF0C\u8BF7\u786E\u8BA4\u6587\u4EF6\u53EF\u8BFB\u3001\u683C\u5F0F\u4E3A YAML \u4E14\u4E0D\u8D85\u8FC7 1 MiB\u3002\u4FEE\u6B63\u540E\u91CD\u65B0\u6253\u5305\u3002",
22893
22905
  deploy_httpsPortsInvalid: "HTTP \u4E0E HTTPS \u7AEF\u53E3\u5FC5\u987B\u4E0D\u540C\uFF1BLet\u2019s Encrypt \u7684 HTTP-01 \u5165\u53E3\u5FC5\u987B\u4F7F\u7528\u5BBF\u4E3B\u673A 80 \u7AEF\u53E3\u3002",
22894
- deploy_httpsCertificateInvalid: "HTTPS \u8BC1\u4E66\u65E0\u6548\uFF1A\u8BF7\u6838\u5BF9 PEM \u6587\u4EF6\u53EF\u8BFB\u3001\u8BC1\u4E66\u4E0E\u672A\u52A0\u5BC6\u79C1\u94A5\u5339\u914D\u3001\u8BC1\u4E66\u6709\u6548\u671F\u53CA\u57DF\u540D\uFF0C\u7136\u540E\u91CD\u65B0\u6253\u5305\u3002"
22906
+ deploy_httpsCertificateInvalid: "HTTPS \u8BC1\u4E66\u65E0\u6548\uFF1A\u8BF7\u6838\u5BF9 PEM \u6587\u4EF6\u53EF\u8BFB\u3001\u8BC1\u4E66\u4E0E\u672A\u52A0\u5BC6\u79C1\u94A5\u5339\u914D\u3001\u8BC1\u4E66\u6709\u6548\u671F\u53CA\u57DF\u540D\uFF0C\u7136\u540E\u91CD\u65B0\u6253\u5305\u3002",
22907
+ deploy_bundleRuntime: "\u8FD0\u884C\u914D\u7F6E\u4E0E\u751F\u6548\uFF1A\n\u672C\u6B21\u53D1\u5E03\u8BB0\u5F55\uFF1A{directory}/releases/{deploymentId}\nNode \u540E\u7AEF\u8BFB\u53D6\u5B9E\u9645\u6302\u8F7D\u5230 /run/hai/.env.runtime \u7684\u6587\u4EF6\uFF1B\u589E\u91CF\u90E8\u7F72\u53EF\u80FD\u7EE7\u7EED\u5F15\u7528\u65E7\u8BB0\u5F55\uFF0C\u4E0D\u80FD\u53EA\u6309 current \u63A8\u65AD\u3002\u7528 docker inspect --format '{{json .Mounts}}' <\u5BB9\u5668\u540D> \u67E5\u770B Source\u3002\n\u666E\u901A\u540E\u7AEF\u914D\u7F6E\uFF1A\u5907\u4EFD\u3001\u4FEE\u6539\u8BE5\u6587\u4EF6\uFF0C\u7136\u540E docker restart <\u5BB9\u5668\u540D>\uFF08Podman \u540C\u7406\uFF09\uFF0C\u6838\u9A8C\u5065\u5EB7\u4E0E\u76F8\u5173\u4E1A\u52A1\u3002HAI \u7236\u5BF9\u8C61\u4F18\u5148\u4E8E\u53F6\u5B50\uFF0Cmiddleware.env \u7684\u6258\u7BA1\u8FDE\u63A5\u4F18\u5148\u3002\nCompose env_file \u6CE8\u5165\u7684\u9759\u6001 Web/\u4E2D\u95F4\u4EF6\u73AF\u5883\u53D8\u66F4\u9700\u8981\u91CD\u5EFA\u5BB9\u5668\uFF1B\u7AEF\u53E3\u3001\u6302\u8F7D\u3001Nginx \u8DEF\u7531/\u9650\u989D\u3001HTTPS \u5E03\u5C40\u9700\u8981\u91CD\u65B0\u751F\u6210\u5168\u91CF\u90E8\u7F72\u5305\u3002\u7F51\u7AD9 base \u53D8\u5316\u8FD8\u9700\u8981\u91CD\u65B0\u6784\u5EFA\u5236\u54C1\u3002\n\u624B\u5DE5\u4FEE\u6539\u540C\u6B65\u56DE\u6253\u5305\u6E90\u73AF\u5883\uFF1B\u4E0B\u6B21\u53D1\u5E03\u4F1A\u91CD\u65B0\u751F\u6210\u3002",
22908
+ deploy_bundleHttpOnly: "HTTPS\uFF1A\u672A\u542F\u7528\u3002\u672C\u5305\u4EC5\u53D1\u5E03 HTTP \u7AEF\u53E3 {port}\uFF0C\u6CA1\u6709\u8BC1\u4E66\u9644\u4EF6\uFF0C\u4E5F\u4E0D\u4F1A\u5728\u670D\u52A1\u5668\u7533\u8BF7\u8BC1\u4E66\u3002",
22909
+ deploy_bundleHttps: "HTTPS\uFF1A\u5DF2\u542F\u7528\uFF0Chttps://{domain}:{port}\uFF1B\u6A21\u5F0F {mode}\u3002\n\u670D\u52A1\u5668\u8BC1\u4E66\uFF1A{certificates}/fullchain.pem\uFF1B\u79C1\u94A5\uFF1A{certificates}/privkey.pem\u3002\u5BB9\u5668\u53EA\u8BFB\u6302\u8F7D\u5230 /etc/nginx/tls/\u3002\n\u4FEE\u6539\u672C\u5730\u6253\u5305\u73AF\u5883 .env.{environment}.local \u7684 HAI_DEPLOY_PROVIDER \u4E2D expose.https\uFF0C\u6216\u672A\u88AB\u8986\u76D6\u7684 hai.json.deploy.provider.expose.https\u3002\u542F\u505C\u3001\u5207\u6362\u6A21\u5F0F/\u57DF\u540D/\u7AEF\u53E3\u540E\u751F\u6210\u65B0\u7684\u5168\u91CF\u90E8\u7F72\u5305\uFF1B\u4FEE\u6539 .env.runtime \u5E76\u91CD\u542F\u4E0D\u80FD\u89E6\u53D1\u65B0\u57DF\u540D\u7B7E\u53D1\u3002",
22910
+ deploy_bundleAcme: "Certbot \u6301\u4E45\u72B6\u6001\uFF1A{state}\uFF1B\u5F53\u524D\u8BC1\u4E66\u5165\u53E3\uFF1A{state}/live/{domain}\u3002\u6253\u5305\u4E0D\u8BF7\u6C42 CA\uFF0C\u670D\u52A1\u5668\u90E8\u7F72\u65F6\u7533\u8BF7\uFF0C\u4E4B\u540E\u81EA\u52A8\u7EED\u671F\u3002\u516C\u7F51 80 \u7AEF\u53E3\u53CA\u6839\u8DEF\u5F84 /.well-known/acme-challenge/ \u5FC5\u987B\u53EF\u8FBE\uFF0C\u4E0D\u80FD\u53EA\u5141\u8BB8\u4E1A\u52A1 context path\u3002",
22911
+ deploy_bundleAccounts: "\u521D\u59CB\u8D26\u53F7\u53D8\u91CF\uFF08\u53EA\u5217\u540D\u79F0\u548C\u6765\u6E90\uFF0C\u4E0D\u663E\u793A\u5BC6\u7801\uFF09\uFF1A\n{sources}\nHAI_CONFIG_ADMIN_PASSWORD \u4F9B\u6709\u76F8\u5E94\u5F15\u5BFC\u903B\u8F91\u7684\u5E94\u7528\u521B\u5EFA config_admin \u914D\u7F6E\u7BA1\u7406\u5458\uFF1BHAI_ADMIN_DEFAULT_PASSWORD\u3001HAI_AUDIT_ADMIN_PASSWORD\u3001HAI_BUSINESS_OPERATOR_PASSWORD \u5BF9\u5E94\u5176\u4ED6\u6A21\u677F\u804C\u8D23\u8D26\u53F7\u3002\nCLI \u521B\u5EFA Fullstack \u65F6\u4E3A\u5404\u73AF\u5883\u751F\u6210\u72EC\u7ACB\u521D\u59CB\u5BC6\u7801\uFF1B\u6253\u5305\u8BFB\u53D6\u6240\u9009\u73AF\u5883\u4E0E\u8FDB\u7A0B\u8986\u76D6\uFF0C\u4E0D\u4F1A\u56E0\u670D\u52A1\u5668\u90E8\u7F72\u518D\u751F\u6210\u5E94\u7528\u8D26\u53F7\u5BC6\u7801\u3002\u6709\u914D\u7F6E\u4E14\u8D26\u53F7\u7F3A\u5931\u65F6\u7531\u5E94\u7528\u542F\u52A8\u5F15\u5BFC\uFF1B\u5DF2\u6709\u8D26\u53F7\u4E0D\u4F1A\u56E0\u4FEE\u6539\u53D8\u91CF\u91CD\u7F6E\u5BC6\u7801\u6216\u6062\u590D\u65E7\u804C\u8D23\u3002\u65E0\u76F8\u5E94\u5F15\u5BFC\u903B\u8F91\u7684\u81EA\u5B9A\u4E49\u5E94\u7528\u4EE5\u81EA\u8EAB\u5B9E\u73B0\u4E3A\u51C6\u3002",
22912
+ deploy_bundleDirectories: "\u670D\u52A1\u5668\u76EE\u5F55\u8BF4\u660E\uFF08\u6839\u76EE\u5F55 {directory}\uFF09\uFF1A\nincoming/\uFF1A\u4E0A\u4F20\u5F52\u6863\u548C .contents \u89E3\u5305\u76EE\u5F55\uFF1B\u6210\u529F\u540E\u6E05\u7406\u672C\u6B21\u5185\u5BB9\uFF0C\u5931\u8D25\u6216\u6267\u884C\u672A\u77E5\u65F6\u4FDD\u7559\u6392\u969C\u8BC1\u636E\u3002\nreleases/{deploymentId}/\uFF1A\u672C\u6B21\u8FD0\u884C\u6587\u4EF6\u548C\u6062\u590D\u8BB0\u5F55\uFF1B\u4E0D\u590D\u5236 images/\uFF0C\u955C\u50CF\u5BFC\u5165\u5BB9\u5668\u5F15\u64CE\uFF0C\u6570\u636E\u5E93\u548C\u5BF9\u8C61\u6570\u636E\u4FDD\u5B58\u5728\u6570\u636E\u5377\u3002\ncompose.json \u662F\u670D\u52A1\u5B9A\u4E49\uFF1Bcompose-entry.json\u3001proxy-entry.json\u3001compose-files \u7EC4\u5408\u5168\u91CF/\u589E\u91CF\u53CA\u4EE3\u7406\u8986\u76D6\u3002\n.env.runtime\u3001middleware.env\u3001middleware-runtime.env\u3001runtime-env.mjs \u8D1F\u8D23\u5E94\u7528\u4E0E\u4E2D\u95F4\u4EF6\u73AF\u5883\uFF1Bweb.conf \u662F\u4EE3\u7406\uFF0Crequest-access.yml \u662F\u6821\u9A8C\u540E\u7684\u7B56\u7565\u5FEB\u7167\u3002\nmanifest.json\u3001image-list\u3001services\u3001dependencies\u3001layout\u3001web-base-path\u3001storage-routing\u3001health-paths \u662F\u5236\u54C1\u3001\u4F9D\u8D56\u548C\u63A2\u6D3B\u5143\u6570\u636E\uFF1Bapply.sh\u3001resolve-*.sh \u6267\u884C\u53D1\u5E03\u53CA\u72B6\u6001\u6838\u9A8C\uFF1BSHA256SUMS \u6821\u9A8C\u4EA4\u4ED8\u5185\u5BB9\u3002\nmanaged-*\u3001state-backends \u63CF\u8FF0\u672C\u5305\u7684\u51ED\u636E\u5019\u9009\u548C\u5377/\u540E\u7AEF\u7ED1\u5B9A\u3002\u6839\u76EE\u5F55 managed-secrets.env \u662F\u670D\u52A1\u5668\u957F\u671F\u51ED\u636E\uFF0Cpersistent-backends \u662F\u957F\u671F\u540E\u7AEF\u8D26\u672C\uFF0C\u987B\u4E0E\u6570\u636E\u5377\u6210\u5957\u5907\u4EFD\u3002\ncurrent \u662F\u6700\u540E\u670D\u52A1\u5668\u672C\u5730\u6210\u529F\u53D1\u5E03 ID \u7684\u666E\u901A\u6587\u672C\u6587\u4EF6\uFF1B\u67E5\u770B result-{deploymentId}.json \u7684 stage/exitCode/recoveryStatus \u548C steps-{deploymentId}.jsonl \u5224\u65AD\u672C\u6B21\u7ED3\u679C\u3002\u4EC5\u51FA\u73B0 release \u76EE\u5F55\u4E0D\u4EE3\u8868\u6210\u529F\u3002\n\u589E\u91CF\u90E8\u7F72\u548C\u8FD0\u884C\u5BB9\u5668\u53EF\u80FD\u5F15\u7528\u65E7 release\uFF1B\u6E05\u7406\u524D\u6838\u5BF9\u6240\u6709\u6D3B\u52A8\u6302\u8F7D\u548C compose-files\uFF0C\u4E0D\u80FD\u53EA\u4FDD\u7559 current\u3002"
22895
22913
  };
22896
22914
 
22897
22915
  // ../deploy/src/deploy-i18n.ts
@@ -23134,6 +23152,13 @@ function mergeEnvironmentLayers(layers, prefix) {
23134
23152
  }
23135
23153
  return result;
23136
23154
  }
23155
+ function describeDeploymentVariableSources(directory, environment, values, names) {
23156
+ const files = [`.env.${environment}.local`, ".env.local", `.env.${environment}`, ".env"].map((name) => ({ path: join(directory, name), values: environmentFile(join(directory, name)) }));
23157
+ return names.filter((name) => values[name]).map((name) => {
23158
+ const source = process6.env[name] !== void 0 ? "process.env" : files.find((file2) => Object.hasOwn(file2.values, name))?.path;
23159
+ return `${name}: ${source ?? ".env.runtime"}`;
23160
+ }).join("\n");
23161
+ }
23137
23162
  function loadDeploymentConfig(name, path, values) {
23138
23163
  try {
23139
23164
  const content = readFileSync(path, "utf8");
@@ -26913,8 +26938,18 @@ async function createDeploymentBundle(options) {
26913
26938
  const selection = deployM("deploy_bundleSelection", { params: { mode, services: selected.join(", ") } });
26914
26939
  const instructions = `${selection}
26915
26940
  ${deployM("deploy_bundleInstructions", { params: instructionParams })}`;
26941
+ const runtimeGuide = deployM("deploy_bundleRuntime", { params: { directory: `${config2.remote.baseDir}/${projectName}`, deploymentId: options.deploymentId } });
26942
+ const https = config2.expose.https;
26943
+ const serverDirectory = `${config2.remote.baseDir}/${projectName}`;
26944
+ const certificates = https?.type === "files" ? `${serverDirectory}/releases/${options.deploymentId}/tls` : `${serverDirectory}/https/certificates/${https?.domain}`;
26945
+ const httpsGuide = https ? deployM("deploy_bundleHttps", { params: { domain: https.domain, port: https.port, mode: https.type, certificates, environment } }) + (https.type === "letsencrypt" ? `
26946
+ ${deployM("deploy_bundleAcme", { params: { state: `${serverDirectory}/https/acme`, domain: https.domain } })}` : "") : deployM("deploy_bundleHttpOnly", { params: { port: config2.expose.hostPort } });
26947
+ const accountGuide = deployM("deploy_bundleAccounts", { params: { sources: options.accountSources || "\u2014" } });
26948
+ const guides = [runtimeGuide, httpsGuide, accountGuide, deployM("deploy_bundleDirectories", { params: { directory: serverDirectory, deploymentId: options.deploymentId } })].join("\n\n");
26916
26949
  const readme = `${deployM("deploy_bundleMetadata", { params: { version: artifact.appVersion, buildId: artifact.buildId, deploymentId: options.deploymentId, compose: "compose.json" } })}
26917
26950
  ${instructions}
26951
+
26952
+ ${guides}
26918
26953
  `;
26919
26954
  const checksums = [];
26920
26955
  for (const file2 of files)
@@ -26965,6 +27000,7 @@ ${instructions}
26965
27000
  rmSync(join(directory, file2), { force: true });
26966
27001
  return { bundlePath: output2, instructions: `${selection}
26967
27002
  ${deployM("deploy_bundleInstructions", { params: { ...instructionParams, file: output2 } })}
27003
+ ${guides}
26968
27004
  ${scripts}`, startName: "apply.sh" };
26969
27005
  } finally {
26970
27006
  rmSync(staging, { recursive: true, force: true });
@@ -27156,6 +27192,15 @@ var IMAGES = {
27156
27192
  smtp: "docker.io/axllent/mailpit:v1.27.4",
27157
27193
  nginx: "docker.io/nginxinc/nginx-unprivileged:1.29.8-alpine"
27158
27194
  };
27195
+ var PROCESS_ENV_KEYS = /* @__PURE__ */ new Set([
27196
+ "HAI_CORE_ENV",
27197
+ "HAI_CRYPTO_TRANSPORT_SERVERKEYRING",
27198
+ "HAI_ADMIN_DEFAULT_PASSWORD",
27199
+ "HAI_AUDIT_ADMIN_PASSWORD",
27200
+ "HAI_CONFIG_ADMIN_PASSWORD",
27201
+ "HAI_BUSINESS_OPERATOR_PASSWORD",
27202
+ "HAI_E2E"
27203
+ ]);
27159
27204
  var CONTAINER_ENV_KEYS = /* @__PURE__ */ new Set([
27160
27205
  "POSTGRES_USER",
27161
27206
  "POSTGRES_PASSWORD",
@@ -27553,7 +27598,7 @@ function generateWebProxyConfig(port, apiPrefix, options = {}) {
27553
27598
  const webBasePath = options.webBasePath ?? "";
27554
27599
  const apiPath = apiPrefix.replace(/\/+$/, "");
27555
27600
  const backendPaths = [...new Set(options.backendPaths ?? ["/health"])];
27556
- if (!/^\/[\w/-]+$/.test(apiPrefix) || ![port, webPort].every((value) => Number.isInteger(value) && value >= 1 && value <= 65535) || backendPaths.some((path) => !/^\/[\w./-]*$/.test(path) || path.startsWith("//") || path.split("/").some((part) => part === "." || part === "..") || path === `${webBasePath}/runtime-config.js` || path === "/_hai/web-health") || webBasePath && (backendPaths.includes(webBasePath) || webBasePath === apiPath || webBasePath.startsWith(`${apiPath}/`))) {
27601
+ if (!/^\/[\w.-]+(?:\/[\w.-]+)*$/.test(apiPrefix) || apiPrefix.split("/").some((part) => part === "." || part === "..") || ![port, webPort].every((value) => Number.isInteger(value) && value >= 1 && value <= 65535) || backendPaths.includes(`${webBasePath}/`) || backendPaths.some((path) => !/^\/[\w./-]*$/.test(path) || path.includes("//") || path.split("/").some((part) => part === "." || part === "..") || path === `${webBasePath}/runtime-config.js` || path === "/_hai/web-health") || webBasePath && (backendPaths.includes(webBasePath) || webBasePath === apiPath || webBasePath.startsWith(`${apiPath}/`))) {
27557
27602
  throw new Error("Invalid web proxy target");
27558
27603
  }
27559
27604
  const webLocation = renderWebLocation(webBasePath);
@@ -27718,8 +27763,19 @@ ${renderWebLocation(webBasePath)} location = ${webBasePath}/runtime-config.js {
27718
27763
  }
27719
27764
  `;
27720
27765
  }
27721
- function serializeEnvFile(env) {
27722
- return `${Object.entries(env).map(([key, value]) => {
27766
+ function serializeEnvFile(env, overrides = {}) {
27767
+ const effective = { ...env, ...overrides };
27768
+ return `${Object.entries(env).filter(([name]) => {
27769
+ if (Object.hasOwn(overrides, name))
27770
+ return false;
27771
+ if (!name.startsWith("HAI_") || PROCESS_ENV_KEYS.has(name) || name.startsWith("HAI_E2E_"))
27772
+ return true;
27773
+ for (let at = name.indexOf("_", 4); at !== -1; at = name.indexOf("_", at + 1)) {
27774
+ if (Object.hasOwn(effective, name.slice(0, at)))
27775
+ return false;
27776
+ }
27777
+ return true;
27778
+ }).map(([key, value]) => {
27723
27779
  let literal2 = value;
27724
27780
  if (/[\s#$'"]/.test(value)) {
27725
27781
  if (value.startsWith("{") || value.startsWith("["))
@@ -27761,7 +27817,7 @@ function prepareRequestAccess(options) {
27761
27817
  var HEALTH_MAX_ATTEMPTS = 40;
27762
27818
  function servicePath(value, fallback) {
27763
27819
  const path = value ?? fallback;
27764
- if (typeof path !== "string" || !/^\/[\w./-]*$/.test(path) || path.startsWith("//") || path.split("/").some((part) => part === "." || part === ".."))
27820
+ if (typeof path !== "string" || !/^\/[\w./-]*$/.test(path) || path.includes("//") || path.split("/").some((part) => part === "." || part === ".."))
27765
27821
  throw new Error("Invalid service endpoint path");
27766
27822
  return path;
27767
27823
  }
@@ -27985,7 +28041,7 @@ function createDockerSshProvider(config2, container) {
27985
28041
  const http = server.data.http;
27986
28042
  const cors = server.data.cors;
27987
28043
  const apiPrefix = http?.apiPrefix ?? "/api/v1";
27988
- if (typeof apiPrefix !== "string" || !/^\/[\w/-]+$/.test(apiPrefix)) {
28044
+ if (typeof apiPrefix !== "string" || !/^\/[\w.-]+(?:\/[\w.-]+)*$/.test(apiPrefix) || apiPrefix.split("/").some((part) => part === "." || part === "..")) {
27989
28045
  return err(HaiDeployError.CONFIG_ERROR, deployM("deploy_webProxyInvalid"));
27990
28046
  }
27991
28047
  if (webBasePath && ([...backendPaths, "/_hai/web-health"].includes(webBasePath) || webBasePath === apiPrefix.replace(/\/+$/, "") || webBasePath.startsWith(`${apiPrefix.replace(/\/+$/, "")}/`)))
@@ -28035,7 +28091,17 @@ function createDockerSshProvider(config2, container) {
28035
28091
  mkdirSync(artifactDir, { mode: 448 });
28036
28092
  chmodSync(artifactDir, 448);
28037
28093
  const envPath = join(artifactDir, ".env.runtime");
28038
- writeFileSync(envPath, serializeEnvFile(env), { mode: 384 });
28094
+ const nodeRuntime = primaryService === "serv" || scan.isSvelteKit;
28095
+ const startupOverrides = nodeRuntime ? { NODE_OPTIONS: "", HAI_DEPLOY_PRIVATE_PROXY: "" } : {};
28096
+ const runtimeEnvironment = serializeEnvFile(env, { ...sidecar.env, ...startupOverrides });
28097
+ const middlewareEnv = serializeEnvFile(sidecar.env, Object.fromEntries(Object.entries(env).filter(([name2]) => !Object.hasOwn(sidecar.env, name2))));
28098
+ const envVarsSet = [.../* @__PURE__ */ new Set([
28099
+ ...Object.keys(parseEnv(runtimeEnvironment)),
28100
+ ...Object.keys(parseEnv(middlewareEnv)),
28101
+ ...nodeRuntime ? ["NODE_OPTIONS"] : [],
28102
+ ...hasWebProxy || gateway ? ["HAI_DEPLOY_PRIVATE_PROXY"] : []
28103
+ ])];
28104
+ writeFileSync(envPath, runtimeEnvironment, { mode: 384 });
28039
28105
  if (requestAccessSnapshot)
28040
28106
  writeFileSync(join(artifactDir, "request-access.yml"), requestAccessSnapshot, { mode: 384 });
28041
28107
  writeFileSync(join(artifactDir, "middleware-runtime.env"), serializeEnvFile(sidecar.containerEnv), { mode: 384 });
@@ -28056,7 +28122,7 @@ function createDockerSshProvider(config2, container) {
28056
28122
  containerPort,
28057
28123
  primaryService,
28058
28124
  requestAccessPolicy: requestAccessSnapshot !== void 0,
28059
- nodeRuntime: primaryService === "serv" || scan.isSvelteKit,
28125
+ nodeRuntime,
28060
28126
  nodeOptions: env.NODE_OPTIONS,
28061
28127
  sidecar,
28062
28128
  web: hasWebProxy ? { imageRef: web?.imageRef ?? "localhost/hai-unselected:0", containerPort: webContainerPort } : void 0,
@@ -28095,14 +28161,15 @@ function createDockerSshProvider(config2, container) {
28095
28161
  proxyService,
28096
28162
  storageRouting,
28097
28163
  containerPort,
28098
- middlewareEnv: serializeEnvFile(sidecar.env),
28164
+ middlewareEnv,
28165
+ accountSources: describeDeploymentVariableSources(options?.envDir ?? scan.envDir ?? appDir, options?.environment ?? "prod", env, ["HAI_ADMIN_DEFAULT_PASSWORD", "HAI_AUDIT_ADMIN_PASSWORD", "HAI_CONFIG_ADMIN_PASSWORD", "HAI_BUSINESS_OPERATOR_PASSWORD"]),
28099
28166
  healthPaths,
28100
28167
  httpsAssets,
28101
28168
  output: join(artifactDir, `${name}.tar${compressed ? ".gz" : ""}`),
28102
28169
  cacheDirectory: join(resolveProjectDirectory(appDir), ".hai", "cache", "images")
28103
28170
  });
28104
28171
  if (options?.bundleOnly)
28105
- return ok({ url: "", deploymentId, status: "packaged", provider: "docker-ssh", healthCheck: "skipped", envVarsSet: Object.keys(env), ...bundle });
28172
+ return ok({ url: "", deploymentId, status: "packaged", provider: "docker-ssh", healthCheck: "skipped", envVarsSet, ...bundle });
28106
28173
  if (!ssh)
28107
28174
  return err(HaiDeployError.CONFIG_ERROR, deployM("deploy_sshRequired"));
28108
28175
  const ping = await ssh.ping();
@@ -28188,7 +28255,7 @@ ${terminal ? deployM("deploy_remoteFinished", { params: { stage: terminal.stage,
28188
28255
  status: "ready",
28189
28256
  provider: "docker-ssh",
28190
28257
  healthCheck: "passed",
28191
- envVarsSet: Object.keys(env),
28258
+ envVarsSet,
28192
28259
  bundlePath: bundle.bundlePath
28193
28260
  };
28194
28261
  logger6.info("docker-ssh deployment complete", { url: applicationUrl, deploymentId });
@@ -29717,5 +29784,5 @@ async function acquireImportLock(path, root) {
29717
29784
  }
29718
29785
 
29719
29786
  export { DEPLOY_MIDDLEWARE, DeployConfigSchema, DeploymentArtifactSchema, HaiDeployError, ProviderConfigSchema, artifactChecksum, createDeploymentPlan, deploy, describeMiddlewareBackend, external_exports, getDeployCommandState, getDeployRecovery, importDeploymentSecrets, loadDeploymentConfig, loadDeploymentEnvironment, mergeEnvironmentLayers, normalizeProjectName, readDeploymentArtifact, saveDeploymentEnvironment };
29720
- //# sourceMappingURL=chunk-K6RWTTHD.js.map
29721
- //# sourceMappingURL=chunk-K6RWTTHD.js.map
29787
+ //# sourceMappingURL=chunk-VUWM43KR.js.map
29788
+ //# sourceMappingURL=chunk-VUWM43KR.js.map