@adep/cli 0.0.4 → 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 +1351 -955
  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({
@@ -2915,6 +2957,25 @@ var init_env = __esm({
2915
2957
  });
2916
2958
 
2917
2959
  // packages/cli/src/sim/invoke.ts
2960
+ function resolveFunctionEntry(files, fnName) {
2961
+ const flat = `${fnName}.ts`;
2962
+ if (files[flat] !== void 0) return flat;
2963
+ const directory = `${fnName}/index.ts`;
2964
+ if (files[directory] !== void 0) return directory;
2965
+ return void 0;
2966
+ }
2967
+ function listFunctionNames(files) {
2968
+ const names = /* @__PURE__ */ new Set();
2969
+ for (const key of Object.keys(files)) {
2970
+ const parts = key.split("/");
2971
+ if (parts.length === 1 && parts[0] !== void 0 && parts[0].endsWith(".ts")) {
2972
+ names.add(parts[0].slice(0, -3));
2973
+ } else if (parts.length === 2 && parts[1] === "index.ts" && parts[0] !== void 0) {
2974
+ names.add(parts[0]);
2975
+ }
2976
+ }
2977
+ return [...names];
2978
+ }
2918
2979
  function createSimInvokeHandler(options) {
2919
2980
  return async (method, args) => {
2920
2981
  if (method !== "invoke") {
@@ -2924,7 +2985,10 @@ function createSimInvokeHandler(options) {
2924
2985
  if (typeof input?.name !== "string" || input.name.length === 0) {
2925
2986
  throw new Error("cloud.invoke \u9700\u8981\u76EE\u6807\u51FD\u6570\u540D\uFF08InvokeInput.name\uFF09");
2926
2987
  }
2927
- const targetEntry = `${input.name}.ts`;
2988
+ const targetEntry = resolveFunctionEntry(options.files, input.name);
2989
+ if (targetEntry === void 0) {
2990
+ throw new Error(`\u76EE\u6807\u51FD\u6570 "${input.name}" \u4E0D\u5B58\u5728`);
2991
+ }
2928
2992
  const executeInput = {
2929
2993
  project: { id: "local", slug: "local" },
2930
2994
  fn: { id: input.name, name: input.name },
@@ -3130,7 +3194,7 @@ async function startDevServer(options) {
3130
3194
  } catch {
3131
3195
  watcher = void 0;
3132
3196
  }
3133
- const buildInput = async (fnName, url, req) => {
3197
+ const buildInput = async (fnName, entry, url, req) => {
3134
3198
  const query = {};
3135
3199
  for (const key of new Set(url.searchParams.keys())) {
3136
3200
  const values = url.searchParams.getAll(key);
@@ -3146,7 +3210,7 @@ async function startDevServer(options) {
3146
3210
  project: { id: "local", slug: config.name },
3147
3211
  fn: { id: fnName, name: fnName },
3148
3212
  files,
3149
- entry: `${fnName}.ts`,
3213
+ entry,
3150
3214
  request: {
3151
3215
  method: req.method ?? "GET",
3152
3216
  path: url.pathname,
@@ -3173,14 +3237,13 @@ async function startDevServer(options) {
3173
3237
  });
3174
3238
  return;
3175
3239
  }
3176
- const entry = `${fnName}.ts`;
3177
- const source = files[entry];
3178
- if (source === void 0) {
3240
+ const entry = resolveFunctionEntry(files, fnName);
3241
+ if (entry === void 0) {
3179
3242
  log(`[adep] ${req.method ?? "GET"} /${fnName} -> 404\uFF08\u51FD\u6570\u4E0D\u5B58\u5728\uFF09`);
3180
3243
  writeJson(res, 404, { error: { code: "FN_NOT_FOUND", message: `\u51FD\u6570 "${fnName}" \u4E0D\u5B58\u5728` } });
3181
3244
  return;
3182
3245
  }
3183
- const input = await buildInput(fnName, url, req);
3246
+ const input = await buildInput(fnName, entry, url, req);
3184
3247
  const startedAt = performance.now();
3185
3248
  try {
3186
3249
  const result = await executor.execute(input);
@@ -3249,321 +3312,68 @@ var init_dev = __esm({
3249
3312
  }
3250
3313
  });
3251
3314
 
3252
- // packages/cli/src/client.ts
3253
- var client_exports = {};
3254
- __export(client_exports, {
3255
- createClient: () => createClient,
3256
- resolveSlug: () => resolveSlug
3257
- });
3258
- async function envelopeError(response, fallbackCode, parsed) {
3259
- const payload = parsed ?? null;
3260
- return new CliError(
3261
- payload?.error?.code ?? fallbackCode,
3262
- payload?.error?.message ?? `\u5E73\u53F0\u8FD4\u56DE HTTP ${response.status}`
3263
- );
3315
+ // packages/cli/src/serve/banner.ts
3316
+ function isLoopback(host) {
3317
+ return host === "127.0.0.1" || host === "localhost" || host === "::1" || host === "[::1]";
3264
3318
  }
3265
- async function parseBody(response) {
3266
- const text = await response.text();
3267
- if (text.length === 0) return null;
3268
- try {
3269
- return JSON.parse(text);
3270
- } catch {
3271
- 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("");
3272
3369
  }
3370
+ lines.push(" \u6309 Ctrl+C \u505C\u6B62\u670D\u52A1\u5668\u3002");
3371
+ lines.push("");
3372
+ return lines.join("\n");
3273
3373
  }
3274
- async function createClient(paths) {
3275
- const credentials = await loadCredentials(paths);
3276
- if (credentials === null) {
3277
- throw new CliError("NOT_LOGGED_IN", "\u672A\u767B\u5F55\uFF1A\u8BF7\u5148\u6267\u884C adep login");
3278
- }
3279
- const server = credentials.server;
3280
- const cookie = `better-auth.session_token=${decodeToken(credentials.encodedToken)}`;
3281
- const request = async (path, init = {}, fallbackCode = "API_REQUEST_FAILED") => {
3282
- const method = init.method ?? (init.body === void 0 ? "GET" : "POST");
3283
- let response;
3284
- try {
3285
- response = await fetch(`${server}${path}`, {
3286
- method,
3287
- headers: { "content-type": "application/json", cookie },
3288
- ...init.body === void 0 ? {} : { body: JSON.stringify(init.body) }
3289
- });
3290
- } catch (error) {
3291
- throw new CliError(
3292
- "SERVER_UNREACHABLE",
3293
- `\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
3294
- );
3295
- }
3296
- const parsed = await parseBody(response);
3297
- if (response.status < 200 || response.status >= 300) {
3298
- throw await envelopeError(response, fallbackCode, parsed);
3299
- }
3300
- return parsed;
3301
- };
3302
- const upload = async (path, form, fallbackCode = "UPLOAD_FAILED") => {
3303
- let response;
3304
- try {
3305
- response = await fetch(`${server}${path}`, {
3306
- method: "POST",
3307
- headers: { cookie },
3308
- body: form
3309
- });
3310
- } catch (error) {
3311
- throw new CliError(
3312
- "SERVER_UNREACHABLE",
3313
- `\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
3314
- );
3315
- }
3316
- if (response.status < 200 || response.status >= 300) {
3317
- throw await envelopeError(response, fallbackCode, await parseBody(response));
3318
- }
3319
- return response;
3320
- };
3321
- const download = async (url, fallbackCode = "DOWNLOAD_FAILED") => {
3322
- const target = url.startsWith("http") ? url : `${server}${url}`;
3323
- let response;
3324
- try {
3325
- response = await fetch(target, { headers: { cookie } });
3326
- } catch (error) {
3327
- throw new CliError(
3328
- "SERVER_UNREACHABLE",
3329
- `\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
3330
- );
3331
- }
3332
- if (response.status < 200 || response.status >= 300) {
3333
- throw await envelopeError(response, fallbackCode, await parseBody(response));
3334
- }
3335
- return response;
3336
- };
3337
- return { server, cookie, request, upload, download };
3338
- }
3339
- async function resolveSlug(cwd, slug) {
3340
- if (slug !== void 0 && slug.length > 0) return slug;
3341
- const config = await loadConfig(cwd);
3342
- return config.name;
3343
- }
3344
- var init_client = __esm({
3345
- "packages/cli/src/client.ts"() {
3346
- "use strict";
3347
- init_auth();
3348
- init_credentials();
3349
- init_dev();
3350
- }
3351
- });
3352
-
3353
- // packages/cli/src/deploy.ts
3354
- var deploy_exports = {};
3355
- __export(deploy_exports, {
3356
- collectEntries: () => collectEntries,
3357
- deploy: () => deploy
3358
- });
3359
- import { createHash as createHash3 } from "node:crypto";
3360
- import { readdir as readdir3, readFile as readFile6 } from "node:fs/promises";
3361
- import { join as join10, resolve as resolve6, basename as basename2 } from "node:path";
3362
- async function collectEntries(functionsDir) {
3363
- const entries = {};
3364
- let names;
3365
- try {
3366
- const dirents = await readdir3(functionsDir, { withFileTypes: true });
3367
- names = dirents.filter((entry) => entry.isFile() && entry.name.endsWith(".ts")).map((entry) => basename2(entry.name, ".ts")).toSorted();
3368
- } catch {
3369
- return entries;
3370
- }
3371
- for (const name of names) {
3372
- entries[name] = await readFile6(join10(functionsDir, `${name}.ts`), "utf8");
3373
- }
3374
- return entries;
3375
- }
3376
- function sha256Hex(content) {
3377
- return createHash3("sha256").update(content).digest("hex");
3378
- }
3379
- async function deploy(paths, options) {
3380
- await requireNetwork("adep deploy");
3381
- const log = options.silent === true ? () => void 0 : options.log ?? ((line) => process.stdout.write(`${line}
3382
- `));
3383
- const client = await createClient(paths);
3384
- const cwd = resolve6(options.cwd);
3385
- const config = await loadConfig(cwd);
3386
- const slug = options.slug ?? config.name;
3387
- const functionsDir = options.functionsDir === void 0 ? join10(cwd, config.functionsDir) : resolve6(cwd, options.functionsDir);
3388
- const local = await collectEntries(functionsDir);
3389
- if (Object.keys(local).length === 0) {
3390
- throw new CliError("NO_FUNCTIONS", `${functionsDir} \u4E0B\u6CA1\u6709\u51FD\u6570\u6587\u4EF6`);
3391
- }
3392
- const remote = await client.request(
3393
- "/api/v1/deploy/diff",
3394
- {
3395
- body: {
3396
- slug,
3397
- functions: Object.entries(local).map(([name, content]) => ({
3398
- name,
3399
- files: { "index.ts": sha256Hex(content) }
3400
- }))
3401
- }
3402
- },
3403
- "DEPLOY_FAILED"
3404
- );
3405
- const baseUrl = `${remote.scheme}://${remote.slug}.${remote.domain}`;
3406
- const deployed = [];
3407
- for (const item of remote.functions) {
3408
- const content = local[item.name];
3409
- if (item.action === "none") {
3410
- deployed.push({
3411
- name: item.name,
3412
- action: "none",
3413
- version: item.version ?? 0,
3414
- url: `${baseUrl}/${item.name}`
3415
- });
3416
- continue;
3417
- }
3418
- log(`[adep] \u90E8\u7F72 ${item.name}\uFF08${item.action === "create" ? "\u65B0\u5EFA" : "\u53D8\u66F4"}\uFF09`);
3419
- let functionId = item.id;
3420
- if (functionId === null) {
3421
- const created = await client.request(
3422
- `/api/v1/projects/${remote.projectId}/functions`,
3423
- {
3424
- body: { name: item.name, files: { "index.ts": content } }
3425
- }
3426
- );
3427
- functionId = created.id;
3428
- } else {
3429
- await client.request(`/api/v1/projects/${remote.projectId}/functions/${item.name}`, {
3430
- method: "PATCH",
3431
- body: { files: { "index.ts": content } }
3432
- });
3433
- }
3434
- const published = await client.request(
3435
- `/api/v1/functions/${functionId}/publish`,
3436
- { method: "POST" }
3437
- );
3438
- deployed.push({
3439
- name: item.name,
3440
- action: item.action,
3441
- version: published.version,
3442
- url: `${baseUrl}/${item.name}`
3443
- });
3444
- }
3445
- return {
3446
- projectId: remote.projectId,
3447
- slug: remote.slug,
3448
- baseUrl,
3449
- noChanges: deployed.every((function_) => function_.action === "none"),
3450
- functions: deployed
3451
- };
3452
- }
3453
- var init_deploy = __esm({
3454
- "packages/cli/src/deploy.ts"() {
3455
- "use strict";
3456
- init_auth();
3457
- init_client();
3458
- init_dev();
3459
- init_net();
3460
- }
3461
- });
3462
-
3463
- // packages/cli/src/prompt.ts
3464
- var prompt_exports = {};
3465
- __export(prompt_exports, {
3466
- createPrompt: () => createPrompt
3467
- });
3468
- import { createInterface } from "node:readline/promises";
3469
- import { Writable } from "node:stream";
3470
- function createPrompt(input = process.stdin) {
3471
- const rl = createInterface({ input, output: process.stdout, terminal: true });
3472
- let muted = null;
3473
- return {
3474
- async ask(question) {
3475
- const answer = await rl.question(question);
3476
- return answer.trim();
3477
- },
3478
- async askHidden(question) {
3479
- muted = createInterface({ input, output: new MutedStream(), terminal: true });
3480
- const answer = await muted.question(question);
3481
- muted.close();
3482
- muted = null;
3483
- process.stdout.write("\n");
3484
- return answer.trim();
3485
- },
3486
- close() {
3487
- muted?.close();
3488
- rl.close();
3489
- }
3490
- };
3491
- }
3492
- var MutedStream;
3493
- var init_prompt = __esm({
3494
- "packages/cli/src/prompt.ts"() {
3495
- "use strict";
3496
- MutedStream = class extends Writable {
3497
- write(_chunk, ...rest) {
3498
- void rest;
3499
- return true;
3500
- }
3501
- };
3502
- }
3503
- });
3504
-
3505
- // packages/cli/src/serve/banner.ts
3506
- function isLoopback(host) {
3507
- return host === "127.0.0.1" || host === "localhost" || host === "::1" || host === "[::1]";
3508
- }
3509
- function renderBanner(options) {
3510
- const { host, port, projectName, functions, hasStatic, staticDir = "public/" } = options;
3511
- const baseUrl = `http://${host}:${port}`;
3512
- const loopback = isLoopback(host);
3513
- const lines = [];
3514
- lines.push("");
3515
- 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");
3516
- lines.push("\u2551 adep serve \u2014 \u5F00\u53D1\u6001\u670D\u52A1\u5668 \u2551");
3517
- lines.push("\u2551 \u26A0 \u8FD9\u4E0D\u662F\u751F\u4EA7\u670D\u52A1\u5668\uFF0C\u4E0D\u63D0\u4F9B TLS / \u96C6\u7FA4 / \u4F18\u96C5\u91CD\u542F \u2551");
3518
- 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");
3519
- lines.push("");
3520
- lines.push(` \u9879\u76EE: ${projectName}`);
3521
- lines.push(` \u5730\u5740: ${baseUrl}`);
3522
- lines.push(` \u7ED1\u5B9A: ${host}${loopback ? "\uFF08\u4EC5\u672C\u673A\u53EF\u8BBF\u95EE\uFF09" : "\uFF08\u26A0 \u5BF9\u5916\u66B4\u9732\uFF09"}`);
3523
- lines.push("");
3524
- lines.push(" \u80FD\u529B:");
3525
- if (functions.length > 0) {
3526
- lines.push(
3527
- ` - \u51FD\u6570\u8DEF\u7531: ${baseUrl}/api/{fn}\uFF08${functions.length} \u4E2A\u51FD\u6570: ${functions.join(", ")}\uFF09`
3528
- );
3529
- } else {
3530
- lines.push(" - \u51FD\u6570\u8DEF\u7531: \u65E0\uFF08functions/ \u76EE\u5F55\u4E3A\u7A7A\uFF09");
3531
- }
3532
- if (hasStatic) {
3533
- lines.push(` - \u9759\u6001\u6258\u7BA1: ${baseUrl}/ \u2192 ${staticDir}`);
3534
- } else {
3535
- lines.push(` - \u9759\u6001\u6258\u7BA1: \u65E0\uFF08${staticDir} \u76EE\u5F55\u4E0D\u5B58\u5728\uFF09`);
3536
- }
3537
- lines.push(" - \u7EC4\u4EF6\u9884\u89C8: Widget / Page \u4EA7\u7269\uFF08\u5982\u5DF2\u6784\u5EFA\uFF09");
3538
- lines.push(` - \u5065\u5EB7\u68C0\u67E5: ${baseUrl}/healthz`);
3539
- lines.push("");
3540
- lines.push(" \u8FB9\u754C\uFF08\u5F00\u53D1\u6001\u9ED8\u8BA4\u503C\uFF0C\u4E0D\u53EF\u5728\u6B64\u6A21\u5F0F\u4E0B\u5F00\u542F\uFF09:");
3541
- lines.push(" - \u65E0\u9274\u6743\uFF1A\u4EFB\u4F55\u4EBA\u53EF\u8C03\u7528\u6240\u6709\u51FD\u6570");
3542
- lines.push(" - \u65E0\u9650\u6D41\uFF1A\u65E0 QPS / \u5E76\u53D1\u9650\u5236");
3543
- lines.push(" - \u65E0\u914D\u989D\uFF1A\u65E0\u8C03\u7528\u6B21\u6570 / \u8D44\u6E90\u7528\u91CF\u9650\u5236");
3544
- lines.push(" - \u65E0 TLS\uFF1A\u660E\u6587 HTTP\uFF0C\u4E0D\u652F\u6301 HTTPS");
3545
- lines.push(" - \u65E0\u96C6\u7FA4\uFF1A\u5355\u8FDB\u7A0B\uFF0C\u4E0D\u652F\u6301\u591A\u5B9E\u4F8B");
3546
- lines.push(" - \u65E0\u4F18\u96C5\u91CD\u542F\uFF1A\u8FDB\u7A0B\u9000\u51FA\u5373\u4E2D\u65AD");
3547
- lines.push("");
3548
- if (!loopback) {
3549
- 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");
3550
- lines.push(" \u2502 \u26A0\u26A0\u26A0 \u5BF9\u5916\u66B4\u9732\u8B66\u544A \u2502");
3551
- lines.push(" \u2502 \u2502");
3552
- lines.push(` \u2502 \u5F53\u524D\u7ED1\u5B9A ${host.padEnd(43)}\u2502`);
3553
- 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");
3554
- 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");
3555
- lines.push(" \u2502 \u2502");
3556
- lines.push(" \u2502 \u9700\u8981\u751F\u4EA7\u90E8\u7F72\uFF1F\u4F7F\u7528 `adep deploy` \u90E8\u7F72\u5230\u5E73\u53F0\u3002 \u2502");
3557
- 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");
3558
- lines.push("");
3559
- }
3560
- lines.push(" \u6309 Ctrl+C \u505C\u6B62\u670D\u52A1\u5668\u3002");
3561
- lines.push("");
3562
- return lines.join("\n");
3563
- }
3564
- var init_banner = __esm({
3565
- "packages/cli/src/serve/banner.ts"() {
3566
- "use strict";
3374
+ var init_banner = __esm({
3375
+ "packages/cli/src/serve/banner.ts"() {
3376
+ "use strict";
3567
3377
  }
3568
3378
  });
3569
3379
 
@@ -3574,8 +3384,9 @@ __export(server_exports, {
3574
3384
  startServeServer: () => startServeServer
3575
3385
  });
3576
3386
  import { createServer as createServer2 } from "node:http";
3577
- import { readdir as readdir4, readFile as readFile7, stat as stat6 } from "node:fs/promises";
3578
- 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";
3579
3390
  function envNumber(name) {
3580
3391
  const raw = process.env[name];
3581
3392
  if (raw === void 0 || raw.trim() === "") return void 0;
@@ -3591,17 +3402,17 @@ async function collectFunctions2(dir) {
3591
3402
  const walk = async (sub, prefix) => {
3592
3403
  let entries;
3593
3404
  try {
3594
- entries = await readdir4(sub, { withFileTypes: true });
3405
+ entries = await readdir3(sub, { withFileTypes: true });
3595
3406
  } catch {
3596
3407
  return;
3597
3408
  }
3598
3409
  for (const entry of entries) {
3599
3410
  const rel = prefix.length === 0 ? entry.name : `${prefix}/${entry.name}`;
3600
- const full = join11(sub, entry.name);
3411
+ const full = join10(sub, entry.name);
3601
3412
  if (entry.isDirectory()) {
3602
3413
  await walk(full, rel);
3603
3414
  } else if (entry.isFile() && entry.name.endsWith(".ts")) {
3604
- files[rel] = await readFile7(full, "utf8");
3415
+ files[rel] = await readFile6(full, "utf8");
3605
3416
  }
3606
3417
  }
3607
3418
  };
@@ -3636,17 +3447,17 @@ function contentTypeFor(path) {
3636
3447
  return MIME_TYPES[ext] ?? "application/octet-stream";
3637
3448
  }
3638
3449
  async function startServeServer(options) {
3639
- const cwd = resolve7(options.cwd);
3450
+ const cwd = resolve6(options.cwd);
3640
3451
  const log = options.log ?? ((line) => process.stdout.write(`${line}
3641
3452
  `));
3642
3453
  const host = options.host ?? envString("HOST") ?? "127.0.0.1";
3643
3454
  const port = options.port ?? envNumber("PORT") ?? 8787;
3644
- const staticDir = resolve7(
3455
+ const staticDir = resolve6(
3645
3456
  cwd,
3646
3457
  options.staticDir ?? envString("ADEP_SERVE_STATIC_DIR") ?? "public"
3647
3458
  );
3648
3459
  const config = await loadConfig(cwd);
3649
- const functionsDir = join11(cwd, config.functionsDir);
3460
+ const functionsDir = join10(cwd, config.functionsDir);
3650
3461
  let hasStatic = false;
3651
3462
  try {
3652
3463
  const publicStat = await stat6(staticDir);
@@ -3654,11 +3465,11 @@ async function startServeServer(options) {
3654
3465
  } catch {
3655
3466
  hasStatic = false;
3656
3467
  }
3657
- const files = await collectFunctions2(functionsDir);
3658
- const functionNames = Object.keys(files).filter((f) => f.endsWith(".ts")).map((f) => f.slice(0, -3));
3659
- const envText = await readFile7(join11(cwd, ".env.local"), "utf8").catch(() => "");
3660
- const env = parseEnvFile(envText);
3661
- 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(() => ({}));
3662
3473
  const runtime = await createSimRuntime({
3663
3474
  cwd,
3664
3475
  projectId: "local",
@@ -3667,8 +3478,45 @@ async function startServeServer(options) {
3667
3478
  });
3668
3479
  const executor = new WorkerFunctionExecutor();
3669
3480
  const dbBundle = runtime.bundle;
3670
- const invokeHandler = createSimInvokeHandler({ executor, files });
3671
- const buildInput = async (fnName, url, req) => {
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
+ }
3519
+ const buildInput = async (fnName, entry, url, req) => {
3672
3520
  const query = {};
3673
3521
  for (const key of new Set(url.searchParams.keys())) {
3674
3522
  const values = url.searchParams.getAll(key);
@@ -3685,7 +3533,7 @@ async function startServeServer(options) {
3685
3533
  project: { id: "local", slug: config.name },
3686
3534
  fn: { id: fnName, name: fnName },
3687
3535
  files,
3688
- entry: `${fnName}.ts`,
3536
+ entry,
3689
3537
  request: {
3690
3538
  method: req.method ?? "GET",
3691
3539
  path: url.pathname,
@@ -3705,16 +3553,16 @@ async function startServeServer(options) {
3705
3553
  const serveStatic = async (pathname, res) => {
3706
3554
  if (!hasStatic) return false;
3707
3555
  const safePath = pathname.replace(/\.\.\//g, "").replace(/^\//, "");
3708
- const filePath = join11(staticDir, safePath);
3709
- 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;
3710
3558
  try {
3711
3559
  const fileStat = await stat6(resolvedPath);
3712
3560
  if (fileStat.isDirectory()) {
3713
- const indexPath = join11(resolvedPath, "index.html");
3561
+ const indexPath = join10(resolvedPath, "index.html");
3714
3562
  try {
3715
3563
  const indexStat = await stat6(indexPath);
3716
3564
  if (indexStat.isFile()) {
3717
- const content2 = await readFile7(indexPath);
3565
+ const content2 = await readFile6(indexPath);
3718
3566
  res.writeHead(200, { "content-type": contentTypeFor(indexPath) });
3719
3567
  res.end(content2);
3720
3568
  return true;
@@ -3723,7 +3571,7 @@ async function startServeServer(options) {
3723
3571
  }
3724
3572
  return false;
3725
3573
  }
3726
- const content = await readFile7(resolvedPath);
3574
+ const content = await readFile6(resolvedPath);
3727
3575
  res.writeHead(200, { "content-type": contentTypeFor(resolvedPath) });
3728
3576
  res.end(content);
3729
3577
  return true;
@@ -3742,19 +3590,21 @@ async function startServeServer(options) {
3742
3590
  });
3743
3591
  return;
3744
3592
  }
3745
- const entry = `${fnName}.ts`;
3746
- const source = files[entry];
3747
- if (source === void 0) {
3593
+ const entry = resolveFunctionEntry(files, fnName);
3594
+ if (entry === void 0) {
3748
3595
  log(`[serve] ${req.method ?? "GET"} ${pathname} -> 404\uFF08\u51FD\u6570\u4E0D\u5B58\u5728\uFF09`);
3749
3596
  writeJson2(res, 404, { error: { code: "FN_NOT_FOUND", message: `\u51FD\u6570 "${fnName}" \u4E0D\u5B58\u5728` } });
3750
3597
  return;
3751
3598
  }
3752
- const input = await buildInput(fnName, url, req);
3599
+ const input = await buildInput(fnName, entry, url, req);
3753
3600
  const startedAt = performance.now();
3754
3601
  try {
3755
3602
  const result = await executor.execute(input);
3756
3603
  const durationMs = Math.round(performance.now() - startedAt);
3757
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
+ }
3758
3608
  writeJson2(res, 200, result.body === void 0 ? null : result.body);
3759
3609
  } catch (error) {
3760
3610
  const durationMs = Math.round(performance.now() - startedAt);
@@ -3788,13 +3638,13 @@ async function startServeServer(options) {
3788
3638
  if (pathname.startsWith("/_preview/")) {
3789
3639
  const widgetName = pathname.slice("/_preview/".length).split("/")[0];
3790
3640
  if (widgetName !== void 0 && widgetName.length > 0) {
3791
- const widgetDir = join11(cwd, ".adep", "widgets", widgetName);
3641
+ const widgetDir = join10(cwd, ".adep", "widgets", widgetName);
3792
3642
  try {
3793
3643
  const widgetStat = await stat6(widgetDir);
3794
3644
  if (widgetStat.isDirectory()) {
3795
- const indexPath = join11(widgetDir, "index.html");
3645
+ const indexPath = join10(widgetDir, "index.html");
3796
3646
  try {
3797
- const content = await readFile7(indexPath, "utf8");
3647
+ const content = await readFile6(indexPath, "utf8");
3798
3648
  res.writeHead(200, { "content-type": "text/html; charset=utf-8" });
3799
3649
  res.end(content);
3800
3650
  return;
@@ -3855,11 +3705,15 @@ async function startServeServer(options) {
3855
3705
  staticDir: relative(cwd, staticDir).length > 0 ? relative(cwd, staticDir) : staticDir
3856
3706
  });
3857
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
+ }
3858
3711
  return {
3859
3712
  port: actualPort,
3860
3713
  host,
3861
3714
  baseUrl: `http://${host}:${actualPort}`,
3862
3715
  close: async () => {
3716
+ stopWatch?.();
3863
3717
  await new Promise((resolveClose) => {
3864
3718
  server.close(() => resolveClose());
3865
3719
  });
@@ -3901,6 +3755,217 @@ var init_server = __esm({
3901
3755
  }
3902
3756
  });
3903
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
+
3904
3969
  // packages/cli/src/projects.ts
3905
3970
  var projects_exports = {};
3906
3971
  __export(projects_exports, {
@@ -4354,7 +4419,7 @@ __export(storage_exports, {
4354
4419
  storageRemove: () => storageRemove,
4355
4420
  storageUpload: () => storageUpload
4356
4421
  });
4357
- 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";
4358
4423
  import { basename as basename3, dirname as dirname7, extname, join as join12, resolve as resolve11 } from "node:path";
4359
4424
  async function open3(paths, options) {
4360
4425
  const client = await createClient(paths);
@@ -4439,7 +4504,7 @@ async function storageDownload(paths, options) {
4439
4504
  const response = await client.download(url, "STORAGE_DOWNLOAD_FAILED");
4440
4505
  const bytes = Buffer.from(await response.arrayBuffer());
4441
4506
  const output = resolve11(options.output ?? join12(resolve11(options.cwd), basename3(options.path)));
4442
- await mkdir7(dirname7(output), { recursive: true });
4507
+ await mkdir8(dirname7(output), { recursive: true });
4443
4508
  await writeFile6(output, bytes);
4444
4509
  return { path: options.path, output, size: bytes.length };
4445
4510
  }
@@ -4545,7 +4610,7 @@ async function hostingPull(paths, options) {
4545
4610
  `));
4546
4611
  const info = await hostingInfo(paths, options);
4547
4612
  const outputDir = resolve12(options.output ?? resolve12(options.cwd));
4548
- const { mkdir: mkdir9, writeFile: writeFile9 } = await import("node:fs/promises");
4613
+ const { mkdir: mkdir10, writeFile: writeFile9 } = await import("node:fs/promises");
4549
4614
  const files = [];
4550
4615
  for (const entry of info.files) {
4551
4616
  if (entry.visibility !== "public" || entry.path === HOSTING_CONFIG_PATH) continue;
@@ -4556,7 +4621,7 @@ async function hostingPull(paths, options) {
4556
4621
  const bytes = Buffer.from(await response.arrayBuffer());
4557
4622
  const rel = entry.path.replace(/^site\//, "");
4558
4623
  const target = join13(outputDir, ...rel.split("/"));
4559
- await mkdir9(dirname8(target), { recursive: true });
4624
+ await mkdir10(dirname8(target), { recursive: true });
4560
4625
  await writeFile9(target, bytes);
4561
4626
  files.push({ path: entry.path, size: bytes.length });
4562
4627
  }
@@ -4730,7 +4795,7 @@ var fs_exports = {};
4730
4795
  __export(fs_exports, {
4731
4796
  createExportFileSystem: () => createExportFileSystem
4732
4797
  });
4733
- 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";
4734
4799
  import { dirname as dirname9, join as join14 } from "node:path";
4735
4800
  function createExportFileSystem() {
4736
4801
  return {
@@ -4749,13 +4814,13 @@ function createExportFileSystem() {
4749
4814
  }
4750
4815
  },
4751
4816
  mkdir: async (path) => {
4752
- await mkdir8(path, { recursive: true });
4817
+ await mkdir9(path, { recursive: true });
4753
4818
  },
4754
4819
  unzip: async (zipPath, targetDir) => {
4755
4820
  const entries = zipRead(await readFile10(zipPath));
4756
4821
  for (const [name, data] of entries) {
4757
4822
  const dest = join14(targetDir, name);
4758
- await mkdir8(dirname9(dest), { recursive: true });
4823
+ await mkdir9(dirname9(dest), { recursive: true });
4759
4824
  await writeFile8(dest, data);
4760
4825
  }
4761
4826
  }
@@ -5269,7 +5334,7 @@ __export(dev_exports2, {
5269
5334
  startWidgetDev: () => startWidgetDev
5270
5335
  });
5271
5336
  import { createServer as createServer3 } from "node:http";
5272
- import { watch as watch2 } from "node:fs";
5337
+ import { watch as watch3 } from "node:fs";
5273
5338
  import { readFile as readFile11, stat as stat11 } from "node:fs/promises";
5274
5339
  import { join as join15, resolve as resolve13 } from "node:path";
5275
5340
  async function loadWidgetProject(cwd) {
@@ -5391,7 +5456,7 @@ data: ${version}
5391
5456
  let debounceTimer;
5392
5457
  let watcher;
5393
5458
  try {
5394
- watcher = watch2(cwd, { recursive: true }, () => {
5459
+ watcher = watch3(cwd, { recursive: true }, () => {
5395
5460
  if (debounceTimer !== void 0) clearTimeout(debounceTimer);
5396
5461
  debounceTimer = setTimeout(() => {
5397
5462
  void buildWidget({ cwd, framework }).then((built) => {
@@ -5553,14 +5618,296 @@ var init_publish = __esm({
5553
5618
  });
5554
5619
 
5555
5620
  // packages/cli/src/cli.ts
5556
- init_auth();
5557
5621
  init_config();
5558
5622
  import { Command } from "commander";
5559
5623
  import { createRequire } from "node:module";
5560
5624
 
5625
+ // packages/cli/src/output.ts
5626
+ init_auth();
5627
+
5561
5628
  // packages/cli/src/init.ts
5562
5629
  import { mkdir as mkdir2, stat as stat2, writeFile } from "node:fs/promises";
5563
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"];
5564
5911
  var InitError = class extends Error {
5565
5912
  constructor(code, message) {
5566
5913
  super(message);
@@ -5578,21 +5925,70 @@ var README = (name, template) => `# ${name}
5578
5925
 
5579
5926
  AgentDeploy \u9879\u76EE\uFF08\u6A21\u677F\uFF1A${template}\uFF09\u3002
5580
5927
 
5581
- - \`adep dev\`\uFF1A\u672C\u5730\u8C03\u8BD5\uFF08CLI-002 \u4EA4\u4ED8\uFF09
5582
- - \`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
5583
5956
  `;
5584
5957
  var HELLO_FUNCTION = `// \u793A\u4F8B\u51FD\u6570\uFF1Aadep deploy \u540E\u7ECF https://<project-slug>.<platform-domain>/hello \u89E6\u53D1\u3002
5585
- // \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
5586
- //\uFF08ctx \u5951\u7EA6\u89C1\u5E73\u53F0\u7684 FunctionContext\uFF1Amethod / path / query / headers / body / cloud.*\uFF09\u3002
5587
- 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) => {
5588
5961
  const name = (ctx.query['name'] as string | undefined) ?? 'world'
5589
5962
  return { message: \`hello \${name}\` }
5590
5963
  }
5591
5964
  `;
5592
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
5593
- // \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
5594
5967
  `;
5595
- 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>
5596
5992
  `;
5597
5993
  async function initProject(cwd, name, template) {
5598
5994
  if (!/^[a-z][a-z0-9-]{0,62}$/.test(name)) {
@@ -5601,6 +5997,12 @@ async function initProject(cwd, name, template) {
5601
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`
5602
5998
  );
5603
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
+ }
5604
6006
  const projectPath = resolve(cwd, name);
5605
6007
  let existing;
5606
6008
  try {
@@ -5613,14 +6015,22 @@ async function initProject(cwd, name, template) {
5613
6015
  }
5614
6016
  const files = [
5615
6017
  { path: "adep.config.ts", content: ADEP_CONFIG(name, template) },
5616
- { 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" }
5617
6023
  ];
5618
6024
  if (template === "function") {
5619
6025
  files.push({ path: "functions/hello.ts", content: HELLO_FUNCTION });
5620
6026
  files.push({ path: "functions/README.md", content: FUNCTION_INDEX });
5621
- 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) });
5622
6033
  } else {
5623
- files.push({ path: ".gitignore", content: "node_modules/\ndata/\n.adep/\n" });
5624
6034
  files.push({ path: "README-EMPTY.md", content: EMPTY_INDEX });
5625
6035
  }
5626
6036
  await mkdir2(projectPath, { recursive: true });
@@ -5634,62 +6044,58 @@ async function initProject(cwd, name, template) {
5634
6044
  return { projectPath, files: files.map((file) => file.path) };
5635
6045
  }
5636
6046
 
5637
- // packages/cli/src/templates.ts
5638
- init_auth();
5639
- async function fetchTemplates(server) {
5640
- let response;
5641
- try {
5642
- response = await fetch(`${server}/api/v1/templates`);
5643
- } catch (error) {
5644
- throw new CliError(
5645
- "SERVER_UNREACHABLE",
5646
- `\u65E0\u6CD5\u8FDE\u63A5\u5E73\u53F0 ${server}\uFF1A${error instanceof Error ? error.message : String(error)}`
5647
- );
5648
- }
5649
- const text = await response.text();
5650
- let parsed = null;
5651
- try {
5652
- parsed = text.length === 0 ? null : JSON.parse(text);
5653
- } catch {
5654
- parsed = null;
5655
- }
5656
- if (response.status < 200 || response.status >= 300) {
5657
- const msg = parsed?.error;
5658
- throw new CliError("TEMPLATE_LIST_FAILED", msg ?? `\u5E73\u53F0\u8FD4\u56DE HTTP ${response.status}`);
5659
- }
5660
- const templates = parsed?.templates;
5661
- return templates ?? [];
5662
- }
5663
-
5664
- // packages/cli/src/cli.ts
6047
+ // packages/cli/src/output.ts
5665
6048
  init_build();
5666
6049
  init_init();
5667
- var requireJson = createRequire(import.meta.url);
5668
- 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
+ }
5669
6053
  function needsRelogin(error) {
5670
6054
  return error.code === "NOT_LOGGED_IN" || error.code === "AUTH_UNAUTHORIZED";
5671
6055
  }
5672
- function emitError(output, command, json, error) {
5673
- 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;
5674
6080
  if (json) {
5675
6081
  output(
5676
- JSON.stringify({
5677
- ok: false,
5678
- command,
5679
- error: { code: error.code, message: error.message }
5680
- })
6082
+ JSON.stringify({ ok: false, command, error: { code: error.code, message: error.message } })
5681
6083
  );
5682
6084
  } else {
5683
6085
  const withCode = error.message.includes(error.code) || error.code.length === 0 ? error.message : `${error.message}\uFF08${error.code}\uFF09`;
5684
6086
  output(`\u9519\u8BEF\uFF1A${withCode}`);
5685
- if (error instanceof CliError && needsRelogin(error)) {
5686
- output("\u63D0\u793A\uFF1A\u5148\u6267\u884C adep login");
5687
- }
6087
+ if (error instanceof CliError && needsRelogin(error)) output("\u63D0\u793A\uFF1A\u5148\u6267\u884C adep login");
5688
6088
  }
5689
6089
  process.exitCode = 1;
5690
- return;
5691
- }
5692
- 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 };
5693
6099
  }
5694
6100
  function formatBytes(bytes) {
5695
6101
  if (bytes < 1024) return `${bytes} B`;
@@ -5710,69 +6116,35 @@ function formatTable(columns, rows) {
5710
6116
  widths[index] = Math.max(widths[index], cell.length);
5711
6117
  });
5712
6118
  }
5713
- 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();
5714
6120
  const parts = [
5715
- line(columns),
5716
- ...rows.map((row) => line(columns.map((c) => String(row[c] ?? ""))))
6121
+ contentLine(columns),
6122
+ ...rows.map((row) => contentLine(columns.map((c) => String(row[c] ?? ""))))
5717
6123
  ];
5718
6124
  return parts.join("\n");
5719
6125
  }
5720
- function parseBool(raw) {
5721
- if (raw === void 0) return void 0;
5722
- if (raw === "true") return true;
5723
- if (raw === "false") return false;
5724
- throw new CliError("INVALID_BOOLEAN", `\u5E03\u5C14\u53C2\u6570\u987B\u4E3A true \u6216 false\uFF0C\u6536\u5230 "${raw}"`);
5725
- }
5726
6126
  function formatSeconds(seconds) {
5727
6127
  return `${Math.max(0.1, Math.round(seconds * 10) / 10)}s`;
5728
6128
  }
5729
- async function runDeploy(paths, output, json, cwd, slug, dir) {
5730
- const { deploy: deploy2 } = await Promise.resolve().then(() => (init_deploy(), deploy_exports));
5731
- const startedAt = Date.now();
5732
- 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,
5733
6136
  cwd,
5734
- ...slug === void 0 ? {} : { slug },
5735
- ...dir === void 0 ? {} : { functionsDir: dir },
5736
- // --json 下逐函数进度会破坏「stdout 恰好一个 JSON 对象」的信封约定(PRD §2.5.3)。
5737
- silent: json,
5738
- // 人读模式的进度也走注入的 output:deploy 内部缺省会直写 process.stdout,
5739
- // 那会让带 sink 的调用方漏收这部分行。
5740
- log: (line) => output(line)
5741
- });
5742
- const elapsedSeconds = (Date.now() - startedAt) / 1e3;
5743
- const deployedCount = result.functions.filter((fn) => fn.action !== "none").length;
5744
- if (json) {
5745
- output(
5746
- JSON.stringify({
5747
- ok: true,
5748
- command: "deploy",
5749
- data: { ...result, elapsedSeconds, deployedCount }
5750
- })
5751
- );
5752
- return;
5753
- }
5754
- for (const fn of result.functions) {
5755
- output(`${fn.name} v${fn.version} ${fn.url}`);
5756
- }
5757
- if (result.noChanges) {
5758
- output(
5759
- `\u2713 no changes \xB7 ${result.functions.length} functions up to date in ${formatSeconds(elapsedSeconds)}`
5760
- );
5761
- return;
5762
- }
5763
- output(`\u2713 ${deployedCount} functions deployed in ${formatSeconds(elapsedSeconds)}`);
6137
+ io: (command) => createCommandIO(command, output, json())
6138
+ };
5764
6139
  }
5765
- function buildProgram(options = {}) {
5766
- const output = options.output ?? ((line) => process.stdout.write(`${line}
5767
- `));
5768
- const paths = options.paths ?? resolvePaths();
5769
- const cwd = options.cwd ?? process.cwd();
5770
- const program2 = new Command();
5771
- program2.name("adep").description("AgentDeploy CLI").version(APP_VERSION);
5772
- program2.option("--json", "\u4EE5\u673A\u5668\u53EF\u8BFB JSON \u8F93\u51FA\uFF08Agent / \u811A\u672C\u8C03\u7528\uFF09", false);
5773
- 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) {
5774
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) => {
5775
- try {
6146
+ const command = ctx.io("login");
6147
+ await command.run(async () => {
5776
6148
  const server = flags.server ?? resolveServer();
5777
6149
  let email = flags.email;
5778
6150
  let password = flags.password;
@@ -5783,89 +6155,113 @@ function buildProgram(options = {}) {
5783
6155
  password = password ?? await prompt.askHidden("\u5BC6\u7801\uFF1A");
5784
6156
  prompt.close();
5785
6157
  }
5786
- const result = await login(paths, {
6158
+ const result = await login(ctx.paths, {
5787
6159
  server,
5788
6160
  email,
5789
6161
  password
5790
6162
  });
5791
- if (jsonMode()) {
5792
- output(JSON.stringify({ ok: true, command: "login", data: result }));
5793
- } else {
5794
- output(`\u5DF2\u767B\u5F55\uFF1A${result.email}\uFF08\u51ED\u636E\u5DF2\u5199\u5165 ${paths.credentialsFile}\uFF0C\u6743\u9650 0600\uFF09`);
5795
- }
5796
- } catch (error) {
5797
- emitError(output, "login", jsonMode(), error);
5798
- }
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
+ });
5799
6168
  });
5800
6169
  program2.command("whoami").description("\u663E\u793A\u5F53\u524D\u767B\u5F55\u8EAB\u4EFD").action(async () => {
5801
- try {
5802
- const result = await whoami(paths);
5803
- if (jsonMode()) {
5804
- output(JSON.stringify({ ok: true, command: "whoami", data: result }));
5805
- } else {
5806
- output(`${result.email} @ ${result.server}`);
5807
- }
5808
- } catch (error) {
5809
- emitError(output, "whoami", jsonMode(), error);
5810
- }
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
+ });
5811
6178
  });
5812
6179
  program2.command("logout").description("\u767B\u51FA\u5E76\u6E05\u9664\u672C\u5730\u51ED\u636E").action(async () => {
5813
- try {
5814
- await logout(paths);
5815
- if (jsonMode()) {
5816
- output(JSON.stringify({ ok: true, command: "logout", data: { done: true } }));
5817
- } else {
5818
- output("\u5DF2\u767B\u51FA");
5819
- }
5820
- } catch (error) {
5821
- emitError(output, "logout", jsonMode(), error);
5822
- }
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
+ });
5823
6185
  });
5824
- 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(
5825
6221
  "-s, --server <url>",
5826
6222
  "\u5E73\u53F0\u5730\u5740\uFF08--list \u7528\uFF1B\u7F3A\u7701\u8BFB ADEP_SERVER \u6216 http://localhost:3000\uFF09"
5827
6223
  ).action(
5828
6224
  async (name, flags) => {
5829
- try {
6225
+ const command = ctx.io("init");
6226
+ await command.run(async () => {
5830
6227
  if (flags.list === true) {
5831
6228
  const server = flags.server ?? resolveServer();
5832
6229
  const templates = await fetchTemplates(server);
5833
- if (jsonMode()) {
5834
- output(JSON.stringify({ ok: true, command: "init", data: { templates } }));
5835
- } else {
5836
- for (const tpl of templates) {
5837
- output(`${tpl.code} ${tpl.name} ${tpl.description ?? ""}`);
5838
- }
5839
- }
6230
+ command.ok(
6231
+ { templates },
6232
+ (data) => data.templates.map(
6233
+ (tpl) => `${tpl.code} ${tpl.name} ${tpl.description ?? ""}`
6234
+ )
6235
+ );
5840
6236
  return;
5841
6237
  }
5842
6238
  if (name === void 0) {
5843
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");
5844
6240
  }
5845
6241
  const template = flags.template;
5846
- if (!["empty", "function"].includes(template)) {
5847
- throw new InitError("INVALID_TEMPLATE", `\u672A\u77E5\u6A21\u677F "${template}"\uFF1A\u53EF\u9009 empty | function`);
5848
- }
5849
- const result = await initProject(cwd, name, template);
5850
- if (jsonMode()) {
5851
- output(JSON.stringify({ ok: true, command: "init", data: result }));
5852
- } else {
5853
- 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
+ );
5854
6247
  }
5855
- } catch (error) {
5856
- emitError(output, "init", jsonMode(), error);
5857
- }
6248
+ const result = await initProject(ctx.cwd, name, template);
6249
+ command.ok(result, (data) => `\u5DF2\u521B\u5EFA ${data.projectPath}`);
6250
+ });
5858
6251
  }
5859
6252
  );
6253
+ }
6254
+
6255
+ // packages/cli/src/commands/dev.ts
6256
+ function registerDevServers(program2, ctx) {
5860
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) => {
5861
- try {
6258
+ const command = ctx.io("dev");
6259
+ await command.run(async () => {
5862
6260
  const { startDevServer: startDevServer2 } = await Promise.resolve().then(() => (init_dev(), dev_exports));
5863
- const started = await startDevServer2({ cwd, port: Number(flags.port ?? "8787") });
5864
- 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`);
5865
6263
  await new Promise(() => void 0);
5866
- } catch (error) {
5867
- emitError(output, "dev", jsonMode(), error);
5868
- }
6264
+ });
5869
6265
  });
5870
6266
  program2.command("serve").description(
5871
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"
@@ -5875,605 +6271,605 @@ function buildProgram(options = {}) {
5875
6271
  ).option(
5876
6272
  "--static <dir>",
5877
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"
5878
6277
  ).action(async (flags) => {
5879
- try {
6278
+ const command = ctx.io("serve");
6279
+ await command.run(async () => {
5880
6280
  const { startServeServer: startServeServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
5881
6281
  await startServeServer2({
5882
- cwd,
6282
+ cwd: ctx.cwd,
5883
6283
  ...flags.port === void 0 ? {} : { port: Number(flags.port) },
5884
6284
  ...flags.host === void 0 ? {} : { host: flags.host },
5885
- ...flags.static === void 0 ? {} : { staticDir: flags.static }
6285
+ ...flags.static === void 0 ? {} : { staticDir: flags.static },
6286
+ ...flags.watch === void 0 ? {} : { watch: true }
5886
6287
  });
5887
6288
  await new Promise(() => void 0);
5888
- } catch (error) {
5889
- 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)}`);
5890
6318
  }
6319
+ return lines;
5891
6320
  });
6321
+ }
6322
+ function registerDeploy(program2, ctx) {
5892
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) => {
5893
- try {
5894
- await runDeploy(paths, output, jsonMode(), cwd, flags.project);
5895
- } catch (error) {
5896
- emitError(output, "deploy", jsonMode(), error);
5897
- }
6324
+ const command = ctx.io("deploy");
6325
+ await command.run(() => runDeploy(ctx.paths, command, ctx.cwd, flags.project));
5898
6326
  });
6327
+ }
6328
+
6329
+ // packages/cli/src/commands/projects.ts
6330
+ function registerProjects(program2, ctx) {
5899
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");
5900
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) => {
5901
- try {
6333
+ const command = ctx.io("projects create");
6334
+ await command.run(async () => {
5902
6335
  const { projectsCreate: projectsCreate2 } = await Promise.resolve().then(() => (init_projects(), projects_exports));
5903
- const created = await projectsCreate2(paths, {
6336
+ const created = await projectsCreate2(ctx.paths, {
5904
6337
  slug,
5905
6338
  ...flags.name === void 0 ? {} : { name: flags.name },
5906
6339
  ...flags.space === void 0 ? {} : { spaceId: flags.space }
5907
6340
  });
5908
- if (jsonMode()) {
5909
- output(JSON.stringify({ ok: true, command: "projects create", data: created }));
5910
- } else {
5911
- output(`\u2713 Project created \xB7 ${created.url}`);
5912
- }
5913
- } catch (error) {
5914
- emitError(output, "projects create", jsonMode(), error);
5915
- }
6341
+ command.ok(created, (data) => `\u2713 Project created \xB7 ${data.url}`);
6342
+ });
5916
6343
  });
5917
6344
  projects.command("list").description("\u5217\u51FA\u5F53\u524D\u7528\u6237\u53EF\u8BBF\u95EE\u7684\u9879\u76EE").action(async () => {
5918
- try {
6345
+ const command = ctx.io("projects list");
6346
+ await command.run(async () => {
5919
6347
  const { projectsList: projectsList2 } = await Promise.resolve().then(() => (init_projects(), projects_exports));
5920
- const list = await projectsList2(paths);
5921
- if (jsonMode()) {
5922
- output(JSON.stringify({ ok: true, command: "projects list", data: { projects: list } }));
5923
- } else {
5924
- if (list.length === 0) output("\uFF08\u8FD8\u6CA1\u6709\u9879\u76EE\uFF1Aadep projects create <slug>\uFF09");
5925
- for (const project2 of list) output(`${project2.slug} ${project2.name} ${project2.url}`);
5926
- }
5927
- } catch (error) {
5928
- emitError(output, "projects list", jsonMode(), error);
5929
- }
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
+ });
5930
6355
  });
5931
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) => {
5932
- try {
6357
+ const command = ctx.io("projects info");
6358
+ await command.run(async () => {
5933
6359
  const { projectsInfo: projectsInfo2 } = await Promise.resolve().then(() => (init_projects(), projects_exports));
5934
- const project2 = await projectsInfo2(paths, { slug });
5935
- if (jsonMode()) {
5936
- output(JSON.stringify({ ok: true, command: "projects info", data: project2 }));
5937
- } else {
5938
- output(`${project2.id} ${project2.slug} ${project2.name} ${project2.url}`);
5939
- }
5940
- } catch (error) {
5941
- emitError(output, "projects info", jsonMode(), error);
5942
- }
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
+ });
5943
6366
  });
6367
+ }
6368
+
6369
+ // packages/cli/src/commands/functions.ts
6370
+ init_auth();
6371
+ function registerFunctions(program2, ctx) {
5944
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");
5945
6373
  functions.command("deploy").description(
5946
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"
5947
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) => {
5948
- try {
5949
- await runDeploy(paths, output, jsonMode(), cwd, flags.project, dir);
5950
- } catch (error) {
5951
- emitError(output, "functions deploy", jsonMode(), error);
5952
- }
6376
+ const command = ctx.io("functions deploy");
6377
+ await command.run(() => runDeploy(ctx.paths, command, ctx.cwd, flags.project, dir));
5953
6378
  });
5954
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) => {
5955
- try {
6380
+ const command = ctx.io("functions list");
6381
+ await command.run(async () => {
5956
6382
  const { functionsList: functionsList2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
5957
- const result = await functionsList2(paths, {
5958
- cwd,
6383
+ const result = await functionsList2(ctx.paths, {
6384
+ cwd: ctx.cwd,
5959
6385
  ...flags.project === void 0 ? {} : { slug: flags.project }
5960
6386
  });
5961
- if (jsonMode()) {
5962
- output(JSON.stringify({ ok: true, command: "functions list", data: result }));
5963
- } else {
5964
- if (result.functions.length === 0) output("\uFF08\u8BE5\u9879\u76EE\u4E0B\u8FD8\u6CA1\u6709\u51FD\u6570\uFF09");
5965
- for (const fn of result.functions) {
5966
- output(`${fn.name} ${result.baseUrl}/${fn.name}`);
5967
- }
5968
- }
5969
- } catch (error) {
5970
- emitError(output, "functions list", jsonMode(), error);
5971
- }
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
+ });
5972
6393
  });
5973
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) => {
5974
- try {
6395
+ const command = ctx.io("functions logs");
6396
+ await command.run(async () => {
5975
6397
  const { functionsLogs: functionsLogs2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
5976
6398
  const tail = flags.tail === void 0 ? void 0 : Number(flags.tail);
5977
6399
  if (tail !== void 0 && (!Number.isFinite(tail) || tail <= 0)) {
5978
6400
  throw new CliError("INVALID_TAIL", `--tail \u987B\u4E3A\u6B63\u6574\u6570\uFF0C\u6536\u5230 "${flags.tail}"`);
5979
6401
  }
5980
- const result = await functionsLogs2(paths, {
5981
- cwd,
6402
+ const result = await functionsLogs2(ctx.paths, {
6403
+ cwd: ctx.cwd,
5982
6404
  name,
5983
6405
  ...tail === void 0 ? {} : { tail },
5984
6406
  ...flags.project === void 0 ? {} : { slug: flags.project }
5985
6407
  });
5986
- if (jsonMode()) {
5987
- output(JSON.stringify({ ok: true, command: "functions logs", data: result }));
5988
- } else {
5989
- if (result.logs.length === 0) {
5990
- 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`;
5991
6412
  }
5992
- for (const log of result.logs) output(`${log.at} [${log.level}] ${log.message}`);
5993
- }
5994
- } catch (error) {
5995
- emitError(output, "functions logs", jsonMode(), error);
5996
- }
6413
+ return r.logs.map((log) => `${log.at} [${log.level}] ${log.message}`);
6414
+ });
6415
+ });
5997
6416
  });
6417
+ }
6418
+
6419
+ // packages/cli/src/commands/mcp.ts
6420
+ function registerMcp(program2, ctx) {
5998
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");
5999
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(
6000
6423
  "--description <text>",
6001
6424
  "\u8986\u76D6\u9762\u5411 Agent \u7684\u5DE5\u5177\u63CF\u8FF0\uFF08\u7F3A\u7701\u7528\u6E90\u7801 @description / \u63A8\u5BFC\u63CF\u8FF0\uFF09"
6002
6425
  ).option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(
6003
6426
  async (flags) => {
6004
- try {
6427
+ const command = ctx.io("mcp publish");
6428
+ await command.run(async () => {
6005
6429
  const { mcpPublish: mcpPublish2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
6006
- const result = await mcpPublish2(paths, {
6007
- cwd,
6430
+ const result = await mcpPublish2(ctx.paths, {
6431
+ cwd: ctx.cwd,
6008
6432
  fn: flags.function,
6009
6433
  ...flags.name === void 0 ? {} : { toolName: flags.name },
6010
6434
  ...flags.description === void 0 ? {} : { description: flags.description },
6011
6435
  ...flags.project === void 0 ? {} : { slug: flags.project }
6012
6436
  });
6013
- if (jsonMode()) {
6014
- output(JSON.stringify({ ok: true, command: "mcp publish", data: result }));
6015
- } else {
6016
- output(`\u2713 MCP tool published \xB7 ${result.tool.name}`);
6017
- }
6018
- } catch (error) {
6019
- emitError(output, "mcp publish", jsonMode(), error);
6020
- }
6437
+ command.ok(result, (data) => {
6438
+ const r = data;
6439
+ return `\u2713 MCP tool published \xB7 ${r.tool.name}`;
6440
+ });
6441
+ });
6021
6442
  }
6022
6443
  );
6023
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) => {
6024
- try {
6445
+ const command = ctx.io("mcp unpublish");
6446
+ await command.run(async () => {
6025
6447
  const { mcpUnpublish: mcpUnpublish2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
6026
- const result = await mcpUnpublish2(paths, {
6027
- cwd,
6448
+ const result = await mcpUnpublish2(ctx.paths, {
6449
+ cwd: ctx.cwd,
6028
6450
  fn: flags.function,
6029
6451
  ...flags.name === void 0 ? {} : { toolName: flags.name },
6030
6452
  ...flags.project === void 0 ? {} : { slug: flags.project }
6031
6453
  });
6032
- if (jsonMode()) {
6033
- output(JSON.stringify({ ok: true, command: "mcp unpublish", data: result }));
6034
- } else if (result.removed) {
6035
- output(`\u2713 MCP tool unpublished \xB7 ${result.toolName}`);
6036
- } else {
6037
- output(`\uFF08\u9879\u76EE\u672A\u53D1\u5E03\u540D\u4E3A ${result.toolName} \u7684 MCP tool\uFF0C\u65E0\u9700\u53D6\u6D88\uFF09`);
6038
- }
6039
- } catch (error) {
6040
- emitError(output, "mcp unpublish", jsonMode(), error);
6041
- }
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
+ });
6042
6459
  });
6043
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) => {
6044
- try {
6461
+ const command = ctx.io("mcp list");
6462
+ await command.run(async () => {
6045
6463
  const { mcpList: mcpList2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
6046
- const result = await mcpList2(paths, {
6047
- cwd,
6464
+ const result = await mcpList2(ctx.paths, {
6465
+ cwd: ctx.cwd,
6048
6466
  ...flags.project === void 0 ? {} : { slug: flags.project }
6049
6467
  });
6050
- if (jsonMode()) {
6051
- output(JSON.stringify({ ok: true, command: "mcp list", data: result }));
6052
- } else {
6053
- output(`\u7AEF\u70B9\uFF1A${result.endpoint}`);
6054
- if (result.tools.length === 0) {
6055
- output("\uFF08\u8FD8\u6CA1\u6709\u5DF2\u53D1\u5E03\u7684 MCP tool\uFF1Aadep mcp publish --function <fn>\uFF09");
6056
- }
6057
- for (const tool of result.tools) {
6058
- 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 ?? ""}`);
6059
6475
  }
6060
- }
6061
- } catch (error) {
6062
- emitError(output, "mcp list", jsonMode(), error);
6063
- }
6476
+ return lines;
6477
+ });
6478
+ });
6064
6479
  });
6480
+ }
6481
+
6482
+ // packages/cli/src/commands/doctor.ts
6483
+ function registerDoctor(program2, ctx) {
6065
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 () => {
6066
- try {
6485
+ const command = ctx.io("doctor");
6486
+ await command.run(async () => {
6067
6487
  const { runDoctor: runDoctor2, formatDoctorReport: formatDoctorReport2 } = await Promise.resolve().then(() => (init_doctor(), doctor_exports));
6068
- const report = await runDoctor2(paths);
6069
- if (jsonMode()) {
6070
- output(JSON.stringify({ ok: true, command: "doctor", data: report }));
6071
- } else {
6072
- for (const line of formatDoctorReport2(report)) output(line);
6073
- }
6074
- } catch (error) {
6075
- emitError(output, "doctor", jsonMode(), error);
6076
- }
6488
+ const report = await runDoctor2(ctx.paths);
6489
+ command.ok(report, () => formatDoctorReport2(report));
6490
+ });
6077
6491
  });
6492
+ }
6493
+
6494
+ // packages/cli/src/commands/db.ts
6495
+ function registerDb(program2, ctx) {
6078
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");
6079
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) => {
6080
- try {
6498
+ const command = ctx.io("db start");
6499
+ await command.run(async () => {
6081
6500
  const { dbStart: dbStart2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
6082
- const result = await dbStart2(paths, {
6083
- cwd,
6501
+ const result = await dbStart2(ctx.paths, {
6502
+ cwd: ctx.cwd,
6084
6503
  ...flags.project === void 0 ? {} : { slug: flags.project }
6085
6504
  });
6086
- if (jsonMode()) {
6087
- output(JSON.stringify({ ok: true, command: "db start", data: result }));
6088
- } else {
6089
- output(
6090
- `\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`
6091
- );
6092
- }
6093
- } catch (error) {
6094
- emitError(output, "db start", jsonMode(), error);
6095
- }
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
+ });
6096
6510
  });
6097
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) => {
6098
- try {
6512
+ const command = ctx.io("db status");
6513
+ await command.run(async () => {
6099
6514
  const { dbStatus: dbStatus2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
6100
- const result = await dbStatus2(paths, {
6101
- cwd,
6515
+ const result = await dbStatus2(ctx.paths, {
6516
+ cwd: ctx.cwd,
6102
6517
  ...flags.project === void 0 ? {} : { slug: flags.project }
6103
6518
  });
6104
- if (jsonMode()) {
6105
- output(JSON.stringify({ ok: true, command: "db status", data: result }));
6106
- } else {
6107
- output(
6108
- `\u72B6\u6001\uFF1A${result.status}\uFF08${result.projectId}\uFF0C${result.usage.tableCount} \u8868 / ${result.usage.rowCount} \u884C / ${formatBytes(result.usage.sizeBytes)}\uFF09`
6109
- );
6110
- }
6111
- } catch (error) {
6112
- emitError(output, "db status", jsonMode(), error);
6113
- }
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
+ });
6114
6524
  });
6115
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) => {
6116
- try {
6526
+ const command = ctx.io("db stop");
6527
+ await command.run(async () => {
6117
6528
  const { dbStop: dbStop2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
6118
- const result = await dbStop2(paths, {
6119
- cwd,
6529
+ const result = await dbStop2(ctx.paths, {
6530
+ cwd: ctx.cwd,
6120
6531
  ...flags.project === void 0 ? {} : { slug: flags.project }
6121
6532
  });
6122
- if (jsonMode()) {
6123
- output(JSON.stringify({ ok: true, command: "db stop", data: result }));
6124
- } else {
6125
- output(`\u6570\u636E\u5E93\u5DF2\u505C\u6B62\uFF1A${result.status}`);
6126
- }
6127
- } catch (error) {
6128
- emitError(output, "db stop", jsonMode(), error);
6129
- }
6533
+ command.ok(result, (data) => `\u6570\u636E\u5E93\u5DF2\u505C\u6B62\uFF1A${data.status}`);
6534
+ });
6130
6535
  });
6131
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) => {
6132
- try {
6537
+ const command = ctx.io("db exec");
6538
+ await command.run(async () => {
6133
6539
  const { dbExec: dbExec2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
6134
- const result = await dbExec2(paths, {
6135
- cwd,
6540
+ const result = await dbExec2(ctx.paths, {
6541
+ cwd: ctx.cwd,
6136
6542
  sql: flags.sql,
6137
6543
  ...flags.project === void 0 ? {} : { slug: flags.project },
6138
6544
  ...flags.confirmTable === void 0 ? {} : { confirmTable: flags.confirmTable }
6139
6545
  });
6140
- if (jsonMode()) {
6141
- output(JSON.stringify({ ok: true, command: "db exec", data: result }));
6142
- } else {
6143
- if (result.columns.length > 0) {
6144
- output(formatTable(result.columns, result.rows));
6145
- if (result.truncated) output(`\uFF08\u7ED3\u679C\u5DF2\u622A\u65AD\u5230 ${result.rows.length} \u884C\uFF09`);
6146
- } else if (result.changes > 0) {
6147
- 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`);
6148
6554
  } else {
6149
- 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");
6150
6556
  }
6151
- output(`\u8017\u65F6 ${result.elapsedMs}ms`);
6152
- }
6153
- } catch (error) {
6154
- emitError(output, "db exec", jsonMode(), error);
6155
- }
6557
+ lines.push(`\u8017\u65F6 ${r.elapsedMs}ms`);
6558
+ return lines;
6559
+ });
6560
+ });
6156
6561
  });
6157
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");
6158
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) => {
6159
- try {
6564
+ const command = ctx.io("db snapshot list");
6565
+ await command.run(async () => {
6160
6566
  const { dbSnapshotList: dbSnapshotList2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
6161
- const result = await dbSnapshotList2(paths, {
6162
- cwd,
6567
+ const result = await dbSnapshotList2(ctx.paths, {
6568
+ cwd: ctx.cwd,
6163
6569
  ...flags.project === void 0 ? {} : { slug: flags.project }
6164
6570
  });
6165
- if (jsonMode()) {
6166
- output(JSON.stringify({ ok: true, command: "db snapshot list", data: result }));
6167
- } else {
6168
- if (result.snapshots.length === 0) {
6169
- output("\u6682\u65E0\u5FEB\u7167");
6170
- }
6171
- for (const snap of result.snapshots) {
6172
- output(
6173
- `${snap.id} ${snap.type} ${snap.plan} ${formatBytes(snap.sizeBytes)} ${snap.createdAt}`
6174
- );
6175
- }
6176
- }
6177
- } catch (error) {
6178
- emitError(output, "db snapshot list", jsonMode(), error);
6179
- }
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
+ });
6180
6579
  });
6181
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) => {
6182
- try {
6581
+ const command = ctx.io("db snapshot create");
6582
+ await command.run(async () => {
6183
6583
  const { dbSnapshotCreate: dbSnapshotCreate2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
6184
- const result = await dbSnapshotCreate2(paths, {
6185
- cwd,
6584
+ const result = await dbSnapshotCreate2(ctx.paths, {
6585
+ cwd: ctx.cwd,
6186
6586
  ...flags.project === void 0 ? {} : { slug: flags.project }
6187
6587
  });
6188
- if (jsonMode()) {
6189
- output(JSON.stringify({ ok: true, command: "db snapshot create", data: result }));
6190
- } else {
6191
- output(`\u5FEB\u7167\u5DF2\u521B\u5EFA\uFF1A${result.id}\uFF08${result.plan}\uFF0C${formatBytes(result.sizeBytes)}\uFF09`);
6192
- }
6193
- } catch (error) {
6194
- emitError(output, "db snapshot create", jsonMode(), error);
6195
- }
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
+ });
6196
6593
  });
6197
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) => {
6198
- try {
6595
+ const command = ctx.io("db snapshot restore");
6596
+ await command.run(async () => {
6199
6597
  const { dbSnapshotRestore: dbSnapshotRestore2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
6200
- const result = await dbSnapshotRestore2(paths, {
6201
- cwd,
6598
+ const result = await dbSnapshotRestore2(ctx.paths, {
6599
+ cwd: ctx.cwd,
6202
6600
  snapshotId,
6203
6601
  ...flags.project === void 0 ? {} : { slug: flags.project }
6204
6602
  });
6205
- if (jsonMode()) {
6206
- output(JSON.stringify({ ok: true, command: "db snapshot restore", data: result }));
6207
- } else {
6208
- output(`\u5DF2\u8FD8\u539F\u5230\u5FEB\u7167 ${result.snapshotId}`);
6209
- }
6210
- } catch (error) {
6211
- emitError(output, "db snapshot restore", jsonMode(), error);
6212
- }
6603
+ command.ok(result, (data) => `\u5DF2\u8FD8\u539F\u5230\u5FEB\u7167 ${data.snapshotId}`);
6604
+ });
6213
6605
  });
6214
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) => {
6215
- try {
6607
+ const command = ctx.io("db rollback");
6608
+ await command.run(async () => {
6216
6609
  const { dbRollback: dbRollback2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
6217
- const result = await dbRollback2(paths, {
6218
- cwd,
6610
+ const result = await dbRollback2(ctx.paths, {
6611
+ cwd: ctx.cwd,
6219
6612
  to: flags.to,
6220
6613
  ...flags.project === void 0 ? {} : { slug: flags.project }
6221
6614
  });
6222
- if (jsonMode()) {
6223
- output(JSON.stringify({ ok: true, command: "db rollback", data: result }));
6224
- } else {
6225
- output(`\u5DF2\u56DE\u6EDA\u5230 ${result.to}\uFF08\u91CD\u653E ${result.reverted} \u6761\u53D8\u66F4\uFF09`);
6226
- }
6227
- } catch (error) {
6228
- emitError(output, "db rollback", jsonMode(), error);
6229
- }
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
+ });
6230
6620
  });
6621
+ }
6622
+
6623
+ // packages/cli/src/commands/storage.ts
6624
+ function registerStorage(program2, ctx) {
6231
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");
6232
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(
6233
6627
  "--visibility <public|private>",
6234
6628
  "public \u76F4\u8FDE / private \u7B7E\u540D\uFF08\u7F3A\u7701 private\uFF09",
6235
6629
  "private"
6236
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) => {
6237
- try {
6631
+ const command = ctx.io("storage upload");
6632
+ await command.run(async () => {
6238
6633
  const { storageUpload: storageUpload2 } = await Promise.resolve().then(() => (init_storage2(), storage_exports));
6239
- const result = await storageUpload2(paths, {
6240
- cwd,
6634
+ const result = await storageUpload2(ctx.paths, {
6635
+ cwd: ctx.cwd,
6241
6636
  file,
6242
6637
  path: flags.path,
6243
6638
  visibility: flags.visibility === "public" ? "public" : "private",
6244
6639
  ...flags.project === void 0 ? {} : { slug: flags.project }
6245
6640
  });
6246
- if (jsonMode()) {
6247
- output(JSON.stringify({ ok: true, command: "storage upload", data: result }));
6248
- } else {
6249
- output(`\u5DF2\u4E0A\u4F20 ${result.path}\uFF08${result.visibility}\uFF0C${formatBytes(result.size)}\uFF09`);
6250
- if (result.signedUrl !== void 0) output(`\u7B7E\u540D URL\uFF1A${result.signedUrl}`);
6251
- }
6252
- } catch (error) {
6253
- emitError(output, "storage upload", jsonMode(), error);
6254
- }
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
+ });
6255
6648
  });
6256
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) => {
6257
- try {
6650
+ const command = ctx.io("storage download");
6651
+ await command.run(async () => {
6258
6652
  const { storageDownload: storageDownload2 } = await Promise.resolve().then(() => (init_storage2(), storage_exports));
6259
- const result = await storageDownload2(paths, {
6260
- cwd,
6653
+ const result = await storageDownload2(ctx.paths, {
6654
+ cwd: ctx.cwd,
6261
6655
  path: remotePath,
6262
6656
  ...flags.output === void 0 ? {} : { output: flags.output },
6263
6657
  ...flags.project === void 0 ? {} : { slug: flags.project }
6264
6658
  });
6265
- if (jsonMode()) {
6266
- output(JSON.stringify({ ok: true, command: "storage download", data: result }));
6267
- } else {
6268
- output(`\u5DF2\u4E0B\u8F7D ${result.path} \u2192 ${result.output}\uFF08${formatBytes(result.size)}\uFF09`);
6269
- }
6270
- } catch (error) {
6271
- emitError(output, "storage download", jsonMode(), error);
6272
- }
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
+ });
6273
6664
  });
6274
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) => {
6275
- try {
6666
+ const command = ctx.io("storage ls");
6667
+ await command.run(async () => {
6276
6668
  const { storageList: storageList2 } = await Promise.resolve().then(() => (init_storage2(), storage_exports));
6277
- const result = await storageList2(paths, {
6278
- cwd,
6669
+ const result = await storageList2(ctx.paths, {
6670
+ cwd: ctx.cwd,
6279
6671
  ...flags.prefix === void 0 ? {} : { prefix: flags.prefix },
6280
6672
  ...flags.project === void 0 ? {} : { slug: flags.project }
6281
6673
  });
6282
- if (jsonMode()) {
6283
- output(JSON.stringify({ ok: true, command: "storage ls", data: result }));
6284
- } else {
6285
- if (result.files.length === 0) {
6286
- output("\uFF08\u65E0\u6587\u4EF6\uFF09");
6287
- }
6288
- for (const file of result.files) {
6289
- output(
6290
- `${file.path} ${file.visibility} ${formatBytes(file.size)} ${file.url ?? file.signedUrl ?? ""}`
6291
- );
6292
- }
6293
- }
6294
- } catch (error) {
6295
- emitError(output, "storage ls", jsonMode(), error);
6296
- }
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
+ });
6297
6682
  });
6298
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) => {
6299
- try {
6684
+ const command = ctx.io("storage rm");
6685
+ await command.run(async () => {
6300
6686
  const { storageRemove: storageRemove2 } = await Promise.resolve().then(() => (init_storage2(), storage_exports));
6301
- const result = await storageRemove2(paths, {
6302
- cwd,
6687
+ const result = await storageRemove2(ctx.paths, {
6688
+ cwd: ctx.cwd,
6303
6689
  path: remotePath,
6304
6690
  ...flags.project === void 0 ? {} : { slug: flags.project }
6305
6691
  });
6306
- if (jsonMode()) {
6307
- output(JSON.stringify({ ok: true, command: "storage rm", data: result }));
6308
- } else {
6309
- output(`\u5DF2\u5220\u9664 ${remotePath}`);
6310
- }
6311
- } catch (error) {
6312
- emitError(output, "storage rm", jsonMode(), error);
6313
- }
6692
+ command.ok(result, () => `\u5DF2\u5220\u9664 ${remotePath}`);
6693
+ });
6314
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) {
6315
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");
6316
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) => {
6317
- try {
6708
+ const command = ctx.io("hosting info");
6709
+ await command.run(async () => {
6318
6710
  const { hostingInfo: hostingInfo2 } = await Promise.resolve().then(() => (init_hosting(), hosting_exports));
6319
- const result = await hostingInfo2(paths, {
6320
- cwd,
6711
+ const result = await hostingInfo2(ctx.paths, {
6712
+ cwd: ctx.cwd,
6321
6713
  ...flags.project === void 0 ? {} : { slug: flags.project }
6322
6714
  });
6323
- if (jsonMode()) {
6324
- output(JSON.stringify({ ok: true, command: "hosting info", data: result }));
6325
- } else {
6326
- output(
6327
- `\u7AD9\u70B9\uFF1A${result.siteUrl}\uFF08\u6258\u7BA1 ${result.config.enabled ? "\u5F00" : "\u5173"}\uFF0CSPA \u56DE\u9000 ${result.config.spaMode ? "\u5F00" : "\u5173"}\uFF09`
6328
- );
6329
- for (const file of result.files) {
6330
- output(`${file.path} ${formatBytes(file.size)}`);
6331
- }
6332
- }
6333
- } catch (error) {
6334
- emitError(output, "hosting info", jsonMode(), error);
6335
- }
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
+ });
6336
6724
  });
6337
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) => {
6338
- try {
6726
+ const command = ctx.io("hosting deploy");
6727
+ await command.run(async () => {
6339
6728
  const { hostingDeploy: hostingDeploy2 } = await Promise.resolve().then(() => (init_hosting(), hosting_exports));
6340
- const result = await hostingDeploy2(paths, {
6341
- cwd,
6729
+ const result = await hostingDeploy2(ctx.paths, {
6730
+ cwd: ctx.cwd,
6342
6731
  dir,
6343
6732
  ...flags.spa === true ? { spa: true } : {},
6344
6733
  ...flags.project === void 0 ? {} : { slug: flags.project }
6345
6734
  });
6346
- if (jsonMode()) {
6347
- output(JSON.stringify({ ok: true, command: "hosting deploy", data: result }));
6348
- } else {
6349
- output(
6350
- `\u7AD9\u70B9\u5DF2\u4E0A\u7EBF\uFF1A${result.siteUrl}\uFF08${result.uploaded.length} \u4E2A\u6587\u4EF6\uFF0CSPA \u56DE\u9000 ${result.config.spaMode ? "\u5F00" : "\u5173"}\uFF09`
6351
- );
6352
- }
6353
- } catch (error) {
6354
- emitError(output, "hosting deploy", jsonMode(), error);
6355
- }
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
+ });
6356
6740
  });
6357
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) => {
6358
- try {
6742
+ const command = ctx.io("hosting pull");
6743
+ await command.run(async () => {
6359
6744
  const { hostingPull: hostingPull2 } = await Promise.resolve().then(() => (init_hosting(), hosting_exports));
6360
- const result = await hostingPull2(paths, {
6361
- cwd,
6745
+ const result = await hostingPull2(ctx.paths, {
6746
+ cwd: ctx.cwd,
6362
6747
  ...flags.output === void 0 ? {} : { output: flags.output },
6363
6748
  ...flags.project === void 0 ? {} : { slug: flags.project }
6364
6749
  });
6365
- if (jsonMode()) {
6366
- output(JSON.stringify({ ok: true, command: "hosting pull", data: result }));
6367
- } else {
6368
- output(
6369
- `\u5DF2\u62C9\u53D6 ${result.files.length} \u4E2A\u6587\u4EF6 \u2192 ${result.outputDir}\uFF08\u7AD9\u70B9\uFF1A${result.siteUrl}\uFF09`
6370
- );
6371
- }
6372
- } catch (error) {
6373
- emitError(output, "hosting pull", jsonMode(), error);
6374
- }
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
+ });
6375
6755
  });
6376
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) => {
6377
- try {
6757
+ const command = ctx.io("hosting config");
6758
+ await command.run(async () => {
6378
6759
  const { hostingConfig: hostingConfig2 } = await Promise.resolve().then(() => (init_hosting(), hosting_exports));
6379
6760
  const enabled = parseBool(flags.enabled);
6380
6761
  const spa = parseBool(flags.spa);
6381
- const config = await hostingConfig2(paths, {
6382
- cwd,
6762
+ const config = await hostingConfig2(ctx.paths, {
6763
+ cwd: ctx.cwd,
6383
6764
  ...enabled === void 0 ? {} : { enabled },
6384
6765
  ...spa === void 0 ? {} : { spa },
6385
6766
  ...flags.project === void 0 ? {} : { slug: flags.project }
6386
6767
  });
6387
- if (jsonMode()) {
6388
- output(JSON.stringify({ ok: true, command: "hosting config", data: { config } }));
6389
- } else {
6390
- output(`\u6258\u7BA1 ${config.enabled ? "\u5F00" : "\u5173"}\uFF0CSPA \u56DE\u9000 ${config.spaMode ? "\u5F00" : "\u5173"}`);
6391
- }
6392
- } catch (error) {
6393
- emitError(output, "hosting config", jsonMode(), error);
6394
- }
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
+ });
6395
6773
  });
6774
+ }
6775
+
6776
+ // packages/cli/src/commands/export.ts
6777
+ function registerExport(program2, ctx) {
6396
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(
6397
6779
  async (flags) => {
6398
- try {
6780
+ const command = ctx.io("export");
6781
+ await command.run(async () => {
6399
6782
  const { createExportApiClient: createExportApiClient2 } = await Promise.resolve().then(() => (init_client2(), client_exports2));
6400
6783
  const { createExportFileSystem: createExportFileSystem2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
6401
6784
  const { ExportCommand: ExportCommand2 } = await Promise.resolve().then(() => (init_command(), command_exports));
6402
6785
  const { resolveSlug: resolveSlug2 } = await Promise.resolve().then(() => (init_client(), client_exports));
6403
- const project2 = await resolveSlug2(cwd, flags.project);
6404
- const apiClient = await createExportApiClient2(paths);
6405
- const command = new ExportCommand2(apiClient, createExportFileSystem2());
6406
- 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({
6407
6790
  project: project2,
6408
6791
  ...flags.withData === true ? { withData: true } : {},
6409
6792
  ...flags.withSource === true ? { withSource: true } : {},
6410
6793
  ...flags.out === void 0 ? {} : { out: flags.out },
6411
- json: jsonMode()
6794
+ json: command.json
6412
6795
  });
6413
- if (jsonMode()) {
6414
- if (result.success) {
6415
- output(JSON.stringify({ ok: true, command: "export", data: result }));
6416
- } else {
6417
- output(
6418
- JSON.stringify({
6419
- ok: false,
6420
- command: "export",
6421
- error: { code: "EXPORT_FAILED", message: result.error ?? "\u5BFC\u51FA\u5931\u8D25" }
6422
- })
6423
- );
6424
- process.exitCode = 1;
6425
- }
6426
- } else if (!result.success) {
6427
- output(`\u9519\u8BEF\uFF1A${result.error ?? "\u5BFC\u51FA\u5931\u8D25"}`);
6428
- process.exitCode = 1;
6796
+ if (!result.success) {
6797
+ command.fail("EXPORT_FAILED", result.error ?? "\u5BFC\u51FA\u5931\u8D25");
6798
+ return;
6429
6799
  }
6430
- } catch (error) {
6431
- emitError(output, "export", jsonMode(), error);
6432
- }
6800
+ command.ok(result);
6801
+ });
6433
6802
  }
6434
6803
  );
6804
+ }
6805
+
6806
+ // packages/cli/src/commands/widget.ts
6807
+ function registerWidget(program2, ctx) {
6435
6808
  const widget = program2.command("widget").description("\u5FAE\u524D\u7AEF\u7EC4\u4EF6\uFF08widget\uFF09\uFF1A\u811A\u624B\u67B6 / \u672C\u5730\u6C99\u7BB1 / \u53D1\u5E03");
6436
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) => {
6437
- try {
6810
+ const command = ctx.io("widget init");
6811
+ await command.run(async () => {
6438
6812
  const { initWidget: initWidget2 } = await Promise.resolve().then(() => (init_init(), init_exports));
6439
- const result = await initWidget2(cwd, name, flags.template);
6440
- if (jsonMode()) {
6441
- output(JSON.stringify({ ok: true, command: "widget init", data: result }));
6442
- } else {
6443
- output(`\u5DF2\u521B\u5EFA widget ${result.projectPath}`);
6444
- }
6445
- } catch (error) {
6446
- emitError(output, "widget init", jsonMode(), error);
6447
- }
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
+ });
6448
6819
  });
6449
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) => {
6450
- try {
6821
+ const command = ctx.io("widget dev");
6822
+ await command.run(async () => {
6451
6823
  const { startWidgetDev: startWidgetDev2 } = await Promise.resolve().then(() => (init_dev2(), dev_exports2));
6452
- const started = await startWidgetDev2({ cwd, port: Number(flags.port ?? "8788") });
6453
- output(
6824
+ const started = await startWidgetDev2({ cwd: ctx.cwd, port: Number(flags.port ?? "8788") });
6825
+ command.raw(
6454
6826
  `[adep] widget dev sandbox on ${started.baseUrl}\uFF08?token=<...> \u6CE8\u5165\u9274\u6743 token\uFF1BCtrl-C \u9000\u51FA\uFF09`
6455
6827
  );
6456
6828
  await new Promise(() => void 0);
6457
- } catch (error) {
6458
- emitError(output, "widget dev", jsonMode(), error);
6459
- }
6829
+ });
6460
6830
  });
6461
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) => {
6462
- try {
6832
+ const command = ctx.io("widget publish");
6833
+ await command.run(async () => {
6463
6834
  const { publishWidget: publishWidget2 } = await Promise.resolve().then(() => (init_publish(), publish_exports));
6464
- const result = await publishWidget2(paths, {
6465
- cwd,
6835
+ const result = await publishWidget2(ctx.paths, {
6836
+ cwd: ctx.cwd,
6466
6837
  project: flags.project
6467
6838
  });
6468
- if (jsonMode()) {
6469
- output(JSON.stringify({ ok: true, command: "widget publish", data: result }));
6470
- } else {
6471
- output(`${result.name} v${result.version} ${result.url}`);
6472
- }
6473
- } catch (error) {
6474
- emitError(output, "widget publish", jsonMode(), error);
6475
- }
6839
+ command.ok(result, (data) => {
6840
+ const r = data;
6841
+ return `${r.name} v${r.version} ${r.url}`;
6842
+ });
6843
+ });
6476
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);
6477
6873
  return program2;
6478
6874
  }
6479
6875