@adep/cli 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +32 -10
  2. package/dist/index.js +1320 -944
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -9,6 +9,20 @@ var __export = (target, all) => {
9
9
  __defProp(target, name, { get: all[name], enumerable: true });
10
10
  };
11
11
 
12
+ // packages/cli/src/config.ts
13
+ function resolvePaths(env = process.env) {
14
+ const home = env["ADEP_HOME"] ?? `${env["HOME"] ?? ""}/.adep`;
15
+ return { home, credentialsFile: `${home}/credentials` };
16
+ }
17
+ function resolveServer(env = process.env) {
18
+ return (env["ADEP_SERVER"] ?? "https://adep.jajabjbj.top").replace(/\/+$/, "");
19
+ }
20
+ var init_config = __esm({
21
+ "packages/cli/src/config.ts"() {
22
+ "use strict";
23
+ }
24
+ });
25
+
12
26
  // packages/cli/src/credentials.ts
13
27
  import { mkdir, open, readFile, rm, stat } from "node:fs/promises";
14
28
  import { dirname } from "node:path";
@@ -218,58 +232,6 @@ var init_auth = __esm({
218
232
  }
219
233
  });
220
234
 
221
- // packages/cli/src/config.ts
222
- function resolvePaths(env = process.env) {
223
- const home = env["ADEP_HOME"] ?? `${env["HOME"] ?? ""}/.adep`;
224
- return { home, credentialsFile: `${home}/credentials` };
225
- }
226
- function resolveServer(env = process.env) {
227
- return (env["ADEP_SERVER"] ?? "https://adep.jajabjbj.top").replace(/\/+$/, "");
228
- }
229
- var init_config = __esm({
230
- "packages/cli/src/config.ts"() {
231
- "use strict";
232
- }
233
- });
234
-
235
- // packages/cli/src/widget/build.ts
236
- import { createHash } from "node:crypto";
237
- import { join as join2, resolve as resolve2 } from "node:path";
238
- import { build as esbuildBuild } from "esbuild";
239
- async function buildWidget(options) {
240
- const root = resolve2(options.cwd);
241
- const entry = join2(root, options.entry ?? "src/index.ts");
242
- const result = await esbuildBuild({
243
- entryPoints: [entry],
244
- bundle: true,
245
- write: false,
246
- format: "esm",
247
- target: ["es2020"],
248
- logLevel: "error",
249
- loader: { ".ts": "ts", ".tsx": "tsx", ".js": "js", ".jsx": "jsx" },
250
- ...options.framework === "react" ? { jsx: "automatic", jsxImportSource: "react" } : {}
251
- });
252
- const text = result.outputFiles?.[0]?.text ?? "";
253
- if (text.length === 0) {
254
- throw new WidgetError("EMPTY_BUILD", "\u6784\u5EFA\u4EA7\u7269\u4E3A\u7A7A\uFF1A\u8BF7\u68C0\u67E5 widget \u5165\u53E3\u662F\u5426\u6B63\u786E");
255
- }
256
- const hash = createHash("sha256").update(text).digest("hex");
257
- return { text, hash };
258
- }
259
- var WidgetError;
260
- var init_build = __esm({
261
- "packages/cli/src/widget/build.ts"() {
262
- "use strict";
263
- WidgetError = class extends Error {
264
- constructor(code, message) {
265
- super(message);
266
- this.code = code;
267
- this.name = "WidgetError";
268
- }
269
- };
270
- }
271
- });
272
-
273
235
  // packages/cli/src/widget/templates.ts
274
236
  function vue3Files(name) {
275
237
  return {
@@ -486,6 +448,44 @@ AgentDeploy \u5FAE\u524D\u7AEF\u7EC4\u4EF6\uFF08widget\uFF09\u3002
486
448
  }
487
449
  });
488
450
 
451
+ // packages/cli/src/widget/build.ts
452
+ import { createHash } from "node:crypto";
453
+ import { join as join2, resolve as resolve2 } from "node:path";
454
+ import { build as esbuildBuild } from "esbuild";
455
+ async function buildWidget(options) {
456
+ const root = resolve2(options.cwd);
457
+ const entry = join2(root, options.entry ?? "src/index.ts");
458
+ const result = await esbuildBuild({
459
+ entryPoints: [entry],
460
+ bundle: true,
461
+ write: false,
462
+ format: "esm",
463
+ target: ["es2020"],
464
+ logLevel: "error",
465
+ loader: { ".ts": "ts", ".tsx": "tsx", ".js": "js", ".jsx": "jsx" },
466
+ ...options.framework === "react" ? { jsx: "automatic", jsxImportSource: "react" } : {}
467
+ });
468
+ const text = result.outputFiles?.[0]?.text ?? "";
469
+ if (text.length === 0) {
470
+ throw new WidgetError("EMPTY_BUILD", "\u6784\u5EFA\u4EA7\u7269\u4E3A\u7A7A\uFF1A\u8BF7\u68C0\u67E5 widget \u5165\u53E3\u662F\u5426\u6B63\u786E");
471
+ }
472
+ const hash = createHash("sha256").update(text).digest("hex");
473
+ return { text, hash };
474
+ }
475
+ var WidgetError;
476
+ var init_build = __esm({
477
+ "packages/cli/src/widget/build.ts"() {
478
+ "use strict";
479
+ WidgetError = class extends Error {
480
+ constructor(code, message) {
481
+ super(message);
482
+ this.code = code;
483
+ this.name = "WidgetError";
484
+ }
485
+ };
486
+ }
487
+ });
488
+
489
489
  // packages/cli/src/widget/init.ts
490
490
  var init_exports = {};
491
491
  __export(init_exports, {
@@ -542,6 +542,48 @@ var init_init = __esm({
542
542
  }
543
543
  });
544
544
 
545
+ // packages/cli/src/prompt.ts
546
+ var prompt_exports = {};
547
+ __export(prompt_exports, {
548
+ createPrompt: () => createPrompt
549
+ });
550
+ import { createInterface } from "node:readline/promises";
551
+ import { Writable } from "node:stream";
552
+ function createPrompt(input = process.stdin) {
553
+ const rl = createInterface({ input, output: process.stdout, terminal: true });
554
+ let muted = null;
555
+ return {
556
+ async ask(question) {
557
+ const answer = await rl.question(question);
558
+ return answer.trim();
559
+ },
560
+ async askHidden(question) {
561
+ muted = createInterface({ input, output: new MutedStream(), terminal: true });
562
+ const answer = await muted.question(question);
563
+ muted.close();
564
+ muted = null;
565
+ process.stdout.write("\n");
566
+ return answer.trim();
567
+ },
568
+ close() {
569
+ muted?.close();
570
+ rl.close();
571
+ }
572
+ };
573
+ }
574
+ var MutedStream;
575
+ var init_prompt = __esm({
576
+ "packages/cli/src/prompt.ts"() {
577
+ "use strict";
578
+ MutedStream = class extends Writable {
579
+ write(_chunk, ...rest) {
580
+ void rest;
581
+ return true;
582
+ }
583
+ };
584
+ }
585
+ });
586
+
545
587
  // packages/runtime/src/shared/capability-keys.ts
546
588
  var RPC_CAPABILITY_KEY, CHAIN_CAPABILITY_KEY, DB_RPC, REALTIME_CAPABILITY_CODES, REALTIME_CAPABILITY_METHODS;
547
589
  var init_capability_keys = __esm({
@@ -2926,9 +2968,9 @@ function listFunctionNames(files) {
2926
2968
  const names = /* @__PURE__ */ new Set();
2927
2969
  for (const key of Object.keys(files)) {
2928
2970
  const parts = key.split("/");
2929
- if (parts.length === 1 && parts[0]?.endsWith(".ts")) {
2971
+ if (parts.length === 1 && parts[0] !== void 0 && parts[0].endsWith(".ts")) {
2930
2972
  names.add(parts[0].slice(0, -3));
2931
- } else if (parts.length === 2 && parts[1] === "index.ts") {
2973
+ } else if (parts.length === 2 && parts[1] === "index.ts" && parts[0] !== void 0) {
2932
2974
  names.add(parts[0]);
2933
2975
  }
2934
2976
  }
@@ -3270,321 +3312,68 @@ var init_dev = __esm({
3270
3312
  }
3271
3313
  });
3272
3314
 
3273
- // packages/cli/src/client.ts
3274
- var client_exports = {};
3275
- __export(client_exports, {
3276
- createClient: () => createClient,
3277
- resolveSlug: () => resolveSlug
3278
- });
3279
- async function envelopeError(response, fallbackCode, parsed) {
3280
- const payload = parsed ?? null;
3281
- return new CliError(
3282
- payload?.error?.code ?? fallbackCode,
3283
- payload?.error?.message ?? `\u5E73\u53F0\u8FD4\u56DE HTTP ${response.status}`
3284
- );
3315
+ // packages/cli/src/serve/banner.ts
3316
+ function isLoopback(host) {
3317
+ return host === "127.0.0.1" || host === "localhost" || host === "::1" || host === "[::1]";
3285
3318
  }
3286
- async function parseBody(response) {
3287
- const text = await response.text();
3288
- if (text.length === 0) return null;
3289
- try {
3290
- return JSON.parse(text);
3291
- } catch {
3292
- return null;
3319
+ function renderBanner(options) {
3320
+ const { host, port, projectName, functions, hasStatic, staticDir = "public/" } = options;
3321
+ const baseUrl = `http://${host}:${port}`;
3322
+ const loopback = isLoopback(host);
3323
+ const lines = [];
3324
+ lines.push("");
3325
+ lines.push("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557");
3326
+ lines.push("\u2551 adep serve \u2014 \u5F00\u53D1\u6001\u670D\u52A1\u5668 \u2551");
3327
+ lines.push("\u2551 \u26A0 \u8FD9\u4E0D\u662F\u751F\u4EA7\u670D\u52A1\u5668\uFF0C\u4E0D\u63D0\u4F9B TLS / \u96C6\u7FA4 / \u4F18\u96C5\u91CD\u542F \u2551");
3328
+ lines.push("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D");
3329
+ lines.push("");
3330
+ lines.push(` \u9879\u76EE: ${projectName}`);
3331
+ lines.push(` \u5730\u5740: ${baseUrl}`);
3332
+ lines.push(` \u7ED1\u5B9A: ${host}${loopback ? "\uFF08\u4EC5\u672C\u673A\u53EF\u8BBF\u95EE\uFF09" : "\uFF08\u26A0 \u5BF9\u5916\u66B4\u9732\uFF09"}`);
3333
+ lines.push("");
3334
+ lines.push(" \u80FD\u529B:");
3335
+ if (functions.length > 0) {
3336
+ lines.push(
3337
+ ` - \u51FD\u6570\u8DEF\u7531: ${baseUrl}/api/{fn}\uFF08${functions.length} \u4E2A\u51FD\u6570: ${functions.join(", ")}\uFF09`
3338
+ );
3339
+ } else {
3340
+ lines.push(" - \u51FD\u6570\u8DEF\u7531: \u65E0\uFF08functions/ \u76EE\u5F55\u4E3A\u7A7A\uFF09");
3341
+ }
3342
+ if (hasStatic) {
3343
+ lines.push(` - \u9759\u6001\u6258\u7BA1: ${baseUrl}/ \u2192 ${staticDir}`);
3344
+ } else {
3345
+ lines.push(` - \u9759\u6001\u6258\u7BA1: \u65E0\uFF08${staticDir} \u76EE\u5F55\u4E0D\u5B58\u5728\uFF09`);
3346
+ }
3347
+ lines.push(" - \u7EC4\u4EF6\u9884\u89C8: Widget / Page \u4EA7\u7269\uFF08\u5982\u5DF2\u6784\u5EFA\uFF09");
3348
+ lines.push(` - \u5065\u5EB7\u68C0\u67E5: ${baseUrl}/healthz`);
3349
+ lines.push("");
3350
+ lines.push(" \u8FB9\u754C\uFF08\u5F00\u53D1\u6001\u9ED8\u8BA4\u503C\uFF0C\u4E0D\u53EF\u5728\u6B64\u6A21\u5F0F\u4E0B\u5F00\u542F\uFF09:");
3351
+ lines.push(" - \u65E0\u9274\u6743\uFF1A\u4EFB\u4F55\u4EBA\u53EF\u8C03\u7528\u6240\u6709\u51FD\u6570");
3352
+ lines.push(" - \u65E0\u9650\u6D41\uFF1A\u65E0 QPS / \u5E76\u53D1\u9650\u5236");
3353
+ lines.push(" - \u65E0\u914D\u989D\uFF1A\u65E0\u8C03\u7528\u6B21\u6570 / \u8D44\u6E90\u7528\u91CF\u9650\u5236");
3354
+ lines.push(" - \u65E0 TLS\uFF1A\u660E\u6587 HTTP\uFF0C\u4E0D\u652F\u6301 HTTPS");
3355
+ lines.push(" - \u65E0\u96C6\u7FA4\uFF1A\u5355\u8FDB\u7A0B\uFF0C\u4E0D\u652F\u6301\u591A\u5B9E\u4F8B");
3356
+ lines.push(" - \u65E0\u4F18\u96C5\u91CD\u542F\uFF1A\u8FDB\u7A0B\u9000\u51FA\u5373\u4E2D\u65AD");
3357
+ lines.push("");
3358
+ if (!loopback) {
3359
+ lines.push(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
3360
+ lines.push(" \u2502 \u26A0\u26A0\u26A0 \u5BF9\u5916\u66B4\u9732\u8B66\u544A \u2502");
3361
+ lines.push(" \u2502 \u2502");
3362
+ lines.push(` \u2502 \u5F53\u524D\u7ED1\u5B9A ${host.padEnd(43)}\u2502`);
3363
+ lines.push(" \u2502 \u5C40\u57DF\u7F51/\u516C\u7F51\u5185\u4EFB\u4F55\u4EBA\u90FD\u53EF\u8BBF\u95EE\u4F60\u7684\u51FD\u6570\u4E0E\u6570\u636E\u3002 \u2502");
3364
+ lines.push(" \u2502 \u65E0\u9274\u6743\u3001\u65E0\u9650\u6D41\u3001\u65E0\u914D\u989D\u2014\u2014\u8BF7\u52FF\u5728\u4E0D\u53EF\u4FE1\u7F51\u7EDC\u4E2D\u4F7F\u7528\u3002 \u2502");
3365
+ lines.push(" \u2502 \u2502");
3366
+ lines.push(" \u2502 \u9700\u8981\u751F\u4EA7\u90E8\u7F72\uFF1F\u4F7F\u7528 `adep deploy` \u90E8\u7F72\u5230\u5E73\u53F0\u3002 \u2502");
3367
+ lines.push(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
3368
+ lines.push("");
3293
3369
  }
3370
+ lines.push(" \u6309 Ctrl+C \u505C\u6B62\u670D\u52A1\u5668\u3002");
3371
+ lines.push("");
3372
+ return lines.join("\n");
3294
3373
  }
3295
- async function createClient(paths) {
3296
- const credentials = await loadCredentials(paths);
3297
- if (credentials === null) {
3298
- throw new CliError("NOT_LOGGED_IN", "\u672A\u767B\u5F55\uFF1A\u8BF7\u5148\u6267\u884C adep login");
3299
- }
3300
- const server = credentials.server;
3301
- const cookie = `better-auth.session_token=${decodeToken(credentials.encodedToken)}`;
3302
- const request = async (path, init = {}, fallbackCode = "API_REQUEST_FAILED") => {
3303
- const method = init.method ?? (init.body === void 0 ? "GET" : "POST");
3304
- let response;
3305
- try {
3306
- response = await fetch(`${server}${path}`, {
3307
- method,
3308
- headers: { "content-type": "application/json", cookie },
3309
- ...init.body === void 0 ? {} : { body: JSON.stringify(init.body) }
3310
- });
3311
- } catch (error) {
3312
- throw new CliError(
3313
- "SERVER_UNREACHABLE",
3314
- `\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
3315
- );
3316
- }
3317
- const parsed = await parseBody(response);
3318
- if (response.status < 200 || response.status >= 300) {
3319
- throw await envelopeError(response, fallbackCode, parsed);
3320
- }
3321
- return parsed;
3322
- };
3323
- const upload = async (path, form, fallbackCode = "UPLOAD_FAILED") => {
3324
- let response;
3325
- try {
3326
- response = await fetch(`${server}${path}`, {
3327
- method: "POST",
3328
- headers: { cookie },
3329
- body: form
3330
- });
3331
- } catch (error) {
3332
- throw new CliError(
3333
- "SERVER_UNREACHABLE",
3334
- `\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
3335
- );
3336
- }
3337
- if (response.status < 200 || response.status >= 300) {
3338
- throw await envelopeError(response, fallbackCode, await parseBody(response));
3339
- }
3340
- return response;
3341
- };
3342
- const download = async (url, fallbackCode = "DOWNLOAD_FAILED") => {
3343
- const target = url.startsWith("http") ? url : `${server}${url}`;
3344
- let response;
3345
- try {
3346
- response = await fetch(target, { headers: { cookie } });
3347
- } catch (error) {
3348
- throw new CliError(
3349
- "SERVER_UNREACHABLE",
3350
- `\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
3351
- );
3352
- }
3353
- if (response.status < 200 || response.status >= 300) {
3354
- throw await envelopeError(response, fallbackCode, await parseBody(response));
3355
- }
3356
- return response;
3357
- };
3358
- return { server, cookie, request, upload, download };
3359
- }
3360
- async function resolveSlug(cwd, slug) {
3361
- if (slug !== void 0 && slug.length > 0) return slug;
3362
- const config = await loadConfig(cwd);
3363
- return config.name;
3364
- }
3365
- var init_client = __esm({
3366
- "packages/cli/src/client.ts"() {
3367
- "use strict";
3368
- init_auth();
3369
- init_credentials();
3370
- init_dev();
3371
- }
3372
- });
3373
-
3374
- // packages/cli/src/deploy.ts
3375
- var deploy_exports = {};
3376
- __export(deploy_exports, {
3377
- collectEntries: () => collectEntries,
3378
- deploy: () => deploy
3379
- });
3380
- import { createHash as createHash3 } from "node:crypto";
3381
- import { readdir as readdir3, readFile as readFile6 } from "node:fs/promises";
3382
- import { join as join10, resolve as resolve6, basename as basename2 } from "node:path";
3383
- async function collectEntries(functionsDir) {
3384
- const entries = {};
3385
- let names;
3386
- try {
3387
- const dirents = await readdir3(functionsDir, { withFileTypes: true });
3388
- names = dirents.filter((entry) => entry.isFile() && entry.name.endsWith(".ts")).map((entry) => basename2(entry.name, ".ts")).toSorted();
3389
- } catch {
3390
- return entries;
3391
- }
3392
- for (const name of names) {
3393
- entries[name] = await readFile6(join10(functionsDir, `${name}.ts`), "utf8");
3394
- }
3395
- return entries;
3396
- }
3397
- function sha256Hex(content) {
3398
- return createHash3("sha256").update(content).digest("hex");
3399
- }
3400
- async function deploy(paths, options) {
3401
- await requireNetwork("adep deploy");
3402
- const log = options.silent === true ? () => void 0 : options.log ?? ((line) => process.stdout.write(`${line}
3403
- `));
3404
- const client = await createClient(paths);
3405
- const cwd = resolve6(options.cwd);
3406
- const config = await loadConfig(cwd);
3407
- const slug = options.slug ?? config.name;
3408
- const functionsDir = options.functionsDir === void 0 ? join10(cwd, config.functionsDir) : resolve6(cwd, options.functionsDir);
3409
- const local = await collectEntries(functionsDir);
3410
- if (Object.keys(local).length === 0) {
3411
- throw new CliError("NO_FUNCTIONS", `${functionsDir} \u4E0B\u6CA1\u6709\u51FD\u6570\u6587\u4EF6`);
3412
- }
3413
- const remote = await client.request(
3414
- "/api/v1/deploy/diff",
3415
- {
3416
- body: {
3417
- slug,
3418
- functions: Object.entries(local).map(([name, content]) => ({
3419
- name,
3420
- files: { "index.ts": sha256Hex(content) }
3421
- }))
3422
- }
3423
- },
3424
- "DEPLOY_FAILED"
3425
- );
3426
- const baseUrl = `${remote.scheme}://${remote.slug}.${remote.domain}`;
3427
- const deployed = [];
3428
- for (const item of remote.functions) {
3429
- const content = local[item.name];
3430
- if (item.action === "none") {
3431
- deployed.push({
3432
- name: item.name,
3433
- action: "none",
3434
- version: item.version ?? 0,
3435
- url: `${baseUrl}/${item.name}`
3436
- });
3437
- continue;
3438
- }
3439
- log(`[adep] \u90E8\u7F72 ${item.name}\uFF08${item.action === "create" ? "\u65B0\u5EFA" : "\u53D8\u66F4"}\uFF09`);
3440
- let functionId = item.id;
3441
- if (functionId === null) {
3442
- const created = await client.request(
3443
- `/api/v1/projects/${remote.projectId}/functions`,
3444
- {
3445
- body: { name: item.name, files: { "index.ts": content } }
3446
- }
3447
- );
3448
- functionId = created.id;
3449
- } else {
3450
- await client.request(`/api/v1/projects/${remote.projectId}/functions/${item.name}`, {
3451
- method: "PATCH",
3452
- body: { files: { "index.ts": content } }
3453
- });
3454
- }
3455
- const published = await client.request(
3456
- `/api/v1/functions/${functionId}/publish`,
3457
- { method: "POST" }
3458
- );
3459
- deployed.push({
3460
- name: item.name,
3461
- action: item.action,
3462
- version: published.version,
3463
- url: `${baseUrl}/${item.name}`
3464
- });
3465
- }
3466
- return {
3467
- projectId: remote.projectId,
3468
- slug: remote.slug,
3469
- baseUrl,
3470
- noChanges: deployed.every((function_) => function_.action === "none"),
3471
- functions: deployed
3472
- };
3473
- }
3474
- var init_deploy = __esm({
3475
- "packages/cli/src/deploy.ts"() {
3476
- "use strict";
3477
- init_auth();
3478
- init_client();
3479
- init_dev();
3480
- init_net();
3481
- }
3482
- });
3483
-
3484
- // packages/cli/src/prompt.ts
3485
- var prompt_exports = {};
3486
- __export(prompt_exports, {
3487
- createPrompt: () => createPrompt
3488
- });
3489
- import { createInterface } from "node:readline/promises";
3490
- import { Writable } from "node:stream";
3491
- function createPrompt(input = process.stdin) {
3492
- const rl = createInterface({ input, output: process.stdout, terminal: true });
3493
- let muted = null;
3494
- return {
3495
- async ask(question) {
3496
- const answer = await rl.question(question);
3497
- return answer.trim();
3498
- },
3499
- async askHidden(question) {
3500
- muted = createInterface({ input, output: new MutedStream(), terminal: true });
3501
- const answer = await muted.question(question);
3502
- muted.close();
3503
- muted = null;
3504
- process.stdout.write("\n");
3505
- return answer.trim();
3506
- },
3507
- close() {
3508
- muted?.close();
3509
- rl.close();
3510
- }
3511
- };
3512
- }
3513
- var MutedStream;
3514
- var init_prompt = __esm({
3515
- "packages/cli/src/prompt.ts"() {
3516
- "use strict";
3517
- MutedStream = class extends Writable {
3518
- write(_chunk, ...rest) {
3519
- void rest;
3520
- return true;
3521
- }
3522
- };
3523
- }
3524
- });
3525
-
3526
- // packages/cli/src/serve/banner.ts
3527
- function isLoopback(host) {
3528
- return host === "127.0.0.1" || host === "localhost" || host === "::1" || host === "[::1]";
3529
- }
3530
- function renderBanner(options) {
3531
- const { host, port, projectName, functions, hasStatic, staticDir = "public/" } = options;
3532
- const baseUrl = `http://${host}:${port}`;
3533
- const loopback = isLoopback(host);
3534
- const lines = [];
3535
- lines.push("");
3536
- lines.push("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557");
3537
- lines.push("\u2551 adep serve \u2014 \u5F00\u53D1\u6001\u670D\u52A1\u5668 \u2551");
3538
- lines.push("\u2551 \u26A0 \u8FD9\u4E0D\u662F\u751F\u4EA7\u670D\u52A1\u5668\uFF0C\u4E0D\u63D0\u4F9B TLS / \u96C6\u7FA4 / \u4F18\u96C5\u91CD\u542F \u2551");
3539
- lines.push("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D");
3540
- lines.push("");
3541
- lines.push(` \u9879\u76EE: ${projectName}`);
3542
- lines.push(` \u5730\u5740: ${baseUrl}`);
3543
- lines.push(` \u7ED1\u5B9A: ${host}${loopback ? "\uFF08\u4EC5\u672C\u673A\u53EF\u8BBF\u95EE\uFF09" : "\uFF08\u26A0 \u5BF9\u5916\u66B4\u9732\uFF09"}`);
3544
- lines.push("");
3545
- lines.push(" \u80FD\u529B:");
3546
- if (functions.length > 0) {
3547
- lines.push(
3548
- ` - \u51FD\u6570\u8DEF\u7531: ${baseUrl}/api/{fn}\uFF08${functions.length} \u4E2A\u51FD\u6570: ${functions.join(", ")}\uFF09`
3549
- );
3550
- } else {
3551
- lines.push(" - \u51FD\u6570\u8DEF\u7531: \u65E0\uFF08functions/ \u76EE\u5F55\u4E3A\u7A7A\uFF09");
3552
- }
3553
- if (hasStatic) {
3554
- lines.push(` - \u9759\u6001\u6258\u7BA1: ${baseUrl}/ \u2192 ${staticDir}`);
3555
- } else {
3556
- lines.push(` - \u9759\u6001\u6258\u7BA1: \u65E0\uFF08${staticDir} \u76EE\u5F55\u4E0D\u5B58\u5728\uFF09`);
3557
- }
3558
- lines.push(" - \u7EC4\u4EF6\u9884\u89C8: Widget / Page \u4EA7\u7269\uFF08\u5982\u5DF2\u6784\u5EFA\uFF09");
3559
- lines.push(` - \u5065\u5EB7\u68C0\u67E5: ${baseUrl}/healthz`);
3560
- lines.push("");
3561
- lines.push(" \u8FB9\u754C\uFF08\u5F00\u53D1\u6001\u9ED8\u8BA4\u503C\uFF0C\u4E0D\u53EF\u5728\u6B64\u6A21\u5F0F\u4E0B\u5F00\u542F\uFF09:");
3562
- lines.push(" - \u65E0\u9274\u6743\uFF1A\u4EFB\u4F55\u4EBA\u53EF\u8C03\u7528\u6240\u6709\u51FD\u6570");
3563
- lines.push(" - \u65E0\u9650\u6D41\uFF1A\u65E0 QPS / \u5E76\u53D1\u9650\u5236");
3564
- lines.push(" - \u65E0\u914D\u989D\uFF1A\u65E0\u8C03\u7528\u6B21\u6570 / \u8D44\u6E90\u7528\u91CF\u9650\u5236");
3565
- lines.push(" - \u65E0 TLS\uFF1A\u660E\u6587 HTTP\uFF0C\u4E0D\u652F\u6301 HTTPS");
3566
- lines.push(" - \u65E0\u96C6\u7FA4\uFF1A\u5355\u8FDB\u7A0B\uFF0C\u4E0D\u652F\u6301\u591A\u5B9E\u4F8B");
3567
- lines.push(" - \u65E0\u4F18\u96C5\u91CD\u542F\uFF1A\u8FDB\u7A0B\u9000\u51FA\u5373\u4E2D\u65AD");
3568
- lines.push("");
3569
- if (!loopback) {
3570
- lines.push(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
3571
- lines.push(" \u2502 \u26A0\u26A0\u26A0 \u5BF9\u5916\u66B4\u9732\u8B66\u544A \u2502");
3572
- lines.push(" \u2502 \u2502");
3573
- lines.push(` \u2502 \u5F53\u524D\u7ED1\u5B9A ${host.padEnd(43)}\u2502`);
3574
- lines.push(" \u2502 \u5C40\u57DF\u7F51/\u516C\u7F51\u5185\u4EFB\u4F55\u4EBA\u90FD\u53EF\u8BBF\u95EE\u4F60\u7684\u51FD\u6570\u4E0E\u6570\u636E\u3002 \u2502");
3575
- lines.push(" \u2502 \u65E0\u9274\u6743\u3001\u65E0\u9650\u6D41\u3001\u65E0\u914D\u989D\u2014\u2014\u8BF7\u52FF\u5728\u4E0D\u53EF\u4FE1\u7F51\u7EDC\u4E2D\u4F7F\u7528\u3002 \u2502");
3576
- lines.push(" \u2502 \u2502");
3577
- lines.push(" \u2502 \u9700\u8981\u751F\u4EA7\u90E8\u7F72\uFF1F\u4F7F\u7528 `adep deploy` \u90E8\u7F72\u5230\u5E73\u53F0\u3002 \u2502");
3578
- lines.push(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
3579
- lines.push("");
3580
- }
3581
- lines.push(" \u6309 Ctrl+C \u505C\u6B62\u670D\u52A1\u5668\u3002");
3582
- lines.push("");
3583
- return lines.join("\n");
3584
- }
3585
- var init_banner = __esm({
3586
- "packages/cli/src/serve/banner.ts"() {
3587
- "use strict";
3374
+ var init_banner = __esm({
3375
+ "packages/cli/src/serve/banner.ts"() {
3376
+ "use strict";
3588
3377
  }
3589
3378
  });
3590
3379
 
@@ -3595,8 +3384,9 @@ __export(server_exports, {
3595
3384
  startServeServer: () => startServeServer
3596
3385
  });
3597
3386
  import { createServer as createServer2 } from "node:http";
3598
- import { readdir as readdir4, readFile as readFile7, stat as stat6 } from "node:fs/promises";
3599
- import { join as join11, relative, resolve as resolve7 } from "node:path";
3387
+ import { watch as watch2 } from "node:fs";
3388
+ import { mkdir as mkdir7, readdir as readdir3, readFile as readFile6, stat as stat6 } from "node:fs/promises";
3389
+ import { join as join10, relative, resolve as resolve6 } from "node:path";
3600
3390
  function envNumber(name) {
3601
3391
  const raw = process.env[name];
3602
3392
  if (raw === void 0 || raw.trim() === "") return void 0;
@@ -3612,17 +3402,17 @@ async function collectFunctions2(dir) {
3612
3402
  const walk = async (sub, prefix) => {
3613
3403
  let entries;
3614
3404
  try {
3615
- entries = await readdir4(sub, { withFileTypes: true });
3405
+ entries = await readdir3(sub, { withFileTypes: true });
3616
3406
  } catch {
3617
3407
  return;
3618
3408
  }
3619
3409
  for (const entry of entries) {
3620
3410
  const rel = prefix.length === 0 ? entry.name : `${prefix}/${entry.name}`;
3621
- const full = join11(sub, entry.name);
3411
+ const full = join10(sub, entry.name);
3622
3412
  if (entry.isDirectory()) {
3623
3413
  await walk(full, rel);
3624
3414
  } else if (entry.isFile() && entry.name.endsWith(".ts")) {
3625
- files[rel] = await readFile7(full, "utf8");
3415
+ files[rel] = await readFile6(full, "utf8");
3626
3416
  }
3627
3417
  }
3628
3418
  };
@@ -3657,17 +3447,17 @@ function contentTypeFor(path) {
3657
3447
  return MIME_TYPES[ext] ?? "application/octet-stream";
3658
3448
  }
3659
3449
  async function startServeServer(options) {
3660
- const cwd = resolve7(options.cwd);
3450
+ const cwd = resolve6(options.cwd);
3661
3451
  const log = options.log ?? ((line) => process.stdout.write(`${line}
3662
3452
  `));
3663
3453
  const host = options.host ?? envString("HOST") ?? "127.0.0.1";
3664
3454
  const port = options.port ?? envNumber("PORT") ?? 8787;
3665
- const staticDir = resolve7(
3455
+ const staticDir = resolve6(
3666
3456
  cwd,
3667
3457
  options.staticDir ?? envString("ADEP_SERVE_STATIC_DIR") ?? "public"
3668
3458
  );
3669
3459
  const config = await loadConfig(cwd);
3670
- const functionsDir = join11(cwd, config.functionsDir);
3460
+ const functionsDir = join10(cwd, config.functionsDir);
3671
3461
  let hasStatic = false;
3672
3462
  try {
3673
3463
  const publicStat = await stat6(staticDir);
@@ -3675,11 +3465,11 @@ async function startServeServer(options) {
3675
3465
  } catch {
3676
3466
  hasStatic = false;
3677
3467
  }
3678
- const files = await collectFunctions2(functionsDir);
3679
- const functionNames = listFunctionNames(files);
3680
- const envText = await readFile7(join11(cwd, ".env.local"), "utf8").catch(() => "");
3681
- const env = parseEnvFile(envText);
3682
- const simEnv = await loadSimEnv(cwd).catch(() => ({}));
3468
+ let files = await collectFunctions2(functionsDir);
3469
+ let functionNames = listFunctionNames(files);
3470
+ const envText = await readFile6(join10(cwd, ".env.local"), "utf8").catch(() => "");
3471
+ let env = parseEnvFile(envText);
3472
+ let simEnv = await loadSimEnv(cwd).catch(() => ({}));
3683
3473
  const runtime = await createSimRuntime({
3684
3474
  cwd,
3685
3475
  projectId: "local",
@@ -3688,7 +3478,44 @@ async function startServeServer(options) {
3688
3478
  });
3689
3479
  const executor = new WorkerFunctionExecutor();
3690
3480
  const dbBundle = runtime.bundle;
3691
- const invokeHandler = createSimInvokeHandler({ executor, files });
3481
+ let invokeHandler = createSimInvokeHandler({ executor, files });
3482
+ let stopWatch;
3483
+ if (options.watch === true) {
3484
+ const reload = async () => {
3485
+ const [nextFiles, envLocalText] = await Promise.all([
3486
+ collectFunctions2(functionsDir),
3487
+ readFile6(join10(cwd, ".env.local"), "utf8").catch(() => "")
3488
+ ]);
3489
+ files = nextFiles;
3490
+ env = parseEnvFile(envLocalText);
3491
+ simEnv = await loadSimEnv(cwd).catch(() => ({}));
3492
+ invokeHandler = createSimInvokeHandler({ executor, files });
3493
+ functionNames = listFunctionNames(files);
3494
+ log(`[serve] \u70ED\u91CD\u8F7D\uFF1A\u68C0\u6D4B\u5230\u53D8\u66F4\uFF0C\u5DF2\u91CD\u65B0\u52A0\u8F7D ${functionNames.length} \u4E2A\u51FD\u6570`);
3495
+ };
3496
+ let debounceTimer;
3497
+ const watchers = [];
3498
+ const scheduleReload = () => {
3499
+ if (debounceTimer !== void 0) clearTimeout(debounceTimer);
3500
+ debounceTimer = setTimeout(() => {
3501
+ void reload();
3502
+ }, 120);
3503
+ };
3504
+ await mkdir7(functionsDir, { recursive: true }).catch(() => void 0);
3505
+ try {
3506
+ watchers.push(watch2(functionsDir, { recursive: true }, scheduleReload));
3507
+ } catch {
3508
+ log("[serve] \u8B66\u544A\uFF1Afunctions/ \u9012\u5F52\u76D1\u542C\u4E0D\u53EF\u7528\uFF0C\u70ED\u91CD\u8F7D\u5173\u95ED\uFF08\u670D\u52A1\u6B63\u5E38\u8FD0\u884C\uFF09");
3509
+ }
3510
+ try {
3511
+ watchers.push(watch2(cwd, scheduleReload));
3512
+ } catch {
3513
+ }
3514
+ stopWatch = () => {
3515
+ if (debounceTimer !== void 0) clearTimeout(debounceTimer);
3516
+ for (const watcher of watchers) watcher.close();
3517
+ };
3518
+ }
3692
3519
  const buildInput = async (fnName, entry, url, req) => {
3693
3520
  const query = {};
3694
3521
  for (const key of new Set(url.searchParams.keys())) {
@@ -3726,16 +3553,16 @@ async function startServeServer(options) {
3726
3553
  const serveStatic = async (pathname, res) => {
3727
3554
  if (!hasStatic) return false;
3728
3555
  const safePath = pathname.replace(/\.\.\//g, "").replace(/^\//, "");
3729
- const filePath = join11(staticDir, safePath);
3730
- const resolvedPath = safePath === "" || safePath === "/" ? join11(filePath, "index.html") : filePath;
3556
+ const filePath = join10(staticDir, safePath);
3557
+ const resolvedPath = safePath === "" || safePath === "/" ? join10(filePath, "index.html") : filePath;
3731
3558
  try {
3732
3559
  const fileStat = await stat6(resolvedPath);
3733
3560
  if (fileStat.isDirectory()) {
3734
- const indexPath = join11(resolvedPath, "index.html");
3561
+ const indexPath = join10(resolvedPath, "index.html");
3735
3562
  try {
3736
3563
  const indexStat = await stat6(indexPath);
3737
3564
  if (indexStat.isFile()) {
3738
- const content2 = await readFile7(indexPath);
3565
+ const content2 = await readFile6(indexPath);
3739
3566
  res.writeHead(200, { "content-type": contentTypeFor(indexPath) });
3740
3567
  res.end(content2);
3741
3568
  return true;
@@ -3744,7 +3571,7 @@ async function startServeServer(options) {
3744
3571
  }
3745
3572
  return false;
3746
3573
  }
3747
- const content = await readFile7(resolvedPath);
3574
+ const content = await readFile6(resolvedPath);
3748
3575
  res.writeHead(200, { "content-type": contentTypeFor(resolvedPath) });
3749
3576
  res.end(content);
3750
3577
  return true;
@@ -3775,6 +3602,9 @@ async function startServeServer(options) {
3775
3602
  const result = await executor.execute(input);
3776
3603
  const durationMs = Math.round(performance.now() - startedAt);
3777
3604
  log(`[serve] ${req.method ?? "GET"} ${pathname} -> 200 ${durationMs}ms`);
3605
+ if (options.watch === true) {
3606
+ for (const line of result.logs) log(`[serve] ${line}`);
3607
+ }
3778
3608
  writeJson2(res, 200, result.body === void 0 ? null : result.body);
3779
3609
  } catch (error) {
3780
3610
  const durationMs = Math.round(performance.now() - startedAt);
@@ -3808,13 +3638,13 @@ async function startServeServer(options) {
3808
3638
  if (pathname.startsWith("/_preview/")) {
3809
3639
  const widgetName = pathname.slice("/_preview/".length).split("/")[0];
3810
3640
  if (widgetName !== void 0 && widgetName.length > 0) {
3811
- const widgetDir = join11(cwd, ".adep", "widgets", widgetName);
3641
+ const widgetDir = join10(cwd, ".adep", "widgets", widgetName);
3812
3642
  try {
3813
3643
  const widgetStat = await stat6(widgetDir);
3814
3644
  if (widgetStat.isDirectory()) {
3815
- const indexPath = join11(widgetDir, "index.html");
3645
+ const indexPath = join10(widgetDir, "index.html");
3816
3646
  try {
3817
- const content = await readFile7(indexPath, "utf8");
3647
+ const content = await readFile6(indexPath, "utf8");
3818
3648
  res.writeHead(200, { "content-type": "text/html; charset=utf-8" });
3819
3649
  res.end(content);
3820
3650
  return;
@@ -3875,11 +3705,15 @@ async function startServeServer(options) {
3875
3705
  staticDir: relative(cwd, staticDir).length > 0 ? relative(cwd, staticDir) : staticDir
3876
3706
  });
3877
3707
  log(banner);
3708
+ if (options.watch === true) {
3709
+ 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`);
3710
+ }
3878
3711
  return {
3879
3712
  port: actualPort,
3880
3713
  host,
3881
3714
  baseUrl: `http://${host}:${actualPort}`,
3882
3715
  close: async () => {
3716
+ stopWatch?.();
3883
3717
  await new Promise((resolveClose) => {
3884
3718
  server.close(() => resolveClose());
3885
3719
  });
@@ -3921,6 +3755,217 @@ var init_server = __esm({
3921
3755
  }
3922
3756
  });
3923
3757
 
3758
+ // packages/cli/src/client.ts
3759
+ var client_exports = {};
3760
+ __export(client_exports, {
3761
+ createClient: () => createClient,
3762
+ resolveSlug: () => resolveSlug
3763
+ });
3764
+ async function envelopeError(response, fallbackCode, parsed) {
3765
+ const payload = parsed ?? null;
3766
+ return new CliError(
3767
+ payload?.error?.code ?? fallbackCode,
3768
+ payload?.error?.message ?? `\u5E73\u53F0\u8FD4\u56DE HTTP ${response.status}`
3769
+ );
3770
+ }
3771
+ async function parseBody(response) {
3772
+ const text = await response.text();
3773
+ if (text.length === 0) return null;
3774
+ try {
3775
+ return JSON.parse(text);
3776
+ } catch {
3777
+ return null;
3778
+ }
3779
+ }
3780
+ async function createClient(paths) {
3781
+ const credentials = await loadCredentials(paths);
3782
+ if (credentials === null) {
3783
+ throw new CliError("NOT_LOGGED_IN", "\u672A\u767B\u5F55\uFF1A\u8BF7\u5148\u6267\u884C adep login");
3784
+ }
3785
+ const server = credentials.server;
3786
+ const cookie = `better-auth.session_token=${decodeToken(credentials.encodedToken)}`;
3787
+ const request = async (path, init = {}, fallbackCode = "API_REQUEST_FAILED") => {
3788
+ const method = init.method ?? (init.body === void 0 ? "GET" : "POST");
3789
+ let response;
3790
+ try {
3791
+ response = await fetch(`${server}${path}`, {
3792
+ method,
3793
+ headers: { "content-type": "application/json", cookie },
3794
+ ...init.body === void 0 ? {} : { body: JSON.stringify(init.body) }
3795
+ });
3796
+ } catch (error) {
3797
+ throw new CliError(
3798
+ "SERVER_UNREACHABLE",
3799
+ `\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
3800
+ );
3801
+ }
3802
+ const parsed = await parseBody(response);
3803
+ if (response.status < 200 || response.status >= 300) {
3804
+ throw await envelopeError(response, fallbackCode, parsed);
3805
+ }
3806
+ return parsed;
3807
+ };
3808
+ const upload = async (path, form, fallbackCode = "UPLOAD_FAILED") => {
3809
+ let response;
3810
+ try {
3811
+ response = await fetch(`${server}${path}`, {
3812
+ method: "POST",
3813
+ headers: { cookie },
3814
+ body: form
3815
+ });
3816
+ } catch (error) {
3817
+ throw new CliError(
3818
+ "SERVER_UNREACHABLE",
3819
+ `\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
3820
+ );
3821
+ }
3822
+ if (response.status < 200 || response.status >= 300) {
3823
+ throw await envelopeError(response, fallbackCode, await parseBody(response));
3824
+ }
3825
+ return response;
3826
+ };
3827
+ const download = async (url, fallbackCode = "DOWNLOAD_FAILED") => {
3828
+ const target = url.startsWith("http") ? url : `${server}${url}`;
3829
+ let response;
3830
+ try {
3831
+ response = await fetch(target, { headers: { cookie } });
3832
+ } catch (error) {
3833
+ throw new CliError(
3834
+ "SERVER_UNREACHABLE",
3835
+ `\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
3836
+ );
3837
+ }
3838
+ if (response.status < 200 || response.status >= 300) {
3839
+ throw await envelopeError(response, fallbackCode, await parseBody(response));
3840
+ }
3841
+ return response;
3842
+ };
3843
+ return { server, cookie, request, upload, download };
3844
+ }
3845
+ async function resolveSlug(cwd, slug) {
3846
+ if (slug !== void 0 && slug.length > 0) return slug;
3847
+ const config = await loadConfig(cwd);
3848
+ return config.name;
3849
+ }
3850
+ var init_client = __esm({
3851
+ "packages/cli/src/client.ts"() {
3852
+ "use strict";
3853
+ init_auth();
3854
+ init_credentials();
3855
+ init_dev();
3856
+ }
3857
+ });
3858
+
3859
+ // packages/cli/src/deploy.ts
3860
+ var deploy_exports = {};
3861
+ __export(deploy_exports, {
3862
+ collectEntries: () => collectEntries,
3863
+ deploy: () => deploy
3864
+ });
3865
+ import { createHash as createHash3 } from "node:crypto";
3866
+ import { readdir as readdir4, readFile as readFile7 } from "node:fs/promises";
3867
+ import { join as join11, resolve as resolve7, basename as basename2 } from "node:path";
3868
+ async function collectEntries(functionsDir) {
3869
+ const entries = {};
3870
+ let names;
3871
+ try {
3872
+ const dirents = await readdir4(functionsDir, { withFileTypes: true });
3873
+ names = dirents.filter((entry) => entry.isFile() && entry.name.endsWith(".ts")).map((entry) => basename2(entry.name, ".ts")).toSorted();
3874
+ } catch {
3875
+ return entries;
3876
+ }
3877
+ for (const name of names) {
3878
+ entries[name] = await readFile7(join11(functionsDir, `${name}.ts`), "utf8");
3879
+ }
3880
+ return entries;
3881
+ }
3882
+ function sha256Hex(content) {
3883
+ return createHash3("sha256").update(content).digest("hex");
3884
+ }
3885
+ async function deploy(paths, options) {
3886
+ await requireNetwork("adep deploy");
3887
+ const log = options.silent === true ? () => void 0 : options.log ?? ((line) => process.stdout.write(`${line}
3888
+ `));
3889
+ const client = await createClient(paths);
3890
+ const cwd = resolve7(options.cwd);
3891
+ const config = await loadConfig(cwd);
3892
+ const slug = options.slug ?? config.name;
3893
+ const functionsDir = options.functionsDir === void 0 ? join11(cwd, config.functionsDir) : resolve7(cwd, options.functionsDir);
3894
+ const local = await collectEntries(functionsDir);
3895
+ if (Object.keys(local).length === 0) {
3896
+ throw new CliError("NO_FUNCTIONS", `${functionsDir} \u4E0B\u6CA1\u6709\u51FD\u6570\u6587\u4EF6`);
3897
+ }
3898
+ const remote = await client.request(
3899
+ "/api/v1/deploy/diff",
3900
+ {
3901
+ body: {
3902
+ slug,
3903
+ functions: Object.entries(local).map(([name, content]) => ({
3904
+ name,
3905
+ files: { "index.ts": sha256Hex(content) }
3906
+ }))
3907
+ }
3908
+ },
3909
+ "DEPLOY_FAILED"
3910
+ );
3911
+ const baseUrl = `${remote.scheme}://${remote.slug}.${remote.domain}`;
3912
+ const deployed = [];
3913
+ for (const item of remote.functions) {
3914
+ const content = local[item.name];
3915
+ if (item.action === "none") {
3916
+ deployed.push({
3917
+ name: item.name,
3918
+ action: "none",
3919
+ version: item.version ?? 0,
3920
+ url: `${baseUrl}/${item.name}`
3921
+ });
3922
+ continue;
3923
+ }
3924
+ log(`[adep] \u90E8\u7F72 ${item.name}\uFF08${item.action === "create" ? "\u65B0\u5EFA" : "\u53D8\u66F4"}\uFF09`);
3925
+ let functionId = item.id;
3926
+ if (functionId === null) {
3927
+ const created = await client.request(
3928
+ `/api/v1/projects/${remote.projectId}/functions`,
3929
+ {
3930
+ body: { name: item.name, files: { "index.ts": content } }
3931
+ }
3932
+ );
3933
+ functionId = created.id;
3934
+ } else {
3935
+ await client.request(`/api/v1/projects/${remote.projectId}/functions/${item.name}`, {
3936
+ method: "PATCH",
3937
+ body: { files: { "index.ts": content } }
3938
+ });
3939
+ }
3940
+ const published = await client.request(
3941
+ `/api/v1/functions/${functionId}/publish`,
3942
+ { method: "POST" }
3943
+ );
3944
+ deployed.push({
3945
+ name: item.name,
3946
+ action: item.action,
3947
+ version: published.version,
3948
+ url: `${baseUrl}/${item.name}`
3949
+ });
3950
+ }
3951
+ return {
3952
+ projectId: remote.projectId,
3953
+ slug: remote.slug,
3954
+ baseUrl,
3955
+ noChanges: deployed.every((function_) => function_.action === "none"),
3956
+ functions: deployed
3957
+ };
3958
+ }
3959
+ var init_deploy = __esm({
3960
+ "packages/cli/src/deploy.ts"() {
3961
+ "use strict";
3962
+ init_auth();
3963
+ init_client();
3964
+ init_dev();
3965
+ init_net();
3966
+ }
3967
+ });
3968
+
3924
3969
  // packages/cli/src/projects.ts
3925
3970
  var projects_exports = {};
3926
3971
  __export(projects_exports, {
@@ -4374,7 +4419,7 @@ __export(storage_exports, {
4374
4419
  storageRemove: () => storageRemove,
4375
4420
  storageUpload: () => storageUpload
4376
4421
  });
4377
- import { mkdir as mkdir7, readFile as readFile8, stat as stat8, writeFile as writeFile6 } from "node:fs/promises";
4422
+ import { mkdir as mkdir8, readFile as readFile8, stat as stat8, writeFile as writeFile6 } from "node:fs/promises";
4378
4423
  import { basename as basename3, dirname as dirname7, extname, join as join12, resolve as resolve11 } from "node:path";
4379
4424
  async function open3(paths, options) {
4380
4425
  const client = await createClient(paths);
@@ -4459,7 +4504,7 @@ async function storageDownload(paths, options) {
4459
4504
  const response = await client.download(url, "STORAGE_DOWNLOAD_FAILED");
4460
4505
  const bytes = Buffer.from(await response.arrayBuffer());
4461
4506
  const output = resolve11(options.output ?? join12(resolve11(options.cwd), basename3(options.path)));
4462
- await mkdir7(dirname7(output), { recursive: true });
4507
+ await mkdir8(dirname7(output), { recursive: true });
4463
4508
  await writeFile6(output, bytes);
4464
4509
  return { path: options.path, output, size: bytes.length };
4465
4510
  }
@@ -4565,7 +4610,7 @@ async function hostingPull(paths, options) {
4565
4610
  `));
4566
4611
  const info = await hostingInfo(paths, options);
4567
4612
  const outputDir = resolve12(options.output ?? resolve12(options.cwd));
4568
- const { mkdir: mkdir9, writeFile: writeFile9 } = await import("node:fs/promises");
4613
+ const { mkdir: mkdir10, writeFile: writeFile9 } = await import("node:fs/promises");
4569
4614
  const files = [];
4570
4615
  for (const entry of info.files) {
4571
4616
  if (entry.visibility !== "public" || entry.path === HOSTING_CONFIG_PATH) continue;
@@ -4576,7 +4621,7 @@ async function hostingPull(paths, options) {
4576
4621
  const bytes = Buffer.from(await response.arrayBuffer());
4577
4622
  const rel = entry.path.replace(/^site\//, "");
4578
4623
  const target = join13(outputDir, ...rel.split("/"));
4579
- await mkdir9(dirname8(target), { recursive: true });
4624
+ await mkdir10(dirname8(target), { recursive: true });
4580
4625
  await writeFile9(target, bytes);
4581
4626
  files.push({ path: entry.path, size: bytes.length });
4582
4627
  }
@@ -4750,7 +4795,7 @@ var fs_exports = {};
4750
4795
  __export(fs_exports, {
4751
4796
  createExportFileSystem: () => createExportFileSystem
4752
4797
  });
4753
- import { mkdir as mkdir8, readFile as readFile10, rm as rm3, stat as stat10, writeFile as writeFile8 } from "node:fs/promises";
4798
+ import { mkdir as mkdir9, readFile as readFile10, rm as rm3, stat as stat10, writeFile as writeFile8 } from "node:fs/promises";
4754
4799
  import { dirname as dirname9, join as join14 } from "node:path";
4755
4800
  function createExportFileSystem() {
4756
4801
  return {
@@ -4769,13 +4814,13 @@ function createExportFileSystem() {
4769
4814
  }
4770
4815
  },
4771
4816
  mkdir: async (path) => {
4772
- await mkdir8(path, { recursive: true });
4817
+ await mkdir9(path, { recursive: true });
4773
4818
  },
4774
4819
  unzip: async (zipPath, targetDir) => {
4775
4820
  const entries = zipRead(await readFile10(zipPath));
4776
4821
  for (const [name, data] of entries) {
4777
4822
  const dest = join14(targetDir, name);
4778
- await mkdir8(dirname9(dest), { recursive: true });
4823
+ await mkdir9(dirname9(dest), { recursive: true });
4779
4824
  await writeFile8(dest, data);
4780
4825
  }
4781
4826
  }
@@ -5289,7 +5334,7 @@ __export(dev_exports2, {
5289
5334
  startWidgetDev: () => startWidgetDev
5290
5335
  });
5291
5336
  import { createServer as createServer3 } from "node:http";
5292
- import { watch as watch2 } from "node:fs";
5337
+ import { watch as watch3 } from "node:fs";
5293
5338
  import { readFile as readFile11, stat as stat11 } from "node:fs/promises";
5294
5339
  import { join as join15, resolve as resolve13 } from "node:path";
5295
5340
  async function loadWidgetProject(cwd) {
@@ -5411,7 +5456,7 @@ data: ${version}
5411
5456
  let debounceTimer;
5412
5457
  let watcher;
5413
5458
  try {
5414
- watcher = watch2(cwd, { recursive: true }, () => {
5459
+ watcher = watch3(cwd, { recursive: true }, () => {
5415
5460
  if (debounceTimer !== void 0) clearTimeout(debounceTimer);
5416
5461
  debounceTimer = setTimeout(() => {
5417
5462
  void buildWidget({ cwd, framework }).then((built) => {
@@ -5573,14 +5618,296 @@ var init_publish = __esm({
5573
5618
  });
5574
5619
 
5575
5620
  // packages/cli/src/cli.ts
5576
- init_auth();
5577
5621
  init_config();
5578
5622
  import { Command } from "commander";
5579
5623
  import { createRequire } from "node:module";
5580
5624
 
5625
+ // packages/cli/src/output.ts
5626
+ init_auth();
5627
+
5581
5628
  // packages/cli/src/init.ts
5582
5629
  import { mkdir as mkdir2, stat as stat2, writeFile } from "node:fs/promises";
5583
5630
  import { dirname as dirname2, join, resolve } from "node:path";
5631
+
5632
+ // shared/sdk/adep-env.ts
5633
+ var ADEP_ENV_DTS = `/**
5634
+ * AgentDeploy \u4E91\u51FD\u6570\u5F00\u53D1\u73AF\u5883\u7C7B\u578B\u58F0\u660E\uFF08\u90E8\u7F72\u5305 / adep init \u751F\u6210\uFF0C\u8BF7\u52FF\u624B\u6539\uFF09\u3002
5635
+ *
5636
+ * \u672C\u6587\u4EF6\u662F @adep/types \u7684\u6E90\u7801\u6587\u672C\u955C\u50CF\uFF1A\u4E3A\u51FD\u6570\u6E90\u7801\u91CC\u7684 ctx \u63D0\u4F9B method/path/query/
5637
+ * headers/body/files/user \u4E0E cloud.db / cloud.storage / cloud.fetch / cloud.realtime \u7684\u5B8C\u6574\u8865\u5168\u3002
5638
+ * \u5168\u5C40 ctx \u4E0E AdepContext \u662F\u5F00\u53D1\u671F\u4E0A\u4E0B\u6587\uFF08\u7F16\u8F91\u5668\u8865\u5168\u7528\uFF09\uFF1B\u51FD\u6570\u8FD0\u884C\u671F\u7ECF\u53C2\u6570\u6CE8\u5165\uFF0C\u4E0D\u8BFB\u53D6\u5168\u5C40\u3002
5639
+ * \u7C7B\u578B\u5951\u7EA6\u7684\u5355\u4E00\u771F\u76F8\u6E90\u89C1 packages/types\uFF08\u4EFB\u52A1\u5355 CORE-006\uFF09\u3002
5640
+ */
5641
+
5642
+ /* ---------- HTTP \u89E6\u53D1\u4E0A\u4E0B\u6587\uFF08FunctionContext \u955C\u50CF\uFF09 ---------- */
5643
+
5644
+ type AdepHttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'
5645
+
5646
+ /* ---------- \u6587\u4EF6\u4E0E\u5B58\u50A8\uFF08CloudStorage \u955C\u50CF\uFF09 ---------- */
5647
+
5648
+ /** multipart \u4E0A\u4F20\u7684\u6587\u4EF6\uFF08\u51FD\u6570 HTTP \u89E6\u53D1\u65F6 ctx.files \u4E2D\u7684\u5355\u4E2A\u6587\u4EF6\uFF09\u3002 */
5649
+ interface AdepFunctionFile {
5650
+ /** \u5BA2\u6237\u7AEF\u63D0\u4F9B\u7684\u6587\u4EF6\u540D\uFF08\u542B\u6269\u5C55\u540D\uFF09\u3002 */
5651
+ name: string
5652
+ /** MIME \u7C7B\u578B\u3002 */
5653
+ type: string
5654
+ /** \u5B57\u8282\u6570\u3002 */
5655
+ size: number
5656
+ data: Uint8Array
5657
+ }
5658
+
5659
+ /** \u4E0A\u4F20\u6570\u636E\uFF1A\u6587\u672C\u3001\u4E8C\u8FDB\u5236\u3001\u6216\u76F4\u63A5\u900F\u4F20\u8BF7\u6C42\u91CC\u7684\u6587\u4EF6\u5BF9\u8C61\u3002 */
5660
+ type AdepStorageUploadData = string | Uint8Array | ArrayBuffer | AdepFunctionFile
5661
+
5662
+ type AdepFileVisibility = 'public' | 'private'
5663
+
5664
+ /** \u4E0A\u4F20 / \u5217\u4E3E\u8FD4\u56DE\u7684\u6587\u4EF6\u5143\u6570\u636E\uFF08\u4E0D\u542B\u5185\u5BB9\uFF09\u3002 */
5665
+ interface AdepStoredFile {
5666
+ /** \u6876\u5185\u76F8\u5BF9\u8DEF\u5F84\uFF0C\u5982 avatars/avatar.png\u3002 */
5667
+ path: string
5668
+ size: number
5669
+ contentType?: string
5670
+ visibility: AdepFileVisibility
5671
+ /** ISO 8601 \u65F6\u95F4\u6233\u3002 */
5672
+ updatedAt?: string
5673
+ }
5674
+
5675
+ interface AdepCloudStorage {
5676
+ /** \u4E0A\u4F20 / \u8986\u76D6\u6587\u4EF6\uFF1B\u8DEF\u5F84\u975E\u6CD5\uFF08\u7A7F\u8D8A\u3001\u8D85\u9650\uFF09\u7531\u5B9E\u73B0\u629B\u9519\u3002 */
5677
+ upload(path: string, data: AdepStorageUploadData): Promise<AdepStoredFile>
5678
+ /** \u8BFB\u53D6\u6587\u4EF6\u5185\u5BB9\uFF1B\u4E0D\u5B58\u5728\u65F6\u629B STORAGE_NOT_FOUND\u3002 */
5679
+ get(path: string): Promise<Uint8Array>
5680
+ /** \u5220\u9664\u6587\u4EF6\uFF1B\u4E0D\u5B58\u5728\u65F6\u629B STORAGE_NOT_FOUND\u3002 */
5681
+ remove(path: string): Promise<void>
5682
+ /** \u6309\u524D\u7F00\u5217\u4E3E\uFF08\u7F3A\u7701\u5168\u6876\uFF09\u3002 */
5683
+ list(prefix?: string): Promise<AdepStoredFile[]>
5684
+ /** \u751F\u6210\u7B7E\u540D URL\uFF08private \u6587\u4EF6\u7684\u5916\u53D1\u901A\u9053\uFF09\uFF1B\u7F3A\u7701 TTL 15 \u5206\u949F\u3002 */
5685
+ getSignedUrl(path: string, ttlSeconds?: number): Promise<string>
5686
+ }
5687
+
5688
+ /* ---------- \u6570\u636E\u5E93\uFF08CloudDb \u955C\u50CF\uFF09 ---------- */
5689
+
5690
+ /** \u53EF\u7ED1\u5B9A\u5230 SQLite \u7684\u53C2\u6570\u503C\u3002 */
5691
+ type AdepSqlValue = string | number | bigint | boolean | null | Uint8Array
5692
+
5693
+ /** where(col, op, value) \u652F\u6301\u7684\u6BD4\u8F83\u7B26\u3002 */
5694
+ type AdepSqlOperator = '=' | '!=' | '>' | '>=' | '<' | '<=' | 'like' | 'in' | 'not in'
5695
+
5696
+ /** \u4E00\u884C\u67E5\u8BE2\u7ED3\u679C\u3002\u5217\u7C7B\u578B\u7F16\u8BD1\u671F\u672A\u77E5\uFF08\u8FD0\u884C\u65F6\u5EFA\u8868\uFF09\uFF0C\u7531\u7528\u6237\u4EE3\u7801\u81EA\u884C\u6536\u7A84\u3002 */
5697
+ type AdepRow = Record<string, unknown>
5698
+
5699
+ /** owned \u8868\u53D8\u66F4\u64CD\u4F5C\u7C7B\u578B\u3002 */
5700
+ type AdepChangeOp = 'insert' | 'update' | 'delete'
5701
+
5702
+ /** owned \u8868 __changes \u53D8\u66F4\u6D41\u8BB0\u5F55\uFF08\u8FFD\u52A0\u5F0F\u3001\u53EF\u91CD\u653E\uFF1Bbefore/after \u4E3A\u6574\u884C\uFF0C\u672A\u6D89\u53CA\u4FA7\u4E3A null\uFF09\u3002 */
5703
+ interface AdepChangeRecord {
5704
+ /** \u8868\u5185\u81EA\u589E\u5E8F\u53F7\uFF08\u65F6\u95F4\u5347\u5E8F\uFF0C\u91CD\u653E\u987A\u5E8F\u4F9D\u636E\uFF09\u3002 */
5705
+ seq: number
5706
+ /** \u53D8\u66F4\u65F6\u95F4\uFF08ISO 8601\uFF09\u3002 */
5707
+ ts: string
5708
+ op: AdepChangeOp
5709
+ /** \u884C\u4E3B\u952E\uFF08ULID\uFF09\u3002 */
5710
+ id: string
5711
+ /** \u884C\u5F52\u5C5E\u5206\u533A\uFF08null = \u672A\u5F52\u5C5E\uFF09\u3002 */
5712
+ ownerKey: string | null
5713
+ /** \u53D8\u66F4\u524D\u6574\u884C\uFF08insert \u4E3A null\uFF09\u3002 */
5714
+ before: AdepRow | null
5715
+ /** \u53D8\u66F4\u540E\u6574\u884C\uFF08delete \u4E3A null\uFF09\u3002 */
5716
+ after: AdepRow | null
5717
+ }
5718
+
5719
+ /** cloud.db.changes(table, query) \u7684\u8FC7\u6EE4\u6761\u4EF6\uFF08\u5168\u90E8\u53EF\u9009\uFF09\u3002 */
5720
+ interface AdepChangeQuery {
5721
+ /** \u53EA\u53D6 seq > afterSeq\uFF08\u589E\u91CF\u62C9\u53D6 / \u6536\u4EF6\u6279\u6B21\uFF09\u3002 */
5722
+ afterSeq?: number
5723
+ /** \u53EA\u53D6\u67D0\u5206\u533A\u884C\uFF1Bnull = \u53EA\u53D6\u672A\u5F52\u5C5E\u884C\uFF08\u7F3A\u7701\u4E0D\u8FC7\u6EE4\uFF09\u3002 */
5724
+ ownerKey?: string | null
5725
+ /** \u6700\u591A\u8FD4\u56DE\u6761\u6570\uFF08\u914D\u5408 afterSeq \u505A\u5206\u9875\uFF09\u3002 */
5726
+ limit?: number
5727
+ }
5728
+
5729
+ /**
5730
+ * \u5355\u8868\u94FE\u5F0F Builder\u3002\u6240\u6709\u94FE\u5F0F\u65B9\u6CD5\u8FD4\u56DE\u65B0 Builder\uFF08\u4E0D\u53EF\u53D8\uFF09\uFF0C\u7EC8\u503C\u65B9\u6CD5
5731
+ * \uFF08get/first/count/insert/update/delete\uFF09\u8FD4\u56DE Promise\u3002\u590D\u7528\u540C\u4E00 Builder
5732
+ * \u5B9E\u4F8B\u6D3E\u751F\u591A\u4E2A\u67E5\u8BE2\u662F\u5B89\u5168\u7684\uFF08\u5B9E\u73B0\u4E0D\u5F97\u6709\u5171\u4EAB\u53EF\u53D8\u72B6\u6001\uFF09\u3002
5733
+ */
5734
+ interface AdepCloudDbTable {
5735
+ /** \u9650\u5B9A\u8FD4\u56DE\u5217\uFF1B\u4E0D\u8C03\u5373 select *\u3002 */
5736
+ select(...columns: string[]): AdepCloudDbTable
5737
+ /** \u58F0\u660E\u4E3A owned \u8868\uFF08DB-006\uFF09\uFF1A\u5199\u5165\u81EA\u52A8\u751F\u6210 ULID \u4E3B\u952E + \u8FFD\u52A0 __changes \u53D8\u66F4\u6D41\u3002 */
5738
+ owned(): AdepCloudDbTable
5739
+ /** \u7B49\u503C\u8FC7\u6EE4\uFF1Awhere('status', 'active')\u3002 */
5740
+ where(column: string, value: AdepSqlValue): AdepCloudDbTable
5741
+ /** \u5E26\u64CD\u4F5C\u7B26\u8FC7\u6EE4\uFF1Awhere('age', '>', 18)\u3002 */
5742
+ where(
5743
+ column: string,
5744
+ operator: AdepSqlOperator,
5745
+ value: AdepSqlValue | readonly AdepSqlValue[]
5746
+ ): AdepCloudDbTable
5747
+ orderBy(column: string, direction?: 'asc' | 'desc'): AdepCloudDbTable
5748
+ limit(n: number): AdepCloudDbTable
5749
+ offset(n: number): AdepCloudDbTable
5750
+ /** \u7ED3\u679C\u6570\u7EC4\uFF08\u53EF\u80FD\u4E3A\u7A7A\uFF09\u3002 */
5751
+ get(): Promise<AdepRow[]>
5752
+ /** \u9996\u884C\u6216 null\u3002 */
5753
+ first(): Promise<AdepRow | null>
5754
+ /** \u884C\u6570\uFF08\u5FFD\u7565 select/orderBy\uFF09\u3002 */
5755
+ count(): Promise<number>
5756
+ /** \u63D2\u5165\u4E00\u884C\uFF1Bwhere \u5BF9\u63D2\u5165\u65E0\u610F\u4E49\u3002 */
5757
+ insert(row: Record<string, AdepSqlValue>): Promise<void>
5758
+ /** \u6279\u91CF\u63D2\u5165\u3002 */
5759
+ insertMany(rows: ReadonlyArray<Record<string, AdepSqlValue>>): Promise<void>
5760
+ /** \u66F4\u65B0\uFF08\u5FC5\u987B\u5148 where\uFF0C\u5426\u5219 DB_UNSAFE_OP\uFF09\uFF1B\u8FD4\u56DE\u53D7\u5F71\u54CD\u884C\u6570\u3002 */
5761
+ update(values: Record<string, AdepSqlValue>): Promise<number>
5762
+ /** \u5220\u9664\uFF08\u5FC5\u987B\u5148 where\uFF0C\u5426\u5219 DB_UNSAFE_OP\uFF09\uFF1B\u8FD4\u56DE\u53D7\u5F71\u54CD\u884C\u6570\u3002 */
5763
+ delete(): Promise<number>
5764
+ }
5765
+
5766
+ /** \u9879\u76EE\u6570\u636E\u5E93\u53E5\u67C4\uFF08\u95ED\u5305\u5C01\u88C5\uFF1A\u4E0D\u66B4\u9732\u8FDE\u63A5\u4E32\u3001schema \u540D\uFF09\u3002 */
5767
+ interface AdepCloudDb {
5768
+ /** \u6253\u5F00\u5355\u8868 Builder\u3002\u8868\u540D\u7531\u8FD0\u884C\u65F6\u767D\u540D\u5355\u6821\u9A8C\u3002 */
5769
+ table(name: string): AdepCloudDbTable
5770
+ /** \u4E8B\u52A1\uFF1Afn \u6536\u5230\u540C\u5F62\u72B6\u7684\u53D7\u63A7\u4E8B\u52A1\u53E5\u67C4\uFF1B\u629B\u9519\u5373\u6574\u4F53\u56DE\u6EDA\u3002\u4E8B\u52A1\u5185\u7981\u6B62\u4E8B\u52A1\u5916\u53E5\u67C4\u5199\u672C\u5E93\u3002 */
5771
+ transaction<T>(fn: (tx: AdepCloudDb) => Promise<T>): Promise<T>
5772
+ /** \u53D7\u63A7\u88F8 SQL\uFF1Bparams \u5FC5\u586B\uFF08\u65E0\u53C2\u4F20 []\uFF09\uFF0C\u5355\u8BED\u53E5\uFF0C\u7981\u591A\u8BED\u53E5\u5806\u53E0\u3002 */
5773
+ query(sql: string, params: readonly AdepSqlValue[]): Promise<AdepRow[]>
5774
+ /** \u8BFB\u53D6 owned \u8868 __changes \u53D8\u66F4\u6D41\uFF08\u6309 seq \u5347\u5E8F\uFF0C\u53EF\u91CD\u653E\uFF09\u3002 */
5775
+ changes(table: string, query?: AdepChangeQuery): Promise<AdepChangeRecord[]>
5776
+ }
5777
+
5778
+ /* ---------- \u53D7\u63A7\u7F51\u7EDC\uFF08CloudFetch \u955C\u50CF\uFF09 ---------- */
5779
+
5780
+ /** cloud.fetch \u8BF7\u6C42\u9009\u9879\uFF08\u53D7\u63A7\u5B50\u96C6\uFF0Cbody \u9650\u5236\u4E3A\u5B57\u7B26\u4E32/JSON\uFF0C\u4E8C\u8FDB\u5236\u4E0A\u4F20\u4E0D\u5728\u672C\u80FD\u529B\u8303\u56F4\uFF09\u3002 */
5781
+ interface AdepCloudFetchInit {
5782
+ method?: string
5783
+ /** \u8BF7\u6C42\u5934\uFF08\u5C0F\u5199\u5316\u540E\u9010\u6761\u900F\u4F20\uFF09\u3002 */
5784
+ headers?: Record<string, string>
5785
+ body?: string
5786
+ /** \u8C03\u7528\u65B9\u4E2D\u6B62\u4FE1\u53F7\uFF08\u4E0E\u5E73\u53F0\u8D85\u65F6\u53E0\u52A0\uFF0C\u4E8C\u8005\u4EFB\u4E00\u89E6\u53D1\u5373\u4E2D\u6B62\uFF09\u3002 */
5787
+ signal?: AbortSignal
5788
+ }
5789
+
5790
+ /** cloud.fetch \u7684\u7ED3\u6784\u5316\u54CD\u5E94\uFF08\u6587\u672C/JSON/\u4E8C\u8FDB\u5236\u8BFB\u53D6\u53D7\u54CD\u5E94\u4F53\u4E0A\u9650\u7EA6\u675F\uFF09\u3002 */
5791
+ interface AdepCloudFetchResponse {
5792
+ ok: boolean
5793
+ status: number
5794
+ statusText: string
5795
+ /** \u5F52\u4E00\u5316\u54CD\u5E94\u5934\uFF08\u952E\u5C0F\u5199\uFF09\u3002 */
5796
+ headers: Record<string, string>
5797
+ text(): Promise<string>
5798
+ json(): Promise<unknown>
5799
+ arrayBuffer(): Promise<ArrayBuffer>
5800
+ }
5801
+
5802
+ /** cloud.fetch\uFF1A\u53D7\u63A7\u7684 HTTPS \u8BF7\u6C42\u3002URL \u4E3B\u673A\u4E0D\u5728\u767D\u540D\u5355\u5219\u629B FN_FETCH_FORBIDDEN\u3002 */
5803
+ type AdepCloudFetch = (url: string, init?: AdepCloudFetchInit) => Promise<AdepCloudFetchResponse>
5804
+
5805
+ /* ---------- \u5B9E\u65F6\u901A\u9053\uFF08CloudRealtime \u955C\u50CF\uFF09 ---------- */
5806
+
5807
+ /** \u4E00\u6761\u901A\u9053\u6D88\u606F\uFF08\u4E0E @adep/types \u7684 RealtimeChannelMessage \u5BF9\u9F50\uFF09\u3002 */
5808
+ interface AdepRealtimeChannelMessage {
5809
+ channel: string
5810
+ seq: number
5811
+ data: unknown
5812
+ publishedAt: string
5813
+ publisher?: string
5814
+ }
5815
+
5816
+ /** publish \u56DE\u6267\uFF1Adelivered = \u5B9E\u9645\u547D\u4E2D\u7684\u8BA2\u9605\u8FDE\u63A5\u6570\uFF08\u5C3D\u529B\u6295\u9012\uFF0C0 \u662F\u5408\u6CD5\u7ED3\u679C\uFF09\u3002 */
5817
+ interface AdepCloudRealtimeReceipt {
5818
+ delivered: number
5819
+ }
5820
+
5821
+ /** subscribe \u56DE\u6267\uFF1Asubscription \u662F\u540E\u7EED receive / unsubscribe \u7684\u53E5\u67C4\u3002 */
5822
+ interface AdepCloudRealtimeSubscription {
5823
+ subscription: string
5824
+ channel: string
5825
+ }
5826
+
5827
+ /**
5828
+ * cloud.realtime\uFF1A\u51FD\u6570\u5185\u6536\u53D1\u5B9E\u65F6\u901A\u9053\u6D88\u606F\u3002
5829
+ * \u26A0\uFE0F subscribe / receive \u662F\u8F6E\u8BE2\u53D6\u4EF6\u800C\u975E\u56DE\u8C03\u8BA2\u9605\uFF08RPC \u53C2\u6570\u8D70\u7ED3\u6784\u5316\u514B\u9686\uFF0C\u4F20\u4E0D\u4E86\u51FD\u6570\uFF09\u3002
5830
+ */
5831
+ interface AdepCloudRealtime {
5832
+ /** except \u4EC5\u7EBF\u4E0A\u652F\u6301\uFF08\u4E0D\u56DE\u53D1\u7ED9\u8BE5\u8FDE\u63A5\uFF09\uFF1B\u672C\u5730 adep dev \u4F20\u7B2C\u4E09\u53C2\u4F1A fail loud\u3002 */
5833
+ publish(channel: string, data: unknown, except?: string): Promise<AdepCloudRealtimeReceipt>
5834
+ subscribe(channel: string): Promise<AdepCloudRealtimeSubscription>
5835
+ receive(subscription: string): Promise<AdepRealtimeChannelMessage[]>
5836
+ unsubscribe(subscription: string): Promise<{ removed: true }>
5837
+ }
5838
+
5839
+ /* ---------- \u80FD\u529B\u6302\u8F7D\u70B9\uFF08Cloud / CapabilityRegistry \u955C\u50CF\uFF09 ---------- */
5840
+
5841
+ /** \u5DF2\u6CE8\u518C\u80FD\u529B\u540D \u2192 \u5B9E\u73B0\u5951\u7EA6\u7684\u6620\u5C04\u3002\u8BBF\u95EE\u672A\u6CE8\u518C\u80FD\u529B\u8FD0\u884C\u65F6\u629B\u5E26\u53EF\u64CD\u4F5C\u63D0\u793A\u7684\u9519\u8BEF\u3002 */
5842
+ interface AdepCapabilityRegistry {
5843
+ db: AdepCloudDb
5844
+ storage: AdepCloudStorage
5845
+ /** \u6C99\u7BB1\u53D7\u63A7\u7F51\u7EDC\uFF08GAME-007\uFF09\uFF1A\u672A\u914D\u7F6E\u767D\u540D\u5355\u65F6\u4E0D\u6CE8\u5165\uFF08\u65E0\u7F51\u7EDC\u5B89\u5168\u9ED8\u8BA4\uFF09\u3002 */
5846
+ fetch: AdepCloudFetch
5847
+ /** \u5B9E\u65F6\u901A\u9053\uFF08FN-020\uFF09\uFF1A\u9879\u76EE\u88C5\u914D realtime \u57DF\u5373\u6CE8\u5165\uFF1B\u8F6E\u8BE2\u8BED\u4E49\u89C1 AdepCloudRealtime\u3002 */
5848
+ realtime: AdepCloudRealtime
5849
+ }
5850
+
5851
+ /** \u7528\u6237\u51FD\u6570\u4FA7\u7684 ctx.cloud\uFF1A\u53EA\u80FD\u8BBF\u95EE\u80FD\u529B\u3002\u5DF2\u77E5\u80FD\u529B\u6709\u7CBE\u786E\u8865\u5168\uFF1B\u81EA\u5B9A\u4E49\u80FD\u529B\u7ECF\u7D22\u5F15\u7B7E\u540D\u8BBF\u95EE\u3002 */
5852
+ type AdepCloud = {
5853
+ readonly [K in keyof AdepCapabilityRegistry]: AdepCapabilityRegistry[K]
5854
+ } & {
5855
+ // \u547D\u540D\u5C5E\u6027\u7ED9\u51FA\u7CBE\u786E\u8865\u5168\uFF1B\u7D22\u5F15\u7B7E\u540D\u653E\u884C\u81EA\u5B9A\u4E49\u80FD\u529B\u8BBF\u95EE\uFF08\u8FD0\u884C\u65F6\u672A\u6CE8\u518C\u5373\u629B\u9519\uFF09\u3002
5856
+ readonly [capability: string]: unknown
5857
+ }
5858
+
5859
+ /* ---------- \u8C03\u7528\u8005\u8EAB\u4EFD\uFF08ExecutorUser \u955C\u50CF\uFF09 ---------- */
5860
+
5861
+ /** \u6267\u884C\u8005\u8EAB\u4EFD\u6295\u5F71\uFF1A\u7F51\u5173\u89E3\u6790\u4F1A\u8BDD\u540E\u6CE8\u5165\uFF1Bnull = \u533F\u540D / \u672A\u6CE8\u5165\uFF08\u900F\u4F20\u4FE1\u606F\uFF0C\u975E\u5F3A\u5236\u95E8\uFF09\u3002 */
5862
+ interface AdepExecutorUser {
5863
+ /** \u5E73\u53F0\u7528\u6237 id\uFF08= better-auth session.user.id\uFF09\u3002 */
5864
+ id: string
5865
+ email?: string
5866
+ name?: string
5867
+ }
5868
+
5869
+ /* ---------- \u5168\u5C40 ctx\uFF08FunctionContext \u955C\u50CF\uFF09 ---------- */
5870
+
5871
+ interface AdepContext {
5872
+ /** \u8BF7\u6C42\u65B9\u6CD5\u3002 */
5873
+ readonly method: AdepHttpMethod
5874
+ /** \u89E6\u53D1\u8DEF\u5F84\uFF08\u4E0D\u542B host\uFF09\uFF0C\u5982 /hello\u3002 */
5875
+ readonly path: string
5876
+ /** \u89E3\u6790\u540E\u7684 query\uFF1B\u540C\u540D\u591A\u503C\u6536\u4E3A\u6570\u7EC4\u3002 */
5877
+ readonly query: Readonly<Record<string, string | readonly string[]>>
5878
+ /** \u8BF7\u6C42\u5934\uFF08\u952E\u4E3A\u5C0F\u5199\uFF09\u3002 */
5879
+ readonly headers: Readonly<Record<string, string>>
5880
+ /** \u8BF7\u6C42\u4F53\uFF1B\u5F62\u72B6\u7531\u7528\u6237\u7528\u7C7B\u578B\u65AD\u8A00\u6536\u7A84\uFF08\u5982 ctx.body as { name: string }\uFF09\u3002 */
5881
+ readonly body: unknown
5882
+ /** multipart \u4E0A\u4F20\u7684\u6587\u4EF6\uFF08\u65E0\u6587\u4EF6\u65F6\u4E3A\u7A7A\u6570\u7EC4\uFF09\u3002 */
5883
+ readonly files: readonly AdepFunctionFile[]
5884
+ /** \u5E73\u53F0\u80FD\u529B\u6302\u8F7D\u70B9\uFF1Acloud.db / cloud.storage / cloud.fetch / cloud.realtime\u3002 */
5885
+ readonly cloud: AdepCloud
5886
+ /** \u8C03\u7528\u8005\u8EAB\u4EFD\u6295\u5F71\uFF1Bnull = \u533F\u540D / \u672A\u6CE8\u5165\u3002 */
5887
+ readonly user: AdepExecutorUser | null
5888
+ }
5889
+
5890
+ /** \u5168\u5C40\u5F00\u53D1\u671F\u4E0A\u4E0B\u6587\uFF08\u7F16\u8F91\u5668\u8865\u5168\u7528\uFF1B\u51FD\u6570\u8FD0\u884C\u671F\u7ECF\u53C2\u6570\u6CE8\u5165\uFF0C\u4E0D\u8BFB\u53D6\u5168\u5C40\uFF09\u3002 */
5891
+ declare const ctx: AdepContext
5892
+ `;
5893
+ var ADEP_TSCONFIG_JSON = `{
5894
+ "compilerOptions": {
5895
+ "target": "ES2021",
5896
+ "module": "ESNext",
5897
+ "moduleResolution": "Bundler",
5898
+ "strict": true,
5899
+ "noEmit": true,
5900
+ "skipLibCheck": true,
5901
+ "types": [],
5902
+ "lib": ["ES2021", "DOM"]
5903
+ },
5904
+ "include": ["**/*.ts", "**/*.d.ts"]
5905
+ }
5906
+ `;
5907
+
5908
+ // packages/cli/src/init.ts
5909
+ init_templates();
5910
+ var TEMPLATE_NAMES = ["empty", "function", "widget", "page"];
5584
5911
  var InitError = class extends Error {
5585
5912
  constructor(code, message) {
5586
5913
  super(message);
@@ -5598,21 +5925,70 @@ var README = (name, template) => `# ${name}
5598
5925
 
5599
5926
  AgentDeploy \u9879\u76EE\uFF08\u6A21\u677F\uFF1A${template}\uFF09\u3002
5600
5927
 
5601
- - \`adep dev\`\uFF1A\u672C\u5730\u8C03\u8BD5\uFF08CLI-002 \u4EA4\u4ED8\uFF09
5602
- - \`adep deploy\`\uFF1A\u53D1\u5E03\uFF08CLI-003 \u4EA4\u4ED8\uFF09
5928
+ ## \u5E38\u7528\u547D\u4EE4
5929
+
5930
+ - \`adep dev\`\uFF1A\u672C\u5730\u8C03\u8BD5\uFF08\u76D1\u542C functions/\uFF0C\u652F\u6301\u70ED\u91CD\u8F7D\uFF0C\u9ED8\u8BA4 http://127.0.0.1:8787/<fnName>\uFF09
5931
+ - \`adep deploy\`\uFF1A\u589E\u91CF\u90E8\u7F72\uFF08\u5BF9\u6BD4\u8FDC\u7AEF\u54C8\u5E0C \u2192 \u4EC5\u4E0A\u4F20\u53D8\u66F4 \u2192 \u53D1\u5E03 \u2192 \u8F93\u51FA\u8BBF\u95EE\u57DF\u540D\uFF09
5932
+ - \`adep serve\`\uFF1A\u5F00\u53D1\u6001\u670D\u52A1\u5668\uFF08\u51FD\u6570 /api/{fn} + /healthz + \u9759\u6001\u6258\u7BA1 + \u7EC4\u4EF6\u9884\u89C8\uFF09
5933
+
5934
+ ## \u76EE\u5F55\u7ED3\u6784
5935
+
5936
+ - \`adep.config.ts\`\uFF1A\u9879\u76EE\u6807\u8BC6\uFF08dev / deploy \u6309\u6B64\u8BC6\u522B\uFF09
5937
+ - \`tsconfig.json\`\uFF1A\u4E91\u51FD\u6570 TypeScript \u7F16\u8F91\u5668\u914D\u7F6E\uFF08strict + noEmit\uFF09
5938
+ - \`adep.d.ts\`\uFF1A\u4E91\u51FD\u6570\u4E0A\u4E0B\u6587\u73AF\u5883\u7C7B\u578B\u58F0\u660E\uFF08\`ctx: AdepContext\` \u8865\u5168\uFF0C\u65E0\u9700\u88C5\u4F9D\u8D56\uFF09
5939
+ ${template === "function" ? "- `functions/`\uFF1A\u4E91\u51FD\u6570\u76EE\u5F55\uFF08\u672C\u6A21\u677F\u751F\u6210\u5355\u4E2A\u793A\u4F8B\u51FD\u6570 `functions/hello.ts`\uFF09" : template === "widget" ? "- `widgets/`\uFF1A\u5FAE\u524D\u7AEF\u7EC4\u4EF6\uFF08widget\uFF09\u76EE\u5F55\uFF08\u672C\u6A21\u677F\u751F\u6210\u5355\u4E2A widget\uFF09" : template === "page" ? "- `web/`\uFF1A\u9759\u6001\u9875\u9762\u76EE\u5F55\uFF08\u672C\u6A21\u677F\u751F\u6210\u5355\u4E2A\u9875\u9762\uFF0C\u53EF\u7ECF `adep serve --static ./web` \u9884\u89C8\uFF09" : "- \u51FD\u6570\u653E\u5165 `functions/`\uFF0C\u914D\u7F6E\u89C1 `adep.config.ts`"}
5940
+
5941
+ ## \u4E91\u51FD\u6570\u7C7B\u578B\u63D0\u793A
5942
+
5943
+ \u7528 VSCode \u6253\u5F00\u672C\u76EE\u5F55\uFF0C\u4EFB\u610F \`functions/**\` \u4E0B\u7684 TS \u6587\u4EF6\u5373\u53EF\u83B7\u5F97 \`AdepContext\` / \`ctx.cloud.*\` \u8865\u5168\uFF1A
5944
+ \`tsconfig.json\` \u4F1A\u628A \`adep.d.ts\` \u7EB3\u5165 include\uFF0C\u51FD\u6570\u53C2\u6570\u5199 \`ctx: AdepContext\` \u5373\u53EF\u3002
5945
+ \`ctx\` \u4E0E \`AdepContext\` \u662F\u5168\u5C40\u5F00\u53D1\u671F\u58F0\u660E\uFF0C\u51FD\u6570\u8FD0\u884C\u671F\u7ECF\u53C2\u6570\u6CE8\u5165\uFF08\u4E0D\u8BFB\u53D6\u5168\u5C40\uFF09\u3002
5946
+
5947
+ ## \u6A21\u677F\u8BF4\u660E\uFF08adep init\uFF09
5948
+
5949
+ - \`adep init <name>\`\uFF1A\u9ED8\u8BA4 \`function\` \u6A21\u677F\uFF08\u5355\u4E2A\u51FD\u6570\uFF09
5950
+ - \`adep init <name> -t empty\`\uFF1A\u7A7A\u6A21\u677F\uFF08\u4EC5\u9879\u76EE\u9AA8\u67B6\uFF09
5951
+ - \`adep init <name> -t function\`\uFF1A\u5355\u4E2A\u51FD\u6570
5952
+ - \`adep init <name> -t widget\`\uFF1A\u5355\u4E2A Widget\uFF08\u5FAE\u524D\u7AEF\u7EC4\u4EF6\uFF09
5953
+ - \`adep init <name> -t page\`\uFF1A\u5355\u4E2A Page\uFF08\u9759\u6001\u9875\u9762\uFF09
5954
+ - \`adep init --list\`\uFF1A\u4ECE\u5E73\u53F0 /api/v1/templates \u5217\u51FA\u53EF\u7528\u6A21\u677F
5955
+ - \`adep init --list -s <server>\`\uFF1A\u6307\u5B9A\u5E73\u53F0\u5730\u5740
5603
5956
  `;
5604
5957
  var HELLO_FUNCTION = `// \u793A\u4F8B\u51FD\u6570\uFF1Aadep deploy \u540E\u7ECF https://<project-slug>.<platform-domain>/hello \u89E6\u53D1\u3002
5605
- // \u7528\u6237\u51FD\u6570\u5373 functions/ \u4E0B\u7684\u72EC\u7ACB\u6587\u4EF6\uFF0C\u9ED8\u8BA4\u5BFC\u51FA (ctx) => Response \u5F62\u72B6\u7684\u5904\u7406\u5668
5606
- //\uFF08ctx \u5951\u7EA6\u89C1\u5E73\u53F0\u7684 FunctionContext\uFF1Amethod / path / query / headers / body / cloud.*\uFF09\u3002
5607
- export default async (ctx) => {
5958
+ // \u7528\u6237\u51FD\u6570\u5373 functions/ \u4E0B\u7684\u72EC\u7ACB\u6587\u4EF6\uFF0C\u9ED8\u8BA4\u5BFC\u51FA (ctx: AdepContext) => Response \u5F62\u72B6\u7684\u5904\u7406\u5668
5959
+ //\uFF08ctx \u5951\u7EA6\u89C1 adep.d.ts\uFF1Amethod / path / query / headers / body / files / user / cloud.*\uFF09\u3002
5960
+ export default async (ctx: AdepContext) => {
5608
5961
  const name = (ctx.query['name'] as string | undefined) ?? 'world'
5609
5962
  return { message: \`hello \${name}\` }
5610
5963
  }
5611
5964
  `;
5612
5965
  var FUNCTION_INDEX = `// \u51FD\u6570\u6A21\u5757\u5165\u53E3\uFF1A\u9879\u76EE\u91CC\u7684\u6BCF\u4E2A\u51FD\u6570\u662F functions/ \u4E0B\u7684\u72EC\u7ACB\u6587\u4EF6\uFF0C
5613
- // \u9ED8\u8BA4\u5BFC\u51FA (ctx) => Response \u5F62\u72B6\u7684\u5904\u7406\u5668\uFF08\u5951\u7EA6\u89C1 @adep/types \u7684 FunctionContext\uFF09\u3002
5966
+ // \u9ED8\u8BA4\u5BFC\u51FA (ctx: AdepContext) => Response \u5F62\u72B6\u7684\u5904\u7406\u5668\uFF08\u5951\u7EA6\u89C1 adep.d.ts\uFF09\u3002
5614
5967
  `;
5615
- var EMPTY_INDEX = `// AgentDeploy \u9879\u76EE\u5165\u53E3\u3002M1 \u4E2D\u6A21\u677F\u6682\u65E0\u66F4\u591A\u5185\u5BB9\u2014\u2014\u51FD\u6570\u653E functions/\uFF0C\u914D\u7F6E\u89C1 adep.config.ts\u3002
5968
+ var EMPTY_INDEX = `// AgentDeploy \u9879\u76EE\u5165\u53E3\u3002\u6A21\u677F\u6682\u65E0\u66F4\u591A\u5185\u5BB9\u2014\u2014\u51FD\u6570\u653E functions/\uFF0C\u914D\u7F6E\u89C1 adep.config.ts\u3002
5969
+ `;
5970
+ var PAGE_INDEX = (name) => `<!doctype html>
5971
+ <html lang="zh-CN">
5972
+ <head>
5973
+ <meta charset="utf-8" />
5974
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
5975
+ <title>${name}</title>
5976
+ <style>
5977
+ :root { --adep-accent: #3370ff; --adep-bg: #0d0f14; --adep-text: #e8eaed; }
5978
+ body { margin: 0; font-family: system-ui, -apple-system, "Segoe UI", sans-serif; background: var(--adep-bg); color: var(--adep-text); }
5979
+ main { max-width: 640px; margin: 0 auto; padding: 5rem 1.5rem; }
5980
+ h1 { color: var(--adep-accent); }
5981
+ code { background: #1b1f27; padding: .15em .4em; border-radius: 4px; }
5982
+ </style>
5983
+ </head>
5984
+ <body>
5985
+ <main>
5986
+ <h1>${name}</h1>
5987
+ <p>\u8FD9\u662F\u4E00\u4E2A AgentDeploy \u9759\u6001\u9875\u9762\u3002\u53EF\u7ECF <code>adep serve --static ./web</code> \u9884\u89C8\u3002</p>
5988
+ <p>\u628A\u9875\u9762\u4EA7\u7269\u653E\u5230 <code>web/</code> \u76EE\u5F55\uFF0C\u5373\u53EF\u88AB <code>adep serve</code> \u76F4\u63A5\u6258\u7BA1\u3002</p>
5989
+ </main>
5990
+ </body>
5991
+ </html>
5616
5992
  `;
5617
5993
  async function initProject(cwd, name, template) {
5618
5994
  if (!/^[a-z][a-z0-9-]{0,62}$/.test(name)) {
@@ -5621,6 +5997,12 @@ async function initProject(cwd, name, template) {
5621
5997
  `\u9879\u76EE\u540D "${name}" \u4E0D\u5408\u6CD5\uFF1A\u9700\u4EE5\u5C0F\u5199\u5B57\u6BCD\u5F00\u5934\uFF0C\u4EC5\u542B\u5C0F\u5199\u5B57\u6BCD / \u6570\u5B57 / \u8FDE\u5B57\u7B26`
5622
5998
  );
5623
5999
  }
6000
+ if (!TEMPLATE_NAMES.includes(template)) {
6001
+ throw new InitError(
6002
+ "INVALID_TEMPLATE",
6003
+ `\u672A\u77E5\u6A21\u677F "${template}"\uFF1A\u53EF\u9009 ${TEMPLATE_NAMES.join(" | ")}`
6004
+ );
6005
+ }
5624
6006
  const projectPath = resolve(cwd, name);
5625
6007
  let existing;
5626
6008
  try {
@@ -5633,14 +6015,22 @@ async function initProject(cwd, name, template) {
5633
6015
  }
5634
6016
  const files = [
5635
6017
  { path: "adep.config.ts", content: ADEP_CONFIG(name, template) },
5636
- { path: "README.md", content: README(name, template) }
6018
+ // 云函数 TypeScript 类型提示:tsconfig 把 adep.d.ts 纳入 include,写 ctx: AdepContext 即有补全。
6019
+ { path: "tsconfig.json", content: ADEP_TSCONFIG_JSON },
6020
+ { path: "adep.d.ts", content: ADEP_ENV_DTS },
6021
+ { path: "README.md", content: README(name, template) },
6022
+ { path: ".gitignore", content: "node_modules/\ndata/\n.adep/\n" }
5637
6023
  ];
5638
6024
  if (template === "function") {
5639
6025
  files.push({ path: "functions/hello.ts", content: HELLO_FUNCTION });
5640
6026
  files.push({ path: "functions/README.md", content: FUNCTION_INDEX });
5641
- files.push({ path: ".gitignore", content: "node_modules/\ndata/\n.adep/\n" });
6027
+ } else if (template === "widget") {
6028
+ for (const [rel, content] of Object.entries(widgetTemplateFiles(name, "vue3-ts"))) {
6029
+ files.push({ path: `widgets/${name}/${rel}`, content });
6030
+ }
6031
+ } else if (template === "page") {
6032
+ files.push({ path: "web/index.html", content: PAGE_INDEX(name) });
5642
6033
  } else {
5643
- files.push({ path: ".gitignore", content: "node_modules/\ndata/\n.adep/\n" });
5644
6034
  files.push({ path: "README-EMPTY.md", content: EMPTY_INDEX });
5645
6035
  }
5646
6036
  await mkdir2(projectPath, { recursive: true });
@@ -5654,62 +6044,58 @@ async function initProject(cwd, name, template) {
5654
6044
  return { projectPath, files: files.map((file) => file.path) };
5655
6045
  }
5656
6046
 
5657
- // packages/cli/src/templates.ts
5658
- init_auth();
5659
- async function fetchTemplates(server) {
5660
- let response;
5661
- try {
5662
- response = await fetch(`${server}/api/v1/templates`);
5663
- } catch (error) {
5664
- throw new CliError(
5665
- "SERVER_UNREACHABLE",
5666
- `\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
5667
- );
5668
- }
5669
- const text = await response.text();
5670
- let parsed = null;
5671
- try {
5672
- parsed = text.length === 0 ? null : JSON.parse(text);
5673
- } catch {
5674
- parsed = null;
5675
- }
5676
- if (response.status < 200 || response.status >= 300) {
5677
- const msg = parsed?.error;
5678
- throw new CliError("TEMPLATE_LIST_FAILED", msg ?? `\u5E73\u53F0\u8FD4\u56DE HTTP ${response.status}`);
5679
- }
5680
- const templates = parsed?.templates;
5681
- return templates ?? [];
5682
- }
5683
-
5684
- // packages/cli/src/cli.ts
6047
+ // packages/cli/src/output.ts
5685
6048
  init_build();
5686
6049
  init_init();
5687
- var requireJson = createRequire(import.meta.url);
5688
- var APP_VERSION = requireJson("../package.json").version;
6050
+ function isCommandError(error) {
6051
+ return error instanceof CliError || error instanceof InitError || error instanceof WidgetError || error instanceof WidgetInitError;
6052
+ }
5689
6053
  function needsRelogin(error) {
5690
6054
  return error.code === "NOT_LOGGED_IN" || error.code === "AUTH_UNAUTHORIZED";
5691
6055
  }
5692
- function emitError(output, command, json, error) {
5693
- if (error instanceof CliError || error instanceof InitError || error instanceof WidgetError || error instanceof WidgetInitError) {
6056
+ function toLines(value) {
6057
+ return Array.isArray(value) ? value : [value];
6058
+ }
6059
+ function createCommandIO(command, output, json) {
6060
+ const ok = (data, render) => {
6061
+ if (json) {
6062
+ output(JSON.stringify({ ok: true, command, data }));
6063
+ return;
6064
+ }
6065
+ if (render !== void 0) for (const lineValue of toLines(render(data))) output(lineValue);
6066
+ };
6067
+ const line = (text) => {
6068
+ if (!json) output(text);
6069
+ };
6070
+ const raw = (text) => {
6071
+ output(text);
6072
+ };
6073
+ const fail = (code, message) => {
6074
+ if (json) output(JSON.stringify({ ok: false, command, error: { code, message } }));
6075
+ else output(`\u9519\u8BEF\uFF1A${message}`);
6076
+ process.exitCode = 1;
6077
+ };
6078
+ const err = (error) => {
6079
+ if (!isCommandError(error)) throw error;
5694
6080
  if (json) {
5695
6081
  output(
5696
- JSON.stringify({
5697
- ok: false,
5698
- command,
5699
- error: { code: error.code, message: error.message }
5700
- })
6082
+ JSON.stringify({ ok: false, command, error: { code: error.code, message: error.message } })
5701
6083
  );
5702
6084
  } else {
5703
6085
  const withCode = error.message.includes(error.code) || error.code.length === 0 ? error.message : `${error.message}\uFF08${error.code}\uFF09`;
5704
6086
  output(`\u9519\u8BEF\uFF1A${withCode}`);
5705
- if (error instanceof CliError && needsRelogin(error)) {
5706
- output("\u63D0\u793A\uFF1A\u5148\u6267\u884C adep login");
5707
- }
6087
+ if (error instanceof CliError && needsRelogin(error)) output("\u63D0\u793A\uFF1A\u5148\u6267\u884C adep login");
5708
6088
  }
5709
6089
  process.exitCode = 1;
5710
- return;
5711
- }
5712
- throw error;
6090
+ };
6091
+ const run = async (fn) => {
6092
+ try {
6093
+ await fn();
6094
+ } catch (error) {
6095
+ err(error);
6096
+ }
6097
+ };
6098
+ return { json, ok, line, raw, fail, err, run };
5713
6099
  }
5714
6100
  function formatBytes(bytes) {
5715
6101
  if (bytes < 1024) return `${bytes} B`;
@@ -5730,69 +6116,35 @@ function formatTable(columns, rows) {
5730
6116
  widths[index] = Math.max(widths[index], cell.length);
5731
6117
  });
5732
6118
  }
5733
- const line = (cells) => cells.map((cell, index) => cell.padEnd(widths[index] ?? 0)).join(" ").trimEnd();
6119
+ const contentLine = (cells) => cells.map((cell, index) => cell.padEnd(widths[index] ?? 0)).join(" ").trimEnd();
5734
6120
  const parts = [
5735
- line(columns),
5736
- ...rows.map((row) => line(columns.map((c) => String(row[c] ?? ""))))
6121
+ contentLine(columns),
6122
+ ...rows.map((row) => contentLine(columns.map((c) => String(row[c] ?? ""))))
5737
6123
  ];
5738
6124
  return parts.join("\n");
5739
6125
  }
5740
- function parseBool(raw) {
5741
- if (raw === void 0) return void 0;
5742
- if (raw === "true") return true;
5743
- if (raw === "false") return false;
5744
- throw new CliError("INVALID_BOOLEAN", `\u5E03\u5C14\u53C2\u6570\u987B\u4E3A true \u6216 false\uFF0C\u6536\u5230 "${raw}"`);
5745
- }
5746
6126
  function formatSeconds(seconds) {
5747
6127
  return `${Math.max(0.1, Math.round(seconds * 10) / 10)}s`;
5748
6128
  }
5749
- async function runDeploy(paths, output, json, cwd, slug, dir) {
5750
- const { deploy: deploy2 } = await Promise.resolve().then(() => (init_deploy(), deploy_exports));
5751
- const startedAt = Date.now();
5752
- const result = await deploy2(paths, {
6129
+
6130
+ // packages/cli/src/commands/context.ts
6131
+ function createCliContext(deps) {
6132
+ const { output, paths, cwd, json } = deps;
6133
+ return {
6134
+ output,
6135
+ paths,
5753
6136
  cwd,
5754
- ...slug === void 0 ? {} : { slug },
5755
- ...dir === void 0 ? {} : { functionsDir: dir },
5756
- // --json 下逐函数进度会破坏「stdout 恰好一个 JSON 对象」的信封约定(PRD §2.5.3)。
5757
- silent: json,
5758
- // 人读模式的进度也走注入的 output:deploy 内部缺省会直写 process.stdout,
5759
- // 那会让带 sink 的调用方漏收这部分行。
5760
- log: (line) => output(line)
5761
- });
5762
- const elapsedSeconds = (Date.now() - startedAt) / 1e3;
5763
- const deployedCount = result.functions.filter((fn) => fn.action !== "none").length;
5764
- if (json) {
5765
- output(
5766
- JSON.stringify({
5767
- ok: true,
5768
- command: "deploy",
5769
- data: { ...result, elapsedSeconds, deployedCount }
5770
- })
5771
- );
5772
- return;
5773
- }
5774
- for (const fn of result.functions) {
5775
- output(`${fn.name} v${fn.version} ${fn.url}`);
5776
- }
5777
- if (result.noChanges) {
5778
- output(
5779
- `\u2713 no changes \xB7 ${result.functions.length} functions up to date in ${formatSeconds(elapsedSeconds)}`
5780
- );
5781
- return;
5782
- }
5783
- output(`\u2713 ${deployedCount} functions deployed in ${formatSeconds(elapsedSeconds)}`);
6137
+ io: (command) => createCommandIO(command, output, json())
6138
+ };
5784
6139
  }
5785
- function buildProgram(options = {}) {
5786
- const output = options.output ?? ((line) => process.stdout.write(`${line}
5787
- `));
5788
- const paths = options.paths ?? resolvePaths();
5789
- const cwd = options.cwd ?? process.cwd();
5790
- const program2 = new Command();
5791
- program2.name("adep").description("AgentDeploy CLI").version(APP_VERSION);
5792
- program2.option("--json", "\u4EE5\u673A\u5668\u53EF\u8BFB JSON \u8F93\u51FA\uFF08Agent / \u811A\u672C\u8C03\u7528\uFF09", false);
5793
- const jsonMode = () => program2.opts()["json"] === true;
6140
+
6141
+ // packages/cli/src/commands/auth.ts
6142
+ init_auth();
6143
+ init_config();
6144
+ function registerAuth(program2, ctx) {
5794
6145
  program2.command("login").description("\u767B\u5F55\u5E73\u53F0\uFF08better-auth \u90AE\u7BB1\u5BC6\u7801\u767B\u5F55\uFF1B\u8BBE\u5907\u6388\u6743\u6D41\u5F52 CORE \u57DF\u540E\u7EED\u4EFB\u52A1\uFF09").option("-s, --server <url>", "\u5E73\u53F0\u5730\u5740\uFF08\u7F3A\u7701\u8BFB\u53D6 ADEP_SERVER \u6216 http://localhost:3000\uFF09").option("-e, --email <email>", "\u767B\u5F55\u90AE\u7BB1").option("-p, --password <password>", "\u767B\u5F55\u5BC6\u7801\uFF08\u6CE8\u610F shell \u5386\u53F2\uFF1B\u7F3A\u7701\u4EA4\u4E92\u8F93\u5165\uFF09").action(async (flags) => {
5795
- try {
6146
+ const command = ctx.io("login");
6147
+ await command.run(async () => {
5796
6148
  const server = flags.server ?? resolveServer();
5797
6149
  let email = flags.email;
5798
6150
  let password = flags.password;
@@ -5803,89 +6155,113 @@ function buildProgram(options = {}) {
5803
6155
  password = password ?? await prompt.askHidden("\u5BC6\u7801\uFF1A");
5804
6156
  prompt.close();
5805
6157
  }
5806
- const result = await login(paths, {
6158
+ const result = await login(ctx.paths, {
5807
6159
  server,
5808
6160
  email,
5809
6161
  password
5810
6162
  });
5811
- if (jsonMode()) {
5812
- output(JSON.stringify({ ok: true, command: "login", data: result }));
5813
- } else {
5814
- output(`\u5DF2\u767B\u5F55\uFF1A${result.email}\uFF08\u51ED\u636E\u5DF2\u5199\u5165 ${paths.credentialsFile}\uFF0C\u6743\u9650 0600\uFF09`);
5815
- }
5816
- } catch (error) {
5817
- emitError(output, "login", jsonMode(), error);
5818
- }
6163
+ command.ok(result, (data) => {
6164
+ const d = data;
6165
+ return `\u5DF2\u767B\u5F55\uFF1A${d.email}\uFF08\u51ED\u636E\u5DF2\u5199\u5165 ${ctx.paths.credentialsFile}\uFF0C\u6743\u9650 0600\uFF09`;
6166
+ });
6167
+ });
5819
6168
  });
5820
6169
  program2.command("whoami").description("\u663E\u793A\u5F53\u524D\u767B\u5F55\u8EAB\u4EFD").action(async () => {
5821
- try {
5822
- const result = await whoami(paths);
5823
- if (jsonMode()) {
5824
- output(JSON.stringify({ ok: true, command: "whoami", data: result }));
5825
- } else {
5826
- output(`${result.email} @ ${result.server}`);
5827
- }
5828
- } catch (error) {
5829
- emitError(output, "whoami", jsonMode(), error);
5830
- }
6170
+ const command = ctx.io("whoami");
6171
+ await command.run(async () => {
6172
+ const result = await whoami(ctx.paths);
6173
+ command.ok(result, (data) => {
6174
+ const d = data;
6175
+ return `${d.email} @ ${d.server}`;
6176
+ });
6177
+ });
5831
6178
  });
5832
6179
  program2.command("logout").description("\u767B\u51FA\u5E76\u6E05\u9664\u672C\u5730\u51ED\u636E").action(async () => {
5833
- try {
5834
- await logout(paths);
5835
- if (jsonMode()) {
5836
- output(JSON.stringify({ ok: true, command: "logout", data: { done: true } }));
5837
- } else {
5838
- output("\u5DF2\u767B\u51FA");
5839
- }
5840
- } catch (error) {
5841
- emitError(output, "logout", jsonMode(), error);
5842
- }
6180
+ const command = ctx.io("logout");
6181
+ await command.run(async () => {
6182
+ await logout(ctx.paths);
6183
+ command.ok({ done: true }, () => "\u5DF2\u767B\u51FA");
6184
+ });
5843
6185
  });
5844
- program2.command("init").description("\u521D\u59CB\u5316\u9879\u76EE\uFF08\u6A21\u677F\uFF1Aempty / function\uFF09\uFF0C\u6216 --list \u4ECE\u5E73\u53F0\u53D6\u6A21\u677F\u6E05\u5355").argument("[name]", "\u9879\u76EE\u76EE\u5F55\u540D\uFF08\u914D\u5408 --list \u65F6\u53EF\u7701\u7565\uFF09").option("-t, --template <template>", "\u6A21\u677F\uFF1Aempty | function", "function").option("-l, --list", "\u4ECE\u5E73\u53F0 /api/v1/templates \u5217\u51FA\u53EF\u7528\u6A21\u677F\uFF08\u4E0D\u811A\u624B\u67B6\uFF09", false).option(
6186
+ }
6187
+
6188
+ // packages/cli/src/commands/init.ts
6189
+ init_config();
6190
+
6191
+ // packages/cli/src/templates.ts
6192
+ init_auth();
6193
+ async function fetchTemplates(server) {
6194
+ let response;
6195
+ try {
6196
+ response = await fetch(`${server}/api/v1/templates`);
6197
+ } catch (error) {
6198
+ throw new CliError(
6199
+ "SERVER_UNREACHABLE",
6200
+ `\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
6201
+ );
6202
+ }
6203
+ const text = await response.text();
6204
+ let parsed = null;
6205
+ try {
6206
+ parsed = text.length === 0 ? null : JSON.parse(text);
6207
+ } catch {
6208
+ parsed = null;
6209
+ }
6210
+ if (response.status < 200 || response.status >= 300) {
6211
+ const msg = parsed?.error;
6212
+ throw new CliError("TEMPLATE_LIST_FAILED", msg ?? `\u5E73\u53F0\u8FD4\u56DE HTTP ${response.status}`);
6213
+ }
6214
+ const templates = parsed?.templates;
6215
+ return templates ?? [];
6216
+ }
6217
+
6218
+ // packages/cli/src/commands/init.ts
6219
+ function registerInit(program2, ctx) {
6220
+ program2.command("init").description("\u521D\u59CB\u5316\u9879\u76EE\uFF08\u6A21\u677F\uFF1Aempty / function / widget / page\uFF09\uFF0C\u6216 --list \u4ECE\u5E73\u53F0\u53D6\u6A21\u677F\u6E05\u5355").argument("[name]", "\u9879\u76EE\u76EE\u5F55\u540D\uFF08\u914D\u5408 --list \u65F6\u53EF\u7701\u7565\uFF09").option("-t, --template <template>", "\u6A21\u677F\uFF1Aempty | function | widget | page", "function").option("-l, --list", "\u4ECE\u5E73\u53F0 /api/v1/templates \u5217\u51FA\u53EF\u7528\u6A21\u677F\uFF08\u4E0D\u811A\u624B\u67B6\uFF09", false).option(
5845
6221
  "-s, --server <url>",
5846
6222
  "\u5E73\u53F0\u5730\u5740\uFF08--list \u7528\uFF1B\u7F3A\u7701\u8BFB ADEP_SERVER \u6216 http://localhost:3000\uFF09"
5847
6223
  ).action(
5848
6224
  async (name, flags) => {
5849
- try {
6225
+ const command = ctx.io("init");
6226
+ await command.run(async () => {
5850
6227
  if (flags.list === true) {
5851
6228
  const server = flags.server ?? resolveServer();
5852
6229
  const templates = await fetchTemplates(server);
5853
- if (jsonMode()) {
5854
- output(JSON.stringify({ ok: true, command: "init", data: { templates } }));
5855
- } else {
5856
- for (const tpl of templates) {
5857
- output(`${tpl.code} ${tpl.name} ${tpl.description ?? ""}`);
5858
- }
5859
- }
6230
+ command.ok(
6231
+ { templates },
6232
+ (data) => data.templates.map(
6233
+ (tpl) => `${tpl.code} ${tpl.name} ${tpl.description ?? ""}`
6234
+ )
6235
+ );
5860
6236
  return;
5861
6237
  }
5862
6238
  if (name === void 0) {
5863
6239
  throw new InitError("MISSING_NAME", "\u9700\u7ED9\u51FA\u9879\u76EE\u540D\uFF0C\u6216\u4F7F\u7528 --list \u5217\u51FA\u5E73\u53F0\u53EF\u7528\u6A21\u677F");
5864
6240
  }
5865
6241
  const template = flags.template;
5866
- if (!["empty", "function"].includes(template)) {
5867
- throw new InitError("INVALID_TEMPLATE", `\u672A\u77E5\u6A21\u677F "${template}"\uFF1A\u53EF\u9009 empty | function`);
5868
- }
5869
- const result = await initProject(cwd, name, template);
5870
- if (jsonMode()) {
5871
- output(JSON.stringify({ ok: true, command: "init", data: result }));
5872
- } else {
5873
- output(`\u5DF2\u521B\u5EFA ${result.projectPath}`);
6242
+ if (!TEMPLATE_NAMES.includes(template)) {
6243
+ throw new InitError(
6244
+ "INVALID_TEMPLATE",
6245
+ `\u672A\u77E5\u6A21\u677F "${template}"\uFF1A\u53EF\u9009 ${TEMPLATE_NAMES.join(" | ")}`
6246
+ );
5874
6247
  }
5875
- } catch (error) {
5876
- emitError(output, "init", jsonMode(), error);
5877
- }
6248
+ const result = await initProject(ctx.cwd, name, template);
6249
+ command.ok(result, (data) => `\u5DF2\u521B\u5EFA ${data.projectPath}`);
6250
+ });
5878
6251
  }
5879
6252
  );
6253
+ }
6254
+
6255
+ // packages/cli/src/commands/dev.ts
6256
+ function registerDevServers(program2, ctx) {
5880
6257
  program2.command("dev").description("\u672C\u5730\u8C03\u8BD5\uFF1A\u76D1\u542C functions/ \u70ED\u91CD\u8F7D\uFF0Chttp://localhost:<port>/<fnName>").option("-p, --port <port>", "\u76D1\u542C\u7AEF\u53E3\uFF08\u7F3A\u7701 8787\uFF09", "8787").action(async (flags) => {
5881
- try {
6258
+ const command = ctx.io("dev");
6259
+ await command.run(async () => {
5882
6260
  const { startDevServer: startDevServer2 } = await Promise.resolve().then(() => (init_dev(), dev_exports));
5883
- const started = await startDevServer2({ cwd, port: Number(flags.port ?? "8787") });
5884
- output(`[adep] dev server listening on ${started.baseUrl}\uFF08Ctrl-C \u9000\u51FA\uFF09`);
6261
+ const started = await startDevServer2({ cwd: ctx.cwd, port: Number(flags.port ?? "8787") });
6262
+ command.raw(`[adep] dev server listening on ${started.baseUrl}\uFF08Ctrl-C \u9000\u51FA\uFF09`);
5885
6263
  await new Promise(() => void 0);
5886
- } catch (error) {
5887
- emitError(output, "dev", jsonMode(), error);
5888
- }
6264
+ });
5889
6265
  });
5890
6266
  program2.command("serve").description(
5891
6267
  "\u5F00\u53D1\u6001\u670D\u52A1\u5668\uFF1A\u51FD\u6570 /api/{fn} + /healthz + \u9759\u6001\u6258\u7BA1 + \u7EC4\u4EF6\u9884\u89C8\uFF08\u9ED8\u8BA4\u4EC5\u56DE\u73AF\uFF0C\u4E0D\u662F\u751F\u4EA7\u670D\u52A1\u5668\uFF09"
@@ -5895,605 +6271,605 @@ function buildProgram(options = {}) {
5895
6271
  ).option(
5896
6272
  "--static <dir>",
5897
6273
  "\u9759\u6001\u6258\u7BA1\u76EE\u5F55\uFF08\u7F3A\u7701\u53D6 ADEP_SERVE_STATIC_DIR\uFF0C\u518D\u7F3A\u7701 public/\uFF1B\u81EA\u6258\u7BA1\u90E8\u7F72\u5305\u6307\u5411\u5305\u5185 web/\uFF09"
6274
+ ).option(
6275
+ "--watch",
6276
+ "\u70ED\u91CD\u8F7D\uFF1A\u76D1\u542C functions/ \u4E0E .env* \u53D8\u66F4\u81EA\u52A8\u751F\u6548\uFF0C\u51FD\u6570 console \u8F93\u51FA\u76F4\u8FBE\u7EC8\u7AEF\uFF08\u5F00\u53D1\u6001\u8C03\u8BD5\u7528\uFF09"
5898
6277
  ).action(async (flags) => {
5899
- try {
6278
+ const command = ctx.io("serve");
6279
+ await command.run(async () => {
5900
6280
  const { startServeServer: startServeServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
5901
6281
  await startServeServer2({
5902
- cwd,
6282
+ cwd: ctx.cwd,
5903
6283
  ...flags.port === void 0 ? {} : { port: Number(flags.port) },
5904
6284
  ...flags.host === void 0 ? {} : { host: flags.host },
5905
- ...flags.static === void 0 ? {} : { staticDir: flags.static }
6285
+ ...flags.static === void 0 ? {} : { staticDir: flags.static },
6286
+ ...flags.watch === void 0 ? {} : { watch: true }
5906
6287
  });
5907
6288
  await new Promise(() => void 0);
5908
- } catch (error) {
5909
- emitError(output, "serve", jsonMode(), error);
6289
+ });
6290
+ });
6291
+ }
6292
+
6293
+ // packages/cli/src/commands/deploy.ts
6294
+ async function runDeploy(paths, io, cwd, slug, dir) {
6295
+ const { deploy: deploy2 } = await Promise.resolve().then(() => (init_deploy(), deploy_exports));
6296
+ const startedAt = Date.now();
6297
+ const result = await deploy2(paths, {
6298
+ cwd,
6299
+ ...slug === void 0 ? {} : { slug },
6300
+ ...dir === void 0 ? {} : { functionsDir: dir },
6301
+ // --json 下逐函数进度会破坏「stdout 恰好一个 JSON 对象」的信封约定(PRD §2.5.3)。
6302
+ silent: io.json,
6303
+ // 人读模式的进度也走注入的 io:deploy 内部缺省会直写 process.stdout,
6304
+ // 那会让带 sink 的调用方漏收这部分行。
6305
+ log: (line) => io.line(line)
6306
+ });
6307
+ const elapsedSeconds = (Date.now() - startedAt) / 1e3;
6308
+ const deployedCount = result.functions.filter((fn) => fn.action !== "none").length;
6309
+ io.ok({ ...result, elapsedSeconds, deployedCount }, (data) => {
6310
+ const r = data;
6311
+ const lines = r.functions.map((fn) => `${fn.name} v${fn.version} ${fn.url}`);
6312
+ if (r.noChanges) {
6313
+ lines.push(
6314
+ `\u2713 no changes \xB7 ${r.functions.length} functions up to date in ${formatSeconds(r.elapsedSeconds)}`
6315
+ );
6316
+ } else {
6317
+ lines.push(`\u2713 ${r.deployedCount} functions deployed in ${formatSeconds(r.elapsedSeconds)}`);
5910
6318
  }
6319
+ return lines;
5911
6320
  });
6321
+ }
6322
+ function registerDeploy(program2, ctx) {
5912
6323
  program2.command("deploy").description("\u589E\u91CF\u90E8\u7F72\uFF1A\u5BF9\u6BD4\u8FDC\u7AEF\u54C8\u5E0C \u2192 \u4EC5\u4E0A\u4F20\u53D8\u66F4 \u2192 \u53D1\u5E03 \u2192 \u8F93\u51FA\u8BBF\u95EE\u57DF\u540D").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
5913
- try {
5914
- await runDeploy(paths, output, jsonMode(), cwd, flags.project);
5915
- } catch (error) {
5916
- emitError(output, "deploy", jsonMode(), error);
5917
- }
6324
+ const command = ctx.io("deploy");
6325
+ await command.run(() => runDeploy(ctx.paths, command, ctx.cwd, flags.project));
5918
6326
  });
6327
+ }
6328
+
6329
+ // packages/cli/src/commands/projects.ts
6330
+ function registerProjects(program2, ctx) {
5919
6331
  const projects = program2.command("projects").description("\u9879\u76EE\uFF1A\u521B\u5EFA / \u5217\u51FA / \u67E5\u770B\uFF08\u5B50\u57DF\u5730\u5740\u7531\u5E73\u53F0\u56DE\u663E\uFF0C\u4E0D\u5728 CLI \u4FA7\u62FC\uFF09");
5920
6332
  projects.command("create").description("\u521B\u5EFA\u9879\u76EE\u5E76\u8F93\u51FA\u5B50\u57DF\u5730\u5740").argument("<slug>", "\u9879\u76EE slug\uFF08\u5168\u5C40\u552F\u4E00\uFF0C\u5373\u5B50\u57DF\u540D\uFF09").option("-n, --name <name>", "\u9879\u76EE\u5C55\u793A\u540D\uFF08\u7F3A\u7701\u53D6 slug\uFF09").option("--space <spaceId>", "\u5F52\u5C5E\u7A7A\u95F4\uFF08\u7F3A\u7701\u4E2A\u4EBA\u7A7A\u95F4\uFF09").action(async (slug, flags) => {
5921
- try {
6333
+ const command = ctx.io("projects create");
6334
+ await command.run(async () => {
5922
6335
  const { projectsCreate: projectsCreate2 } = await Promise.resolve().then(() => (init_projects(), projects_exports));
5923
- const created = await projectsCreate2(paths, {
6336
+ const created = await projectsCreate2(ctx.paths, {
5924
6337
  slug,
5925
6338
  ...flags.name === void 0 ? {} : { name: flags.name },
5926
6339
  ...flags.space === void 0 ? {} : { spaceId: flags.space }
5927
6340
  });
5928
- if (jsonMode()) {
5929
- output(JSON.stringify({ ok: true, command: "projects create", data: created }));
5930
- } else {
5931
- output(`\u2713 Project created \xB7 ${created.url}`);
5932
- }
5933
- } catch (error) {
5934
- emitError(output, "projects create", jsonMode(), error);
5935
- }
6341
+ command.ok(created, (data) => `\u2713 Project created \xB7 ${data.url}`);
6342
+ });
5936
6343
  });
5937
6344
  projects.command("list").description("\u5217\u51FA\u5F53\u524D\u7528\u6237\u53EF\u8BBF\u95EE\u7684\u9879\u76EE").action(async () => {
5938
- try {
6345
+ const command = ctx.io("projects list");
6346
+ await command.run(async () => {
5939
6347
  const { projectsList: projectsList2 } = await Promise.resolve().then(() => (init_projects(), projects_exports));
5940
- const list = await projectsList2(paths);
5941
- if (jsonMode()) {
5942
- output(JSON.stringify({ ok: true, command: "projects list", data: { projects: list } }));
5943
- } else {
5944
- if (list.length === 0) output("\uFF08\u8FD8\u6CA1\u6709\u9879\u76EE\uFF1Aadep projects create <slug>\uFF09");
5945
- for (const project2 of list) output(`${project2.slug} ${project2.name} ${project2.url}`);
5946
- }
5947
- } catch (error) {
5948
- emitError(output, "projects list", jsonMode(), error);
5949
- }
6348
+ const list = await projectsList2(ctx.paths);
6349
+ command.ok({ projects: list }, (data) => {
6350
+ const projectsData = data.projects;
6351
+ if (projectsData.length === 0) return "\uFF08\u8FD8\u6CA1\u6709\u9879\u76EE\uFF1Aadep projects create <slug>\uFF09";
6352
+ return projectsData.map((p) => `${p.slug} ${p.name} ${p.url}`);
6353
+ });
6354
+ });
5950
6355
  });
5951
6356
  projects.command("info").description("\u67E5\u770B\u5355\u4E2A\u9879\u76EE\u7684 id / slug / \u5B50\u57DF\u5730\u5740").argument("<slug>", "\u9879\u76EE slug").action(async (slug) => {
5952
- try {
6357
+ const command = ctx.io("projects info");
6358
+ await command.run(async () => {
5953
6359
  const { projectsInfo: projectsInfo2 } = await Promise.resolve().then(() => (init_projects(), projects_exports));
5954
- const project2 = await projectsInfo2(paths, { slug });
5955
- if (jsonMode()) {
5956
- output(JSON.stringify({ ok: true, command: "projects info", data: project2 }));
5957
- } else {
5958
- output(`${project2.id} ${project2.slug} ${project2.name} ${project2.url}`);
5959
- }
5960
- } catch (error) {
5961
- emitError(output, "projects info", jsonMode(), error);
5962
- }
6360
+ const project2 = await projectsInfo2(ctx.paths, { slug });
6361
+ command.ok(project2, (data) => {
6362
+ const p = data;
6363
+ return `${p.id} ${p.slug} ${p.name} ${p.url}`;
6364
+ });
6365
+ });
5963
6366
  });
6367
+ }
6368
+
6369
+ // packages/cli/src/commands/functions.ts
6370
+ init_auth();
6371
+ function registerFunctions(program2, ctx) {
5964
6372
  const functions = program2.command("functions").description("\u4E91\u51FD\u6570\uFF1A\u90E8\u7F72\uFF08\u53EF\u6307\u5B9A\u76EE\u5F55\uFF09/ \u5217\u51FA / \u67E5\u65E5\u5FD7");
5965
6373
  functions.command("deploy").description(
5966
6374
  "\u90E8\u7F72\u51FD\u6570\u76EE\u5F55\uFF08`adep deploy` \u7684\u547D\u4EE4\u65CF\u5165\u53E3\uFF1Bdir \u8986\u76D6 adep.config.ts \u7684 functionsDir\uFF09"
5967
6375
  ).argument("[dir]", "\u51FD\u6570\u76EE\u5F55\uFF08\u76F8\u5BF9\u9879\u76EE\u6839\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u7F3A\u7701\u53D6\u914D\u7F6E\u91CC\u7684 functionsDir\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (dir, flags) => {
5968
- try {
5969
- await runDeploy(paths, output, jsonMode(), cwd, flags.project, dir);
5970
- } catch (error) {
5971
- emitError(output, "functions deploy", jsonMode(), error);
5972
- }
6376
+ const command = ctx.io("functions deploy");
6377
+ await command.run(() => runDeploy(ctx.paths, command, ctx.cwd, flags.project, dir));
5973
6378
  });
5974
6379
  functions.command("list").description("\u5217\u51FA\u9879\u76EE\u4E0B\u7684\u4E91\u51FD\u6570\uFF08\u542B\u516C\u7F51\u8BBF\u95EE\u524D\u7F00\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
5975
- try {
6380
+ const command = ctx.io("functions list");
6381
+ await command.run(async () => {
5976
6382
  const { functionsList: functionsList2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
5977
- const result = await functionsList2(paths, {
5978
- cwd,
6383
+ const result = await functionsList2(ctx.paths, {
6384
+ cwd: ctx.cwd,
5979
6385
  ...flags.project === void 0 ? {} : { slug: flags.project }
5980
6386
  });
5981
- if (jsonMode()) {
5982
- output(JSON.stringify({ ok: true, command: "functions list", data: result }));
5983
- } else {
5984
- if (result.functions.length === 0) output("\uFF08\u8BE5\u9879\u76EE\u4E0B\u8FD8\u6CA1\u6709\u51FD\u6570\uFF09");
5985
- for (const fn of result.functions) {
5986
- output(`${fn.name} ${result.baseUrl}/${fn.name}`);
5987
- }
5988
- }
5989
- } catch (error) {
5990
- emitError(output, "functions list", jsonMode(), error);
5991
- }
6387
+ command.ok(result, (data) => {
6388
+ const r = data;
6389
+ if (r.functions.length === 0) return "\uFF08\u8BE5\u9879\u76EE\u4E0B\u8FD8\u6CA1\u6709\u51FD\u6570\uFF09";
6390
+ return r.functions.map((fn) => `${fn.name} ${r.baseUrl}/${fn.name}`);
6391
+ });
6392
+ });
5992
6393
  });
5993
6394
  functions.command("logs").description("\u67E5\u8BE2\u51FD\u6570\u6700\u8FD1\u6267\u884C\u65E5\u5FD7\uFF08\u7F13\u51B2\u5728\u5E73\u53F0\u8FDB\u7A0B\u5185\uFF0C\u672A\u6267\u884C\u8FC7\u7684\u51FD\u6570\u4E3A\u7A7A\uFF09").argument("<name>", "\u51FD\u6570\u540D").option("--tail <count>", "\u53D6\u6700\u8FD1\u591A\u5C11\u6761\uFF08\u7F3A\u7701 100\uFF0C\u670D\u52A1\u7AEF\u6709\u4E0A\u9650\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (name, flags) => {
5994
- try {
6395
+ const command = ctx.io("functions logs");
6396
+ await command.run(async () => {
5995
6397
  const { functionsLogs: functionsLogs2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
5996
6398
  const tail = flags.tail === void 0 ? void 0 : Number(flags.tail);
5997
6399
  if (tail !== void 0 && (!Number.isFinite(tail) || tail <= 0)) {
5998
6400
  throw new CliError("INVALID_TAIL", `--tail \u987B\u4E3A\u6B63\u6574\u6570\uFF0C\u6536\u5230 "${flags.tail}"`);
5999
6401
  }
6000
- const result = await functionsLogs2(paths, {
6001
- cwd,
6402
+ const result = await functionsLogs2(ctx.paths, {
6403
+ cwd: ctx.cwd,
6002
6404
  name,
6003
6405
  ...tail === void 0 ? {} : { tail },
6004
6406
  ...flags.project === void 0 ? {} : { slug: flags.project }
6005
6407
  });
6006
- if (jsonMode()) {
6007
- output(JSON.stringify({ ok: true, command: "functions logs", data: result }));
6008
- } else {
6009
- if (result.logs.length === 0) {
6010
- output(`\uFF08\u51FD\u6570 ${name} \u6682\u65E0\u6267\u884C\u65E5\u5FD7\uFF1A\u5148\u7528 adep deploy \u53D1\u5E03\u5E76\u7ECF\u7F51\u5173\u6216\u8C03\u8BD5\u9762\u677F\u6267\u884C\u4E00\u6B21\uFF09`);
6408
+ command.ok(result, (data) => {
6409
+ const r = data;
6410
+ if (r.logs.length === 0) {
6411
+ return `\uFF08\u51FD\u6570 ${name} \u6682\u65E0\u6267\u884C\u65E5\u5FD7\uFF1A\u5148\u7528 adep deploy \u53D1\u5E03\u5E76\u7ECF\u7F51\u5173\u6216\u8C03\u8BD5\u9762\u677F\u6267\u884C\u4E00\u6B21\uFF09`;
6011
6412
  }
6012
- for (const log of result.logs) output(`${log.at} [${log.level}] ${log.message}`);
6013
- }
6014
- } catch (error) {
6015
- emitError(output, "functions logs", jsonMode(), error);
6016
- }
6413
+ return r.logs.map((log) => `${log.at} [${log.level}] ${log.message}`);
6414
+ });
6415
+ });
6017
6416
  });
6417
+ }
6418
+
6419
+ // packages/cli/src/commands/mcp.ts
6420
+ function registerMcp(program2, ctx) {
6018
6421
  const mcp = program2.command("mcp").description("MCP Tool\uFF1A\u628A\u4E91\u51FD\u6570\u53D1\u5E03\u4E3A\u5DE5\u5177 / \u53D6\u6D88\u53D1\u5E03 / \u5217\u51FA");
6019
6422
  mcp.command("publish").description("\u53D1\u5E03\u4E91\u51FD\u6570\u4E3A\u9879\u76EE MCP Tool\uFF08Tool \u540D\u7F3A\u7701\u53D6\u51FD\u6570\u540D\uFF0C--name \u53EF\u8986\u76D6\uFF09").requiredOption("--function <fn>", "\u8981\u53D1\u5E03\u7684\u51FD\u6570\u540D").option("--name <tool>", "\u6CE8\u518C\u7684 Tool \u540D\uFF08\u7F3A\u7701\u53D6\u51FD\u6570\u540D\uFF09").option(
6020
6423
  "--description <text>",
6021
6424
  "\u8986\u76D6\u9762\u5411 Agent \u7684\u5DE5\u5177\u63CF\u8FF0\uFF08\u7F3A\u7701\u7528\u6E90\u7801 @description / \u63A8\u5BFC\u63CF\u8FF0\uFF09"
6022
6425
  ).option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(
6023
6426
  async (flags) => {
6024
- try {
6427
+ const command = ctx.io("mcp publish");
6428
+ await command.run(async () => {
6025
6429
  const { mcpPublish: mcpPublish2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
6026
- const result = await mcpPublish2(paths, {
6027
- cwd,
6430
+ const result = await mcpPublish2(ctx.paths, {
6431
+ cwd: ctx.cwd,
6028
6432
  fn: flags.function,
6029
6433
  ...flags.name === void 0 ? {} : { toolName: flags.name },
6030
6434
  ...flags.description === void 0 ? {} : { description: flags.description },
6031
6435
  ...flags.project === void 0 ? {} : { slug: flags.project }
6032
6436
  });
6033
- if (jsonMode()) {
6034
- output(JSON.stringify({ ok: true, command: "mcp publish", data: result }));
6035
- } else {
6036
- output(`\u2713 MCP tool published \xB7 ${result.tool.name}`);
6037
- }
6038
- } catch (error) {
6039
- emitError(output, "mcp publish", jsonMode(), error);
6040
- }
6437
+ command.ok(result, (data) => {
6438
+ const r = data;
6439
+ return `\u2713 MCP tool published \xB7 ${r.tool.name}`;
6440
+ });
6441
+ });
6041
6442
  }
6042
6443
  );
6043
6444
  mcp.command("unpublish").description("\u53D6\u6D88\u53D1\u5E03\u4E91\u51FD\u6570\u5BF9\u5E94\u7684 MCP Tool\uFF08\u7ACB\u5373\u4ECE\u9879\u76EE tools/list \u79FB\u9664\uFF09").requiredOption("--function <fn>", "\u51FD\u6570\u540D").option("--name <tool>", "\u5DF2\u6CE8\u518C\u7684 Tool \u540D\uFF08\u7F3A\u7701\u53D6\u51FD\u6570\u540D\uFF1B\u53D1\u5E03\u65F6\u7528\u4E86\u522B\u540D\u624D\u9700\u7ED9\u51FA\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
6044
- try {
6445
+ const command = ctx.io("mcp unpublish");
6446
+ await command.run(async () => {
6045
6447
  const { mcpUnpublish: mcpUnpublish2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
6046
- const result = await mcpUnpublish2(paths, {
6047
- cwd,
6448
+ const result = await mcpUnpublish2(ctx.paths, {
6449
+ cwd: ctx.cwd,
6048
6450
  fn: flags.function,
6049
6451
  ...flags.name === void 0 ? {} : { toolName: flags.name },
6050
6452
  ...flags.project === void 0 ? {} : { slug: flags.project }
6051
6453
  });
6052
- if (jsonMode()) {
6053
- output(JSON.stringify({ ok: true, command: "mcp unpublish", data: result }));
6054
- } else if (result.removed) {
6055
- output(`\u2713 MCP tool unpublished \xB7 ${result.toolName}`);
6056
- } else {
6057
- output(`\uFF08\u9879\u76EE\u672A\u53D1\u5E03\u540D\u4E3A ${result.toolName} \u7684 MCP tool\uFF0C\u65E0\u9700\u53D6\u6D88\uFF09`);
6058
- }
6059
- } catch (error) {
6060
- emitError(output, "mcp unpublish", jsonMode(), error);
6061
- }
6454
+ command.ok(result, (data) => {
6455
+ const r = data;
6456
+ return r.removed ? `\u2713 MCP tool unpublished \xB7 ${r.toolName}` : `\uFF08\u9879\u76EE\u672A\u53D1\u5E03\u540D\u4E3A ${r.toolName} \u7684 MCP tool\uFF0C\u65E0\u9700\u53D6\u6D88\uFF09`;
6457
+ });
6458
+ });
6062
6459
  });
6063
6460
  mcp.command("list").description("\u5217\u51FA\u9879\u76EE\u5DF2\u53D1\u5E03\u7684 MCP Tool \u4E0E\u7AEF\u70B9\u5730\u5740\uFF08\u8BFB\u9879\u76EE /mcp \u7684 tools/list\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
6064
- try {
6461
+ const command = ctx.io("mcp list");
6462
+ await command.run(async () => {
6065
6463
  const { mcpList: mcpList2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
6066
- const result = await mcpList2(paths, {
6067
- cwd,
6464
+ const result = await mcpList2(ctx.paths, {
6465
+ cwd: ctx.cwd,
6068
6466
  ...flags.project === void 0 ? {} : { slug: flags.project }
6069
6467
  });
6070
- if (jsonMode()) {
6071
- output(JSON.stringify({ ok: true, command: "mcp list", data: result }));
6072
- } else {
6073
- output(`\u7AEF\u70B9\uFF1A${result.endpoint}`);
6074
- if (result.tools.length === 0) {
6075
- output("\uFF08\u8FD8\u6CA1\u6709\u5DF2\u53D1\u5E03\u7684 MCP tool\uFF1Aadep mcp publish --function <fn>\uFF09");
6076
- }
6077
- for (const tool of result.tools) {
6078
- output(`${tool.name} ${tool.description ?? ""}`);
6468
+ command.ok(result, (data) => {
6469
+ const r = data;
6470
+ const lines = [`\u7AEF\u70B9\uFF1A${r.endpoint}`];
6471
+ if (r.tools.length === 0) {
6472
+ lines.push("\uFF08\u8FD8\u6CA1\u6709\u5DF2\u53D1\u5E03\u7684 MCP tool\uFF1Aadep mcp publish --function <fn>\uFF09");
6473
+ } else {
6474
+ for (const tool of r.tools) lines.push(`${tool.name} ${tool.description ?? ""}`);
6079
6475
  }
6080
- }
6081
- } catch (error) {
6082
- emitError(output, "mcp list", jsonMode(), error);
6083
- }
6476
+ return lines;
6477
+ });
6478
+ });
6084
6479
  });
6480
+ }
6481
+
6482
+ // packages/cli/src/commands/doctor.ts
6483
+ function registerDoctor(program2, ctx) {
6085
6484
  program2.command("doctor").description("\u73AF\u5883\u81EA\u68C0\uFF1A\u51ED\u636E\u72B6\u6001 / \u5E73\u53F0\u53EF\u8FBE\u6027 / \u79BB\u7EBF\u53EF\u7528\u8303\u56F4\uFF08\u8865\u9F50\u65AD\u7F51\u6587\u6848\u5F15\u7528\u7684\u60AC\u7A7A\u547D\u4EE4\uFF09").action(async () => {
6086
- try {
6485
+ const command = ctx.io("doctor");
6486
+ await command.run(async () => {
6087
6487
  const { runDoctor: runDoctor2, formatDoctorReport: formatDoctorReport2 } = await Promise.resolve().then(() => (init_doctor(), doctor_exports));
6088
- const report = await runDoctor2(paths);
6089
- if (jsonMode()) {
6090
- output(JSON.stringify({ ok: true, command: "doctor", data: report }));
6091
- } else {
6092
- for (const line of formatDoctorReport2(report)) output(line);
6093
- }
6094
- } catch (error) {
6095
- emitError(output, "doctor", jsonMode(), error);
6096
- }
6488
+ const report = await runDoctor2(ctx.paths);
6489
+ command.ok(report, () => formatDoctorReport2(report));
6490
+ });
6097
6491
  });
6492
+ }
6493
+
6494
+ // packages/cli/src/commands/db.ts
6495
+ function registerDb(program2, ctx) {
6098
6496
  const db = program2.command("db").description("\u9879\u76EE\u6570\u636E\u5E93\u7EF4\u62A4\uFF1A\u542F\u52A8 / \u72B6\u6001 / \u505C\u6B62 / SQL / \u5FEB\u7167 / \u56DE\u6EDA").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09");
6099
6497
  db.command("start").description("\u542F\u52A8\u9879\u76EE\u6570\u636E\u5E93\uFF08\u5DF2\u5B58\u5728\u5219\u91CD\u65B0\u6FC0\u6D3B\uFF0C\u4E0D\u91CD\u5EFA\u6570\u636E\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
6100
- try {
6498
+ const command = ctx.io("db start");
6499
+ await command.run(async () => {
6101
6500
  const { dbStart: dbStart2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
6102
- const result = await dbStart2(paths, {
6103
- cwd,
6501
+ const result = await dbStart2(ctx.paths, {
6502
+ cwd: ctx.cwd,
6104
6503
  ...flags.project === void 0 ? {} : { slug: flags.project }
6105
6504
  });
6106
- if (jsonMode()) {
6107
- output(JSON.stringify({ ok: true, command: "db start", data: result }));
6108
- } else {
6109
- output(
6110
- `\u6570\u636E\u5E93\u5DF2\u5C31\u7EEA\uFF1A${result.projectId}\uFF08${result.journalMode}\uFF0C${result.usage.tableCount} \u8868 / ${result.usage.rowCount} \u884C / ${formatBytes(result.usage.sizeBytes)}\uFF09`
6111
- );
6112
- }
6113
- } catch (error) {
6114
- emitError(output, "db start", jsonMode(), error);
6115
- }
6505
+ command.ok(result, (data) => {
6506
+ const r = data;
6507
+ return `\u6570\u636E\u5E93\u5DF2\u5C31\u7EEA\uFF1A${r.projectId}\uFF08${r.journalMode}\uFF0C${r.usage.tableCount} \u8868 / ${r.usage.rowCount} \u884C / ${formatBytes(r.usage.sizeBytes)}\uFF09`;
6508
+ });
6509
+ });
6116
6510
  });
6117
6511
  db.command("status").description("\u67E5\u8BE2\u9879\u76EE\u6570\u636E\u5E93\u72B6\u6001\u4E0E\u7528\u91CF\uFF08\u4F53\u79EF / \u8868\u6570 / \u884C\u6570\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
6118
- try {
6512
+ const command = ctx.io("db status");
6513
+ await command.run(async () => {
6119
6514
  const { dbStatus: dbStatus2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
6120
- const result = await dbStatus2(paths, {
6121
- cwd,
6515
+ const result = await dbStatus2(ctx.paths, {
6516
+ cwd: ctx.cwd,
6122
6517
  ...flags.project === void 0 ? {} : { slug: flags.project }
6123
6518
  });
6124
- if (jsonMode()) {
6125
- output(JSON.stringify({ ok: true, command: "db status", data: result }));
6126
- } else {
6127
- output(
6128
- `\u72B6\u6001\uFF1A${result.status}\uFF08${result.projectId}\uFF0C${result.usage.tableCount} \u8868 / ${result.usage.rowCount} \u884C / ${formatBytes(result.usage.sizeBytes)}\uFF09`
6129
- );
6130
- }
6131
- } catch (error) {
6132
- emitError(output, "db status", jsonMode(), error);
6133
- }
6519
+ command.ok(result, (data) => {
6520
+ const r = data;
6521
+ return `\u72B6\u6001\uFF1A${r.status}\uFF08${r.projectId}\uFF0C${r.usage.tableCount} \u8868 / ${r.usage.rowCount} \u884C / ${formatBytes(r.usage.sizeBytes)}\uFF09`;
6522
+ });
6523
+ });
6134
6524
  });
6135
6525
  db.command("stop").description("\u505C\u6B62\u9879\u76EE\u6570\u636E\u5E93\uFF08\u8FDE\u63A5\u5173\u95ED\u5E76\u6807\u8BB0\uFF1B\u6587\u4EF6\u4FDD\u7559\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
6136
- try {
6526
+ const command = ctx.io("db stop");
6527
+ await command.run(async () => {
6137
6528
  const { dbStop: dbStop2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
6138
- const result = await dbStop2(paths, {
6139
- cwd,
6529
+ const result = await dbStop2(ctx.paths, {
6530
+ cwd: ctx.cwd,
6140
6531
  ...flags.project === void 0 ? {} : { slug: flags.project }
6141
6532
  });
6142
- if (jsonMode()) {
6143
- output(JSON.stringify({ ok: true, command: "db stop", data: result }));
6144
- } else {
6145
- output(`\u6570\u636E\u5E93\u5DF2\u505C\u6B62\uFF1A${result.status}`);
6146
- }
6147
- } catch (error) {
6148
- emitError(output, "db stop", jsonMode(), error);
6149
- }
6533
+ command.ok(result, (data) => `\u6570\u636E\u5E93\u5DF2\u505C\u6B62\uFF1A${data.status}`);
6534
+ });
6150
6535
  });
6151
6536
  db.command("exec").description("\u6267\u884C\u5355\u6761 SQL\uFF08\u5199 / \u7834\u574F\u6027\u8BED\u53E5\u9700 --confirm-table \u4E8C\u6B21\u786E\u8BA4\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").requiredOption("--sql <sql>", "\u5F85\u6267\u884C SQL").option("--confirm-table <table>", "\u7834\u574F\u6027\u64CD\u4F5C\u7684\u76EE\u6807\u8868\u540D\uFF08\u4E8C\u6B21\u786E\u8BA4\uFF09").action(async (flags) => {
6152
- try {
6537
+ const command = ctx.io("db exec");
6538
+ await command.run(async () => {
6153
6539
  const { dbExec: dbExec2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
6154
- const result = await dbExec2(paths, {
6155
- cwd,
6540
+ const result = await dbExec2(ctx.paths, {
6541
+ cwd: ctx.cwd,
6156
6542
  sql: flags.sql,
6157
6543
  ...flags.project === void 0 ? {} : { slug: flags.project },
6158
6544
  ...flags.confirmTable === void 0 ? {} : { confirmTable: flags.confirmTable }
6159
6545
  });
6160
- if (jsonMode()) {
6161
- output(JSON.stringify({ ok: true, command: "db exec", data: result }));
6162
- } else {
6163
- if (result.columns.length > 0) {
6164
- output(formatTable(result.columns, result.rows));
6165
- if (result.truncated) output(`\uFF08\u7ED3\u679C\u5DF2\u622A\u65AD\u5230 ${result.rows.length} \u884C\uFF09`);
6166
- } else if (result.changes > 0) {
6167
- output(`${result.changes} \u884C\u53D7\u5F71\u54CD`);
6546
+ command.ok(result, (data) => {
6547
+ const r = data;
6548
+ const lines = [];
6549
+ if (r.columns.length > 0) {
6550
+ lines.push(formatTable(r.columns, r.rows));
6551
+ if (r.truncated) lines.push(`\uFF08\u7ED3\u679C\u5DF2\u622A\u65AD\u5230 ${r.rows.length} \u884C\uFF09`);
6552
+ } else if (r.changes > 0) {
6553
+ lines.push(`${r.changes} \u884C\u53D7\u5F71\u54CD`);
6168
6554
  } else {
6169
- output("\u8BED\u53E5\u6267\u884C\u6210\u529F\uFF08\u65E0\u8FD4\u56DE\u884C\uFF09");
6555
+ lines.push("\u8BED\u53E5\u6267\u884C\u6210\u529F\uFF08\u65E0\u8FD4\u56DE\u884C\uFF09");
6170
6556
  }
6171
- output(`\u8017\u65F6 ${result.elapsedMs}ms`);
6172
- }
6173
- } catch (error) {
6174
- emitError(output, "db exec", jsonMode(), error);
6175
- }
6557
+ lines.push(`\u8017\u65F6 ${r.elapsedMs}ms`);
6558
+ return lines;
6559
+ });
6560
+ });
6176
6561
  });
6177
6562
  const snapshot = db.command("snapshot").description("\u6570\u636E\u5E93\u5FEB\u7167\uFF08\u4ED8\u8D39\u6863\u4F4D\uFF09\uFF1A\u5217\u51FA\uFF08\u7F3A\u7701\uFF09/ \u521B\u5EFA / \u8FD8\u539F");
6178
6563
  snapshot.command("list").description("\u5217\u51FA\u9879\u76EE\u6570\u636E\u5E93\u5FEB\u7167\uFF08\u6309\u521B\u5EFA\u65F6\u95F4\u5012\u5E8F\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
6179
- try {
6564
+ const command = ctx.io("db snapshot list");
6565
+ await command.run(async () => {
6180
6566
  const { dbSnapshotList: dbSnapshotList2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
6181
- const result = await dbSnapshotList2(paths, {
6182
- cwd,
6567
+ const result = await dbSnapshotList2(ctx.paths, {
6568
+ cwd: ctx.cwd,
6183
6569
  ...flags.project === void 0 ? {} : { slug: flags.project }
6184
6570
  });
6185
- if (jsonMode()) {
6186
- output(JSON.stringify({ ok: true, command: "db snapshot list", data: result }));
6187
- } else {
6188
- if (result.snapshots.length === 0) {
6189
- output("\u6682\u65E0\u5FEB\u7167");
6190
- }
6191
- for (const snap of result.snapshots) {
6192
- output(
6193
- `${snap.id} ${snap.type} ${snap.plan} ${formatBytes(snap.sizeBytes)} ${snap.createdAt}`
6194
- );
6195
- }
6196
- }
6197
- } catch (error) {
6198
- emitError(output, "db snapshot list", jsonMode(), error);
6199
- }
6571
+ command.ok(result, (data) => {
6572
+ const r = data;
6573
+ if (r.snapshots.length === 0) return "\u6682\u65E0\u5FEB\u7167";
6574
+ return r.snapshots.map(
6575
+ (snap) => `${snap.id} ${snap.type} ${snap.plan} ${formatBytes(snap.sizeBytes)} ${snap.createdAt}`
6576
+ );
6577
+ });
6578
+ });
6200
6579
  });
6201
6580
  snapshot.command("create").description("\u521B\u5EFA\u624B\u52A8\u6570\u636E\u5E93\u5FEB\u7167\uFF08\u514D\u8D39\u7248\u5E73\u53F0\u8FD4\u56DE 403 \u6743\u76CA\u672A\u5F00\u653E\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
6202
- try {
6581
+ const command = ctx.io("db snapshot create");
6582
+ await command.run(async () => {
6203
6583
  const { dbSnapshotCreate: dbSnapshotCreate2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
6204
- const result = await dbSnapshotCreate2(paths, {
6205
- cwd,
6584
+ const result = await dbSnapshotCreate2(ctx.paths, {
6585
+ cwd: ctx.cwd,
6206
6586
  ...flags.project === void 0 ? {} : { slug: flags.project }
6207
6587
  });
6208
- if (jsonMode()) {
6209
- output(JSON.stringify({ ok: true, command: "db snapshot create", data: result }));
6210
- } else {
6211
- output(`\u5FEB\u7167\u5DF2\u521B\u5EFA\uFF1A${result.id}\uFF08${result.plan}\uFF0C${formatBytes(result.sizeBytes)}\uFF09`);
6212
- }
6213
- } catch (error) {
6214
- emitError(output, "db snapshot create", jsonMode(), error);
6215
- }
6588
+ command.ok(result, (data) => {
6589
+ const r = data;
6590
+ return `\u5FEB\u7167\u5DF2\u521B\u5EFA\uFF1A${r.id}\uFF08${r.plan}\uFF0C${formatBytes(r.sizeBytes)}\uFF09`;
6591
+ });
6592
+ });
6216
6593
  });
6217
6594
  snapshot.command("restore").description("\u6574\u4F53\u8FD8\u539F\u6570\u636E\u5E93\u5230\u5FEB\u7167\u65F6\u523B\uFF08\u4ED8\u8D39\u6863\u4F4D\uFF09").argument("<snapshotId>", "\u5FEB\u7167 id").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (snapshotId, flags) => {
6218
- try {
6595
+ const command = ctx.io("db snapshot restore");
6596
+ await command.run(async () => {
6219
6597
  const { dbSnapshotRestore: dbSnapshotRestore2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
6220
- const result = await dbSnapshotRestore2(paths, {
6221
- cwd,
6598
+ const result = await dbSnapshotRestore2(ctx.paths, {
6599
+ cwd: ctx.cwd,
6222
6600
  snapshotId,
6223
6601
  ...flags.project === void 0 ? {} : { slug: flags.project }
6224
6602
  });
6225
- if (jsonMode()) {
6226
- output(JSON.stringify({ ok: true, command: "db snapshot restore", data: result }));
6227
- } else {
6228
- output(`\u5DF2\u8FD8\u539F\u5230\u5FEB\u7167 ${result.snapshotId}`);
6229
- }
6230
- } catch (error) {
6231
- emitError(output, "db snapshot restore", jsonMode(), error);
6232
- }
6603
+ command.ok(result, (data) => `\u5DF2\u8FD8\u539F\u5230\u5FEB\u7167 ${data.snapshotId}`);
6604
+ });
6233
6605
  });
6234
6606
  db.command("rollback").description("\u65F6\u95F4\u70B9\u56DE\u6EDA\u5230\u6307\u5B9A\u65F6\u523B\uFF08\u56E2\u961F\u7248\uFF1B\u57FA\u4E8E\u53D8\u66F4\u6D41\u91CD\u653E\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").requiredOption("--to <iso-time>", "\u56DE\u6EDA\u76EE\u6807\u65F6\u523B\uFF08ISO 8601\uFF09").action(async (flags) => {
6235
- try {
6607
+ const command = ctx.io("db rollback");
6608
+ await command.run(async () => {
6236
6609
  const { dbRollback: dbRollback2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
6237
- const result = await dbRollback2(paths, {
6238
- cwd,
6610
+ const result = await dbRollback2(ctx.paths, {
6611
+ cwd: ctx.cwd,
6239
6612
  to: flags.to,
6240
6613
  ...flags.project === void 0 ? {} : { slug: flags.project }
6241
6614
  });
6242
- if (jsonMode()) {
6243
- output(JSON.stringify({ ok: true, command: "db rollback", data: result }));
6244
- } else {
6245
- output(`\u5DF2\u56DE\u6EDA\u5230 ${result.to}\uFF08\u91CD\u653E ${result.reverted} \u6761\u53D8\u66F4\uFF09`);
6246
- }
6247
- } catch (error) {
6248
- emitError(output, "db rollback", jsonMode(), error);
6249
- }
6615
+ command.ok(result, (data) => {
6616
+ const r = data;
6617
+ return `\u5DF2\u56DE\u6EDA\u5230 ${r.to}\uFF08\u91CD\u653E ${r.reverted} \u6761\u53D8\u66F4\uFF09`;
6618
+ });
6619
+ });
6250
6620
  });
6621
+ }
6622
+
6623
+ // packages/cli/src/commands/storage.ts
6624
+ function registerStorage(program2, ctx) {
6251
6625
  const storage = program2.command("storage").description("\u4E91\u5B58\u50A8 / \u6587\u4EF6\u5B58\u50A8\uFF1A\u4E0A\u4F20 / \u4E0B\u8F7D / \u5217\u8868 / \u5220\u9664").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09");
6252
6626
  storage.command("upload").description("\u4E0A\u4F20\u5355\u4E2A\u6587\u4EF6\uFF08multipart\uFF1B\u5355\u6587\u4EF6 \u2264 50MB\uFF09").argument("<file>", "\u672C\u5730\u6587\u4EF6\u8DEF\u5F84").requiredOption("--path <remote-path>", "\u6876\u5185\u76EE\u6807\u8DEF\u5F84\uFF08\u5982 avatars/a.png\uFF09").option(
6253
6627
  "--visibility <public|private>",
6254
6628
  "public \u76F4\u8FDE / private \u7B7E\u540D\uFF08\u7F3A\u7701 private\uFF09",
6255
6629
  "private"
6256
6630
  ).option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (file, flags) => {
6257
- try {
6631
+ const command = ctx.io("storage upload");
6632
+ await command.run(async () => {
6258
6633
  const { storageUpload: storageUpload2 } = await Promise.resolve().then(() => (init_storage2(), storage_exports));
6259
- const result = await storageUpload2(paths, {
6260
- cwd,
6634
+ const result = await storageUpload2(ctx.paths, {
6635
+ cwd: ctx.cwd,
6261
6636
  file,
6262
6637
  path: flags.path,
6263
6638
  visibility: flags.visibility === "public" ? "public" : "private",
6264
6639
  ...flags.project === void 0 ? {} : { slug: flags.project }
6265
6640
  });
6266
- if (jsonMode()) {
6267
- output(JSON.stringify({ ok: true, command: "storage upload", data: result }));
6268
- } else {
6269
- output(`\u5DF2\u4E0A\u4F20 ${result.path}\uFF08${result.visibility}\uFF0C${formatBytes(result.size)}\uFF09`);
6270
- if (result.signedUrl !== void 0) output(`\u7B7E\u540D URL\uFF1A${result.signedUrl}`);
6271
- }
6272
- } catch (error) {
6273
- emitError(output, "storage upload", jsonMode(), error);
6274
- }
6641
+ command.ok(result, (data) => {
6642
+ const r = data;
6643
+ const lines = [`\u5DF2\u4E0A\u4F20 ${r.path}\uFF08${r.visibility}\uFF0C${formatBytes(r.size)}\uFF09`];
6644
+ if (r.signedUrl !== void 0) lines.push(`\u7B7E\u540D URL\uFF1A${r.signedUrl}`);
6645
+ return lines;
6646
+ });
6647
+ });
6275
6648
  });
6276
6649
  storage.command("download").description("\u4E0B\u8F7D\u6587\u4EF6\u5230\u672C\u5730\uFF08public \u76F4\u8FDE / private \u7B7E\u540D URL\uFF09").argument("<remote-path>", "\u6876\u5185\u6587\u4EF6\u8DEF\u5F84").option("-o, --output <file>", "\u672C\u5730\u8F93\u51FA\u8DEF\u5F84\uFF08\u7F3A\u7701\u5199\u5230 cwd\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (remotePath, flags) => {
6277
- try {
6650
+ const command = ctx.io("storage download");
6651
+ await command.run(async () => {
6278
6652
  const { storageDownload: storageDownload2 } = await Promise.resolve().then(() => (init_storage2(), storage_exports));
6279
- const result = await storageDownload2(paths, {
6280
- cwd,
6653
+ const result = await storageDownload2(ctx.paths, {
6654
+ cwd: ctx.cwd,
6281
6655
  path: remotePath,
6282
6656
  ...flags.output === void 0 ? {} : { output: flags.output },
6283
6657
  ...flags.project === void 0 ? {} : { slug: flags.project }
6284
6658
  });
6285
- if (jsonMode()) {
6286
- output(JSON.stringify({ ok: true, command: "storage download", data: result }));
6287
- } else {
6288
- output(`\u5DF2\u4E0B\u8F7D ${result.path} \u2192 ${result.output}\uFF08${formatBytes(result.size)}\uFF09`);
6289
- }
6290
- } catch (error) {
6291
- emitError(output, "storage download", jsonMode(), error);
6292
- }
6659
+ command.ok(result, (data) => {
6660
+ const r = data;
6661
+ return `\u5DF2\u4E0B\u8F7D ${r.path} \u2192 ${r.output}\uFF08${formatBytes(r.size)}\uFF09`;
6662
+ });
6663
+ });
6293
6664
  });
6294
6665
  storage.command("ls").description("\u5217\u51FA\u9879\u76EE\u6587\u4EF6\uFF08\u6309\u524D\u7F00\u8FC7\u6EE4\uFF1Bpublic \u9644\u76F4\u8FDE url\u3001private \u9644\u7B7E\u540D url\uFF09").option("--prefix <prefix>", "\u6309\u524D\u7F00\u8FC7\u6EE4").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
6295
- try {
6666
+ const command = ctx.io("storage ls");
6667
+ await command.run(async () => {
6296
6668
  const { storageList: storageList2 } = await Promise.resolve().then(() => (init_storage2(), storage_exports));
6297
- const result = await storageList2(paths, {
6298
- cwd,
6669
+ const result = await storageList2(ctx.paths, {
6670
+ cwd: ctx.cwd,
6299
6671
  ...flags.prefix === void 0 ? {} : { prefix: flags.prefix },
6300
6672
  ...flags.project === void 0 ? {} : { slug: flags.project }
6301
6673
  });
6302
- if (jsonMode()) {
6303
- output(JSON.stringify({ ok: true, command: "storage ls", data: result }));
6304
- } else {
6305
- if (result.files.length === 0) {
6306
- output("\uFF08\u65E0\u6587\u4EF6\uFF09");
6307
- }
6308
- for (const file of result.files) {
6309
- output(
6310
- `${file.path} ${file.visibility} ${formatBytes(file.size)} ${file.url ?? file.signedUrl ?? ""}`
6311
- );
6312
- }
6313
- }
6314
- } catch (error) {
6315
- emitError(output, "storage ls", jsonMode(), error);
6316
- }
6674
+ command.ok(result, (data) => {
6675
+ const r = data;
6676
+ if (r.files.length === 0) return "\uFF08\u65E0\u6587\u4EF6\uFF09";
6677
+ return r.files.map(
6678
+ (file) => `${file.path} ${file.visibility} ${formatBytes(file.size)} ${file.url ?? file.signedUrl ?? ""}`
6679
+ );
6680
+ });
6681
+ });
6317
6682
  });
6318
6683
  storage.command("rm").description("\u5220\u9664\u6587\u4EF6\uFF08\u4EC5\u9879\u76EE\u6240\u6709\u8005\uFF09").argument("<remote-path>", "\u6876\u5185\u6587\u4EF6\u8DEF\u5F84").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (remotePath, flags) => {
6319
- try {
6684
+ const command = ctx.io("storage rm");
6685
+ await command.run(async () => {
6320
6686
  const { storageRemove: storageRemove2 } = await Promise.resolve().then(() => (init_storage2(), storage_exports));
6321
- const result = await storageRemove2(paths, {
6322
- cwd,
6687
+ const result = await storageRemove2(ctx.paths, {
6688
+ cwd: ctx.cwd,
6323
6689
  path: remotePath,
6324
6690
  ...flags.project === void 0 ? {} : { slug: flags.project }
6325
6691
  });
6326
- if (jsonMode()) {
6327
- output(JSON.stringify({ ok: true, command: "storage rm", data: result }));
6328
- } else {
6329
- output(`\u5DF2\u5220\u9664 ${remotePath}`);
6330
- }
6331
- } catch (error) {
6332
- emitError(output, "storage rm", jsonMode(), error);
6333
- }
6692
+ command.ok(result, () => `\u5DF2\u5220\u9664 ${remotePath}`);
6693
+ });
6334
6694
  });
6695
+ }
6696
+
6697
+ // packages/cli/src/commands/hosting.ts
6698
+ init_auth();
6699
+ function parseBool(raw) {
6700
+ if (raw === void 0) return void 0;
6701
+ if (raw === "true") return true;
6702
+ if (raw === "false") return false;
6703
+ throw new CliError("INVALID_BOOLEAN", `\u5E03\u5C14\u53C2\u6570\u987B\u4E3A true \u6216 false\uFF0C\u6536\u5230 "${raw}"`);
6704
+ }
6705
+ function registerHosting(program2, ctx) {
6335
6706
  const hosting = program2.command("hosting").description("\u9759\u6001\u6258\u7BA1\uFF1A\u67E5\u770B / \u90E8\u7F72 / \u62C9\u53D6 / \u914D\u7F6E").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09");
6336
6707
  hosting.command("info").description("\u67E5\u770B\u9759\u6001\u6258\u7BA1\u914D\u7F6E\u3001\u7AD9\u70B9\u5730\u5740\u4E0E\u6587\u4EF6\u6811").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
6337
- try {
6708
+ const command = ctx.io("hosting info");
6709
+ await command.run(async () => {
6338
6710
  const { hostingInfo: hostingInfo2 } = await Promise.resolve().then(() => (init_hosting(), hosting_exports));
6339
- const result = await hostingInfo2(paths, {
6340
- cwd,
6711
+ const result = await hostingInfo2(ctx.paths, {
6712
+ cwd: ctx.cwd,
6341
6713
  ...flags.project === void 0 ? {} : { slug: flags.project }
6342
6714
  });
6343
- if (jsonMode()) {
6344
- output(JSON.stringify({ ok: true, command: "hosting info", data: result }));
6345
- } else {
6346
- output(
6347
- `\u7AD9\u70B9\uFF1A${result.siteUrl}\uFF08\u6258\u7BA1 ${result.config.enabled ? "\u5F00" : "\u5173"}\uFF0CSPA \u56DE\u9000 ${result.config.spaMode ? "\u5F00" : "\u5173"}\uFF09`
6348
- );
6349
- for (const file of result.files) {
6350
- output(`${file.path} ${formatBytes(file.size)}`);
6351
- }
6352
- }
6353
- } catch (error) {
6354
- emitError(output, "hosting info", jsonMode(), error);
6355
- }
6715
+ command.ok(result, (data) => {
6716
+ const r = data;
6717
+ const lines = [
6718
+ `\u7AD9\u70B9\uFF1A${r.siteUrl}\uFF08\u6258\u7BA1 ${r.config.enabled ? "\u5F00" : "\u5173"}\uFF0CSPA \u56DE\u9000 ${r.config.spaMode ? "\u5F00" : "\u5173"}\uFF09`
6719
+ ];
6720
+ for (const file of r.files) lines.push(`${file.path} ${formatBytes(file.size)}`);
6721
+ return lines;
6722
+ });
6723
+ });
6356
6724
  });
6357
6725
  hosting.command("deploy").description("\u90E8\u7F72\u672C\u5730\u76EE\u5F55\u4E3A\u9759\u6001\u7AD9\u70B9\uFF1A\u9012\u5F52\u4E0A\u4F20\u5230 site/ \u5E76\u6253\u5F00\u6258\u7BA1").argument("<dir>", "\u672C\u5730\u7AD9\u70B9\u76EE\u5F55").option("--spa", "\u6253\u5F00\u6258\u7BA1\u5E76\u542F\u7528 SPA \u56DE\u9000\uFF08\u7F3A\u7701\u4EC5\u6253\u5F00\u6258\u7BA1\uFF09", false).option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (dir, flags) => {
6358
- try {
6726
+ const command = ctx.io("hosting deploy");
6727
+ await command.run(async () => {
6359
6728
  const { hostingDeploy: hostingDeploy2 } = await Promise.resolve().then(() => (init_hosting(), hosting_exports));
6360
- const result = await hostingDeploy2(paths, {
6361
- cwd,
6729
+ const result = await hostingDeploy2(ctx.paths, {
6730
+ cwd: ctx.cwd,
6362
6731
  dir,
6363
6732
  ...flags.spa === true ? { spa: true } : {},
6364
6733
  ...flags.project === void 0 ? {} : { slug: flags.project }
6365
6734
  });
6366
- if (jsonMode()) {
6367
- output(JSON.stringify({ ok: true, command: "hosting deploy", data: result }));
6368
- } else {
6369
- output(
6370
- `\u7AD9\u70B9\u5DF2\u4E0A\u7EBF\uFF1A${result.siteUrl}\uFF08${result.uploaded.length} \u4E2A\u6587\u4EF6\uFF0CSPA \u56DE\u9000 ${result.config.spaMode ? "\u5F00" : "\u5173"}\uFF09`
6371
- );
6372
- }
6373
- } catch (error) {
6374
- emitError(output, "hosting deploy", jsonMode(), error);
6375
- }
6735
+ command.ok(result, (data) => {
6736
+ const r = data;
6737
+ return `\u7AD9\u70B9\u5DF2\u4E0A\u7EBF\uFF1A${r.siteUrl}\uFF08${r.uploaded.length} \u4E2A\u6587\u4EF6\uFF0CSPA \u56DE\u9000 ${r.config.spaMode ? "\u5F00" : "\u5173"}\uFF09`;
6738
+ });
6739
+ });
6376
6740
  });
6377
6741
  hosting.command("pull").description("\u62C9\u53D6\u7AD9\u70B9\u516C\u5F00\u6587\u4EF6\u5230\u672C\u5730\u76EE\u5F55\uFF08\u8DF3\u8FC7\u6258\u7BA1\u914D\u7F6E\uFF09").option("-o, --output <dir>", "\u672C\u5730\u8F93\u51FA\u76EE\u5F55\uFF08\u7F3A\u7701\u5199\u5230 cwd\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
6378
- try {
6742
+ const command = ctx.io("hosting pull");
6743
+ await command.run(async () => {
6379
6744
  const { hostingPull: hostingPull2 } = await Promise.resolve().then(() => (init_hosting(), hosting_exports));
6380
- const result = await hostingPull2(paths, {
6381
- cwd,
6745
+ const result = await hostingPull2(ctx.paths, {
6746
+ cwd: ctx.cwd,
6382
6747
  ...flags.output === void 0 ? {} : { output: flags.output },
6383
6748
  ...flags.project === void 0 ? {} : { slug: flags.project }
6384
6749
  });
6385
- if (jsonMode()) {
6386
- output(JSON.stringify({ ok: true, command: "hosting pull", data: result }));
6387
- } else {
6388
- output(
6389
- `\u5DF2\u62C9\u53D6 ${result.files.length} \u4E2A\u6587\u4EF6 \u2192 ${result.outputDir}\uFF08\u7AD9\u70B9\uFF1A${result.siteUrl}\uFF09`
6390
- );
6391
- }
6392
- } catch (error) {
6393
- emitError(output, "hosting pull", jsonMode(), error);
6394
- }
6750
+ command.ok(result, (data) => {
6751
+ const r = data;
6752
+ return `\u5DF2\u62C9\u53D6 ${r.files.length} \u4E2A\u6587\u4EF6 \u2192 ${r.outputDir}\uFF08\u7AD9\u70B9\uFF1A${r.siteUrl}\uFF09`;
6753
+ });
6754
+ });
6395
6755
  });
6396
6756
  hosting.command("config").description("\u66F4\u65B0\u9759\u6001\u6258\u7BA1\u914D\u7F6E\uFF08\u6258\u7BA1\u5F00\u5173 / SPA \u56DE\u9000\u6A21\u5F0F\uFF0C\u5E42\u7B49\uFF09").option("--enabled <true|false>", "\u6258\u7BA1\u5F00\u5173").option("--spa <true|false>", "SPA \u56DE\u9000\u6A21\u5F0F").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
6397
- try {
6757
+ const command = ctx.io("hosting config");
6758
+ await command.run(async () => {
6398
6759
  const { hostingConfig: hostingConfig2 } = await Promise.resolve().then(() => (init_hosting(), hosting_exports));
6399
6760
  const enabled = parseBool(flags.enabled);
6400
6761
  const spa = parseBool(flags.spa);
6401
- const config = await hostingConfig2(paths, {
6402
- cwd,
6762
+ const config = await hostingConfig2(ctx.paths, {
6763
+ cwd: ctx.cwd,
6403
6764
  ...enabled === void 0 ? {} : { enabled },
6404
6765
  ...spa === void 0 ? {} : { spa },
6405
6766
  ...flags.project === void 0 ? {} : { slug: flags.project }
6406
6767
  });
6407
- if (jsonMode()) {
6408
- output(JSON.stringify({ ok: true, command: "hosting config", data: { config } }));
6409
- } else {
6410
- output(`\u6258\u7BA1 ${config.enabled ? "\u5F00" : "\u5173"}\uFF0CSPA \u56DE\u9000 ${config.spaMode ? "\u5F00" : "\u5173"}`);
6411
- }
6412
- } catch (error) {
6413
- emitError(output, "hosting config", jsonMode(), error);
6414
- }
6768
+ command.ok({ config }, (data) => {
6769
+ const c = data.config;
6770
+ return `\u6258\u7BA1 ${c.enabled ? "\u5F00" : "\u5173"}\uFF0CSPA \u56DE\u9000 ${c.spaMode ? "\u5F00" : "\u5173"}`;
6771
+ });
6772
+ });
6415
6773
  });
6774
+ }
6775
+
6776
+ // packages/cli/src/commands/export.ts
6777
+ function registerExport(program2, ctx) {
6416
6778
  program2.command("export").description("\u5BFC\u51FA\u81EA\u6258\u7BA1\u90E8\u7F72\u5305\uFF1A\u89E6\u53D1\u957F\u4EFB\u52A1 \u2192 \u8F6E\u8BE2\u8FDB\u5EA6 \u2192 \u4E0B\u8F7D zip \u2192 manifest \u9010\u9879\u81EA\u68C0").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").option("--with-data", "\u5305\u542B\u6570\u636E\u5E93\u884C\u6570\u636E\uFF08\u7F3A\u7701\u4EC5 schema\uFF09").option("--with-source", "\u5305\u542B\u51FD\u6570\u6E90\u7801\uFF08\u7F3A\u7701\u5E73\u53F0\u5DF2\u542B\uFF0C\u663E\u5F0F\u7F6E\u6B64\u4E0D\u6539\u53D8\u9ED8\u8BA4\uFF09").option("--out <dir>", "\u8F93\u51FA\u76EE\u5F55\uFF08\u7F3A\u7701 ./exports\uFF09").action(
6417
6779
  async (flags) => {
6418
- try {
6780
+ const command = ctx.io("export");
6781
+ await command.run(async () => {
6419
6782
  const { createExportApiClient: createExportApiClient2 } = await Promise.resolve().then(() => (init_client2(), client_exports2));
6420
6783
  const { createExportFileSystem: createExportFileSystem2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
6421
6784
  const { ExportCommand: ExportCommand2 } = await Promise.resolve().then(() => (init_command(), command_exports));
6422
6785
  const { resolveSlug: resolveSlug2 } = await Promise.resolve().then(() => (init_client(), client_exports));
6423
- const project2 = await resolveSlug2(cwd, flags.project);
6424
- const apiClient = await createExportApiClient2(paths);
6425
- const command = new ExportCommand2(apiClient, createExportFileSystem2());
6426
- const result = await command.execute({
6786
+ const project2 = await resolveSlug2(ctx.cwd, flags.project);
6787
+ const apiClient = await createExportApiClient2(ctx.paths);
6788
+ const exportCommand = new ExportCommand2(apiClient, createExportFileSystem2());
6789
+ const result = await exportCommand.execute({
6427
6790
  project: project2,
6428
6791
  ...flags.withData === true ? { withData: true } : {},
6429
6792
  ...flags.withSource === true ? { withSource: true } : {},
6430
6793
  ...flags.out === void 0 ? {} : { out: flags.out },
6431
- json: jsonMode()
6794
+ json: command.json
6432
6795
  });
6433
- if (jsonMode()) {
6434
- if (result.success) {
6435
- output(JSON.stringify({ ok: true, command: "export", data: result }));
6436
- } else {
6437
- output(
6438
- JSON.stringify({
6439
- ok: false,
6440
- command: "export",
6441
- error: { code: "EXPORT_FAILED", message: result.error ?? "\u5BFC\u51FA\u5931\u8D25" }
6442
- })
6443
- );
6444
- process.exitCode = 1;
6445
- }
6446
- } else if (!result.success) {
6447
- output(`\u9519\u8BEF\uFF1A${result.error ?? "\u5BFC\u51FA\u5931\u8D25"}`);
6448
- process.exitCode = 1;
6796
+ if (!result.success) {
6797
+ command.fail("EXPORT_FAILED", result.error ?? "\u5BFC\u51FA\u5931\u8D25");
6798
+ return;
6449
6799
  }
6450
- } catch (error) {
6451
- emitError(output, "export", jsonMode(), error);
6452
- }
6800
+ command.ok(result);
6801
+ });
6453
6802
  }
6454
6803
  );
6804
+ }
6805
+
6806
+ // packages/cli/src/commands/widget.ts
6807
+ function registerWidget(program2, ctx) {
6455
6808
  const widget = program2.command("widget").description("\u5FAE\u524D\u7AEF\u7EC4\u4EF6\uFF08widget\uFF09\uFF1A\u811A\u624B\u67B6 / \u672C\u5730\u6C99\u7BB1 / \u53D1\u5E03");
6456
6809
  widget.command("init").description("\u521D\u59CB\u5316 widget \u5DE5\u7A0B\uFF08\u6A21\u677F\uFF1Avue3-ts / react-ts\uFF09").argument("<name>", "widget \u540D\u79F0\uFF08\u5C0F\u5199\u5B57\u6BCD\u5F00\u5934\uFF0C\u4EC5\u5C0F\u5199\u5B57\u6BCD/\u6570\u5B57/\u8FDE\u5B57\u7B26\uFF09").option("-t, --template <template>", "\u6A21\u677F\uFF1Avue3-ts | react-ts", "vue3-ts").action(async (name, flags) => {
6457
- try {
6810
+ const command = ctx.io("widget init");
6811
+ await command.run(async () => {
6458
6812
  const { initWidget: initWidget2 } = await Promise.resolve().then(() => (init_init(), init_exports));
6459
- const result = await initWidget2(cwd, name, flags.template);
6460
- if (jsonMode()) {
6461
- output(JSON.stringify({ ok: true, command: "widget init", data: result }));
6462
- } else {
6463
- output(`\u5DF2\u521B\u5EFA widget ${result.projectPath}`);
6464
- }
6465
- } catch (error) {
6466
- emitError(output, "widget init", jsonMode(), error);
6467
- }
6813
+ const result = await initWidget2(ctx.cwd, name, flags.template);
6814
+ command.ok(
6815
+ result,
6816
+ (data) => `\u5DF2\u521B\u5EFA widget ${data.projectPath}`
6817
+ );
6818
+ });
6468
6819
  });
6469
6820
  widget.command("dev").description("\u672C\u5730\u5BBF\u4E3B\u6C99\u7BB1\uFF1A\u4E3B\u9898\u53D8\u91CF + mock props + token \u6CE8\u5165 + \u70ED\u66F4\u65B0").option("-p, --port <port>", "\u76D1\u542C\u7AEF\u53E3\uFF08\u7F3A\u7701 8788\uFF09", "8788").action(async (flags) => {
6470
- try {
6821
+ const command = ctx.io("widget dev");
6822
+ await command.run(async () => {
6471
6823
  const { startWidgetDev: startWidgetDev2 } = await Promise.resolve().then(() => (init_dev2(), dev_exports2));
6472
- const started = await startWidgetDev2({ cwd, port: Number(flags.port ?? "8788") });
6473
- output(
6824
+ const started = await startWidgetDev2({ cwd: ctx.cwd, port: Number(flags.port ?? "8788") });
6825
+ command.raw(
6474
6826
  `[adep] widget dev sandbox on ${started.baseUrl}\uFF08?token=<...> \u6CE8\u5165\u9274\u6743 token\uFF1BCtrl-C \u9000\u51FA\uFF09`
6475
6827
  );
6476
6828
  await new Promise(() => void 0);
6477
- } catch (error) {
6478
- emitError(output, "widget dev", jsonMode(), error);
6479
- }
6829
+ });
6480
6830
  });
6481
6831
  widget.command("publish").description("\u6309\u6846\u67B6\u6784\u5EFA \u2192 \u4E0A\u4F20\u5E73\u53F0\u9759\u6001\u8D44\u6E90 \u2192 \u7248\u672C\u5316\u8F93\u51FA URL").requiredOption("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug").action(async (flags) => {
6482
- try {
6832
+ const command = ctx.io("widget publish");
6833
+ await command.run(async () => {
6483
6834
  const { publishWidget: publishWidget2 } = await Promise.resolve().then(() => (init_publish(), publish_exports));
6484
- const result = await publishWidget2(paths, {
6485
- cwd,
6835
+ const result = await publishWidget2(ctx.paths, {
6836
+ cwd: ctx.cwd,
6486
6837
  project: flags.project
6487
6838
  });
6488
- if (jsonMode()) {
6489
- output(JSON.stringify({ ok: true, command: "widget publish", data: result }));
6490
- } else {
6491
- output(`${result.name} v${result.version} ${result.url}`);
6492
- }
6493
- } catch (error) {
6494
- emitError(output, "widget publish", jsonMode(), error);
6495
- }
6839
+ command.ok(result, (data) => {
6840
+ const r = data;
6841
+ return `${r.name} v${r.version} ${r.url}`;
6842
+ });
6843
+ });
6496
6844
  });
6845
+ }
6846
+
6847
+ // packages/cli/src/cli.ts
6848
+ var requireJson = createRequire(import.meta.url);
6849
+ var APP_VERSION = requireJson("../package.json").version;
6850
+ function buildProgram(options = {}) {
6851
+ const output = options.output ?? ((line) => process.stdout.write(`${line}
6852
+ `));
6853
+ const paths = options.paths ?? resolvePaths();
6854
+ const cwd = options.cwd ?? process.cwd();
6855
+ const program2 = new Command();
6856
+ program2.name("adep").description("AgentDeploy CLI").version(APP_VERSION);
6857
+ program2.option("--json", "\u4EE5\u673A\u5668\u53EF\u8BFB JSON \u8F93\u51FA\uFF08Agent / \u811A\u672C\u8C03\u7528\uFF09", false);
6858
+ const jsonMode = () => program2.opts()["json"] === true;
6859
+ const ctx = createCliContext({ output, paths, cwd, json: jsonMode });
6860
+ registerAuth(program2, ctx);
6861
+ registerInit(program2, ctx);
6862
+ registerDevServers(program2, ctx);
6863
+ registerDeploy(program2, ctx);
6864
+ registerProjects(program2, ctx);
6865
+ registerFunctions(program2, ctx);
6866
+ registerMcp(program2, ctx);
6867
+ registerDoctor(program2, ctx);
6868
+ registerDb(program2, ctx);
6869
+ registerStorage(program2, ctx);
6870
+ registerHosting(program2, ctx);
6871
+ registerExport(program2, ctx);
6872
+ registerWidget(program2, ctx);
6497
6873
  return program2;
6498
6874
  }
6499
6875