@adep/cli 0.2.2 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,58 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 yunke
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ ---
24
+
25
+ Commercial Modules Reservation
26
+
27
+ The MIT license above applies to this repository EXCEPT the following
28
+ directories, which are proprietary commercial modules and are NOT licensed
29
+ under MIT (2026-10-05 decision, dual-track licensing):
30
+
31
+ - server/domains/billing/
32
+ - server/domains/appbuild/
33
+ - server/domains/license/
34
+ - server/domains/wallet/
35
+ - server/domains/voucher/
36
+
37
+ Each of these directories contains its own LICENSE.md stating the applicable
38
+ terms. They are licensed exclusively under the AgentDeploy Commercial License
39
+ and distributed under separate commercial agreements. All rights reserved.
40
+ No part of these modules may be copied, modified, distributed, or used
41
+ outside the terms of such commercial agreements.
42
+
43
+ Everything else in this repository — including the platform core, all
44
+ packages published to npm as `@adep/*`, the frontend application, and public
45
+ documentation — is licensed under the MIT license stated above.
46
+
47
+ ---
48
+
49
+ Trademark Notice
50
+
51
+ This license grants rights to use, copy, modify and distribute the source code
52
+ and software of this repository only. It does not grant any right, title or
53
+ interest in the trademarks, service marks, logos or brand names of the project
54
+ (including but not limited to "AgentDeploy", "云柯驿站" and related marks),
55
+ which remain the exclusive property of the project owner. Use of project
56
+ trademarks for purposes of identifying forked deployments must comply with
57
+ fair-use principles and must not suggest endorsement by or affiliation with
58
+ the project.
package/dist/index.js CHANGED
@@ -497,7 +497,8 @@ var init_generated = __esm({
497
497
  "packageJson",
498
498
  "adepConfig",
499
499
  "adepEnv",
500
- "gitignore"
500
+ "gitignore",
501
+ "dockerAssets"
501
502
  ]
502
503
  },
503
504
  "files": [
@@ -530,7 +531,8 @@ var init_generated = __esm({
530
531
  "readme",
531
532
  "helloFunction",
532
533
  "functionIndex",
533
- "gitignore"
534
+ "gitignore",
535
+ "dockerAssets"
534
536
  ]
535
537
  },
536
538
  "files": []
@@ -562,7 +564,8 @@ var init_generated = __esm({
562
564
  "viteConfig",
563
565
  "indexHtml",
564
566
  "webSrc",
565
- "gitignore"
567
+ "gitignore",
568
+ "dockerAssets"
566
569
  ]
567
570
  },
568
571
  "files": []
@@ -594,7 +597,8 @@ var init_generated = __esm({
594
597
  "adepEnv",
595
598
  "indexHtml",
596
599
  "viteConfig",
597
- "gitignore"
600
+ "gitignore",
601
+ "dockerAssets"
598
602
  ],
599
603
  "source": "\u672C\u76EE\u5F55\u5373\u771F\u76F8\u6E90\uFF08\u539F apps/countdown \u5DF2\u79FB\u51FA\u4ED3\u5E93\uFF0C\u72EC\u7ACB\u7EF4\u62A4\u4E8E git.a.jajabjbj.top:6602/a/countdown-adep.git\uFF09"
600
604
  },
@@ -3676,7 +3680,7 @@ var init_web_project_template = __esm({
3676
3680
  });
3677
3681
 
3678
3682
  // packages/cli/src/templates/shared-assets.ts
3679
- var ADEP_CONFIG_HEADER, PACKAGE_JSON, COUNTDOWN_PACKAGE_JSON, README, FUNCTION_INDEX, SCHEMA_SQL, INDEX_HTML, VITE_CONFIG, GITIGNORE, SHARED_ASSETS;
3683
+ var ADEP_CONFIG_HEADER, PACKAGE_JSON, COUNTDOWN_PACKAGE_JSON, DOCKER_SERVE_PORT, DOCKERFILE, COMPOSE_YAML, DOCKERIGNORE, ENV_EXAMPLE, DOCKER_README_SECTION, DOCKER_ASSETS, README, FUNCTION_INDEX, SCHEMA_SQL, INDEX_HTML, VITE_CONFIG, GITIGNORE, SHARED_ASSETS;
3680
3684
  var init_shared_assets = __esm({
3681
3685
  "packages/cli/src/templates/shared-assets.ts"() {
3682
3686
  "use strict";
@@ -3704,6 +3708,10 @@ var init_shared_assets = __esm({
3704
3708
  build: "vite build",
3705
3709
  "site:deploy": "adep hosting deploy site --spa",
3706
3710
  serve: "adep serve",
3711
+ // 容器内启动入口(Dockerfile 的 CMD 只有 `bun run start`):静态目录 / 端口口径
3712
+ // 只在这一个地方定档——Dockerfile 与 package.json 各写一套必然漂移(2026-10-08 收敛)。
3713
+ // fullstack 的前端产物在 site/(vite build);function / empty 无前端产物,故不指目录。
3714
+ start: template === "fullstack" ? "adep serve --host 0.0.0.0 --static site" : "adep serve --host 0.0.0.0",
3707
3715
  deploy: "adep publish --only functions",
3708
3716
  doctor: "adep doctor"
3709
3717
  },
@@ -3767,6 +3775,121 @@ var init_shared_assets = __esm({
3767
3775
  return `${JSON.stringify(pkg, null, 2)}
3768
3776
  `;
3769
3777
  };
3778
+ DOCKER_SERVE_PORT = 8787;
3779
+ DOCKERFILE = `# \u672C\u5730\u4E00\u952E\u8FD0\u884C\u955C\u50CF\uFF08docker compose up --build\uFF09
3780
+ # \u8FD0\u884C\u65F6 = adep serve\uFF1A\u51FD\u6570 /api/{fn} + /healthz + \u9759\u6001\u6258\u7BA1 + SQLite\uFF08Bun \u539F\u751F\uFF0C\u7F3A\u7701\u964D\u7EA7 sim\uFF09
3781
+ # \u6A21\u677F\u53C2\u6570\uFF08\u9879\u76EE\u6839\u6709 data.yml \u65F6\uFF09\u7531 serve \u5728**\u54CD\u5E94\u671F**\u6CE8\u5165 window.__ADEP_ENV__\uFF0C
3782
+ # \u4E0E\u5E73\u53F0\u9759\u6001\u6258\u7BA1\u540C\u4E00\u673A\u5236 \u2014\u2014 \u955C\u50CF\u91CC\u4E0D\u9700\u8981\u53E6\u653E\u6CE8\u5165\u811A\u672C\uFF0C\u4E5F\u4E0D\u6539\u5199\u5DE5\u4F5C\u533A\u91CC\u7684 HTML\u3002
3783
+ FROM oven/bun:1
3784
+
3785
+ WORKDIR /app
3786
+
3787
+ # \u5B89\u88C5\u4F9D\u8D56\uFF08\u542B @adep/cli \u2014\u2014 serve \u7684\u540C\u6E90\u8FD0\u884C\u65F6\uFF09
3788
+ COPY package.json ./
3789
+ RUN bun install
3790
+
3791
+ # \u5E94\u7528\u4EE3\u7801\uFF08.dockerignore \u5DF2\u6392\u9664 node_modules / .env / \u6784\u5EFA\u4EA7\u7269\uFF09
3792
+ COPY . .
3793
+
3794
+ # \u524D\u7AEF\u6784\u5EFA\uFF1A\u4EC5\u5F53\u672C\u6A21\u677F\u58F0\u660E\u4E86 build \u811A\u672C\u65F6\u6267\u884C\uFF08\u7EAF\u4E91\u51FD\u6570\u6A21\u677F\u6CA1\u6709\u524D\u7AEF\u4EA7\u7269\uFF09\u3002
3795
+ # \u26A0\uFE0F \u523B\u610F\u300C\u5148\u5224\u811A\u672C\u5B58\u5728\u518D\u6267\u884C\u300D\uFF0C\u800C\u4E0D\u662F \`bun run build || true\` \u2014\u2014 \u540E\u8005\u4F1A\u628A**\u6784\u5EFA\u5931\u8D25**\u4E00\u8D77\u541E\u6389\uFF0C
3796
+ # \u4E8E\u662F\u955C\u50CF\u6784\u5EFA\u6210\u529F\u3001\u5BB9\u5668\u8D77\u6765\u540E\u524D\u7AEF\u5374\u662F\u7A7A\u7684\uFF08\u6700\u96BE\u67E5\u7684\u90A3\u7C7B\u5047\u7EFF\uFF09\u3002
3797
+ RUN if bun -e "process.exit(JSON.parse(require('fs').readFileSync('package.json','utf8')).scripts?.build ? 0 : 1)"; then bun run build; else echo "[docker] \u672C\u6A21\u677F\u65E0 build \u811A\u672C\uFF0C\u8DF3\u8FC7\u524D\u7AEF\u6784\u5EFA"; fi
3798
+
3799
+ EXPOSE ${DOCKER_SERVE_PORT}
3800
+
3801
+ # \u5BB9\u5668\u5185\u5FC5\u987B\u7ED1\u975E\u56DE\u73AF\u624D\u53EF\u8FBE\uFF08serve \u7684 HOST \u73AF\u5883\u53D8\u91CF\u8BED\u4E49\uFF09
3802
+ ENV HOST=0.0.0.0 PORT=${DOCKER_SERVE_PORT}
3803
+
3804
+ # \u5065\u5EB7\u68C0\u67E5\uFF08\u4E0E compose healthcheck \u540C\u4E00\u4E2A /healthz\uFF09
3805
+ # \u63A2\u9488\u7528 bun \u81EA\u8EAB\uFF1Aoven/bun \u57FA\u7840\u955C\u50CF\u4E0D\u5E26\u4EFB\u4F55 HTTP \u5BA2\u6237\u7AEF\u5DE5\u5177\uFF08\u5B9E\u6D4B\u8E29\u8FC7\uFF09\uFF0Cbun \u81EA\u5E26 fetch \u96F6\u5916\u90E8\u4F9D\u8D56\u3002
3806
+ HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \\
3807
+ CMD bun -e "await fetch('http://localhost:' + (process.env.PORT ?? '${DOCKER_SERVE_PORT}') + '/healthz').then(r => { if (!r.ok) process.exit(1) })" || exit 1
3808
+
3809
+ # \u542F\u52A8 = package.json \u7684 scripts.start\uFF1A\u9759\u6001\u76EE\u5F55\uFF08--static\uFF09/ --schema / --spa \u90FD\u5728\u90A3\u91CC\u5B9A\u6863\uFF0C
3810
+ # \u540C\u4E00\u4EF6\u4E8B\u53EA\u7559\u4E00\u4E2A\u771F\u76F8\u6E90\uFF08CMD \u91CC\u518D\u5199\u4E00\u904D\u5C31\u4F1A\u4E0E scripts.start \u6F02\u79FB\u2014\u20142026-10-08 \u6536\u655B\uFF09\u3002
3811
+ CMD ["bun", "run", "start"]
3812
+ `;
3813
+ COMPOSE_YAML = `# \u4E00\u952E\u8FD0\u884C\uFF1Acp .env.example .env && docker compose up --build
3814
+ # \u670D\u52A1 = adep serve\uFF08\u5F00\u53D1\u6001\u5355\u8FDB\u7A0B\uFF1A\u51FD\u6570 + \u9759\u6001 + SQLite + \u6A21\u677F\u53C2\u6570\u6CE8\u5165\uFF09\uFF1B\u751F\u4EA7\u7EA7\u7F16\u6392\u7528 adep export \u81EA\u6258\u7BA1\u5305\u3002
3815
+ services:
3816
+ app:
3817
+ build: .
3818
+ container_name: {{name}}-app
3819
+ restart: unless-stopped
3820
+ ports:
3821
+ - "\${APP_PORT:-${DOCKER_SERVE_PORT}}:${DOCKER_SERVE_PORT}"
3822
+ env_file:
3823
+ - .env
3824
+ volumes:
3825
+ # SQLite \u5E93\u4E0E\u672C\u5730\u6001\uFF08.adep/ \u4E0B\uFF09\u6302\u5377\u2014\u2014\u6570\u636E\u6D3B\u5F97\u8FC7\u5BB9\u5668\u91CD\u5EFA
3826
+ - app-data:/app/.adep
3827
+ healthcheck:
3828
+ # bun \u63A2\u9488\uFF08\u955C\u50CF\u5185\u65E0 HTTP \u5BA2\u6237\u7AEF\u5DE5\u5177\uFF1Boven/bun \u81EA\u5E26 fetch\uFF09
3829
+ test: ["CMD", "bun", "-e", "await fetch('http://localhost:${DOCKER_SERVE_PORT}/healthz').then(r => { if (!r.ok) process.exit(1) })"]
3830
+ interval: 30s
3831
+ timeout: 5s
3832
+ retries: 3
3833
+ start_period: 10s
3834
+
3835
+ volumes:
3836
+ app-data:
3837
+ driver: local
3838
+ `;
3839
+ DOCKERIGNORE = `# \u955C\u50CF\u6784\u5EFA\u6392\u9664\uFF08\u4F9D\u8D56\u5BB9\u5668\u5185\u91CD\u88C5\uFF1B\u672C\u5730\u6001\u4E0E\u5BC6\u94A5\u7EDD\u4E0D\u70E4\u8FDB\u955C\u50CF\u5C42\uFF09
3840
+ # \u26A0\uFE0F web/\uFF08\u7AD9\u70B9\uFF09\u3001functions/\u3001database/\u3001data.yml \u662F\u5BB9\u5668\u8FD0\u884C\u65F6\u5FC5\u9700\uFF0C\u522B\u52A0\u8FDB\u672C\u6587\u4EF6
3841
+ node_modules/
3842
+ .adep/
3843
+ site/
3844
+ data/
3845
+ .env
3846
+ .env.local
3847
+ .env.*.local
3848
+ compose.yaml
3849
+ .env.example
3850
+ README.md
3851
+ preview.gif
3852
+ .git/
3853
+ .gitignore
3854
+ *.log
3855
+ .DS_Store
3856
+ `;
3857
+ ENV_EXAMPLE = `# adep \u9879\u76EE\u73AF\u5883\u53D8\u91CF\uFF08docker compose \u7528\uFF09
3858
+ # \u590D\u5236\u4E3A .env \u540E\u6309\u9700\u4FEE\u6539\uFF1Acp .env.example .env
3859
+
3860
+ # \u5BBF\u4E3B\u673A\u6620\u5C04\u7AEF\u53E3\uFF08\u5BB9\u5668\u5185\u56FA\u5B9A ${DOCKER_SERVE_PORT}\uFF09
3861
+ APP_PORT=${DOCKER_SERVE_PORT}
3862
+
3863
+ # \u5E94\u7528\u81EA\u5B9A\u4E49\u53D8\u91CF\uFF1Aserve \u4F1A\u6CE8\u5165\u51FD\u6570\u8FD0\u884C\u65F6\uFF08ctx.env / process.env\uFF09\uFF0C\u5BB9\u5668\u5185\u53EF\u76F4\u63A5\u88AB\u4E91\u51FD\u6570\u8BFB\u5230\u3002
3864
+ # \u82E5\u9879\u76EE\u6839\u6709 data.yml\uFF0C\u5219\u5B83\u58F0\u660E\u7684\u6BCF\u4E2A envKey \u8FD8\u4F1A**\u6CE8\u5165\u9875\u9762**\uFF08window.__ADEP_ENV__.<KEY>\uFF09\u2014\u2014
3865
+ # \u952E\u540D\u5FC5\u987B\u4E0E data.yml \u5B8C\u5168\u4E00\u81F4\uFF0C\u672A\u8BBE\u7F6E\u7684\u952E\u4E0D\u6CE8\u5165\uFF08\u9875\u9762\u56DE\u843D\u5185\u7F6E\u9ED8\u8BA4\u503C\uFF09\u3002
3866
+ # MY_TITLE=\u6211\u7684\u5E94\u7528
3867
+ `;
3868
+ DOCKER_README_SECTION = () => `## \u{1F433} Docker \u4E00\u952E\u8FD0\u884C
3869
+
3870
+ \`\`\`bash
3871
+ cp .env.example .env # \u6309\u9700\u6539\u7AEF\u53E3\u7B49
3872
+ docker compose up --build # http://localhost:8787
3873
+ \`\`\`
3874
+
3875
+ \u5BB9\u5668\u5185\u8DD1\u7684\u662F \`adep serve\`\uFF08\u51FD\u6570 /api/{fn} + \u5065\u5EB7\u68C0\u67E5 /healthz + \u9759\u6001\u6258\u7BA1 + SQLite\uFF09\u3002
3876
+ \u542F\u52A8\u53C2\u6570\u5728 \`package.json\` \u7684 \`scripts.start\` \u91CC\u5B9A\u6863\uFF08Dockerfile \u7684 \`CMD\` \u53EA\u662F \`bun run start\`\uFF09\uFF0C
3877
+ \u8981\u52A0 \`--schema\` / \`--spa\` / \u6362\u9759\u6001\u76EE\u5F55\u6539\u90A3\u4E00\u5904\u5373\u53EF\u3002
3878
+
3879
+ \u9879\u76EE\u6839\u6709 \`data.yml\` \u65F6\uFF0C**\u5B83\u58F0\u660E\u7684\u53C2\u6570\u952E\u4F1A\u81EA\u52A8\u6CE8\u5165\u9875\u9762**\uFF08\`window.__ADEP_ENV__\`\uFF09\uFF1Aserve \u8BFB\u540C\u540D
3880
+ \u73AF\u5883\u53D8\u91CF\uFF08\`.env\` / compose \u6CE8\u5165\uFF09\uFF0C\u5728\u54CD\u5E94\u671F\u6CE8\u5165 HTML\uFF0C\u4E0E\u5E73\u53F0\u6258\u7BA1\u540C\u4E00\u673A\u5236\u2014\u2014\u6539\u503C\u91CD\u542F\u5373\u751F\u6548\uFF0C
3881
+ \u4E14\u4E0D\u4F1A\u6539\u5199\u5DE5\u4F5C\u533A\u91CC\u7684 \`web/index.html\`\u3002\u672A\u8BBE\u7F6E\u7684\u952E\u4E0D\u6CE8\u5165\uFF0C\u9875\u9762\u56DE\u843D\u5185\u7F6E\u9ED8\u8BA4\u503C\uFF1B
3882
+ \`data.yml\` \u5B58\u5728\u4F46\u5199\u9519\u4F1A\u8BA9 serve **\u62D2\u7EDD\u542F\u52A8\u5E76\u6253\u5370\u9519\u8BEF\u7801**\uFF08\u4E0D\u9759\u9ED8\u5F53\u300C\u65E0\u53C2\u6570\u300D\uFF09\u3002
3883
+
3884
+ \u6570\u636E\u843D\u5728 \`app-data\` \u5377\uFF08\`.adep/\` \u76EE\u5F55\uFF09\uFF0C\`docker compose down\` \u4E0D\u4E22\u3001\`down -v\` \u624D\u6E05\u7A7A\u3002
3885
+ \u751F\u4EA7\u7EA7\u81EA\u6258\u7BA1\uFF08\u7F51\u5173 / TLS / \u5355\u5B9E\u4F8B\u5B88\u62A4\uFF09\u7528 \`adep export\` \u5BFC\u51FA\u4E13\u7528\u90E8\u7F72\u5305\u3002
3886
+ `;
3887
+ DOCKER_ASSETS = (name) => [
3888
+ { path: "Dockerfile", content: DOCKERFILE },
3889
+ { path: "compose.yaml", content: COMPOSE_YAML.replace("{{name}}", name) },
3890
+ { path: ".dockerignore", content: DOCKERIGNORE },
3891
+ { path: ".env.example", content: ENV_EXAMPLE }
3892
+ ];
3770
3893
  README = (name, template) => `# ${name}
3771
3894
 
3772
3895
  AgentDeploy \u5168\u6808\u9879\u76EE\uFF08\u6A21\u677F\uFF1A${template}\uFF09\u3002
@@ -3783,6 +3906,8 @@ AgentDeploy \u5168\u6808\u9879\u76EE\uFF08\u6A21\u677F\uFF1A${template}\uFF09\u3
3783
3906
  - \`pnpm deploy\`\uFF08= \`adep publish --only functions\`\uFF09\uFF1A\u589E\u91CF\u90E8\u7F72\u4E91\u51FD\u6570\uFF08\u5BF9\u6BD4\u8FDC\u7AEF\u54C8\u5E0C \u2192 \u4EC5\u4E0A\u4F20\u53D8\u66F4 \u2192 \u53D1\u5E03 \u2192 \u8F93\u51FA\u8BBF\u95EE\u57DF\u540D\uFF09
3784
3907
  - \`pnpm doctor\`\uFF08= \`adep doctor\`\uFF09\uFF1A\u672C\u5730\u73AF\u5883\u79BB\u7EBF\u8BCA\u65AD
3785
3908
 
3909
+ ${DOCKER_README_SECTION()}
3910
+
3786
3911
  ## \u76EE\u5F55\u7ED3\u6784
3787
3912
 
3788
3913
  - \`package.json\`\uFF1A\u5E94\u7528\u5B9A\u4E49\uFF08@adep/cli + \u524D\u7AEF\u4F9D\u8D56\u540C\u6839\u58F0\u660E\uFF1Bvite \u5DE5\u7A0B\u6839\u5728\u9879\u76EE\u6839\u76EE\u5F55\uFF09
@@ -3940,7 +4065,8 @@ export default defineConfig({
3940
4065
  schemaPlaceholder: () => [{ path: "database/schema.sql", content: SCHEMA_SQL }],
3941
4066
  viteConfig: () => [{ path: "vite.config.ts", content: VITE_CONFIG }],
3942
4067
  indexHtml: () => [{ path: "index.html", content: INDEX_HTML }],
3943
- gitignore: () => [{ path: ".gitignore", content: GITIGNORE }]
4068
+ gitignore: () => [{ path: ".gitignore", content: GITIGNORE }],
4069
+ dockerAssets: (ctx) => DOCKER_ASSETS(ctx.name)
3944
4070
  };
3945
4071
  }
3946
4072
  });
@@ -21960,7 +22086,11 @@ function assertStoragePrefix(prefix) {
21960
22086
  }
21961
22087
  return prefix ?? "";
21962
22088
  }
21963
- var PROJECT_QUOTA_BYTES, StorageError, STORAGE_CODES;
22089
+ function isDevSegmentHidden(relPath, prefix) {
22090
+ if (prefix !== void 0 && prefix !== "" && prefix.startsWith(DEV_STORAGE_SEGMENT)) return false;
22091
+ return relPath.startsWith(DEV_STORAGE_SEGMENT);
22092
+ }
22093
+ var PROJECT_QUOTA_BYTES, StorageError, STORAGE_CODES, DEV_STORAGE_SEGMENT;
21964
22094
  var init_driver = __esm({
21965
22095
  "packages/runtime/src/storage/driver.ts"() {
21966
22096
  "use strict";
@@ -21978,6 +22108,7 @@ var init_driver = __esm({
21978
22108
  notFound: "STORAGE_NOT_FOUND",
21979
22109
  quotaExceeded: "STORAGE_QUOTA_EXCEEDED"
21980
22110
  };
22111
+ DEV_STORAGE_SEGMENT = ".env-dev/";
21981
22112
  }
21982
22113
  });
21983
22114
 
@@ -22453,8 +22584,7 @@ function createLocalStorageDriver(options) {
22453
22584
  await Promise.all(tasks);
22454
22585
  };
22455
22586
  await walk(root, "");
22456
- metas.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
22457
- return metas;
22587
+ return metas.filter((meta3) => !isDevSegmentHidden(meta3.path, prefix)).toSorted((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
22458
22588
  },
22459
22589
  async usage(projectId) {
22460
22590
  return totalSize(projectId);
@@ -23450,6 +23580,17 @@ var init_runtime2 = __esm({
23450
23580
  evictAll() {
23451
23581
  this.instances.clear();
23452
23582
  }
23583
+ /**
23584
+ * 先落盘再释放(CORE-079 惰性驱逐):逐实例 `flush()` 持久化后清空内存驻留,
23585
+ * 类型注册表保留(runtime 对象本身可复用;驱逐方通常直接丢弃整个 runtime)。
23586
+ * 任一实例 flush 抛错则**整体上抛且不清空**——调用方据此放弃驱逐,绝不静默丢未落盘状态。
23587
+ */
23588
+ async dispose() {
23589
+ for (const inst of this.instances.values()) {
23590
+ await this.flush(inst);
23591
+ }
23592
+ this.instances.clear();
23593
+ }
23453
23594
  };
23454
23595
  }
23455
23596
  });
@@ -24108,11 +24249,58 @@ var init_sandbox_fetch = __esm({
24108
24249
  }
24109
24250
  });
24110
24251
 
24111
- // packages/runtime/src/functions/runtime/rpc-key.ts
24112
- var init_rpc_key = __esm({
24113
- "packages/runtime/src/functions/runtime/rpc-key.ts"() {
24252
+ // packages/runtime/src/functions/runtime/flat-rpc-proxy.ts
24253
+ function isImplicitProtocolKey(key) {
24254
+ return IMPLICIT_PROTOCOL_KEYS.has(key);
24255
+ }
24256
+ function createFlatRpcProxy(dispatch) {
24257
+ return new Proxy(
24258
+ {},
24259
+ {
24260
+ get(_target, method) {
24261
+ if (typeof method !== "string") return void 0;
24262
+ if (isImplicitProtocolKey(method)) return Reflect.get(Object.prototype, method);
24263
+ return (...args) => dispatch(method, args);
24264
+ }
24265
+ }
24266
+ );
24267
+ }
24268
+ var IMPLICIT_PROTOCOL_KEYS;
24269
+ var init_flat_rpc_proxy = __esm({
24270
+ "packages/runtime/src/functions/runtime/flat-rpc-proxy.ts"() {
24271
+ "use strict";
24272
+ IMPLICIT_PROTOCOL_KEYS = /* @__PURE__ */ new Set([
24273
+ "then",
24274
+ "catch",
24275
+ "finally",
24276
+ "toJSON",
24277
+ "toString",
24278
+ "valueOf",
24279
+ "constructor",
24280
+ "__proto__",
24281
+ "inspect"
24282
+ ]);
24283
+ }
24284
+ });
24285
+
24286
+ // packages/runtime/src/functions/runtime/rpc-client.ts
24287
+ function isRpcCapability(value) {
24288
+ return typeof value === "object" && value !== null && value[RPC_CAPABILITY_KEY] === true;
24289
+ }
24290
+ function createRpcClient(capability, port, pending, nextId) {
24291
+ return createFlatRpcProxy((method, args) => {
24292
+ const id = nextId();
24293
+ return new Promise((resolve18, reject) => {
24294
+ pending.set(id, { resolve: resolve18, reject });
24295
+ port.postMessage({ type: "rpc", id, capability, method, args });
24296
+ });
24297
+ });
24298
+ }
24299
+ var init_rpc_client = __esm({
24300
+ "packages/runtime/src/functions/runtime/rpc-client.ts"() {
24114
24301
  "use strict";
24115
24302
  init_capability_keys();
24303
+ init_flat_rpc_proxy();
24116
24304
  }
24117
24305
  });
24118
24306
 
@@ -24226,26 +24414,6 @@ var init_regexp = __esm({
24226
24414
  import { parentPort, workerData } from "node:worker_threads";
24227
24415
  import { createRequire } from "node:module";
24228
24416
  import { join as join13 } from "node:path";
24229
- function isRpcCapability(value) {
24230
- return typeof value === "object" && value !== null && value[RPC_CAPABILITY_KEY] === true;
24231
- }
24232
- function createRpcClient(capability, port, pending, nextId) {
24233
- return new Proxy(
24234
- {},
24235
- {
24236
- get(_target, method) {
24237
- if (typeof method !== "string") return void 0;
24238
- return (...args) => {
24239
- const id = nextId();
24240
- return new Promise((resolve18, reject) => {
24241
- pending.set(id, { resolve: resolve18, reject });
24242
- port.postMessage({ type: "rpc", id, capability, method, args });
24243
- });
24244
- };
24245
- }
24246
- }
24247
- );
24248
- }
24249
24417
  function errorMessageOf2(error51) {
24250
24418
  if (error51 instanceof Error) return error51.message;
24251
24419
  if (typeof error51 === "object" && error51 !== null && "message" in error51) {
@@ -24413,7 +24581,7 @@ var init_worker_entry = __esm({
24413
24581
  init_cloud_container();
24414
24582
  init_sandbox();
24415
24583
  init_sandbox_fetch();
24416
- init_rpc_key();
24584
+ init_rpc_client();
24417
24585
  init_rpc_wire();
24418
24586
  init_chain();
24419
24587
  init_sandbox();
@@ -25789,6 +25957,203 @@ var init_banner = __esm({
25789
25957
  }
25790
25958
  });
25791
25959
 
25960
+ // shared/sdk/template-params.ts
25961
+ function extractTemplateFields(root) {
25962
+ if (root === null || typeof root !== "object") {
25963
+ throw new TemplateParamsParseError("TPL_YAML_SHAPE", "data.yml \u6839\u8282\u70B9\u5FC5\u987B\u662F\u5BF9\u8C61");
25964
+ }
25965
+ const additional = root["additionalProperties"];
25966
+ if (additional === null || typeof additional !== "object") {
25967
+ throw new TemplateParamsParseError(
25968
+ "TPL_YAML_SHAPE",
25969
+ "data.yml \u7F3A\u5C11 additionalProperties \u8282\uFF08\u53C2\u8003 adep \u6A21\u677F\u89C4\u8303\uFF09"
25970
+ );
25971
+ }
25972
+ const rawFields = additional["formFields"];
25973
+ if (!Array.isArray(rawFields)) {
25974
+ throw new TemplateParamsParseError(
25975
+ "TPL_YAML_SHAPE",
25976
+ "data.yml \u7684 additionalProperties.formFields \u5FC5\u987B\u662F\u6570\u7EC4"
25977
+ );
25978
+ }
25979
+ if (rawFields.length === 0) {
25980
+ throw new TemplateParamsParseError(
25981
+ "TPL_YAML_SHAPE",
25982
+ "formFields \u4E0D\u80FD\u4E3A\u7A7A\uFF08\u65E0\u53C2\u6570\u8BF7\u5220\u9664 data.yml\uFF09"
25983
+ );
25984
+ }
25985
+ if (rawFields.length > TEMPLATE_MAX_FIELDS) {
25986
+ throw new TemplateParamsParseError(
25987
+ "TPL_YAML_SHAPE",
25988
+ `\u8868\u5355\u5B57\u6BB5\u8FC7\u591A\uFF08>${TEMPLATE_MAX_FIELDS}\uFF09`
25989
+ );
25990
+ }
25991
+ const seenKeys = /* @__PURE__ */ new Set();
25992
+ const fields = [];
25993
+ for (const rawItem of rawFields) {
25994
+ if (rawItem === null || typeof rawItem !== "object") {
25995
+ throw new TemplateParamsParseError("TPL_YAML_SHAPE", "formFields \u7684\u6BCF\u4E00\u9879\u5FC5\u987B\u662F\u5BF9\u8C61");
25996
+ }
25997
+ const envKey = typeof rawItem.envKey === "string" ? rawItem.envKey.trim() : "";
25998
+ if (!TEMPLATE_ENV_KEY_RE.test(envKey) || envKey.length > TEMPLATE_ENV_KEY_MAX) {
25999
+ throw new TemplateParamsParseError(
26000
+ "TPL_YAML_ENVKEY",
26001
+ `\u5B57\u6BB5 envKey \u975E\u6CD5\uFF08\u987B\u5B57\u6BCD/\u4E0B\u5212\u7EBF\u5F00\u5934\uFF0C\u2264128 \u5B57\u7B26\uFF09\uFF1A${JSON.stringify(rawItem.envKey)}`
26002
+ );
26003
+ }
26004
+ if (seenKeys.has(envKey)) {
26005
+ throw new TemplateParamsParseError("TPL_YAML_ENVKEY", `envKey \u91CD\u590D\uFF1A${envKey}`);
26006
+ }
26007
+ seenKeys.add(envKey);
26008
+ const label = typeof rawItem.label === "string" && rawItem.label.trim() !== "" ? rawItem.label.trim() : envKey;
26009
+ const type = typeof rawItem.type === "string" ? rawItem.type : "text";
26010
+ if (!TEMPLATE_FIELD_TYPES.includes(type)) {
26011
+ throw new TemplateParamsParseError(
26012
+ "TPL_YAML_TYPE",
26013
+ `\u5B57\u6BB5 ${envKey} \u7684 type \u975E\u6CD5\uFF1A${JSON.stringify(rawItem.type)}\uFF08\u53EF\u9009\uFF1A${TEMPLATE_FIELD_TYPES.join("/")}`
26014
+ );
26015
+ }
26016
+ const required2 = rawItem.required === true;
26017
+ let defaultValue = null;
26018
+ if (rawItem.default !== void 0 && rawItem.default !== null) {
26019
+ if (typeof rawItem.default === "string") defaultValue = rawItem.default;
26020
+ else if (typeof rawItem.default === "number" || typeof rawItem.default === "boolean") {
26021
+ defaultValue = String(rawItem.default);
26022
+ } else {
26023
+ throw new TemplateParamsParseError(
26024
+ "TPL_YAML_DEFAULT",
26025
+ `\u5B57\u6BB5 ${envKey} \u7684 default \u5FC5\u987B\u662F\u6807\u91CF`
26026
+ );
26027
+ }
26028
+ }
26029
+ let options = [];
26030
+ if (type === "select") {
26031
+ if (!Array.isArray(rawItem.options) || rawItem.options.length === 0) {
26032
+ throw new TemplateParamsParseError(
26033
+ "TPL_YAML_OPTIONS",
26034
+ `\u5B57\u6BB5 ${envKey} \u662F select \u7C7B\u578B\uFF0C\u5FC5\u987B\u63D0\u4F9B\u975E\u7A7A options \u6570\u7EC4`
26035
+ );
26036
+ }
26037
+ options = rawItem.options.map((o, i) => {
26038
+ if (typeof o !== "string" || o.trim() === "") {
26039
+ throw new TemplateParamsParseError(
26040
+ "TPL_YAML_OPTIONS",
26041
+ `\u5B57\u6BB5 ${envKey} \u7684 options[${i}] \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32`
26042
+ );
26043
+ }
26044
+ return o.trim();
26045
+ });
26046
+ if (defaultValue !== null && !options.includes(defaultValue)) {
26047
+ throw new TemplateParamsParseError(
26048
+ "TPL_YAML_OPTIONS",
26049
+ `\u5B57\u6BB5 ${envKey} \u7684 default \u4E0D\u5728 options \u91CC`
26050
+ );
26051
+ }
26052
+ }
26053
+ fields.push({ envKey, label, type, required: required2, defaultValue, options });
26054
+ }
26055
+ return fields;
26056
+ }
26057
+ function resolveTemplateEnvValues(fields, env) {
26058
+ const out = {};
26059
+ for (const field of fields) {
26060
+ const value = env[field.envKey];
26061
+ if (value === void 0 || value === "") continue;
26062
+ out[field.envKey] = value;
26063
+ }
26064
+ return out;
26065
+ }
26066
+ var TEMPLATE_FIELD_TYPES, TEMPLATE_MAX_FIELDS, TEMPLATE_ENV_KEY_RE, TEMPLATE_ENV_KEY_MAX, TemplateParamsParseError;
26067
+ var init_template_params = __esm({
26068
+ "shared/sdk/template-params.ts"() {
26069
+ "use strict";
26070
+ TEMPLATE_FIELD_TYPES = ["text", "password", "number", "select", "boolean"];
26071
+ TEMPLATE_MAX_FIELDS = 50;
26072
+ TEMPLATE_ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
26073
+ TEMPLATE_ENV_KEY_MAX = 128;
26074
+ TemplateParamsParseError = class extends Error {
26075
+ code;
26076
+ constructor(code, message) {
26077
+ super(message);
26078
+ this.name = "TemplateParamsParseError";
26079
+ this.code = code;
26080
+ }
26081
+ };
26082
+ }
26083
+ });
26084
+
26085
+ // packages/cli/src/serve/template-params.ts
26086
+ import { readFile as readFile15 } from "node:fs/promises";
26087
+ import { join as join19 } from "node:path";
26088
+ import { parse as parse3 } from "yaml";
26089
+ function mergeTemplateEnvSource(source) {
26090
+ return { ...source.processEnv, ...source.dotenv, ...source.dotenvLocal };
26091
+ }
26092
+ async function loadTemplateFields(cwd) {
26093
+ let text;
26094
+ try {
26095
+ text = await readFile15(join19(cwd, TEMPLATE_PARAMS_FILE), "utf8");
26096
+ } catch {
26097
+ return null;
26098
+ }
26099
+ let root;
26100
+ try {
26101
+ root = parse3(text);
26102
+ } catch (error51) {
26103
+ throw new TemplateParamsParseError(
26104
+ "TPL_YAML_SYNTAX",
26105
+ `${TEMPLATE_PARAMS_FILE} \u4E0D\u662F\u5408\u6CD5 YAML\uFF1A${error51 instanceof Error ? error51.message : "\u672A\u77E5\u9519\u8BEF"}`
26106
+ );
26107
+ }
26108
+ return extractTemplateFields(root);
26109
+ }
26110
+ async function readDotenvFile(cwd, name) {
26111
+ const text = await readFile15(join19(cwd, name), "utf8").catch(() => "");
26112
+ if (text === "") return {};
26113
+ return parseEnvFile(text);
26114
+ }
26115
+ async function resolveServeTemplateEnv(options) {
26116
+ const fields = await loadTemplateFields(options.cwd);
26117
+ if (fields === null) return null;
26118
+ return {
26119
+ envKeys: fields.map((f) => f.envKey),
26120
+ // 每次调用重算:`.env` 改动(重启)与 `.env.local` 改动(`--watch` 重载)都能立刻反映,
26121
+ // 与平台「改值刷新即生效」同一体验。字段数 ≤50,白名单过滤的开销可忽略。
26122
+ values: () => resolveTemplateEnvValues(fields, mergeTemplateEnvSource(options.source()))
26123
+ };
26124
+ }
26125
+ var TEMPLATE_PARAMS_FILE;
26126
+ var init_template_params2 = __esm({
26127
+ "packages/cli/src/serve/template-params.ts"() {
26128
+ "use strict";
26129
+ init_dev();
26130
+ init_template_params();
26131
+ TEMPLATE_PARAMS_FILE = "data.yml";
26132
+ }
26133
+ });
26134
+
26135
+ // shared/sdk/adep-env-inject.ts
26136
+ function escapeJsonForScript(json2) {
26137
+ return json2.replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026");
26138
+ }
26139
+ function injectAdepEnv(html, env) {
26140
+ const payload = escapeJsonForScript(JSON.stringify(env));
26141
+ const tag = `<script>window.__ADEP_ENV__=${payload};</script>`;
26142
+ const idx = html.search(/<head[^>]*>/i);
26143
+ if (idx === -1) return html;
26144
+ const after = html.indexOf(">", idx);
26145
+ if (after === -1) return html;
26146
+ return `${html.slice(0, after + 1)}${tag}${html.slice(after + 1)}`;
26147
+ }
26148
+ function isHtmlContentType(contentType) {
26149
+ return contentType.toLowerCase().startsWith("text/html");
26150
+ }
26151
+ var init_adep_env_inject = __esm({
26152
+ "shared/sdk/adep-env-inject.ts"() {
26153
+ "use strict";
26154
+ }
26155
+ });
26156
+
25792
26157
  // packages/cli/src/serve/server.ts
25793
26158
  var server_exports = {};
25794
26159
  __export(server_exports, {
@@ -25798,8 +26163,8 @@ __export(server_exports, {
25798
26163
  });
25799
26164
  import { createServer as createServer2 } from "node:http";
25800
26165
  import { watch as watch2 } from "node:fs";
25801
- import { mkdir as mkdir12, readFile as readFile15, stat as stat11 } from "node:fs/promises";
25802
- import { extname, join as join19, relative as relative4, resolve as resolve11 } from "node:path";
26166
+ import { mkdir as mkdir12, readFile as readFile16, stat as stat11 } from "node:fs/promises";
26167
+ import { extname, join as join20, relative as relative4, resolve as resolve11 } from "node:path";
25803
26168
  function envNumber(name) {
25804
26169
  const raw = process.env[name];
25805
26170
  if (raw === void 0 || raw.trim() === "") return void 0;
@@ -25832,7 +26197,7 @@ async function startServeServer(options) {
25832
26197
  ...options.dbFile === void 0 ? {} : { dbFile: options.dbFile }
25833
26198
  });
25834
26199
  const config2 = await loadConfig(cwd);
25835
- const functionsDir = join19(cwd, config2.functionsDir);
26200
+ const functionsDir = join20(cwd, config2.functionsDir);
25836
26201
  const bearerUser = bearerUserResolverFromEnv();
25837
26202
  let hasStatic = false;
25838
26203
  try {
@@ -25844,9 +26209,27 @@ async function startServeServer(options) {
25844
26209
  const loadFunctionFiles = async () => mergeSharedIntoFunctions(await collectFunctions(functionsDir));
25845
26210
  let files = await loadFunctionFiles();
25846
26211
  let functionNames = listFunctionNames(files);
25847
- const envText = await readFile15(join19(cwd, ".env.local"), "utf8").catch(() => "");
26212
+ const envText = await readFile16(join20(cwd, ".env.local"), "utf8").catch(() => "");
25848
26213
  let env = parseEnvFile(envText);
25849
26214
  let simEnv = await loadSimEnv(cwd).catch(() => ({}));
26215
+ const dotenvFile = await readDotenvFile(cwd, ".env");
26216
+ let templateEnv;
26217
+ try {
26218
+ templateEnv = await resolveServeTemplateEnv({
26219
+ cwd,
26220
+ // 传 getter 而非快照:`env` 在本作用域是 `let`(`--watch` 会重新赋值为新解析的
26221
+ // .env.local),快照会让「改 .env.local 立即生效」落空。
26222
+ source: () => ({ processEnv: process.env, dotenv: dotenvFile, dotenvLocal: env })
26223
+ });
26224
+ } catch (error51) {
26225
+ if (error51 instanceof TemplateParamsParseError) {
26226
+ throw new Error(
26227
+ `[serve] ${TEMPLATE_PARAMS_FILE} \u89E3\u6790\u5931\u8D25\uFF08${error51.code}\uFF09\uFF1A${error51.message}`,
26228
+ { cause: error51 }
26229
+ );
26230
+ }
26231
+ throw error51;
26232
+ }
25850
26233
  const db = await openLocalDbDriver(dbTarget, { cwd, tag: "serve", log });
25851
26234
  const dbMode = db.mode;
25852
26235
  const sqliteFile = db.file;
@@ -25877,7 +26260,7 @@ async function startServeServer(options) {
25877
26260
  const reload = async () => {
25878
26261
  const [nextFiles, envLocalText] = await Promise.all([
25879
26262
  loadFunctionFiles(),
25880
- readFile15(join19(cwd, ".env.local"), "utf8").catch(() => "")
26263
+ readFile16(join20(cwd, ".env.local"), "utf8").catch(() => "")
25881
26264
  ]);
25882
26265
  files = nextFiles;
25883
26266
  env = parseEnvFile(envLocalText);
@@ -25929,39 +26312,51 @@ async function startServeServer(options) {
25929
26312
  ...hasEnv ? { env: mergedEnv } : {}
25930
26313
  };
25931
26314
  };
26315
+ const sendStaticFile = (res, filePath, content) => {
26316
+ const contentType = contentTypeFor(filePath);
26317
+ if (templateEnv !== null && isHtmlContentType(contentType)) {
26318
+ const values = templateEnv.values();
26319
+ if (Object.keys(values).length > 0) {
26320
+ const injected = injectAdepEnv(content.toString("utf8"), values);
26321
+ res.writeHead(200, {
26322
+ "content-type": contentType,
26323
+ "content-length": String(Buffer.byteLength(injected, "utf8"))
26324
+ });
26325
+ res.end(injected);
26326
+ return;
26327
+ }
26328
+ }
26329
+ res.writeHead(200, { "content-type": contentType });
26330
+ res.end(content);
26331
+ };
25932
26332
  const serveStatic = async (pathname, res) => {
25933
26333
  if (!hasStatic) return false;
25934
26334
  const safePath = pathname.replace(/\.\.\//g, "").replace(/^\//, "");
25935
- const filePath = join19(staticDir, safePath);
25936
- const resolvedPath = safePath === "" || safePath === "/" ? join19(filePath, "index.html") : filePath;
26335
+ const filePath = join20(staticDir, safePath);
26336
+ const resolvedPath = safePath === "" || safePath === "/" ? join20(filePath, "index.html") : filePath;
25937
26337
  try {
25938
26338
  const fileStat = await stat11(resolvedPath);
25939
26339
  if (fileStat.isDirectory()) {
25940
- const indexPath = join19(resolvedPath, "index.html");
26340
+ const indexPath = join20(resolvedPath, "index.html");
25941
26341
  try {
25942
26342
  const indexStat = await stat11(indexPath);
25943
26343
  if (indexStat.isFile()) {
25944
- const content2 = await readFile15(indexPath);
25945
- res.writeHead(200, { "content-type": contentTypeFor(indexPath) });
25946
- res.end(content2);
26344
+ sendStaticFile(res, indexPath, await readFile16(indexPath));
25947
26345
  return true;
25948
26346
  }
25949
26347
  } catch {
25950
26348
  }
25951
26349
  return false;
25952
26350
  }
25953
- const content = await readFile15(resolvedPath);
25954
- res.writeHead(200, { "content-type": contentTypeFor(resolvedPath) });
25955
- res.end(content);
26351
+ sendStaticFile(res, resolvedPath, await readFile16(resolvedPath));
25956
26352
  return true;
25957
26353
  } catch {
25958
26354
  if (options.spaFallback === true) {
25959
26355
  const ext = extname(pathname);
25960
26356
  if (ext === "" || ext === ".html") {
25961
26357
  try {
25962
- const indexContent = await readFile15(join19(staticDir, "index.html"));
25963
- res.writeHead(200, { "content-type": "text/html; charset=utf-8" });
25964
- res.end(indexContent);
26358
+ const indexContent = await readFile16(join20(staticDir, "index.html"));
26359
+ sendStaticFile(res, join20(staticDir, "index.html"), indexContent);
25965
26360
  return true;
25966
26361
  } catch {
25967
26362
  }
@@ -26149,6 +26544,12 @@ async function startServeServer(options) {
26149
26544
  ...sqliteModule === null ? {} : { dbDriver: sqliteModule }
26150
26545
  });
26151
26546
  log(banner);
26547
+ if (templateEnv !== null) {
26548
+ const currentKeys = Object.keys(templateEnv.values());
26549
+ log(
26550
+ `[serve] \u6A21\u677F\u53C2\u6570\u6CE8\u5165\u5DF2\u542F\u7528\uFF08${TEMPLATE_PARAMS_FILE} \u58F0\u660E ${templateEnv.envKeys.join(", ")}\uFF09\uFF1B\u5F53\u524D\u6709\u503C\u7684\u952E\uFF1A${currentKeys.length > 0 ? currentKeys.join(", ") : "\uFF08\u65E0\u2014\u2014\u9875\u9762\u5C06\u56DE\u843D\u5185\u7F6E\u9ED8\u8BA4\u503C\uFF09"}`
26551
+ );
26552
+ }
26152
26553
  if (options.watch === true) {
26153
26554
  log(`[serve] \u70ED\u91CD\u8F7D\u5DF2\u5F00\u542F\uFF1A\u6539 functions/ \u4E0E .env* \u5373\u751F\u6548\uFF0C\u51FD\u6570 console \u8F93\u51FA\u76F4\u8FBE\u7EC8\u7AEF\uFF08--watch\uFF09`);
26154
26555
  }
@@ -26186,6 +26587,9 @@ var init_server = __esm({
26186
26587
  init_invoke();
26187
26588
  init_dev();
26188
26589
  init_banner();
26590
+ init_template_params2();
26591
+ init_adep_env_inject();
26592
+ init_template_params();
26189
26593
  init_db_mode();
26190
26594
  init_dev_shared();
26191
26595
  MIME_TYPES = {
@@ -26221,8 +26625,8 @@ __export(deploy_exports, {
26221
26625
  deploy: () => deploy
26222
26626
  });
26223
26627
  import { createHash as createHash4 } from "node:crypto";
26224
- import { readdir as readdir7, readFile as readFile16 } from "node:fs/promises";
26225
- import { join as join20, resolve as resolve12, basename as basename4, relative as relative5, sep } from "node:path";
26628
+ import { readdir as readdir7, readFile as readFile17 } from "node:fs/promises";
26629
+ import { join as join21, resolve as resolve12, basename as basename4, relative as relative5, sep } from "node:path";
26226
26630
  function functionUrlBase(prefix) {
26227
26631
  const raw = (prefix ?? "/api").trim();
26228
26632
  const normalized = raw === "/" ? "/" : raw.replace(/\/+$/, "");
@@ -26248,10 +26652,10 @@ async function collectFunctionFiles(functionsDir) {
26248
26652
  if (conflicting.length > 0) throw new AmbiguousFunctionError(functionsDir, conflicting);
26249
26653
  const out = {};
26250
26654
  for (const name of flatNames) {
26251
- out[name] = { [`${name}.ts`]: await readFile16(join20(functionsDir, `${name}.ts`), "utf8") };
26655
+ out[name] = { [`${name}.ts`]: await readFile17(join21(functionsDir, `${name}.ts`), "utf8") };
26252
26656
  }
26253
26657
  for (const name of dirNames) {
26254
- const files = await collectFunctionDir(join20(functionsDir, name));
26658
+ const files = await collectFunctionDir(join21(functionsDir, name));
26255
26659
  if (files["index.ts"] === void 0) continue;
26256
26660
  out[name] = files;
26257
26661
  }
@@ -26270,11 +26674,11 @@ async function collectFunctionDir(absDir) {
26270
26674
  const rel = prefix === "" ? entry.name : `${prefix}/${entry.name}`;
26271
26675
  if (entry.isDirectory()) {
26272
26676
  if (entry.name === "__tests__" || IGNORED_DIRS.has(entry.name)) continue;
26273
- await walk(join20(dir, entry.name), rel);
26677
+ await walk(join21(dir, entry.name), rel);
26274
26678
  continue;
26275
26679
  }
26276
26680
  if (!isRuntimeSource2(entry.name)) continue;
26277
- files[rel] = await readFile16(join20(dir, entry.name), "utf8");
26681
+ files[rel] = await readFile17(join21(dir, entry.name), "utf8");
26278
26682
  }
26279
26683
  };
26280
26684
  await walk(absDir, "");
@@ -26284,7 +26688,7 @@ function sha256Hex(content) {
26284
26688
  return createHash4("sha256").update(content).digest("hex");
26285
26689
  }
26286
26690
  async function collectShared(functionsDir) {
26287
- const sharedDir = join20(functionsDir, FUNCTION_SHARED_DIR);
26691
+ const sharedDir = join21(functionsDir, FUNCTION_SHARED_DIR);
26288
26692
  const files = {};
26289
26693
  const walk = async (dir) => {
26290
26694
  let entries;
@@ -26296,13 +26700,13 @@ async function collectShared(functionsDir) {
26296
26700
  for (const entry of entries) {
26297
26701
  if (entry.isDirectory()) {
26298
26702
  if (entry.name === "__tests__" || entry.name === "node_modules") continue;
26299
- await walk(join20(dir, entry.name));
26703
+ await walk(join21(dir, entry.name));
26300
26704
  continue;
26301
26705
  }
26302
26706
  if (!isRuntimeSource2(entry.name)) continue;
26303
- const full = join20(dir, entry.name);
26707
+ const full = join21(dir, entry.name);
26304
26708
  const rel = relative5(sharedDir, full).split(sep).join("/");
26305
- files[`${SHARED_SOURCE_ROOT}${rel}`] = await readFile16(full, "utf8");
26709
+ files[`${SHARED_SOURCE_ROOT}${rel}`] = await readFile17(full, "utf8");
26306
26710
  }
26307
26711
  };
26308
26712
  await walk(sharedDir);
@@ -26314,7 +26718,7 @@ async function deploy(paths, options) {
26314
26718
  const cwd = resolve12(options.cwd);
26315
26719
  const config2 = await loadConfig(cwd);
26316
26720
  const slug = options.slug ?? config2.name;
26317
- const functionsDir = options.functionsDir === void 0 ? join20(cwd, config2.functionsDir) : resolve12(cwd, options.functionsDir);
26721
+ const functionsDir = options.functionsDir === void 0 ? join21(cwd, config2.functionsDir) : resolve12(cwd, options.functionsDir);
26318
26722
  const local = await collectFunctionFiles(functionsDir);
26319
26723
  if (Object.keys(local).length === 0) {
26320
26724
  throw new CliError("NO_FUNCTIONS", `${functionsDir} \u4E0B\u6CA1\u6709\u51FD\u6570\u6587\u4EF6`);
@@ -26452,8 +26856,8 @@ var frontend_exports = {};
26452
26856
  __export(frontend_exports, {
26453
26857
  frontendSync: () => frontendSync
26454
26858
  });
26455
- import { readdir as readdir8, readFile as readFile17, stat as stat12 } from "node:fs/promises";
26456
- import { join as join21, relative as relative6, sep as sep2 } from "node:path";
26859
+ import { readdir as readdir8, readFile as readFile18, stat as stat12 } from "node:fs/promises";
26860
+ import { join as join22, relative as relative6, sep as sep2 } from "node:path";
26457
26861
  async function collectFiles(root, dir) {
26458
26862
  const files = /* @__PURE__ */ new Map();
26459
26863
  const skipped = [];
@@ -26461,13 +26865,13 @@ async function collectFiles(root, dir) {
26461
26865
  for (const entry of entries) {
26462
26866
  if (entry.isDirectory()) {
26463
26867
  if (IGNORED_DIRS2.has(entry.name)) continue;
26464
- const nested = await collectFiles(root, join21(dir, entry.name));
26868
+ const nested = await collectFiles(root, join22(dir, entry.name));
26465
26869
  for (const [path, content] of nested.files) files.set(path, content);
26466
26870
  skipped.push(...nested.skipped);
26467
26871
  continue;
26468
26872
  }
26469
26873
  if (IGNORED_FILES.has(entry.name)) continue;
26470
- const full = join21(dir, entry.name);
26874
+ const full = join22(dir, entry.name);
26471
26875
  const rel = relative6(root, full).split(sep2).join("/");
26472
26876
  const info = await stat12(full);
26473
26877
  if (info.size > 1024 * 1024) {
@@ -26475,7 +26879,7 @@ async function collectFiles(root, dir) {
26475
26879
  continue;
26476
26880
  }
26477
26881
  try {
26478
- const content = await readFile17(full, "utf8");
26882
+ const content = await readFile18(full, "utf8");
26479
26883
  if (content.includes("\0")) {
26480
26884
  skipped.push(rel);
26481
26885
  continue;
@@ -26490,7 +26894,7 @@ async function collectFiles(root, dir) {
26490
26894
  async function frontendSync(paths, options) {
26491
26895
  const log = options.silent === true ? () => void 0 : options.log ?? ((line) => process.stdout.write(`${line}
26492
26896
  `));
26493
- const webDir = options.dir ?? join21(options.cwd, "web");
26897
+ const webDir = options.dir ?? join22(options.cwd, "web");
26494
26898
  const rootStat = await stat12(webDir).catch(() => null);
26495
26899
  if (rootStat === null || !rootStat.isDirectory()) {
26496
26900
  throw new CliError(
@@ -26564,11 +26968,11 @@ var fs_exports = {};
26564
26968
  __export(fs_exports, {
26565
26969
  createExportFileSystem: () => createExportFileSystem
26566
26970
  });
26567
- import { mkdir as mkdir13, readFile as readFile18, rm as rm5, stat as stat14, writeFile as writeFile11 } from "node:fs/promises";
26568
- import { dirname as dirname13, join as join23 } from "node:path";
26971
+ import { mkdir as mkdir13, readFile as readFile19, rm as rm5, stat as stat14, writeFile as writeFile11 } from "node:fs/promises";
26972
+ import { dirname as dirname13, join as join24 } from "node:path";
26569
26973
  function createExportFileSystem() {
26570
26974
  return {
26571
- readFile: (path) => readFile18(path),
26975
+ readFile: (path) => readFile19(path),
26572
26976
  writeFile: (path, content) => writeFile11(path, content),
26573
26977
  // 同时用于清理解压临时目录(${zip}.tmp 是个目录)——递归强制删除,缺失不报错。
26574
26978
  deleteFile: async (path) => {
@@ -26586,9 +26990,9 @@ function createExportFileSystem() {
26586
26990
  await mkdir13(path, { recursive: true });
26587
26991
  },
26588
26992
  unzip: async (zipPath, targetDir) => {
26589
- const entries = zipRead(await readFile18(zipPath));
26993
+ const entries = zipRead(await readFile19(zipPath));
26590
26994
  for (const [name, data] of entries) {
26591
- const dest = join23(targetDir, name);
26995
+ const dest = join24(targetDir, name);
26592
26996
  await mkdir13(dirname13(dest), { recursive: true });
26593
26997
  await writeFile11(dest, data);
26594
26998
  }
@@ -26842,8 +27246,8 @@ __export(storage_exports, {
26842
27246
  storageRemove: () => storageRemove,
26843
27247
  storageUpload: () => storageUpload
26844
27248
  });
26845
- import { mkdir as mkdir14, readFile as readFile19, stat as stat15, writeFile as writeFile12 } from "node:fs/promises";
26846
- import { basename as basename5, dirname as dirname14, extname as extname2, join as join24, resolve as resolve14 } from "node:path";
27249
+ import { mkdir as mkdir14, readFile as readFile20, stat as stat15, writeFile as writeFile12 } from "node:fs/promises";
27250
+ import { basename as basename5, dirname as dirname14, extname as extname2, join as join25, resolve as resolve14 } from "node:path";
26847
27251
  async function open3(paths, options) {
26848
27252
  const client = await createClient(paths);
26849
27253
  const project2 = await resolveSlug(resolve14(options.cwd), options.slug);
@@ -26885,7 +27289,7 @@ async function storageUpload(paths, options) {
26885
27289
  throw new CliError("FILE_NOT_FOUND", `\u672C\u5730\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${local}`);
26886
27290
  }
26887
27291
  const visibility = options.visibility ?? "private";
26888
- const bytes = await readFile19(local);
27292
+ const bytes = await readFile20(local);
26889
27293
  const form = new FormData();
26890
27294
  form.set("path", options.path);
26891
27295
  form.set("visibility", visibility);
@@ -26926,7 +27330,7 @@ async function storageDownload(paths, options) {
26926
27330
  const url2 = await resolveDownloadUrl(client, project2, options.path);
26927
27331
  const response = await client.download(url2, "STORAGE_DOWNLOAD_FAILED");
26928
27332
  const bytes = Buffer.from(await response.arrayBuffer());
26929
- const output = resolve14(options.output ?? join24(resolve14(options.cwd), basename5(options.path)));
27333
+ const output = resolve14(options.output ?? join25(resolve14(options.cwd), basename5(options.path)));
26930
27334
  await mkdir14(dirname14(output), { recursive: true });
26931
27335
  await writeFile12(output, bytes);
26932
27336
  return { path: options.path, output, size: bytes.length };
@@ -26947,8 +27351,8 @@ var init_storage2 = __esm({
26947
27351
  });
26948
27352
 
26949
27353
  // packages/cli/src/sandbox-scan.ts
26950
- import { readdir as readdir9, readFile as readFile20 } from "node:fs/promises";
26951
- import { join as join25, relative as relative7, sep as sep3 } from "node:path";
27354
+ import { readdir as readdir9, readFile as readFile21 } from "node:fs/promises";
27355
+ import { join as join26, relative as relative7, sep as sep3 } from "node:path";
26952
27356
  function extractSpecifiers(line) {
26953
27357
  const out = [];
26954
27358
  const patterns = [
@@ -26992,7 +27396,7 @@ function classify(specifier) {
26992
27396
  return null;
26993
27397
  }
26994
27398
  async function scanFunctionSources(rootDir, functionsDir) {
26995
- const base = join25(rootDir, functionsDir);
27399
+ const base = join26(rootDir, functionsDir);
26996
27400
  const findings = [];
26997
27401
  async function walk(current) {
26998
27402
  let entries;
@@ -27002,7 +27406,7 @@ async function scanFunctionSources(rootDir, functionsDir) {
27002
27406
  return;
27003
27407
  }
27004
27408
  for (const entry of entries) {
27005
- const abs = join25(current, entry.name);
27409
+ const abs = join26(current, entry.name);
27006
27410
  if (entry.isDirectory()) {
27007
27411
  if (SKIP_DIRS.has(entry.name)) continue;
27008
27412
  await walk(abs);
@@ -27013,7 +27417,7 @@ async function scanFunctionSources(rootDir, functionsDir) {
27013
27417
  if (entry.name.endsWith(".d.ts")) continue;
27014
27418
  let content;
27015
27419
  try {
27016
- content = await readFile20(abs, "utf8");
27420
+ content = await readFile21(abs, "utf8");
27017
27421
  } catch {
27018
27422
  continue;
27019
27423
  }
@@ -27623,8 +28027,8 @@ __export(hosting_exports, {
27623
28027
  hostingInfo: () => hostingInfo,
27624
28028
  hostingPull: () => hostingPull
27625
28029
  });
27626
- import { readdir as readdir10, readFile as readFile21, stat as stat17 } from "node:fs/promises";
27627
- import { dirname as dirname15, join as join26, relative as relative8, resolve as resolve17, sep as sep4 } from "node:path";
28030
+ import { readdir as readdir10, readFile as readFile22, stat as stat17 } from "node:fs/promises";
28031
+ import { dirname as dirname15, join as join27, relative as relative8, resolve as resolve17, sep as sep4 } from "node:path";
27628
28032
  async function open4(paths, options) {
27629
28033
  const client = await createClient(paths);
27630
28034
  const project2 = await resolveSlug(resolve17(options.cwd), options.slug);
@@ -27650,7 +28054,7 @@ async function collectSiteFiles(dir) {
27650
28054
  return;
27651
28055
  }
27652
28056
  for (const entry of entries) {
27653
- const full = join26(sub, entry.name);
28057
+ const full = join27(sub, entry.name);
27654
28058
  if (entry.isDirectory()) {
27655
28059
  await walk(full);
27656
28060
  } else if (entry.isFile()) {
@@ -27674,7 +28078,7 @@ async function hostingDeploy(paths, options) {
27674
28078
  for (const [rel, full] of files) {
27675
28079
  log(`[adep] \u4E0A\u4F20 site/${rel}`);
27676
28080
  const info2 = await stat17(full);
27677
- const bytes = await readFile21(full);
28081
+ const bytes = await readFile22(full);
27678
28082
  const form = new FormData();
27679
28083
  form.set("path", `site/${rel}`);
27680
28084
  form.set("visibility", "public");
@@ -27712,7 +28116,7 @@ async function hostingPull(paths, options) {
27712
28116
  const response = await client.download(url2, "HOSTING_DOWNLOAD_FAILED");
27713
28117
  const bytes = Buffer.from(await response.arrayBuffer());
27714
28118
  const rel = entry.path.replace(/^site\//, "");
27715
- const target = join26(outputDir, ...rel.split("/"));
28119
+ const target = join27(outputDir, ...rel.split("/"));
27716
28120
  await mkdir15(dirname15(target), { recursive: true });
27717
28121
  await writeFile13(target, bytes);
27718
28122
  files.push({ path: entry.path, size: bytes.length });
@@ -29427,7 +29831,7 @@ init_auth();
29427
29831
  init_client();
29428
29832
  init_deploy();
29429
29833
  import { stat as stat13 } from "node:fs/promises";
29430
- import { join as join22, resolve as resolve13 } from "node:path";
29834
+ import { join as join23, resolve as resolve13 } from "node:path";
29431
29835
  async function resolveProjectId2(client, cwd, slug) {
29432
29836
  const resolvedSlug = await resolveSlug(resolve13(cwd), slug);
29433
29837
  const listed = await client.request("/api/v1/projects", {}, "PROJECT_LIST_FAILED");
@@ -29495,7 +29899,7 @@ async function runPublish(paths, io, cwd, flags) {
29495
29899
  });
29496
29900
  }
29497
29901
  if (wantFrontend) {
29498
- const webDir = join22(cwd, "web");
29902
+ const webDir = join23(cwd, "web");
29499
29903
  const webStat = await stat13(webDir).catch(() => null);
29500
29904
  if (webStat !== null && webStat.isDirectory()) {
29501
29905
  const { frontendSync: frontendSync2 } = await Promise.resolve().then(() => (init_frontend(), frontend_exports));
package/dist/vite.js CHANGED
@@ -2006,6 +2006,11 @@ function assertStoragePrefix(prefix) {
2006
2006
  }
2007
2007
  return prefix ?? "";
2008
2008
  }
2009
+ var DEV_STORAGE_SEGMENT = ".env-dev/";
2010
+ function isDevSegmentHidden(relPath, prefix) {
2011
+ if (prefix !== void 0 && prefix !== "" && prefix.startsWith(DEV_STORAGE_SEGMENT)) return false;
2012
+ return relPath.startsWith(DEV_STORAGE_SEGMENT);
2013
+ }
2009
2014
 
2010
2015
  // packages/runtime/src/storage/hmac-sha256.ts
2011
2016
  var K = new Uint32Array([
@@ -2434,8 +2439,7 @@ function createLocalStorageDriver(options) {
2434
2439
  await Promise.all(tasks);
2435
2440
  };
2436
2441
  await walk(root, "");
2437
- metas.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
2438
- return metas;
2442
+ return metas.filter((meta) => !isDevSegmentHidden(meta.path, prefix)).toSorted((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
2439
2443
  },
2440
2444
  async usage(projectId) {
2441
2445
  return totalSize(projectId);
@@ -3416,6 +3420,17 @@ var StateObjectRuntime = class {
3416
3420
  evictAll() {
3417
3421
  this.instances.clear();
3418
3422
  }
3423
+ /**
3424
+ * 先落盘再释放(CORE-079 惰性驱逐):逐实例 `flush()` 持久化后清空内存驻留,
3425
+ * 类型注册表保留(runtime 对象本身可复用;驱逐方通常直接丢弃整个 runtime)。
3426
+ * 任一实例 flush 抛错则**整体上抛且不清空**——调用方据此放弃驱逐,绝不静默丢未落盘状态。
3427
+ */
3428
+ async dispose() {
3429
+ for (const inst of this.instances.values()) {
3430
+ await this.flush(inst);
3431
+ }
3432
+ this.instances.clear();
3433
+ }
3419
3434
  };
3420
3435
 
3421
3436
  // packages/runtime/src/state-objects/backend.ts
@@ -4017,6 +4032,48 @@ function createSandboxFetch(options) {
4017
4032
  };
4018
4033
  }
4019
4034
 
4035
+ // packages/runtime/src/functions/runtime/flat-rpc-proxy.ts
4036
+ var IMPLICIT_PROTOCOL_KEYS = /* @__PURE__ */ new Set([
4037
+ "then",
4038
+ "catch",
4039
+ "finally",
4040
+ "toJSON",
4041
+ "toString",
4042
+ "valueOf",
4043
+ "constructor",
4044
+ "__proto__",
4045
+ "inspect"
4046
+ ]);
4047
+ function isImplicitProtocolKey(key) {
4048
+ return IMPLICIT_PROTOCOL_KEYS.has(key);
4049
+ }
4050
+ function createFlatRpcProxy(dispatch) {
4051
+ return new Proxy(
4052
+ {},
4053
+ {
4054
+ get(_target, method) {
4055
+ if (typeof method !== "string") return void 0;
4056
+ if (isImplicitProtocolKey(method)) return Reflect.get(Object.prototype, method);
4057
+ return (...args) => dispatch(method, args);
4058
+ }
4059
+ }
4060
+ );
4061
+ }
4062
+
4063
+ // packages/runtime/src/functions/runtime/rpc-client.ts
4064
+ function isRpcCapability(value) {
4065
+ return typeof value === "object" && value !== null && value[RPC_CAPABILITY_KEY] === true;
4066
+ }
4067
+ function createRpcClient(capability, port, pending, nextId) {
4068
+ return createFlatRpcProxy((method, args) => {
4069
+ const id = nextId();
4070
+ return new Promise((resolve5, reject) => {
4071
+ pending.set(id, { resolve: resolve5, reject });
4072
+ port.postMessage({ type: "rpc", id, capability, method, args });
4073
+ });
4074
+ });
4075
+ }
4076
+
4020
4077
  // packages/runtime/src/functions/runtime/rpc-wire.ts
4021
4078
  function wireRpcResponses(port, pending) {
4022
4079
  port.on?.((message) => {
@@ -4107,26 +4164,6 @@ function escapeRegExp(text) {
4107
4164
  }
4108
4165
 
4109
4166
  // packages/runtime/src/functions/runtime/worker-entry.ts
4110
- function isRpcCapability(value) {
4111
- return typeof value === "object" && value !== null && value[RPC_CAPABILITY_KEY] === true;
4112
- }
4113
- function createRpcClient(capability, port, pending, nextId) {
4114
- return new Proxy(
4115
- {},
4116
- {
4117
- get(_target, method) {
4118
- if (typeof method !== "string") return void 0;
4119
- return (...args) => {
4120
- const id = nextId();
4121
- return new Promise((resolve5, reject) => {
4122
- pending.set(id, { resolve: resolve5, reject });
4123
- port.postMessage({ type: "rpc", id, capability, method, args });
4124
- });
4125
- };
4126
- }
4127
- }
4128
- );
4129
- }
4130
4167
  function errorMessageOf2(error) {
4131
4168
  if (error instanceof Error) return error.message;
4132
4169
  if (typeof error === "object" && error !== null && "message" in error) {
@@ -434,6 +434,48 @@ var DB_RPC = {
434
434
  chain: "chain"
435
435
  };
436
436
 
437
+ // packages/runtime/src/functions/runtime/flat-rpc-proxy.ts
438
+ var IMPLICIT_PROTOCOL_KEYS = /* @__PURE__ */ new Set([
439
+ "then",
440
+ "catch",
441
+ "finally",
442
+ "toJSON",
443
+ "toString",
444
+ "valueOf",
445
+ "constructor",
446
+ "__proto__",
447
+ "inspect"
448
+ ]);
449
+ function isImplicitProtocolKey(key) {
450
+ return IMPLICIT_PROTOCOL_KEYS.has(key);
451
+ }
452
+ function createFlatRpcProxy(dispatch) {
453
+ return new Proxy(
454
+ {},
455
+ {
456
+ get(_target, method) {
457
+ if (typeof method !== "string") return void 0;
458
+ if (isImplicitProtocolKey(method)) return Reflect.get(Object.prototype, method);
459
+ return (...args) => dispatch(method, args);
460
+ }
461
+ }
462
+ );
463
+ }
464
+
465
+ // packages/runtime/src/functions/runtime/rpc-client.ts
466
+ function isRpcCapability(value) {
467
+ return typeof value === "object" && value !== null && value[RPC_CAPABILITY_KEY] === true;
468
+ }
469
+ function createRpcClient(capability, port, pending, nextId) {
470
+ return createFlatRpcProxy((method, args) => {
471
+ const id = nextId();
472
+ return new Promise((resolve, reject) => {
473
+ pending.set(id, { resolve, reject });
474
+ port.postMessage({ type: "rpc", id, capability, method, args });
475
+ });
476
+ });
477
+ }
478
+
437
479
  // packages/runtime/src/functions/runtime/rpc-wire.ts
438
480
  function wireRpcResponses(port, pending) {
439
481
  port.on?.((message) => {
@@ -533,26 +575,6 @@ function escapeRegExp(text) {
533
575
  }
534
576
 
535
577
  // packages/runtime/src/functions/runtime/worker-entry.ts
536
- function isRpcCapability(value) {
537
- return typeof value === "object" && value !== null && value[RPC_CAPABILITY_KEY] === true;
538
- }
539
- function createRpcClient(capability, port, pending, nextId) {
540
- return new Proxy(
541
- {},
542
- {
543
- get(_target, method) {
544
- if (typeof method !== "string") return void 0;
545
- return (...args) => {
546
- const id = nextId();
547
- return new Promise((resolve, reject) => {
548
- pending.set(id, { resolve, reject });
549
- port.postMessage({ type: "rpc", id, capability, method, args });
550
- });
551
- };
552
- }
553
- }
554
- );
555
- }
556
578
  function errorMessageOf2(error) {
557
579
  if (error instanceof Error) return error.message;
558
580
  if (typeof error === "object" && error !== null && "message" in error) {
package/package.json CHANGED
@@ -1,6 +1,13 @@
1
1
  {
2
2
  "name": "@adep/cli",
3
- "version": "0.2.2",
3
+ "license": "MIT",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://gitcode.com/yunqiang_wu/ai-yunke.git"
7
+ },
8
+ "homepage": "https://adep.jajabjbj.top",
9
+ "bugs": "https://gitcode.com/yunqiang_wu/ai-yunke/issues",
10
+ "version": "0.3.1",
4
11
  "type": "module",
5
12
  "description": "`adep` 命令行工具包位:登录 / 初始化 / 本地调试 / 部署 / 数据库维护 / 云存储 / 静态托管 / 微前端组件(widget),实现见任务单 CLI-001 ~ CLI-003 与 FE-002;子路径 `@adep/cli/vite` 提供云函数 vite 插件(CLI-014)",
6
13
  "bin": {
@@ -21,11 +28,12 @@
21
28
  "dependencies": {
22
29
  "commander": "14.0.2",
23
30
  "esbuild": "0.25.12",
31
+ "yaml": "2.9.1",
24
32
  "zod": "^4.4.3",
25
33
  "@adep/cf-compat": "0.1.1",
26
34
  "@adep/runtime": "0.3.2",
27
- "@adep/crypto": "0.1.0",
28
- "@adep/vite-plugin": "0.1.8"
35
+ "@adep/vite-plugin": "0.1.8",
36
+ "@adep/crypto": "0.1.0"
29
37
  },
30
38
  "devDependencies": {
31
39
  "@adep/types": "0.3.0"
@@ -6,7 +6,7 @@
6
6
 
7
7
  移动端与桌面端能力对齐(§2.11.1),差异只在打包壳与分发口径:iOS / Android 有应用商店
8
8
  审核约束,签名与上架由开发者自行完成(见下方「签名与上架」,完整指引
9
- [`docs/mobile-shell-signing.md`](../../docs/mobile-shell-signing.md))。
9
+ [`docs/mobile-shell-signing.md`](../../../../docs/mobile-shell-signing.md))。
10
10
 
11
11
  ## 目录结构
12
12