@faapi/faapi 6.22.0 → 6.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -3082,8 +3082,6 @@ var init_generateToolArtifacts = __esm({
3082
3082
 
3083
3083
  // src/agents/scanAgents.ts
3084
3084
  import fg3 from "fast-glob";
3085
- import path15 from "path";
3086
- import fs12 from "fs";
3087
3085
  function extractAgentNameFromPath(filePath) {
3088
3086
  const normalized = filePath.replace(/\\/g, "/");
3089
3087
  const match = normalized.match(/(?:^|\/)agents\/(.+)\/handler\.ts$/);
@@ -3094,11 +3092,6 @@ function extractAgentNameFromPath(filePath) {
3094
3092
  }
3095
3093
  return match[1].replace(/\//g, ".");
3096
3094
  }
3097
- function detectAgentExports(source) {
3098
- return {
3099
- hasRun: RUN_EXPORT_RE.test(source)
3100
- };
3101
- }
3102
3095
  async function scanAgents(rootDir, patterns) {
3103
3096
  const files = await fg3(patterns, {
3104
3097
  cwd: rootDir,
@@ -3113,9 +3106,6 @@ async function scanAgents(rootDir, patterns) {
3113
3106
  if (fileName !== "handler.ts" && fileName !== "handler.js") {
3114
3107
  continue;
3115
3108
  }
3116
- const absPath = path15.resolve(rootDir, normalizedFile);
3117
- const source = await fs12.promises.readFile(absPath, "utf8").catch(() => "");
3118
- const { hasRun } = detectAgentExports(source);
3119
3109
  const name = extractAgentNameFromPath(normalizedFile);
3120
3110
  const prevFile = seen.get(name);
3121
3111
  if (prevFile) {
@@ -3126,18 +3116,16 @@ async function scanAgents(rootDir, patterns) {
3126
3116
  seen.set(name, normalizedFile);
3127
3117
  agents.push({
3128
3118
  name,
3129
- filePath: normalizedFile,
3130
- hasRun
3119
+ filePath: normalizedFile
3131
3120
  });
3132
3121
  }
3133
3122
  return agents;
3134
3123
  }
3135
- var DEFAULT_AGENT_PATTERNS, RUN_EXPORT_RE;
3124
+ var DEFAULT_AGENT_PATTERNS;
3136
3125
  var init_scanAgents = __esm({
3137
3126
  "src/agents/scanAgents.ts"() {
3138
3127
  "use strict";
3139
3128
  DEFAULT_AGENT_PATTERNS = ["src/agents/**/handler.ts"];
3140
- RUN_EXPORT_RE = /export\s+(?:async\s+)?(?:function\s+|const\s+)run\b/;
3141
3129
  }
3142
3130
  });
3143
3131
 
@@ -3146,12 +3134,21 @@ import ts11 from "typescript";
3146
3134
  function extractAgentMetadata(program, filePath, pathMeta) {
3147
3135
  const sourceFile = program.getSourceFile(filePath);
3148
3136
  if (!sourceFile) return null;
3137
+ const runOwner = findRunExportOwner(sourceFile);
3138
+ if (runOwner) {
3139
+ throw SchemaExtractionError.at(
3140
+ runOwner,
3141
+ "run",
3142
+ "agent \u81EA\u5B9A\u4E49 run \u5DF2\u79FB\u9664\u2014\u2014agent \u7EDF\u4E00\u4E3A\u58F0\u660E\u5F0F\u6267\u884C\uFF08config + \u9ED8\u8BA4 reactLoop\uFF09\u3002\u7F16\u6392\u573A\u666F\u8BF7\u6CE8\u518C tool\uFF08src/tools/ \u4E0B\u5BFC\u51FA\u51FD\u6570\uFF0C\u6709 schema/trace/\u9274\u6743\u94A9\u5B50\uFF09\uFF0C\u591A agent \u534F\u4F5C\u7528 config.agents \u58F0\u660E sub-agent",
3143
+ sourceFile
3144
+ );
3145
+ }
3149
3146
  const configFound = findConfigExport(sourceFile);
3150
3147
  if (!configFound) {
3151
3148
  throw SchemaExtractionError.at(
3152
3149
  sourceFile,
3153
3150
  "config.systemPrompt",
3154
- "agent \u5FC5\u586B\u2014\u2014\u8BF7\u5728 config \u5757\u58F0\u660E\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF08\u5B57\u7B26\u4E32\u5B57\u9762\u91CF\u3001\u65E0\u63D2\u503C\u6A21\u677F\u5B57\u7B26\u4E32\u6216\u5176 + \u62FC\u63A5\uFF09",
3151
+ "agent \u5FC5\u586B\u2014\u2014\u8BF7\u5728 config \u5757\u58F0\u660E systemPrompt\uFF08\u5B57\u7B26\u4E32\u5B57\u9762\u91CF\u3001\u65E0\u63D2\u503C\u6A21\u677F\u5B57\u7B26\u4E32\u6216\u5176 + \u62FC\u63A5\uFF09\u6216 systemPromptFile\uFF08\u76F8\u5BF9 resources \u76EE\u5F55\u7684\u8DEF\u5F84\u5B57\u9762\u91CF\uFF09\u4E8C\u9009\u4E00",
3155
3152
  sourceFile
3156
3153
  );
3157
3154
  }
@@ -3167,16 +3164,13 @@ function extractAgentMetadata(program, filePath, pathMeta) {
3167
3164
  const jsDoc = getJSDocFromNode(configFound.jsDocOwner);
3168
3165
  const description = extractDescription(jsDoc);
3169
3166
  const agentNameOverride = extractJSDocTagValue(jsDoc, "agent");
3170
- const { systemPrompt, tools, agents, model, maxTurns, inputDescription } = extractConfigFields(
3171
- objectLiteral,
3172
- sourceFile
3173
- );
3167
+ const { systemPrompt, systemPromptFile, tools, agents, model, maxTurns, inputDescription } = extractConfigFields(objectLiteral, sourceFile);
3174
3168
  return {
3175
3169
  name: agentNameOverride ?? pathMeta.name,
3176
3170
  description,
3177
3171
  filePath: pathMeta.filePath,
3178
- hasRun: pathMeta.hasRun,
3179
3172
  systemPrompt,
3173
+ systemPromptFile,
3180
3174
  tools,
3181
3175
  agents,
3182
3176
  model,
@@ -3184,6 +3178,25 @@ function extractAgentMetadata(program, filePath, pathMeta) {
3184
3178
  inputDescription
3185
3179
  };
3186
3180
  }
3181
+ function findRunExportOwner(sourceFile) {
3182
+ let result = null;
3183
+ ts11.forEachChild(sourceFile, (node) => {
3184
+ if (result) return;
3185
+ if (ts11.isFunctionDeclaration(node) && hasExportModifier(node) && node.name?.text === "run") {
3186
+ result = node;
3187
+ return;
3188
+ }
3189
+ if (ts11.isVariableStatement(node) && hasExportModifier(node)) {
3190
+ for (const decl of node.declarationList.declarations) {
3191
+ if (ts11.isIdentifier(decl.name) && decl.name.text === "run") {
3192
+ result = node;
3193
+ return;
3194
+ }
3195
+ }
3196
+ }
3197
+ });
3198
+ return result;
3199
+ }
3187
3200
  function findConfigExport(sourceFile) {
3188
3201
  let result = null;
3189
3202
  ts11.forEachChild(sourceFile, (node) => {
@@ -3226,6 +3239,7 @@ function getReturnObjectLiteral(fn) {
3226
3239
  }
3227
3240
  function extractConfigFields(objLit, sourceFile) {
3228
3241
  let systemPrompt;
3242
+ let systemPromptFile;
3229
3243
  let tools;
3230
3244
  let agents;
3231
3245
  let model;
@@ -3249,6 +3263,9 @@ function extractConfigFields(objLit, sourceFile) {
3249
3263
  case "systemPrompt":
3250
3264
  systemPrompt = requireStringValue(prop, "systemPrompt", sourceFile);
3251
3265
  break;
3266
+ case "systemPromptFile":
3267
+ systemPromptFile = requireStringValue(prop, "systemPromptFile", sourceFile);
3268
+ break;
3252
3269
  case "tools":
3253
3270
  tools = requireStringArrayValue(prop, "tools", sourceFile);
3254
3271
  break;
@@ -3268,20 +3285,28 @@ function extractConfigFields(objLit, sourceFile) {
3268
3285
  throw SchemaExtractionError.at(
3269
3286
  prop,
3270
3287
  `config.${propName}`,
3271
- "\u672A\u77E5 config \u5B57\u6BB5\u2014\u2014\u4EC5\u652F\u6301 systemPrompt / tools / agents / model / maxTurns / inputDescription",
3288
+ "\u672A\u77E5 config \u5B57\u6BB5\u2014\u2014\u4EC5\u652F\u6301 systemPrompt / systemPromptFile / tools / agents / model / maxTurns / inputDescription",
3272
3289
  sourceFile
3273
3290
  );
3274
3291
  }
3275
3292
  }
3276
- if (systemPrompt === void 0) {
3293
+ if (systemPrompt !== void 0 && systemPromptFile !== void 0) {
3294
+ throw SchemaExtractionError.at(
3295
+ objLit,
3296
+ "config.systemPrompt",
3297
+ "systemPrompt \u4E0E systemPromptFile \u4E92\u65A5\u2014\u2014\u5185\u8054\u7CFB\u7EDF\u63D0\u793A\u8BCD\u4E0E resources \u6587\u4EF6\u4E8C\u9009\u4E00",
3298
+ sourceFile
3299
+ );
3300
+ }
3301
+ if (systemPrompt === void 0 && systemPromptFile === void 0) {
3277
3302
  throw SchemaExtractionError.at(
3278
3303
  objLit,
3279
3304
  "config.systemPrompt",
3280
- "agent \u5FC5\u586B\u2014\u2014\u8BF7\u5728 config \u5757\u58F0\u660E\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF08\u5B57\u7B26\u4E32\u5B57\u9762\u91CF\u3001\u65E0\u63D2\u503C\u6A21\u677F\u5B57\u7B26\u4E32\u6216\u5176 + \u62FC\u63A5\uFF09",
3305
+ "agent \u5FC5\u586B\u2014\u2014\u8BF7\u5728 config \u5757\u58F0\u660E systemPrompt\uFF08\u5B57\u7B26\u4E32\u5B57\u9762\u91CF\u3001\u65E0\u63D2\u503C\u6A21\u677F\u5B57\u7B26\u4E32\u6216\u5176 + \u62FC\u63A5\uFF09\u6216 systemPromptFile\uFF08\u76F8\u5BF9 resources \u76EE\u5F55\u7684\u8DEF\u5F84\u5B57\u9762\u91CF\uFF09\u4E8C\u9009\u4E00",
3281
3306
  sourceFile
3282
3307
  );
3283
3308
  }
3284
- return { systemPrompt, tools, agents, model, maxTurns, inputDescription };
3309
+ return { systemPrompt, systemPromptFile, tools, agents, model, maxTurns, inputDescription };
3285
3310
  }
3286
3311
  function getPropertyName(name) {
3287
3312
  if (ts11.isIdentifier(name)) return name.text;
@@ -3364,13 +3389,13 @@ var init_extractAgentMetadata = __esm({
3364
3389
  });
3365
3390
 
3366
3391
  // src/cli/generateAgentArtifacts.ts
3367
- import path16 from "path";
3392
+ import path15 from "path";
3368
3393
  function serializeAgents(agents, dist = "dist") {
3369
3394
  return agents.map((a) => ({
3370
3395
  name: a.name,
3371
3396
  description: a.description,
3372
- hasRun: a.hasRun,
3373
3397
  systemPrompt: a.systemPrompt,
3398
+ systemPromptFile: a.systemPromptFile,
3374
3399
  tools: a.tools,
3375
3400
  agents: a.agents,
3376
3401
  model: a.model,
@@ -3390,8 +3415,8 @@ function hydrateAgents(manifest) {
3390
3415
  name: a.name,
3391
3416
  description: a.description ?? void 0,
3392
3417
  filePath: a.filePath,
3393
- hasRun: a.hasRun,
3394
3418
  systemPrompt: a.systemPrompt ?? void 0,
3419
+ systemPromptFile: a.systemPromptFile ?? void 0,
3395
3420
  tools: a.tools ?? void 0,
3396
3421
  agents: a.agents ?? void 0,
3397
3422
  model: a.model ?? void 0,
@@ -3423,14 +3448,13 @@ function validateAgentList(metadata) {
3423
3448
  }
3424
3449
  async function generateAgentArtifacts(agents, rootDir, dist) {
3425
3450
  const metadata = [];
3426
- const programByFile = createPrograms(agents.map((m) => path16.resolve(rootDir, m.filePath)));
3451
+ const programByFile = createPrograms(agents.map((m) => path15.resolve(rootDir, m.filePath)));
3427
3452
  for (const manifest of agents) {
3428
- const absPath = path16.resolve(rootDir, manifest.filePath);
3453
+ const absPath = path15.resolve(rootDir, manifest.filePath);
3429
3454
  const program = programByFile.get(absPath);
3430
3455
  const result = extractAgentMetadata(program, absPath, {
3431
3456
  name: manifest.name,
3432
- filePath: manifest.filePath,
3433
- hasRun: manifest.hasRun
3457
+ filePath: manifest.filePath
3434
3458
  });
3435
3459
  if (!result) {
3436
3460
  throw new Error(
@@ -3441,7 +3465,7 @@ async function generateAgentArtifacts(agents, rootDir, dist) {
3441
3465
  }
3442
3466
  validateAgentList(metadata);
3443
3467
  const serialized = serializeAgents(metadata, dist);
3444
- const agentsPath = path16.resolve(rootDir, dist, AGENTS_FILE);
3468
+ const agentsPath = path15.resolve(rootDir, dist, AGENTS_FILE);
3445
3469
  await writeAgentsModule(serialized, agentsPath);
3446
3470
  return metadata;
3447
3471
  }
@@ -3459,8 +3483,8 @@ var init_generateAgentArtifacts = __esm({
3459
3483
 
3460
3484
  // src/task/scanTasks.ts
3461
3485
  import fg4 from "fast-glob";
3462
- import path17 from "path";
3463
- import fs13 from "fs";
3486
+ import path16 from "path";
3487
+ import fs12 from "fs";
3464
3488
  function parseNumericLiteral(raw) {
3465
3489
  return Number(raw.replace(/_/g, ""));
3466
3490
  }
@@ -3482,12 +3506,12 @@ async function scanTasks(rootDir, patterns) {
3482
3506
  const seen = /* @__PURE__ */ new Map();
3483
3507
  for (const file of files) {
3484
3508
  const normalizedFile = file.replace(/\\/g, "/");
3485
- const fileName = path17.posix.basename(normalizedFile);
3509
+ const fileName = path16.posix.basename(normalizedFile);
3486
3510
  if (fileName !== TASK_FILENAME) {
3487
3511
  continue;
3488
3512
  }
3489
- const absPath = path17.resolve(rootDir, normalizedFile);
3490
- const source = await fs13.promises.readFile(absPath, "utf8").catch(() => "");
3513
+ const absPath = path16.resolve(rootDir, normalizedFile);
3514
+ const source = await fs12.promises.readFile(absPath, "utf8").catch(() => "");
3491
3515
  const name = filePathToTaskName(normalizedFile);
3492
3516
  const prevFile = seen.get(name);
3493
3517
  if (prevFile) {
@@ -3536,7 +3560,7 @@ var init_scanTasks = __esm({
3536
3560
  });
3537
3561
 
3538
3562
  // src/cli/generateTaskArtifacts.ts
3539
- import path18 from "path";
3563
+ import path17 from "path";
3540
3564
  function serializeTasks(tasks, dist = "dist") {
3541
3565
  return tasks.map((t) => ({
3542
3566
  name: t.name,
@@ -3569,7 +3593,7 @@ function collectTaskSchemaSources(tasks, rootDir) {
3569
3593
  const tasksByFile = /* @__PURE__ */ new Map();
3570
3594
  for (const task of tasks) {
3571
3595
  if (!task.inputTypeName) continue;
3572
- const absPath = path18.resolve(rootDir, task.filePath);
3596
+ const absPath = path17.resolve(rootDir, task.filePath);
3573
3597
  let list = tasksByFile.get(absPath);
3574
3598
  if (!list) {
3575
3599
  list = [];
@@ -3626,9 +3650,9 @@ function generateTaskSchemaFileSource(sources, resolveType, helpersImportPath) {
3626
3650
  async function generateTaskArtifacts(manifests, rootDir, dist) {
3627
3651
  const metadata = [];
3628
3652
  if (manifests.length > 0) {
3629
- const programByFile = createPrograms(manifests.map((m) => path18.resolve(rootDir, m.filePath)));
3653
+ const programByFile = createPrograms(manifests.map((m) => path17.resolve(rootDir, m.filePath)));
3630
3654
  for (const manifest of manifests) {
3631
- const absPath = path18.resolve(rootDir, manifest.filePath);
3655
+ const absPath = path17.resolve(rootDir, manifest.filePath);
3632
3656
  const result = extractToolMetadata(programByFile.get(absPath), absPath, "run", {
3633
3657
  name: manifest.name,
3634
3658
  filePath: manifest.filePath
@@ -3639,7 +3663,7 @@ async function generateTaskArtifacts(manifests, rootDir, dist) {
3639
3663
  }
3640
3664
  }
3641
3665
  const serialized = serializeTasks(manifests, dist);
3642
- const tasksPath = path18.resolve(rootDir, dist, TASKS_FILE);
3666
+ const tasksPath = path17.resolve(rootDir, dist, TASKS_FILE);
3643
3667
  await writeTasksModule(serialized, tasksPath);
3644
3668
  if (metadata.length === 0) {
3645
3669
  return hydrateTasks(serialized);
@@ -3672,8 +3696,8 @@ var init_generateTaskArtifacts = __esm({
3672
3696
  });
3673
3697
 
3674
3698
  // src/cli/compileSourceFiles.ts
3675
- import path19 from "path";
3676
- import fs14 from "fs";
3699
+ import path18 from "path";
3700
+ import fs13 from "fs";
3677
3701
  import fg5 from "fast-glob";
3678
3702
  async function compileSourceFiles(options) {
3679
3703
  const { rootDir, dist, files, logLevel = "silent", production, atomicWrite } = options;
@@ -3681,16 +3705,16 @@ async function compileSourceFiles(options) {
3681
3705
  cwd: rootDir,
3682
3706
  onlyFiles: true,
3683
3707
  absolute: true,
3684
- ignore: ["**/*.test.ts", "**/*.e2e.test.ts", "**/*.d.ts"]
3708
+ ignore: SOURCE_IGNORE
3685
3709
  });
3686
3710
  if (entryPoints.length === 0) {
3687
3711
  return { compiledFiles: [] };
3688
3712
  }
3689
- const absDist = path19.resolve(rootDir, dist);
3690
- await fs14.promises.mkdir(absDist, { recursive: true });
3713
+ const absDist = path18.resolve(rootDir, dist);
3714
+ await fs13.promises.mkdir(absDist, { recursive: true });
3691
3715
  const plugins = buildAliasPlugins(rootDir);
3692
3716
  const esbuild = await import("esbuild");
3693
- const outbase = path19.resolve(rootDir, APP_DIR);
3717
+ const outbase = path18.resolve(rootDir, APP_DIR);
3694
3718
  const result = await esbuild.build({
3695
3719
  entryPoints,
3696
3720
  outdir: absDist,
@@ -3710,20 +3734,22 @@ async function compileSourceFiles(options) {
3710
3734
  if (atomicWrite && result.outputFiles) {
3711
3735
  await Promise.all(
3712
3736
  result.outputFiles.map(async (file) => {
3713
- await fs14.promises.mkdir(path19.dirname(file.path), { recursive: true });
3737
+ await fs13.promises.mkdir(path18.dirname(file.path), { recursive: true });
3714
3738
  const tmp = `${file.path}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;
3715
- await fs14.promises.writeFile(tmp, file.contents);
3716
- await fs14.promises.rename(tmp, file.path);
3739
+ await fs13.promises.writeFile(tmp, file.contents);
3740
+ await fs13.promises.rename(tmp, file.path);
3717
3741
  })
3718
3742
  );
3719
3743
  }
3720
3744
  return { compiledFiles: entryPoints };
3721
3745
  }
3746
+ var SOURCE_IGNORE;
3722
3747
  var init_compileSourceFiles = __esm({
3723
3748
  "src/cli/compileSourceFiles.ts"() {
3724
3749
  "use strict";
3725
3750
  init_aliasPlugin();
3726
3751
  init_prodPaths();
3752
+ SOURCE_IGNORE = ["**/*.test.ts", "**/*.e2e.test.ts", "**/*.d.ts", `${APP_DIR}/resources/**`];
3727
3753
  }
3728
3754
  });
3729
3755
 
@@ -3739,12 +3765,12 @@ var init_compileDevRoutes = __esm({
3739
3765
  });
3740
3766
 
3741
3767
  // src/cli/compileOnDemand.ts
3742
- import path20 from "path";
3743
- import fs15 from "fs";
3768
+ import path19 from "path";
3769
+ import fs14 from "fs";
3744
3770
  function isProductFresh(sourceAbsPath, productAbsPath) {
3745
3771
  try {
3746
- const srcStat = fs15.statSync(sourceAbsPath);
3747
- const prodStat = fs15.statSync(productAbsPath);
3772
+ const srcStat = fs14.statSync(sourceAbsPath);
3773
+ const prodStat = fs14.statSync(productAbsPath);
3748
3774
  return prodStat.mtimeMs >= srcStat.mtimeMs;
3749
3775
  } catch {
3750
3776
  return false;
@@ -3774,7 +3800,7 @@ async function ensureCompiled(sourceAbsPath, rootDir, dist) {
3774
3800
  if (state.compiledFiles.has(sourceAbsPath)) {
3775
3801
  return false;
3776
3802
  }
3777
- if (!fs15.existsSync(sourceAbsPath)) {
3803
+ if (!fs14.existsSync(sourceAbsPath)) {
3778
3804
  return false;
3779
3805
  }
3780
3806
  const productPath = prodSourcePathToProductPath(sourceAbsPath, rootDir, dist);
@@ -3824,11 +3850,11 @@ async function ensureMiddlewaresCompiled(middlewarePaths, rootDir) {
3824
3850
  }
3825
3851
  }
3826
3852
  function prodSourcePathToProductPath(sourceAbsPath, rootDir, dist) {
3827
- const rel = path20.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
3853
+ const rel = path19.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
3828
3854
  if (!rel.startsWith("src/")) return null;
3829
3855
  const relWithoutSrc = rel.slice(4);
3830
3856
  const jsRel = relWithoutSrc.replace(/\.ts$/, ".js");
3831
- return path20.resolve(rootDir, dist, jsRel);
3857
+ return path19.resolve(rootDir, dist, jsRel);
3832
3858
  }
3833
3859
  function clearGeneratedSchemas() {
3834
3860
  state.generatedSchemas.clear();
@@ -3843,9 +3869,9 @@ async function ensureSchemaGenerated(schemaPath, routeFilePath, routes, rootDir,
3843
3869
  if (state.generatedSchemas.has(schemaPath)) {
3844
3870
  return false;
3845
3871
  }
3846
- const prodAbsPath = path20.resolve(rootDir, routeFilePath);
3872
+ const prodAbsPath = path19.resolve(rootDir, routeFilePath);
3847
3873
  const sourceAbsPath = prodPathToSourcePath(prodAbsPath, rootDir, dist);
3848
- if (!fs15.existsSync(sourceAbsPath)) {
3874
+ if (!fs14.existsSync(sourceAbsPath)) {
3849
3875
  return false;
3850
3876
  }
3851
3877
  if (isProductFresh(sourceAbsPath, schemaPath)) {
@@ -3857,7 +3883,7 @@ async function ensureSchemaGenerated(schemaPath, routeFilePath, routes, rootDir,
3857
3883
  if (fileRoutes.length === 0 && fileWsRoutes.length === 0) {
3858
3884
  return false;
3859
3885
  }
3860
- const sourceRelPath = path20.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
3886
+ const sourceRelPath = path19.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
3861
3887
  const sourceRoutes = fileRoutes.map((r) => ({ ...r, filePath: sourceRelPath }));
3862
3888
  const sourceWsRoutes = fileWsRoutes.map((r) => ({ ...r, filePath: sourceRelPath }));
3863
3889
  const generatePromise = (async () => {
@@ -3879,7 +3905,7 @@ async function deleteSchemaFiles(routes, rootDir, dist) {
3879
3905
  if (deleted.has(schemaPath)) continue;
3880
3906
  deleted.add(schemaPath);
3881
3907
  try {
3882
- await fs15.promises.unlink(schemaPath);
3908
+ await fs14.promises.unlink(schemaPath);
3883
3909
  } catch {
3884
3910
  }
3885
3911
  }
@@ -3887,19 +3913,19 @@ async function deleteSchemaFiles(routes, rootDir, dist) {
3887
3913
  function prodPathToSourcePath(prodAbsPath, rootDir, dist) {
3888
3914
  const cached = sourcePathCache.get(prodAbsPath);
3889
3915
  if (cached) return cached;
3890
- const rel = path20.relative(rootDir, prodAbsPath).replace(/\\/g, "/");
3916
+ const rel = path19.relative(rootDir, prodAbsPath).replace(/\\/g, "/");
3891
3917
  let relWithoutDist = rel;
3892
3918
  if (relWithoutDist.startsWith(`${dist}/`)) {
3893
3919
  relWithoutDist = relWithoutDist.slice(dist.length + 1);
3894
3920
  }
3895
3921
  const srcRel = `src/${relWithoutDist}`;
3896
3922
  const tsRel = srcRel.replace(/\.js$/, ".ts");
3897
- const tsAbs = path20.resolve(rootDir, tsRel);
3923
+ const tsAbs = path19.resolve(rootDir, tsRel);
3898
3924
  let result;
3899
- if (fs15.existsSync(tsAbs)) {
3925
+ if (fs14.existsSync(tsAbs)) {
3900
3926
  result = tsAbs;
3901
3927
  } else {
3902
- result = path20.resolve(rootDir, srcRel);
3928
+ result = path19.resolve(rootDir, srcRel);
3903
3929
  }
3904
3930
  sourcePathCache.set(prodAbsPath, result);
3905
3931
  return result;
@@ -3930,15 +3956,15 @@ var init_compileOnDemand = __esm({
3930
3956
  });
3931
3957
 
3932
3958
  // src/config/loadConfig.ts
3933
- import path21 from "path";
3934
- import fs16 from "fs";
3959
+ import path20 from "path";
3960
+ import fs15 from "fs";
3935
3961
  async function loadConfig(rootDir, dist) {
3936
- const configProductPath = path21.resolve(rootDir, dist, CONFIG_PRODUCT_FILE);
3937
- if (fs16.existsSync(configProductPath)) {
3962
+ const configProductPath = path20.resolve(rootDir, dist, CONFIG_PRODUCT_FILE);
3963
+ if (fs15.existsSync(configProductPath)) {
3938
3964
  const module = await importWithCacheBust(configProductPath);
3939
3965
  return module.default ?? {};
3940
3966
  }
3941
- const hasSourceConfig = fs16.existsSync(path21.join(rootDir, "faapi.config.ts")) || fs16.existsSync(path21.join(rootDir, "faapi.config.js"));
3967
+ const hasSourceConfig = fs15.existsSync(path20.join(rootDir, "faapi.config.ts")) || fs15.existsSync(path20.join(rootDir, "faapi.config.js"));
3942
3968
  if (hasSourceConfig) {
3943
3969
  throw new Error(
3944
3970
  `[faapi] ${dist}/${CONFIG_PRODUCT_FILE} \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6267\u884C \`faapi build\`\uFF08\u6216 \`faapi dev\`\uFF09\u751F\u6210\u4EA7\u7269\u3002`
@@ -3956,8 +3982,8 @@ var init_loadConfig = __esm({
3956
3982
  });
3957
3983
 
3958
3984
  // src/cli/loadEnv.ts
3959
- import fs17 from "fs";
3960
- import path22 from "path";
3985
+ import fs16 from "fs";
3986
+ import path21 from "path";
3961
3987
  function resolveEnv() {
3962
3988
  return process.env.NODE_ENV || "development";
3963
3989
  }
@@ -4024,9 +4050,9 @@ function loadEnv(rootDir) {
4024
4050
  const files = getEnvFiles(env);
4025
4051
  const merged = {};
4026
4052
  for (const file of files) {
4027
- const filePath = path22.join(rootDir, file);
4028
- if (!fs17.existsSync(filePath)) continue;
4029
- const content = fs17.readFileSync(filePath, "utf-8");
4053
+ const filePath = path21.join(rootDir, file);
4054
+ if (!fs16.existsSync(filePath)) continue;
4055
+ const content = fs16.readFileSync(filePath, "utf-8");
4030
4056
  const parsed = parseEnvFile(content, merged);
4031
4057
  Object.assign(merged, parsed);
4032
4058
  }
@@ -5816,6 +5842,53 @@ var init_rebuildScheduler = __esm({
5816
5842
  }
5817
5843
  });
5818
5844
 
5845
+ // src/cli/copyResources.ts
5846
+ import path22 from "path";
5847
+ import fs17 from "fs";
5848
+ function isResourceSourcePath(rootDir, absPath) {
5849
+ return isInsideDir(absPath, path22.resolve(rootDir, RESOURCES_DIR));
5850
+ }
5851
+ function resolveResourcesDir(rootDir, dist) {
5852
+ return path22.resolve(rootDir, dist, RESOURCES_OUTPUT_DIR);
5853
+ }
5854
+ async function copyResources(rootDir, dist) {
5855
+ const sourceDir = path22.resolve(rootDir, RESOURCES_DIR);
5856
+ if (!fs17.existsSync(sourceDir)) return false;
5857
+ const outDir = resolveResourcesDir(rootDir, dist);
5858
+ await fs17.promises.rm(outDir, { recursive: true, force: true });
5859
+ await fs17.promises.cp(sourceDir, outDir, { recursive: true });
5860
+ return true;
5861
+ }
5862
+ async function copyResourceFile(rootDir, dist, absSourceFile) {
5863
+ const sourceDir = path22.resolve(rootDir, RESOURCES_DIR);
5864
+ if (!isInsideDir(absSourceFile, sourceDir)) {
5865
+ throw new Error(`[faapi] copyResourceFile: ${absSourceFile} is not under ${RESOURCES_DIR}`);
5866
+ }
5867
+ if (!fs17.existsSync(absSourceFile)) return;
5868
+ const rel = path22.relative(sourceDir, absSourceFile);
5869
+ const dest = path22.join(resolveResourcesDir(rootDir, dist), rel);
5870
+ await fs17.promises.mkdir(path22.dirname(dest), { recursive: true });
5871
+ await fs17.promises.cp(absSourceFile, dest);
5872
+ }
5873
+ async function removeResourceFile(rootDir, dist, absSourceFile) {
5874
+ const sourceDir = path22.resolve(rootDir, RESOURCES_DIR);
5875
+ if (!isInsideDir(absSourceFile, sourceDir)) {
5876
+ throw new Error(`[faapi] removeResourceFile: ${absSourceFile} is not under ${RESOURCES_DIR}`);
5877
+ }
5878
+ const rel = path22.relative(sourceDir, absSourceFile);
5879
+ const dest = path22.join(resolveResourcesDir(rootDir, dist), rel);
5880
+ await fs17.promises.rm(dest, { force: true });
5881
+ }
5882
+ var RESOURCES_DIR, RESOURCES_OUTPUT_DIR;
5883
+ var init_copyResources = __esm({
5884
+ "src/cli/copyResources.ts"() {
5885
+ "use strict";
5886
+ init_prodPaths();
5887
+ RESOURCES_DIR = "src/resources";
5888
+ RESOURCES_OUTPUT_DIR = "resources";
5889
+ }
5890
+ });
5891
+
5819
5892
  // src/cli/watcher.ts
5820
5893
  import path23 from "path";
5821
5894
  import { existsSync as existsSync2 } from "fs";
@@ -5865,6 +5938,7 @@ function startWatcher(options) {
5865
5938
  }
5866
5939
  if (!stats) return false;
5867
5940
  if (stats.isDirectory()) return false;
5941
+ if (isResourceSourcePath(rootDir, path23.resolve(rootDir, filePath))) return false;
5868
5942
  return !filePath.endsWith(".ts") && !filePath.endsWith(".js");
5869
5943
  }
5870
5944
  });
@@ -5872,6 +5946,15 @@ function startWatcher(options) {
5872
5946
  watcher.on("change", (file) => handleFileEvent(file));
5873
5947
  function handleFileEvent(file) {
5874
5948
  const abs = path23.resolve(rootDir, file);
5949
+ if (isResourceSourcePath(rootDir, abs)) {
5950
+ void copyResourceFile(rootDir, devDist, abs).catch((err) => {
5951
+ console.error(
5952
+ "- Error copying resource:",
5953
+ err instanceof Error ? err.message : String(err)
5954
+ );
5955
+ });
5956
+ return;
5957
+ }
5875
5958
  if (scheduleOnly.has(abs)) {
5876
5959
  scheduler.schedule();
5877
5960
  return;
@@ -5882,7 +5965,17 @@ function startWatcher(options) {
5882
5965
  scheduler.addFiles([abs]);
5883
5966
  }
5884
5967
  watcher.on("unlink", (file) => {
5885
- scheduler.removeFiles([path23.resolve(rootDir, file)]);
5968
+ const abs = path23.resolve(rootDir, file);
5969
+ if (isResourceSourcePath(rootDir, abs)) {
5970
+ void removeResourceFile(rootDir, devDist, abs).catch((err) => {
5971
+ console.error(
5972
+ "- Error removing resource:",
5973
+ err instanceof Error ? err.message : String(err)
5974
+ );
5975
+ });
5976
+ return;
5977
+ }
5978
+ scheduler.removeFiles([abs]);
5886
5979
  scheduler.schedule();
5887
5980
  });
5888
5981
  watcher.on("error", (err) => {
@@ -5903,6 +5996,7 @@ var init_watcher = __esm({
5903
5996
  init_compileDevRoutes();
5904
5997
  init_compileConfig();
5905
5998
  init_rebuildScheduler();
5999
+ init_copyResources();
5906
6000
  }
5907
6001
  });
5908
6002
 
@@ -6962,10 +7056,18 @@ function formatSetCookie(name, value, options) {
6962
7056
  if (options?.sameSite) cookie += `; SameSite=${options.sameSite}`;
6963
7057
  return cookie;
6964
7058
  }
6965
- function createContext(request, params, config = {}, ip = "", registries) {
6966
- return createContextFromUrl(request, new URL(request.url), params, config, ip, registries);
7059
+ function createContext(request, params, config = {}, ip = "", registries, resourcesDir) {
7060
+ return createContextFromUrl(
7061
+ request,
7062
+ new URL(request.url),
7063
+ params,
7064
+ config,
7065
+ ip,
7066
+ registries,
7067
+ resourcesDir
7068
+ );
6967
7069
  }
6968
- function createContextFromUrl(request, url, params, config = {}, ip = "", registries) {
7070
+ function createContextFromUrl(request, url, params, config = {}, ip = "", registries, resourcesDir) {
6969
7071
  const meta = { headers: {}, setCookies: [] };
6970
7072
  const parsedCookies = parseCookies(request.headers.get("cookie") ?? "");
6971
7073
  const cookiesObj = {};
@@ -6993,6 +7095,9 @@ function createContextFromUrl(request, url, params, config = {}, ip = "", regist
6993
7095
  ua: request.headers.get("user-agent") ?? "",
6994
7096
  cookies: cookiesObj,
6995
7097
  config,
7098
+ // 运行时资源根目录(HTTP/WS 链路由 createServer/handleWsUpgrade 传入;
7099
+ // testing 直调未传时为 undefined,见 contextTypes.resourcesDir 注释)
7100
+ resourcesDir,
6996
7101
  meta,
6997
7102
  setStatus(status) {
6998
7103
  meta.status = status;
@@ -8528,6 +8633,7 @@ function attachWebSocket(options) {
8528
8633
  trustedProxy = false,
8529
8634
  registries
8530
8635
  } = options;
8636
+ const resourcesDir = resolveResourcesDir(rootDir, dist);
8531
8637
  const wss = new WebSocketServer({ noServer: true });
8532
8638
  server.on("upgrade", async (req, socket, head) => {
8533
8639
  try {
@@ -8559,7 +8665,14 @@ function attachWebSocket(options) {
8559
8665
  const host = req.headers.host ?? "localhost";
8560
8666
  const fullUrl = new URL(`http://${host}${req.url ?? "/"}`);
8561
8667
  const request = new Request(fullUrl.toString(), { method: "GET", headers });
8562
- const ctx = createContext(request, params, config, getClientIp(req, trustedProxy), registries);
8668
+ const ctx = createContext(
8669
+ request,
8670
+ params,
8671
+ config,
8672
+ getClientIp(req, trustedProxy),
8673
+ registries,
8674
+ resourcesDir
8675
+ );
8563
8676
  const meta = ctx.meta;
8564
8677
  let upgraded = false;
8565
8678
  const finalHandler = async () => {
@@ -8661,6 +8774,7 @@ var init_handleWsUpgrade = __esm({
8661
8774
  "use strict";
8662
8775
  init_matchRoute();
8663
8776
  init_createContext();
8777
+ init_copyResources();
8664
8778
  init_invokeHandler();
8665
8779
  init_importWithCacheBust();
8666
8780
  init_getClientIp();
@@ -8787,6 +8901,7 @@ function createServer(options) {
8787
8901
  trustedProxy = false
8788
8902
  } = options;
8789
8903
  const routesRef = { current: routes, wsCurrent: wsRoutes ?? [] };
8904
+ const resourcesDir = resolveResourcesDir(rootDir, dist);
8790
8905
  const configMiddlewares = [];
8791
8906
  if (compressionOption) {
8792
8907
  const compOpts = typeof compressionOption === "object" ? compressionOption : {};
@@ -8833,7 +8948,8 @@ function createServer(options) {
8833
8948
  bodyLimit,
8834
8949
  trustedProxy,
8835
8950
  registries,
8836
- routesRef.wsCurrent
8951
+ routesRef.wsCurrent,
8952
+ resourcesDir
8837
8953
  ).catch((err) => {
8838
8954
  console.error("[faapi] Request pipeline failed after error response attempt:", err);
8839
8955
  try {
@@ -8859,7 +8975,7 @@ function createServer(options) {
8859
8975
  });
8860
8976
  return { server, routesRef };
8861
8977
  }
8862
- function prepareRequest(req, request, url, config, trustedProxy, registries, preMatched) {
8978
+ function prepareRequest(req, request, url, config, trustedProxy, registries, preMatched, resourcesDir) {
8863
8979
  const method = request.method.toUpperCase();
8864
8980
  const urlPath = url.pathname;
8865
8981
  const ctx = createContextFromUrl(
@@ -8868,7 +8984,8 @@ function prepareRequest(req, request, url, config, trustedProxy, registries, pre
8868
8984
  preMatched?.params ?? {},
8869
8985
  config,
8870
8986
  getClientIp(req, trustedProxy),
8871
- registries
8987
+ registries,
8988
+ resourcesDir
8872
8989
  );
8873
8990
  const meta = ctx.meta;
8874
8991
  return { request, url, ctx, meta, method, urlPath };
@@ -9008,7 +9125,7 @@ async function sendErrorResponse(err, meta, res, onError, ctx) {
9008
9125
  }
9009
9126
  }
9010
9127
  }
9011
- async function handleRequest(routes, rootDir, dist, req, res, outerMiddlewares, onError, config, globalInjectors, bodyLimit, trustedProxy, registries, wsRoutes) {
9128
+ async function handleRequest(routes, rootDir, dist, req, res, outerMiddlewares, onError, config, globalInjectors, bodyLimit, trustedProxy, registries, wsRoutes, resourcesDir) {
9012
9129
  let meta = { headers: {}, setCookies: [] };
9013
9130
  let ctx;
9014
9131
  let sseEarlySent = false;
@@ -9028,7 +9145,8 @@ async function handleRequest(routes, rootDir, dist, req, res, outerMiddlewares,
9028
9145
  config,
9029
9146
  trustedProxy,
9030
9147
  registries,
9031
- preMatched
9148
+ preMatched,
9149
+ resourcesDir
9032
9150
  );
9033
9151
  ctx = prepared.ctx;
9034
9152
  meta = prepared.meta;
@@ -9097,6 +9215,7 @@ var init_createServer = __esm({
9097
9215
  init_handleWsUpgrade();
9098
9216
  init_serverUtils();
9099
9217
  init_generateSchemaFiles();
9218
+ init_copyResources();
9100
9219
  init_compileOnDemand();
9101
9220
  init_loadMiddlewares();
9102
9221
  DEFAULT_BODY_LIMIT = 10 * 1024 * 1024;
@@ -9317,7 +9436,11 @@ async function runTaskInWorker(options) {
9317
9436
  worker.postMessage({
9318
9437
  type: "run",
9319
9438
  payload,
9320
- taskCtx: { config: safeConfig(taskCtx.config), job: taskCtx.job },
9439
+ taskCtx: {
9440
+ config: safeConfig(taskCtx.config),
9441
+ resourcesDir: taskCtx.resourcesDir,
9442
+ job: taskCtx.job
9443
+ },
9321
9444
  registries: options.registries,
9322
9445
  log: options.log
9323
9446
  });
@@ -9541,6 +9664,7 @@ function createTaskQueue(deps) {
9541
9664
  payload: job.payload,
9542
9665
  taskCtx: {
9543
9666
  config: deps.config,
9667
+ resourcesDir: deps.resourcesDir,
9544
9668
  job: { id: job.id, name: job.name, attempt: job.attempt }
9545
9669
  },
9546
9670
  registries: snapshotRegistries(),
@@ -9571,6 +9695,7 @@ function createTaskQueue(deps) {
9571
9695
  const taskCtx = {
9572
9696
  signal: job.signal,
9573
9697
  config: deps.config,
9698
+ resourcesDir: deps.resourcesDir,
9574
9699
  job: { id: job.id, name: job.name, attempt: job.attempt },
9575
9700
  registries: registriesView,
9576
9701
  log: createLogger(`task:${job.name}`, {
@@ -10204,8 +10329,7 @@ function logStartupSummary(routes, wsRoutes, tools, agents, taskMetas, p) {
10204
10329
  if (agents.length > 0) {
10205
10330
  console.log(`- Loaded ${agents.length} agent(s):`);
10206
10331
  for (const agent of agents) {
10207
- const exports = agent.hasRun ? "run" : "-";
10208
- console.log(` ${agent.name} [${exports}] ${agent.filePath}`);
10332
+ console.log(` ${agent.name} ${agent.filePath}`);
10209
10333
  }
10210
10334
  }
10211
10335
  if (taskMetas.length > 0) {
@@ -10219,6 +10343,7 @@ function logStartupSummary(routes, wsRoutes, tools, agents, taskMetas, p) {
10219
10343
  async function createAppBase(options) {
10220
10344
  const rootDir = options?.rootDir ?? process.cwd();
10221
10345
  const dist = options?.dist ?? process.env.FAAPI_DIST ?? DEFAULT_DIST;
10346
+ const resourcesDir = resolveResourcesDir(rootDir, dist);
10222
10347
  const routesPath = path30.resolve(rootDir, dist, ROUTES_FILE);
10223
10348
  if (!fs22.existsSync(routesPath)) {
10224
10349
  throw new Error(
@@ -10241,6 +10366,7 @@ async function createAppBase(options) {
10241
10366
  registry: registries.task,
10242
10367
  rootDir,
10243
10368
  config,
10369
+ resourcesDir,
10244
10370
  registries: createTaskRegistriesView(registries),
10245
10371
  driver: taskDriver,
10246
10372
  onFailed: config?.task?.onFailed
@@ -10282,6 +10408,7 @@ async function createAppBase(options) {
10282
10408
  config?.plugins,
10283
10409
  {
10284
10410
  rootDir,
10411
+ resourcesDir,
10285
10412
  registries,
10286
10413
  routes: sorted,
10287
10414
  getRoutes: () => sorted,
@@ -10299,6 +10426,8 @@ async function createAppBase(options) {
10299
10426
  routes: sorted,
10300
10427
  wsRoutes,
10301
10428
  rootDir,
10429
+ dist,
10430
+ resourcesDir,
10302
10431
  tasks: taskQueue,
10303
10432
  async listen(listenPort) {
10304
10433
  const envPort = process.env.PORT ? Number(process.env.PORT) : void 0;
@@ -10310,7 +10439,8 @@ async function createAppBase(options) {
10310
10439
  routes: sorted,
10311
10440
  server,
10312
10441
  registries,
10313
- tasks: taskQueue
10442
+ tasks: taskQueue,
10443
+ resourcesDir
10314
10444
  });
10315
10445
  console.log("- onBoot hook executed");
10316
10446
  } catch (err) {
@@ -10345,7 +10475,8 @@ async function createAppBase(options) {
10345
10475
  routes: sorted,
10346
10476
  server,
10347
10477
  registries,
10348
- tasks: taskQueue
10478
+ tasks: taskQueue,
10479
+ resourcesDir
10349
10480
  });
10350
10481
  console.log("- onReady hook executed");
10351
10482
  }
@@ -10369,7 +10500,8 @@ async function createAppBase(options) {
10369
10500
  routes: sorted,
10370
10501
  server,
10371
10502
  registries,
10372
- tasks: taskQueue
10503
+ tasks: taskQueue,
10504
+ resourcesDir
10373
10505
  });
10374
10506
  }
10375
10507
  registries.tool.clear();
@@ -10451,6 +10583,7 @@ var init_createAppCore = __esm({
10451
10583
  init_manifestLoader();
10452
10584
  init_appSingleton();
10453
10585
  init_injectMock();
10586
+ init_copyResources();
10454
10587
  init_manifestLoader();
10455
10588
  DEFAULT_DIST = "dist";
10456
10589
  DEFAULT_PORT = 3e3;
@@ -10604,6 +10737,10 @@ async function devCommand(options) {
10604
10737
  await generateAgentArtifactsForDev(rootDir, devDist);
10605
10738
  console.log("- Generating task artifacts...");
10606
10739
  await generateTaskArtifactsForDev(rootDir, devDist);
10740
+ console.log("- Copying resources...");
10741
+ const copied = await copyResources(rootDir, devDist);
10742
+ if (copied)
10743
+ console.log(` Copied src/resources \u2192 ${path32.resolve(rootDir, devDist, "resources")}`);
10607
10744
  console.log("- Starting dev app...");
10608
10745
  const app = await createDevApp({ rootDir, port: options?.port });
10609
10746
  await app.listen();
@@ -10653,6 +10790,7 @@ var init_devCommand = __esm({
10653
10790
  init_watcher();
10654
10791
  init_createDevApp();
10655
10792
  init_compileOnDemand();
10793
+ init_copyResources();
10656
10794
  init_prodPaths();
10657
10795
  DEV_DIST = ".faapi";
10658
10796
  ROUTES_FILE2 = "faapi-routes.js";
@@ -10707,7 +10845,7 @@ async function buildCommand(options) {
10707
10845
  console.log(`- Root: ${rootDir}`);
10708
10846
  console.log(`- Source: src/`);
10709
10847
  console.log(`- Output: ${outdir}`);
10710
- console.log("\n[1/8] Compiling TypeScript (bundle: false)...");
10848
+ console.log("\n[1/9] Compiling TypeScript (bundle: false)...");
10711
10849
  const result = await compileBuildRoutes({
10712
10850
  rootDir,
10713
10851
  dist: outdir,
@@ -10720,7 +10858,7 @@ async function buildCommand(options) {
10720
10858
  }
10721
10859
  const localPluginSources = extractLocalPluginSources(_config?.plugins, rootDir);
10722
10860
  if (localPluginSources.length > 0) {
10723
- console.log("\n[2.5/8] Compiling local plugins...");
10861
+ console.log("\n[2.5/9] Compiling local plugins...");
10724
10862
  const outside = localPluginSources.filter((p) => {
10725
10863
  const rel = path33.relative(rootDir, p).replace(/\\/g, "/");
10726
10864
  return !rel.startsWith("src/");
@@ -10730,35 +10868,40 @@ async function buildCommand(options) {
10730
10868
  }
10731
10869
  console.log(` Compiled ${localPluginSources.length} local plugin(s)`);
10732
10870
  }
10733
- console.log("\n[3/8] Scanning routes...");
10871
+ console.log("\n[3/9] Scanning routes...");
10734
10872
  const { routes, wsRoutes } = await scanRoutes(rootDir, ROUTE_PATTERNS, outdir);
10735
10873
  const sorted = sortRoutes(routes);
10736
10874
  console.log(` Found ${sorted.length} routes, ${wsRoutes.length} WS routes`);
10737
10875
  reportRouteConflicts(sorted);
10738
- console.log("\n[4/8] Generating schema...");
10876
+ console.log("\n[4/9] Generating schema...");
10739
10877
  await generateSchemaFiles(sorted, rootDir, outdir, wsRoutes);
10740
10878
  console.log(` Schema: zod.js files under ${path33.resolve(rootDir, outdir)}`);
10741
- console.log("\n[5/8] Generating routes manifest...");
10879
+ console.log("\n[5/9] Generating routes manifest...");
10742
10880
  const routesPath = path33.resolve(rootDir, outdir, "faapi-routes.js");
10743
10881
  const serialized = serializeRoutes(sorted, wsRoutes, rootDir, outdir);
10744
10882
  await writeRoutesModule(serialized, routesPath);
10745
10883
  console.log(` Written to ${routesPath}`);
10746
- console.log("\n[6/8] Generating tool manifest and schema...");
10884
+ console.log("\n[6/9] Generating tool manifest and schema...");
10747
10885
  const tools = await scanTools(rootDir, TOOL_PATTERNS);
10748
10886
  const toolMeta = await generateToolArtifacts(tools, rootDir, outdir);
10749
10887
  console.log(` Found ${toolMeta.length} tool(s)`);
10750
10888
  console.log(` Tool manifest: ${path33.resolve(rootDir, outdir, "faapi-tools.js")}`);
10751
- console.log("\n[7/8] Generating agent manifest...");
10889
+ console.log("\n[7/9] Generating agent manifest...");
10752
10890
  const agents = await scanAgents(rootDir, DEFAULT_AGENT_PATTERNS);
10753
10891
  const agentMeta = await generateAgentArtifacts(agents, rootDir, outdir);
10754
10892
  console.log(` Found ${agentMeta.length} agent(s)`);
10755
10893
  console.log(` Agent manifest: ${path33.resolve(rootDir, outdir, "faapi-agents.js")}`);
10756
- console.log("\n[7.5/8] Generating task manifest and schema...");
10894
+ console.log("\n[7.5/9] Generating task manifest and schema...");
10757
10895
  const tasks = await scanTasks(rootDir, TASK_PATTERNS);
10758
10896
  const taskMeta = await generateTaskArtifacts(tasks, rootDir, outdir);
10759
10897
  console.log(` Found ${taskMeta.length} task(s)`);
10760
10898
  console.log(` Task manifest: ${path33.resolve(rootDir, outdir, "faapi-tasks.js")}`);
10761
- console.log("\n[8/8] Generating entry file...");
10899
+ console.log("\n[8/9] Copying resources...");
10900
+ const resourcesCopied = await copyResources(rootDir, outdir);
10901
+ if (resourcesCopied) {
10902
+ console.log(` Copied src/resources \u2192 ${path33.resolve(rootDir, outdir, "resources")}`);
10903
+ }
10904
+ console.log("\n[9/9] Generating entry file...");
10762
10905
  const mainPath = path33.resolve(rootDir, outdir, "main.js");
10763
10906
  const createProdAppArgs = options?.dist && options.dist !== DEFAULT_DIST2 ? `{ dist: ${JSON.stringify(outdir)} }` : "";
10764
10907
  const mainContent = `// \u7531 faapi build \u81EA\u52A8\u751F\u6210\uFF0C\u8BF7\u52FF\u624B\u52A8\u7F16\u8F91
@@ -10814,6 +10957,7 @@ var init_buildCommand = __esm({
10814
10957
  init_generateSchemaFiles();
10815
10958
  init_generateRoutes();
10816
10959
  init_compileBuildRoutes();
10960
+ init_copyResources();
10817
10961
  init_prodPaths();
10818
10962
  init_compileConfig();
10819
10963
  init_loadConfig();