@standardagents/builder 0.15.0 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/built-in-routes.js +1650 -502
  2. package/dist/built-in-routes.js.map +1 -1
  3. package/dist/client/ApiKeysView.js +1 -1
  4. package/dist/client/CenteredContentView.js +1 -1
  5. package/dist/client/CompositionView.js +5 -5
  6. package/dist/client/ConfirmDialog.vue_vue_type_script_setup_true_lang.js +1 -1
  7. package/dist/client/CopyButton.vue_vue_type_script_setup_true_lang.js +1 -1
  8. package/dist/client/DataTable.vue_vue_type_script_setup_true_lang.js +1 -0
  9. package/dist/client/JsonViewer.js +1 -1
  10. package/dist/client/LoginView.js +1 -1
  11. package/dist/client/Modal.vue_vue_type_script_setup_true_lang.js +1 -1
  12. package/dist/client/ModelModal.vue_vue_type_script_setup_true_lang.js +1 -1
  13. package/dist/client/ModelsView.js +1 -1
  14. package/dist/client/PromptEditView.js +1 -1
  15. package/dist/client/PromptModal.js +1 -1
  16. package/dist/client/PromptsView.js +1 -1
  17. package/dist/client/ProvidersView.js +2 -2
  18. package/dist/client/ThreadInspectorPane.vue_vue_type_script_setup_true_lang.js +19 -19
  19. package/dist/client/ToolsView.js +1 -1
  20. package/dist/client/UsersView.js +1 -1
  21. package/dist/client/VariablesView.js +1 -0
  22. package/dist/client/assets/CompositionView.css +1 -1
  23. package/dist/client/assets/ThreadInspectorPane.css +1 -1
  24. package/dist/client/assets/VariablesView.css +1 -0
  25. package/dist/client/assets/index.css +1 -1
  26. package/dist/client/index.js +6 -6
  27. package/dist/{index-D6_KjpVv.d.ts → index-BwqQtJ4r.d.ts} +47 -0
  28. package/dist/index.d.ts +116 -4
  29. package/dist/index.js +1547 -706
  30. package/dist/index.js.map +1 -1
  31. package/dist/plugin.js +548 -372
  32. package/dist/plugin.js.map +1 -1
  33. package/dist/test.d.ts +1 -1
  34. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -2,10 +2,10 @@ import { ProviderError, mapReasoningLevel } from '@standardagents/spec';
2
2
  export { ProviderError, belongsToPackage, defineAgent, defineHook, defineModel, definePrompt, defineTool, isPacked, isVisibleInNamespace, mapReasoningLevel } from '@standardagents/spec';
3
3
  import { z } from 'zod';
4
4
  import { transform, collect } from '@standardagents/sip';
5
- import * as fs7 from 'fs';
6
- import fs7__default from 'fs';
7
- import * as path7 from 'path';
8
- import path7__default from 'path';
5
+ import * as fs8 from 'fs';
6
+ import fs8__default from 'fs';
7
+ import * as path8 from 'path';
8
+ import path8__default from 'path';
9
9
  import { fileURLToPath } from 'url';
10
10
  import MagicString from 'magic-string';
11
11
  import { exec } from 'child_process';
@@ -873,8 +873,10 @@ var init_ProviderRegistry = __esm({
873
873
  ProviderRegistryImpl = class {
874
874
  providerCache = /* @__PURE__ */ new Map();
875
875
  providerOverrideFn = null;
876
+ providerOverrideRevision = 0;
876
877
  setProviderOverride(fn) {
877
878
  this.providerOverrideFn = fn;
879
+ this.providerOverrideRevision += 1;
878
880
  }
879
881
  /**
880
882
  * Get provider for a model.
@@ -894,17 +896,6 @@ var init_ProviderRegistry = __esm({
894
896
  if (!modelDef) {
895
897
  throw new Error(`Model not found: ${modelName}`);
896
898
  }
897
- if (this.providerOverrideFn) {
898
- const overrideFingerprint = this.getProviderFingerprint("override", modelDef);
899
- const cached2 = this.providerCache.get(modelName);
900
- if (cached2?.fingerprint === overrideFingerprint) {
901
- return this.buildResult(cached2.provider, modelDef);
902
- }
903
- const overrideProvider = this.providerOverrideFn(modelName, modelDef, env);
904
- if (overrideProvider) {
905
- return this.cacheAndReturn(modelName, overrideProvider, modelDef, overrideFingerprint);
906
- }
907
- }
908
899
  if (typeof modelDef.provider !== "function") {
909
900
  throw new Error(
910
901
  `Model '${modelName}' has invalid provider. Provider must be a ProviderFactory function imported from a provider package (e.g., @standardagents/openai).`
@@ -912,29 +903,45 @@ var init_ProviderRegistry = __esm({
912
903
  }
913
904
  const providerFactory = modelDef.provider;
914
905
  const providerName = providerFactory({ apiKey: "" }).name;
915
- const fingerprint = this.getProviderFingerprint(providerName, modelDef);
916
- const cached = this.providerCache.get(modelName);
917
- if (cached?.fingerprint === fingerprint) {
918
- return this.buildResult(cached.provider, modelDef);
919
- }
920
906
  if (providerName === "test") {
907
+ const fingerprint = this.getProviderFingerprint(providerName, modelDef);
908
+ const cached = this.providerCache.get(modelName);
909
+ if (cached?.fingerprint === fingerprint) {
910
+ return this.buildResult(cached.provider, modelDef);
911
+ }
921
912
  return this.cacheAndReturn(modelName, createTestProvider(), modelDef, fingerprint);
922
913
  }
923
914
  const apiKey = this.getApiKeyForProvider(providerName, env);
924
- if (!apiKey) {
925
- throw new Error(`No API key found for provider: ${providerName}. Set the appropriate environment variable (e.g., OPENAI_API_KEY, OPENROUTER_API_KEY).`);
926
- }
927
- const config = { apiKey };
928
- if (modelDef.providerOptions?.baseUrl) {
929
- config.baseUrl = modelDef.providerOptions.baseUrl;
930
- }
931
- if (providerName === "cloudflare" && !config.baseUrl && env.CLOUDFLARE_ACCOUNT_ID) {
932
- config.baseUrl = `https://api.cloudflare.com/client/v4/accounts/${env.CLOUDFLARE_ACCOUNT_ID}/ai/v1`;
915
+ if (apiKey) {
916
+ const config = { apiKey };
917
+ if (modelDef.providerOptions?.baseUrl) {
918
+ config.baseUrl = modelDef.providerOptions.baseUrl;
919
+ }
920
+ if (providerName === "cloudflare" && !config.baseUrl && env.CLOUDFLARE_ACCOUNT_ID) {
921
+ config.baseUrl = `https://api.cloudflare.com/client/v4/accounts/${env.CLOUDFLARE_ACCOUNT_ID}/ai/v1`;
922
+ }
923
+ if (providerName === "cloudflare" && env.CLOUDFLARE_ACCOUNT_ID) {
924
+ config.accountId = env.CLOUDFLARE_ACCOUNT_ID;
925
+ }
926
+ const fingerprint = this.getProviderFingerprint(providerName, modelDef, config);
927
+ const cached = this.providerCache.get(modelName);
928
+ if (cached?.fingerprint === fingerprint) {
929
+ return this.buildResult(cached.provider, modelDef);
930
+ }
931
+ return this.cacheAndReturn(modelName, providerFactory(config), modelDef, fingerprint);
933
932
  }
934
- if (providerName === "cloudflare" && env.CLOUDFLARE_ACCOUNT_ID) {
935
- config.accountId = env.CLOUDFLARE_ACCOUNT_ID;
933
+ if (this.providerOverrideFn) {
934
+ const overrideFingerprint = this.getProviderFingerprint(`override:${this.providerOverrideRevision}`, modelDef);
935
+ const overrideCached = this.providerCache.get(modelName);
936
+ if (overrideCached?.fingerprint === overrideFingerprint) {
937
+ return this.buildResult(overrideCached.provider, modelDef);
938
+ }
939
+ const overrideProvider = this.providerOverrideFn(modelName, modelDef, env);
940
+ if (overrideProvider) {
941
+ return this.cacheAndReturn(modelName, overrideProvider, modelDef, overrideFingerprint);
942
+ }
936
943
  }
937
- return this.cacheAndReturn(modelName, providerFactory(config), modelDef, fingerprint);
944
+ throw new Error(`No API key found for provider: ${providerName}. Set the provider key or STANDARD_AGENTS_API_KEY.`);
938
945
  }
939
946
  buildResult(provider, modelDef) {
940
947
  return { provider, modelName: modelDef.model, modelDef };
@@ -943,10 +950,12 @@ var init_ProviderRegistry = __esm({
943
950
  this.providerCache.set(modelName, { provider, fingerprint });
944
951
  return this.buildResult(provider, modelDef);
945
952
  }
946
- getProviderFingerprint(providerName, modelDef) {
953
+ getProviderFingerprint(providerName, modelDef, config) {
947
954
  return JSON.stringify({
948
955
  providerName,
949
- baseUrl: modelDef.providerOptions?.baseUrl ?? null
956
+ baseUrl: modelDef.providerOptions?.baseUrl ?? null,
957
+ apiKey: config?.apiKey ?? null,
958
+ accountId: config?.accountId ?? null
950
959
  });
951
960
  }
952
961
  /**
@@ -1150,11 +1159,11 @@ function stripBase64FromMessages(messages, imagePathMap) {
1150
1159
  const data = part.data;
1151
1160
  if (typeof data === "string") {
1152
1161
  if (data.startsWith("data:") || data.length > 1e3) {
1153
- const path19 = imagePathMap?.get(data);
1162
+ const path20 = imagePathMap?.get(data);
1154
1163
  return {
1155
1164
  ...part,
1156
1165
  data: "[base64 omitted]",
1157
- ...path19 ? { path: path19 } : {}
1166
+ ...path20 ? { path: path20 } : {}
1158
1167
  };
1159
1168
  }
1160
1169
  }
@@ -1831,6 +1840,7 @@ var init_LLMRequest = __esm({
1831
1840
  try {
1832
1841
  const toolsCalled = response.tool_calls ? JSON.stringify(response.tool_calls.map((tc) => tc.function.name)) : null;
1833
1842
  const providerName = response._provider?.name;
1843
+ const standardAgentsRouterUsed = providerName === "platform";
1834
1844
  const resolvedPricing = resolveModelPricing(modelDef, providerName);
1835
1845
  const calculatedCost = calculateUsageCost(response.usage, resolvedPricing);
1836
1846
  const providerReportedCost = typeof response.usage.cost === "number" ? response.usage.cost : typeof response.usage.cost === "string" ? parseFloat(response.usage.cost) : null;
@@ -1904,6 +1914,7 @@ var init_LLMRequest = __esm({
1904
1914
  cost_total: cost_total ?? void 0,
1905
1915
  actual_provider: actualProvider ?? void 0,
1906
1916
  // Store actual provider separately (e.g., from OpenRouter)
1917
+ standard_agents_router_used: standardAgentsRouterUsed,
1907
1918
  is_complete: true,
1908
1919
  // Now complete
1909
1920
  reasoning_content: response.reasoning_content ?? void 0,
@@ -1931,8 +1942,9 @@ var init_LLMRequest = __esm({
1931
1942
  is_complete = ?13,
1932
1943
  reasoning_content = ?14,
1933
1944
  provider_tools = ?15,
1934
- actual_provider = ?16
1935
- WHERE id = ?17
1945
+ actual_provider = ?16,
1946
+ standard_agents_router_used = ?17
1947
+ WHERE id = ?18
1936
1948
  `,
1937
1949
  logData.response_body,
1938
1950
  logData.input_tokens,
@@ -1950,6 +1962,7 @@ var init_LLMRequest = __esm({
1950
1962
  logData.reasoning_content,
1951
1963
  providerToolsJson,
1952
1964
  actualProvider,
1965
+ standardAgentsRouterUsed ? 1 : 0,
1953
1966
  logId
1954
1967
  );
1955
1968
  }
@@ -2030,11 +2043,11 @@ var init_LLMRequest = __esm({
2030
2043
  ...choice.message,
2031
2044
  images: choice.message?.images?.map(
2032
2045
  (img) => {
2033
- const path19 = img._id ? imagePathMap.get(img._id) : void 0;
2034
- if (path19) {
2046
+ const path20 = img._id ? imagePathMap.get(img._id) : void 0;
2047
+ if (path20) {
2035
2048
  return {
2036
2049
  type: img.type,
2037
- image_url: { url: path19 }
2050
+ image_url: { url: path20 }
2038
2051
  };
2039
2052
  }
2040
2053
  return img;
@@ -2412,20 +2425,20 @@ function detectStorageBackend(location) {
2412
2425
  return "url";
2413
2426
  return "local";
2414
2427
  }
2415
- function basename2(path19) {
2416
- const parts = path19.split("/").filter(Boolean);
2428
+ function basename2(path20) {
2429
+ const parts = path20.split("/").filter(Boolean);
2417
2430
  return parts[parts.length - 1] || "";
2418
2431
  }
2419
- function normalizePath(path19) {
2420
- let normalized = path19.replace(/\/+/g, "/");
2432
+ function normalizePath(path20) {
2433
+ let normalized = path20.replace(/\/+/g, "/");
2421
2434
  if (!normalized.startsWith("/")) normalized = "/" + normalized;
2422
2435
  if (normalized.length > 1 && normalized.endsWith("/")) {
2423
2436
  normalized = normalized.slice(0, -1);
2424
2437
  }
2425
2438
  return normalized;
2426
2439
  }
2427
- function dirname3(path19) {
2428
- const normalized = normalizePath(path19);
2440
+ function dirname3(path20) {
2441
+ const normalized = normalizePath(path20);
2429
2442
  const lastSlash = normalized.lastIndexOf("/");
2430
2443
  if (lastSlash <= 0) return "/";
2431
2444
  return normalized.slice(0, lastSlash);
@@ -2550,8 +2563,8 @@ var init_files = __esm({
2550
2563
  * Write a file to storage.
2551
2564
  * Files > CHUNK_SIZE are automatically chunked into file_chunks table.
2552
2565
  */
2553
- async writeFile(path19, data, mimeType, options) {
2554
- const normalizedPath = normalizePath(path19);
2566
+ async writeFile(path20, data, mimeType, options) {
2567
+ const normalizedPath = normalizePath(path20);
2555
2568
  const name = basename2(normalizedPath);
2556
2569
  const isText = isTextMimeType(mimeType);
2557
2570
  const now = Date.now();
@@ -2663,8 +2676,8 @@ var init_files = __esm({
2663
2676
  /**
2664
2677
  * Link to an external file (URL, S3, R2)
2665
2678
  */
2666
- async linkFile(path19, location, options) {
2667
- const normalizedPath = normalizePath(path19);
2679
+ async linkFile(path20, location, options) {
2680
+ const normalizedPath = normalizePath(path20);
2668
2681
  const name = basename2(normalizedPath);
2669
2682
  const storage = detectStorageBackend(location);
2670
2683
  const now = Date.now();
@@ -2703,8 +2716,8 @@ var init_files = __esm({
2703
2716
  * WARNING: For large chunked files, this loads the entire file into memory.
2704
2717
  * Use streamFile() for memory-efficient access to large files.
2705
2718
  */
2706
- async readFile(path19) {
2707
- const normalizedPath = normalizePath(path19);
2719
+ async readFile(path20) {
2720
+ const normalizedPath = normalizePath(path20);
2708
2721
  const cursor = await this.sql.exec(
2709
2722
  `SELECT data, content, storage, is_chunked, chunk_count FROM files WHERE path = ? AND is_directory = 0`,
2710
2723
  normalizedPath
@@ -2756,8 +2769,8 @@ var init_files = __esm({
2756
2769
  * Memory-efficient way to read large chunked files.
2757
2770
  * Yields one chunk at a time for streaming HTTP responses.
2758
2771
  */
2759
- async *streamFile(path19) {
2760
- const normalizedPath = normalizePath(path19);
2772
+ async *streamFile(path20) {
2773
+ const normalizedPath = normalizePath(path20);
2761
2774
  const cursor = await this.sql.exec(
2762
2775
  `SELECT data, content, storage, is_chunked, chunk_count FROM files WHERE path = ? AND is_directory = 0`,
2763
2776
  normalizedPath
@@ -2791,8 +2804,8 @@ var init_files = __esm({
2791
2804
  /**
2792
2805
  * Read text file content
2793
2806
  */
2794
- async readTextFile(path19) {
2795
- const normalizedPath = normalizePath(path19);
2807
+ async readTextFile(path20) {
2808
+ const normalizedPath = normalizePath(path20);
2796
2809
  const cursor = await this.sql.exec(
2797
2810
  `SELECT content, data, storage FROM files WHERE path = ? AND is_directory = 0`,
2798
2811
  normalizedPath
@@ -2810,8 +2823,8 @@ var init_files = __esm({
2810
2823
  /**
2811
2824
  * Get file metadata (stat)
2812
2825
  */
2813
- async stat(path19) {
2814
- const normalizedPath = normalizePath(path19);
2826
+ async stat(path20) {
2827
+ const normalizedPath = normalizePath(path20);
2815
2828
  const cursor = await this.sql.exec(
2816
2829
  `SELECT path, name, mime_type, storage, location, size, metadata, is_directory, created_at, width, height, is_chunked, chunk_count
2817
2830
  FROM files WHERE path = ?`,
@@ -2824,8 +2837,8 @@ var init_files = __esm({
2824
2837
  /**
2825
2838
  * Check if file or directory exists
2826
2839
  */
2827
- async exists(path19) {
2828
- const normalizedPath = normalizePath(path19);
2840
+ async exists(path20) {
2841
+ const normalizedPath = normalizePath(path20);
2829
2842
  const cursor = await this.sql.exec(
2830
2843
  `SELECT COUNT(*) as count FROM files WHERE path = ?`,
2831
2844
  normalizedPath
@@ -2835,8 +2848,8 @@ var init_files = __esm({
2835
2848
  /**
2836
2849
  * Delete a file
2837
2850
  */
2838
- async unlink(path19) {
2839
- const normalizedPath = normalizePath(path19);
2851
+ async unlink(path20) {
2852
+ const normalizedPath = normalizePath(path20);
2840
2853
  await this.sql.exec(
2841
2854
  `DELETE FROM files WHERE path = ? AND is_directory = 0`,
2842
2855
  normalizedPath
@@ -2846,8 +2859,8 @@ var init_files = __esm({
2846
2859
  /**
2847
2860
  * Create a directory marker
2848
2861
  */
2849
- async mkdir(path19) {
2850
- const normalizedPath = normalizePath(path19);
2862
+ async mkdir(path20) {
2863
+ const normalizedPath = normalizePath(path20);
2851
2864
  const name = basename2(normalizedPath);
2852
2865
  const now = Date.now();
2853
2866
  await this.sql.exec(
@@ -2872,8 +2885,8 @@ var init_files = __esm({
2872
2885
  /**
2873
2886
  * List directory contents
2874
2887
  */
2875
- async readdir(path19) {
2876
- const normalizedPath = normalizePath(path19);
2888
+ async readdir(path20) {
2889
+ const normalizedPath = normalizePath(path20);
2877
2890
  const prefix = normalizedPath === "/" ? "/" : normalizedPath + "/";
2878
2891
  const cursor = await this.sql.exec(
2879
2892
  `SELECT path, name, mime_type, storage, location, size, metadata, is_directory, created_at
@@ -2891,8 +2904,8 @@ var init_files = __esm({
2891
2904
  /**
2892
2905
  * Remove empty directory
2893
2906
  */
2894
- async rmdir(path19) {
2895
- const normalizedPath = normalizePath(path19);
2907
+ async rmdir(path20) {
2908
+ const normalizedPath = normalizePath(path20);
2896
2909
  const prefix = normalizedPath + "/";
2897
2910
  const cursor = await this.sql.exec(
2898
2911
  `SELECT COUNT(*) as count FROM files WHERE path LIKE ? || '%'`,
@@ -2934,8 +2947,8 @@ var init_files = __esm({
2934
2947
  /**
2935
2948
  * Get thumbnail for an image
2936
2949
  */
2937
- async getThumbnail(path19) {
2938
- const normalizedPath = normalizePath(path19);
2950
+ async getThumbnail(path20) {
2951
+ const normalizedPath = normalizePath(path20);
2939
2952
  const cursor = await this.sql.exec(
2940
2953
  `SELECT thumbnail FROM files WHERE path = ? AND is_directory = 0`,
2941
2954
  normalizedPath
@@ -3276,8 +3289,8 @@ var init_ToolExecutor = __esm({
3276
3289
  const validation = argsSchema.safeParse(args);
3277
3290
  if (!validation.success) {
3278
3291
  const errorMessage = validation.error.issues.map((issue) => {
3279
- const path19 = issue.path.length > 0 ? issue.path.map(String).join(".") : "root";
3280
- return `[${path19}] ${issue.message}`;
3292
+ const path20 = issue.path.length > 0 ? issue.path.map(String).join(".") : "root";
3293
+ return `[${path20}] ${issue.message}`;
3281
3294
  }).join("; ");
3282
3295
  return {
3283
3296
  status: "error",
@@ -4396,8 +4409,8 @@ Reference: ${referenceId}` : `Reference: ${referenceId}`;
4396
4409
  }
4397
4410
  return [];
4398
4411
  }
4399
- static inferMimeTypeFromPath(path19) {
4400
- const normalized = path19.toLowerCase();
4412
+ static inferMimeTypeFromPath(path20) {
4413
+ const normalized = path20.toLowerCase();
4401
4414
  if (normalized.endsWith(".png")) return "image/png";
4402
4415
  if (normalized.endsWith(".jpg") || normalized.endsWith(".jpeg")) return "image/jpeg";
4403
4416
  if (normalized.endsWith(".webp")) return "image/webp";
@@ -4436,7 +4449,7 @@ Reference: ${referenceId}` : `Reference: ${referenceId}`;
4436
4449
  ext: value.slice(lastDot + 1).toLowerCase()
4437
4450
  };
4438
4451
  }
4439
- static resolveAttachmentMimeType(sourceMimeType, fallbackMimeType, path19) {
4452
+ static resolveAttachmentMimeType(sourceMimeType, fallbackMimeType, path20) {
4440
4453
  const source = sourceMimeType?.trim();
4441
4454
  if (source && source !== "application/octet-stream") {
4442
4455
  return source;
@@ -4445,7 +4458,7 @@ Reference: ${referenceId}` : `Reference: ${referenceId}`;
4445
4458
  if (fallback && fallback !== "application/octet-stream") {
4446
4459
  return fallback;
4447
4460
  }
4448
- return this.inferMimeTypeFromPath(path19) ?? source ?? fallback ?? "application/octet-stream";
4461
+ return this.inferMimeTypeFromPath(path20) ?? source ?? fallback ?? "application/octet-stream";
4449
4462
  }
4450
4463
  static buildAttachmentTargetPath(preferredName, mimeType, sourcePath) {
4451
4464
  const safeName = this.sanitizeFilename(preferredName);
@@ -4541,8 +4554,8 @@ Reference: ${referenceId}` : `Reference: ${referenceId}`;
4541
4554
  }
4542
4555
  return copied;
4543
4556
  }
4544
- static async readAttachmentDataFromSource(sourceThread, path19, sourceFile) {
4545
- const sourceData = await sourceThread.readFile(path19);
4557
+ static async readAttachmentDataFromSource(sourceThread, path20, sourceFile) {
4558
+ const sourceData = await sourceThread.readFile(path20);
4546
4559
  if (sourceData.success && sourceData.data) {
4547
4560
  return sourceData.data;
4548
4561
  }
@@ -4576,7 +4589,7 @@ Reference: ${referenceId}` : `Reference: ${referenceId}`;
4576
4589
  if (!attachments || attachments.length === 0) {
4577
4590
  return "";
4578
4591
  }
4579
- const paths = attachments.map((attachment) => attachment.path).filter((path19) => typeof path19 === "string" && path19.length > 0);
4592
+ const paths = attachments.map((attachment) => attachment.path).filter((path20) => typeof path20 === "string" && path20.length > 0);
4580
4593
  if (paths.length === 0) {
4581
4594
  return "";
4582
4595
  }
@@ -4872,7 +4885,7 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
4872
4885
  mappedAttachmentValue
4873
4886
  );
4874
4887
  const resolvedPaths = new Set(mappedRefs.map((ref) => ref.path));
4875
- const missingPaths = candidatePaths.filter((path19) => !resolvedPaths.has(path19));
4888
+ const missingPaths = candidatePaths.filter((path20) => !resolvedPaths.has(path20));
4876
4889
  if (candidatePaths.length === 0 || missingPaths.length > 0) {
4877
4890
  processedResult = {
4878
4891
  status: "error",
@@ -5026,8 +5039,8 @@ ${attachmentPaths}`;
5026
5039
  if (mimeType.startsWith("image/")) {
5027
5040
  return true;
5028
5041
  }
5029
- const path19 = ref.path.toLowerCase();
5030
- return path19.endsWith(".png") || path19.endsWith(".jpg") || path19.endsWith(".jpeg") || path19.endsWith(".webp") || path19.endsWith(".gif") || path19.endsWith(".bmp") || path19.endsWith(".svg");
5042
+ const path20 = ref.path.toLowerCase();
5043
+ return path20.endsWith(".png") || path20.endsWith(".jpg") || path20.endsWith(".jpeg") || path20.endsWith(".webp") || path20.endsWith(".gif") || path20.endsWith(".bmp") || path20.endsWith(".svg");
5031
5044
  });
5032
5045
  if (imageRefs.length === 0) {
5033
5046
  return;
@@ -5093,27 +5106,27 @@ ${attachmentPaths}`;
5093
5106
  */
5094
5107
  static async processToolAttachments(attachments, state) {
5095
5108
  const { FileStorage: FileStorage2 } = await Promise.resolve().then(() => (init_files(), files_exports));
5096
- const fs17 = new FileStorage2(state.storage.sql);
5109
+ const fs18 = new FileStorage2(state.storage.sql);
5097
5110
  const refs = [];
5098
5111
  for (const attachment of attachments) {
5099
5112
  try {
5100
5113
  const attachmentId = crypto.randomUUID();
5101
5114
  const timestamp = Date.now();
5102
5115
  const ext = attachment.mimeType === "image/png" ? "png" : attachment.mimeType === "image/jpeg" ? "jpg" : attachment.mimeType === "image/gif" ? "gif" : attachment.mimeType === "image/webp" ? "webp" : attachment.name.split(".").pop() || "bin";
5103
- const path19 = `/attachments/${timestamp}-${attachmentId}.${ext}`;
5116
+ const path20 = `/attachments/${timestamp}-${attachmentId}.${ext}`;
5104
5117
  const binaryString = atob(attachment.data);
5105
5118
  const dataBuffer = new Uint8Array(binaryString.length);
5106
5119
  for (let i = 0; i < binaryString.length; i++) {
5107
5120
  dataBuffer[i] = binaryString.charCodeAt(i);
5108
5121
  }
5109
- await fs17.writeFile(path19, dataBuffer.buffer, attachment.mimeType, {
5122
+ await fs18.writeFile(path20, dataBuffer.buffer, attachment.mimeType, {
5110
5123
  width: attachment.width,
5111
5124
  height: attachment.height
5112
5125
  });
5113
5126
  const ref = {
5114
5127
  id: attachmentId,
5115
5128
  type: "file",
5116
- path: path19,
5129
+ path: path20,
5117
5130
  name: attachment.name,
5118
5131
  mimeType: attachment.mimeType,
5119
5132
  size: dataBuffer.byteLength
@@ -8399,16 +8412,16 @@ ${lines.join("\n\n")}`
8399
8412
  const base64Data = match[2];
8400
8413
  const ext = mimeType.split("/")[1] || "png";
8401
8414
  const attachmentId = crypto.randomUUID();
8402
- const path19 = `/attachments/${Date.now()}-${attachmentId}.${ext}`;
8415
+ const path20 = `/attachments/${Date.now()}-${attachmentId}.${ext}`;
8403
8416
  try {
8404
- await state.thread.instance.writeFile(path19, base64Data, mimeType);
8417
+ await state.thread.instance.writeFile(path20, base64Data, mimeType);
8405
8418
  if (image.id) {
8406
- imagePathMap.set(image.id, path19);
8419
+ imagePathMap.set(image.id, path20);
8407
8420
  }
8408
8421
  refs.push({
8409
8422
  id: attachmentId,
8410
8423
  type: "file",
8411
- path: path19,
8424
+ path: path20,
8412
8425
  name: `generated-${attachmentId}.${ext}`,
8413
8426
  mimeType,
8414
8427
  size: Math.ceil(base64Data.length * 3 / 4)
@@ -8469,13 +8482,13 @@ ${lines.join("\n\n")}`
8469
8482
  const base64Data = imageUrl.slice(base64Index + base64Marker.length);
8470
8483
  const ext = mimeType.split("/")[1] || "png";
8471
8484
  const attachmentId = crypto.randomUUID();
8472
- const path19 = `/attachments/${Date.now()}-${attachmentId}.${ext}`;
8485
+ const path20 = `/attachments/${Date.now()}-${attachmentId}.${ext}`;
8473
8486
  try {
8474
- await state.thread.instance.writeFile(path19, base64Data, mimeType);
8487
+ await state.thread.instance.writeFile(path20, base64Data, mimeType);
8475
8488
  const attachmentRef = {
8476
8489
  id: attachmentId,
8477
8490
  type: "file",
8478
- path: path19,
8491
+ path: path20,
8479
8492
  name: `generated-${attachmentId}.${ext}`,
8480
8493
  mimeType,
8481
8494
  size: Math.ceil(base64Data.length * 3 / 4)
@@ -8538,7 +8551,7 @@ ${lines.join("\n\n")}`
8538
8551
  content: "Image generated successfully",
8539
8552
  status: "success",
8540
8553
  timestamp: Date.now(),
8541
- attachment_path: path19
8554
+ attachment_path: path20
8542
8555
  });
8543
8556
  await state.storage.sql.exec(
8544
8557
  `UPDATE logs SET tool_results = ?1 WHERE id = ?2`,
@@ -8560,7 +8573,7 @@ ${lines.join("\n\n")}`
8560
8573
  }
8561
8574
  }
8562
8575
  if (image.id) {
8563
- imagePathMap.set(image.id, path19);
8576
+ imagePathMap.set(image.id, path20);
8564
8577
  }
8565
8578
  } catch (error) {
8566
8579
  console.error(`[FlowEngine] Failed to store provider tool result for ${toolName}:`, error);
@@ -9294,7 +9307,7 @@ async function updateThread(thread, params) {
9294
9307
  }
9295
9308
  return result.thread;
9296
9309
  }
9297
- async function writeFile(flow, path19, data, mimeType, options) {
9310
+ async function writeFile(flow, path20, data, mimeType, options) {
9298
9311
  const instance = flow.thread.instance;
9299
9312
  let base64Data;
9300
9313
  if (typeof data === "string") {
@@ -9316,7 +9329,7 @@ async function writeFile(flow, path19, data, mimeType, options) {
9316
9329
  }
9317
9330
  base64Thumbnail = btoa(binary);
9318
9331
  }
9319
- const result = await instance.writeFile(path19, base64Data, mimeType, {
9332
+ const result = await instance.writeFile(path20, base64Data, mimeType, {
9320
9333
  metadata: options?.metadata,
9321
9334
  thumbnail: base64Thumbnail
9322
9335
  });
@@ -9325,20 +9338,20 @@ async function writeFile(flow, path19, data, mimeType, options) {
9325
9338
  }
9326
9339
  return result.file;
9327
9340
  }
9328
- async function writeImage(flow, path19, data, mimeType, options) {
9329
- return writeFile(flow, path19, data, mimeType, options);
9341
+ async function writeImage(flow, path20, data, mimeType, options) {
9342
+ return writeFile(flow, path20, data, mimeType, options);
9330
9343
  }
9331
- async function linkFile(flow, path19, location, options) {
9344
+ async function linkFile(flow, path20, location, options) {
9332
9345
  const instance = flow.thread.instance;
9333
- const result = await instance.linkFile(path19, location, options);
9346
+ const result = await instance.linkFile(path20, location, options);
9334
9347
  if (!result.success) {
9335
9348
  throw new Error(result.error || "Failed to link file");
9336
9349
  }
9337
9350
  return result.file;
9338
9351
  }
9339
- async function readFile(flow, path19) {
9352
+ async function readFile(flow, path20) {
9340
9353
  const instance = flow.thread.instance;
9341
- const result = await instance.readFile(path19);
9354
+ const result = await instance.readFile(path20);
9342
9355
  if (!result.success) {
9343
9356
  return null;
9344
9357
  }
@@ -9349,45 +9362,45 @@ async function readFile(flow, path19) {
9349
9362
  }
9350
9363
  return bytes.buffer;
9351
9364
  }
9352
- async function stat(flow, path19) {
9365
+ async function stat(flow, path20) {
9353
9366
  const instance = flow.thread.instance;
9354
- const result = await instance.statFile(path19);
9367
+ const result = await instance.statFile(path20);
9355
9368
  if (!result.success) {
9356
9369
  return null;
9357
9370
  }
9358
9371
  return result.file;
9359
9372
  }
9360
- async function exists(flow, path19) {
9373
+ async function exists(flow, path20) {
9361
9374
  const instance = flow.thread.instance;
9362
- const result = await instance.fileExists(path19);
9375
+ const result = await instance.fileExists(path20);
9363
9376
  return result.success && result.exists;
9364
9377
  }
9365
- async function unlink(flow, path19) {
9378
+ async function unlink(flow, path20) {
9366
9379
  const instance = flow.thread.instance;
9367
- const result = await instance.unlinkFile(path19);
9380
+ const result = await instance.unlinkFile(path20);
9368
9381
  if (!result.success) {
9369
9382
  throw new Error(result.error || "Failed to delete file");
9370
9383
  }
9371
9384
  }
9372
- async function mkdir(flow, path19) {
9385
+ async function mkdir(flow, path20) {
9373
9386
  const instance = flow.thread.instance;
9374
- const result = await instance.mkdirFile(path19);
9387
+ const result = await instance.mkdirFile(path20);
9375
9388
  if (!result.success) {
9376
9389
  throw new Error(result.error || "Failed to create directory");
9377
9390
  }
9378
9391
  return result.directory;
9379
9392
  }
9380
- async function readdir(flow, path19) {
9393
+ async function readdir(flow, path20) {
9381
9394
  const instance = flow.thread.instance;
9382
- const result = await instance.readdirFile(path19);
9395
+ const result = await instance.readdirFile(path20);
9383
9396
  if (!result.success) {
9384
9397
  throw new Error(result.error || "Failed to read directory");
9385
9398
  }
9386
9399
  return result.files;
9387
9400
  }
9388
- async function rmdir(flow, path19) {
9401
+ async function rmdir(flow, path20) {
9389
9402
  const instance = flow.thread.instance;
9390
- const result = await instance.rmdirFile(path19);
9403
+ const result = await instance.rmdirFile(path20);
9391
9404
  if (!result.success) {
9392
9405
  throw new Error(result.error || "Failed to remove directory");
9393
9406
  }
@@ -9400,9 +9413,9 @@ async function getFileStats(flow) {
9400
9413
  }
9401
9414
  return result.stats;
9402
9415
  }
9403
- async function getThumbnail(flow, path19) {
9416
+ async function getThumbnail(flow, path20) {
9404
9417
  const instance = flow.thread.instance;
9405
- const result = await instance.getFileThumbnail(path19);
9418
+ const result = await instance.getFileThumbnail(path20);
9406
9419
  if (!result.success) {
9407
9420
  return null;
9408
9421
  }
@@ -9413,22 +9426,22 @@ async function getThumbnail(flow, path19) {
9413
9426
  }
9414
9427
  return bytes.buffer;
9415
9428
  }
9416
- async function cat(flow, path19) {
9429
+ async function cat(flow, path20) {
9417
9430
  const instance = flow.thread.instance;
9418
- const result = await instance.readTextFile(path19);
9431
+ const result = await instance.readTextFile(path20);
9419
9432
  if (!result.success) {
9420
9433
  return null;
9421
9434
  }
9422
9435
  return result.content;
9423
9436
  }
9424
- async function head(flow, path19, lines = 10) {
9425
- const content = await cat(flow, path19);
9437
+ async function head(flow, path20, lines = 10) {
9438
+ const content = await cat(flow, path20);
9426
9439
  if (content === null) return null;
9427
9440
  const allLines = content.split("\n");
9428
9441
  return allLines.slice(0, lines).join("\n");
9429
9442
  }
9430
- async function tail(flow, path19, lines = 10) {
9431
- const content = await cat(flow, path19);
9443
+ async function tail(flow, path20, lines = 10) {
9444
+ const content = await cat(flow, path20);
9432
9445
  if (content === null) return null;
9433
9446
  const allLines = content.split("\n");
9434
9447
  return allLines.slice(-lines).join("\n");
@@ -9967,32 +9980,32 @@ function prepareBridge(options, reports, logs) {
9967
9980
  logs
9968
9981
  };
9969
9982
  }
9970
- function prepareNamespaceRecord(value, path19, functions) {
9983
+ function prepareNamespaceRecord(value, path20, functions) {
9971
9984
  const out = {};
9972
9985
  for (const [key, namespace] of Object.entries(value)) {
9973
- out[key] = prepareValueRecord(namespace, `${path19}.${key}`, functions);
9986
+ out[key] = prepareValueRecord(namespace, `${path20}.${key}`, functions);
9974
9987
  }
9975
9988
  return out;
9976
9989
  }
9977
- function prepareValueRecord(value, path19, functions) {
9990
+ function prepareValueRecord(value, path20, functions) {
9978
9991
  const out = {};
9979
9992
  for (const [key, item] of Object.entries(value)) {
9980
- out[key] = prepareBridgeValue(item, `${path19}.${key}`, functions);
9993
+ out[key] = prepareBridgeValue(item, `${path20}.${key}`, functions);
9981
9994
  }
9982
9995
  return out;
9983
9996
  }
9984
- function prepareBridgeValue(value, path19, functions) {
9997
+ function prepareBridgeValue(value, path20, functions) {
9985
9998
  if (typeof value === "function") {
9986
- functions.set(path19, value);
9987
- return { __agentbuilderType: "function", id: path19 };
9999
+ functions.set(path20, value);
10000
+ return { __agentbuilderType: "function", id: path20 };
9988
10001
  }
9989
10002
  if (isThenable(value)) {
9990
- const promiseId = `${path19}.__promise`;
10003
+ const promiseId = `${path20}.__promise`;
9991
10004
  functions.set(promiseId, async () => value);
9992
10005
  return { __agentbuilderType: "promise", id: promiseId };
9993
10006
  }
9994
10007
  if (Array.isArray(value)) {
9995
- return value.map((item, index) => prepareBridgeValue(item, `${path19}.${index}`, functions));
10008
+ return value.map((item, index) => prepareBridgeValue(item, `${path20}.${index}`, functions));
9996
10009
  }
9997
10010
  if (value && typeof value === "object") {
9998
10011
  if (value instanceof Date || value instanceof Map || value instanceof Set || ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
@@ -10003,7 +10016,7 @@ function prepareBridgeValue(value, path19, functions) {
10003
10016
  }
10004
10017
  const out = {};
10005
10018
  for (const [key, item] of Object.entries(value)) {
10006
- out[key] = prepareBridgeValue(item, `${path19}.${key}`, functions);
10019
+ out[key] = prepareBridgeValue(item, `${path20}.${key}`, functions);
10007
10020
  }
10008
10021
  return out;
10009
10022
  }
@@ -10878,12 +10891,12 @@ function normalizeVirtualModulePath(basePath, specifier) {
10878
10891
  }
10879
10892
  return normalized;
10880
10893
  }
10881
- function dirnameModulePath(path19) {
10882
- const index = path19.lastIndexOf("/");
10883
- return index <= 0 ? "" : path19.slice(0, index);
10894
+ function dirnameModulePath(path20) {
10895
+ const index = path20.lastIndexOf("/");
10896
+ return index <= 0 ? "" : path20.slice(0, index);
10884
10897
  }
10885
- function hasModuleExtension(path19) {
10886
- return /\.[A-Za-z0-9]+$/.test(path19);
10898
+ function hasModuleExtension(path20) {
10899
+ return /\.[A-Za-z0-9]+$/.test(path20);
10887
10900
  }
10888
10901
  function resolveGraphModuleSpecifier(fromPath, specifier, modulePaths) {
10889
10902
  const base = normalizeVirtualModulePath(dirnameModulePath(fromPath), specifier);
@@ -11214,9 +11227,9 @@ function isPlainObject2(value) {
11214
11227
  const prototype = Object.getPrototypeOf(value);
11215
11228
  return prototype === Object.prototype || prototype === null;
11216
11229
  }
11217
- function findUntransferableOption(value, path19, seen = /* @__PURE__ */ new WeakSet()) {
11230
+ function findUntransferableOption(value, path20, seen = /* @__PURE__ */ new WeakSet()) {
11218
11231
  if (typeof value === "function" || typeof value === "symbol") {
11219
- return path19;
11232
+ return path20;
11220
11233
  }
11221
11234
  if (!value || typeof value !== "object") {
11222
11235
  return null;
@@ -11230,7 +11243,7 @@ function findUntransferableOption(value, path19, seen = /* @__PURE__ */ new Weak
11230
11243
  seen.add(value);
11231
11244
  if (Array.isArray(value)) {
11232
11245
  for (const [index, item] of value.entries()) {
11233
- const found = findUntransferableOption(item, `${path19}.${index}`, seen);
11246
+ const found = findUntransferableOption(item, `${path20}.${index}`, seen);
11234
11247
  if (found) return found;
11235
11248
  }
11236
11249
  return null;
@@ -11238,9 +11251,9 @@ function findUntransferableOption(value, path19, seen = /* @__PURE__ */ new Weak
11238
11251
  if (value instanceof Map) {
11239
11252
  let index = 0;
11240
11253
  for (const [key, item] of value.entries()) {
11241
- const foundKey = findUntransferableOption(key, `${path19}.mapKey${index}`, seen);
11254
+ const foundKey = findUntransferableOption(key, `${path20}.mapKey${index}`, seen);
11242
11255
  if (foundKey) return foundKey;
11243
- const foundValue = findUntransferableOption(item, `${path19}.mapValue${index}`, seen);
11256
+ const foundValue = findUntransferableOption(item, `${path20}.mapValue${index}`, seen);
11244
11257
  if (foundValue) return foundValue;
11245
11258
  index += 1;
11246
11259
  }
@@ -11249,17 +11262,17 @@ function findUntransferableOption(value, path19, seen = /* @__PURE__ */ new Weak
11249
11262
  if (value instanceof Set) {
11250
11263
  let index = 0;
11251
11264
  for (const item of value.values()) {
11252
- const found = findUntransferableOption(item, `${path19}.setValue${index}`, seen);
11265
+ const found = findUntransferableOption(item, `${path20}.setValue${index}`, seen);
11253
11266
  if (found) return found;
11254
11267
  index += 1;
11255
11268
  }
11256
11269
  return null;
11257
11270
  }
11258
11271
  if (!isPlainObject2(value)) {
11259
- return path19;
11272
+ return path20;
11260
11273
  }
11261
11274
  for (const [key, item] of Object.entries(value)) {
11262
- const found = findUntransferableOption(item, `${path19}.${key}`, seen);
11275
+ const found = findUntransferableOption(item, `${path20}.${key}`, seen);
11263
11276
  if (found) return found;
11264
11277
  }
11265
11278
  return null;
@@ -11769,7 +11782,7 @@ var init_ThreadStateImpl = __esm({
11769
11782
  // ─────────────────────────────────────────────────────────────────────────
11770
11783
  // File System
11771
11784
  // ─────────────────────────────────────────────────────────────────────────
11772
- async writeFile(path19, data, mimeType, options) {
11785
+ async writeFile(path20, data, mimeType, options) {
11773
11786
  const isText = this._isTextMimeType(mimeType);
11774
11787
  if (isText) {
11775
11788
  let textContent;
@@ -11778,7 +11791,7 @@ var init_ThreadStateImpl = __esm({
11778
11791
  } else {
11779
11792
  textContent = new TextDecoder().decode(data);
11780
11793
  }
11781
- const result = await this._threadInstance.writeTextFile(path19, textContent, mimeType, options);
11794
+ const result = await this._threadInstance.writeTextFile(path20, textContent, mimeType, options);
11782
11795
  return this._mapFileRecord(result.file);
11783
11796
  } else {
11784
11797
  let base64Data;
@@ -11798,7 +11811,7 @@ var init_ThreadStateImpl = __esm({
11798
11811
  }
11799
11812
  base64Data = btoa(binary);
11800
11813
  }
11801
- const result = await this._threadInstance.writeFile(path19, base64Data, mimeType, options);
11814
+ const result = await this._threadInstance.writeFile(path20, base64Data, mimeType, options);
11802
11815
  return this._mapFileRecord(result.file);
11803
11816
  }
11804
11817
  }
@@ -11870,8 +11883,8 @@ var init_ThreadStateImpl = __esm({
11870
11883
  (type) => mimeType === type || mimeType.startsWith(type + ";")
11871
11884
  );
11872
11885
  }
11873
- async readFile(path19) {
11874
- const result = await this._threadInstance.readFile(path19);
11886
+ async readFile(path20) {
11887
+ const result = await this._threadInstance.readFile(path20);
11875
11888
  if (!result.success || !result.data) {
11876
11889
  return null;
11877
11890
  }
@@ -11882,8 +11895,8 @@ var init_ThreadStateImpl = __esm({
11882
11895
  }
11883
11896
  return bytes.buffer;
11884
11897
  }
11885
- async readFileStream(path19, options) {
11886
- const fileInfo = await this._threadInstance.statFile(path19);
11898
+ async readFileStream(path20, options) {
11899
+ const fileInfo = await this._threadInstance.statFile(path20);
11887
11900
  if (!fileInfo) {
11888
11901
  return null;
11889
11902
  }
@@ -11898,7 +11911,7 @@ var init_ThreadStateImpl = __esm({
11898
11911
  return {
11899
11912
  [Symbol.asyncIterator]: async function* () {
11900
11913
  if (!isChunked) {
11901
- const result = await threadInstance.readFile(path19);
11914
+ const result = await threadInstance.readFile(path20);
11902
11915
  if (!result.success || !result.data) {
11903
11916
  return;
11904
11917
  }
@@ -11919,7 +11932,7 @@ var init_ThreadStateImpl = __esm({
11919
11932
  if (signal?.aborted) {
11920
11933
  return;
11921
11934
  }
11922
- const result = await threadInstance.readFileChunk(path19, i);
11935
+ const result = await threadInstance.readFileChunk(path20, i);
11923
11936
  if (!result.success || !result.data) {
11924
11937
  throw new Error(result.error || `Failed to read chunk ${i}`);
11925
11938
  }
@@ -11938,25 +11951,25 @@ var init_ThreadStateImpl = __esm({
11938
11951
  }
11939
11952
  };
11940
11953
  }
11941
- async statFile(path19) {
11942
- const result = await this._threadInstance.statFile(path19);
11954
+ async statFile(path20) {
11955
+ const result = await this._threadInstance.statFile(path20);
11943
11956
  return result ? this._mapFileRecord(result) : null;
11944
11957
  }
11945
- async readdirFile(path19) {
11946
- const entries = await this._threadInstance.readdirFile(path19);
11958
+ async readdirFile(path20) {
11959
+ const entries = await this._threadInstance.readdirFile(path20);
11947
11960
  return {
11948
11961
  entries: entries.map((e) => this._mapFileRecord(e))
11949
11962
  };
11950
11963
  }
11951
- async unlinkFile(path19) {
11952
- await this._threadInstance.unlinkFile(path19);
11964
+ async unlinkFile(path20) {
11965
+ await this._threadInstance.unlinkFile(path20);
11953
11966
  }
11954
- async mkdirFile(path19) {
11955
- const result = await this._threadInstance.mkdirFile(path19);
11967
+ async mkdirFile(path20) {
11968
+ const result = await this._threadInstance.mkdirFile(path20);
11956
11969
  return this._mapFileRecord(result);
11957
11970
  }
11958
- async rmdirFile(path19) {
11959
- await this._threadInstance.rmdirFile(path19);
11971
+ async rmdirFile(path20) {
11972
+ await this._threadInstance.rmdirFile(path20);
11960
11973
  }
11961
11974
  async getFileStats() {
11962
11975
  const stats = await this._threadInstance.getFileStats();
@@ -11979,8 +11992,8 @@ var init_ThreadStateImpl = __esm({
11979
11992
  paths: Array.isArray(results) ? results : results.paths || []
11980
11993
  };
11981
11994
  }
11982
- async getFileThumbnail(path19) {
11983
- return this._threadInstance.getFileThumbnail(path19);
11995
+ async getFileThumbnail(path20) {
11996
+ return this._threadInstance.getFileThumbnail(path20);
11984
11997
  }
11985
11998
  // ─────────────────────────────────────────────────────────────────────────
11986
11999
  // Execution State
@@ -12293,15 +12306,15 @@ function extractSchemaFields(content) {
12293
12306
  }
12294
12307
  function scanPromptsWithSchemas(dir) {
12295
12308
  const results = [];
12296
- if (!fs7__default.existsSync(dir)) {
12309
+ if (!fs8__default.existsSync(dir)) {
12297
12310
  return results;
12298
12311
  }
12299
12312
  try {
12300
- const entries = fs7__default.readdirSync(dir, { withFileTypes: true });
12313
+ const entries = fs8__default.readdirSync(dir, { withFileTypes: true });
12301
12314
  for (const entry of entries) {
12302
12315
  if (entry.isFile() && entry.name.endsWith(".ts")) {
12303
- const filePath = path7__default.join(dir, entry.name);
12304
- const content = fs7__default.readFileSync(filePath, "utf-8");
12316
+ const filePath = path8__default.join(dir, entry.name);
12317
+ const content = fs8__default.readFileSync(filePath, "utf-8");
12305
12318
  const nameMatch = content.match(/name:\s*['"]([^'"]+)['"]/);
12306
12319
  if (nameMatch) {
12307
12320
  const name = nameMatch[1];
@@ -12317,15 +12330,15 @@ function scanPromptsWithSchemas(dir) {
12317
12330
  }
12318
12331
  function scanAgentsWithSideA(dir) {
12319
12332
  const results = [];
12320
- if (!fs7__default.existsSync(dir)) {
12333
+ if (!fs8__default.existsSync(dir)) {
12321
12334
  return results;
12322
12335
  }
12323
12336
  try {
12324
- const entries = fs7__default.readdirSync(dir, { withFileTypes: true });
12337
+ const entries = fs8__default.readdirSync(dir, { withFileTypes: true });
12325
12338
  for (const entry of entries) {
12326
12339
  if (entry.isFile() && entry.name.endsWith(".ts")) {
12327
- const filePath = path7__default.join(dir, entry.name);
12328
- const content = fs7__default.readFileSync(filePath, "utf-8");
12340
+ const filePath = path8__default.join(dir, entry.name);
12341
+ const content = fs8__default.readFileSync(filePath, "utf-8");
12329
12342
  const nameMatch = content.match(/name:\s*['"]([^'"]+)['"]/);
12330
12343
  if (nameMatch) {
12331
12344
  const name = nameMatch[1];
@@ -12345,15 +12358,15 @@ function scanAgentsWithSideA(dir) {
12345
12358
  }
12346
12359
  function scanForNames(dir, useFilename = false) {
12347
12360
  const names = [];
12348
- if (!fs7__default.existsSync(dir)) {
12361
+ if (!fs8__default.existsSync(dir)) {
12349
12362
  return names;
12350
12363
  }
12351
12364
  try {
12352
- const entries = fs7__default.readdirSync(dir, { withFileTypes: true });
12365
+ const entries = fs8__default.readdirSync(dir, { withFileTypes: true });
12353
12366
  for (const entry of entries) {
12354
12367
  if (entry.isFile() && entry.name.endsWith(".ts")) {
12355
- const filePath = path7__default.join(dir, entry.name);
12356
- const content = fs7__default.readFileSync(filePath, "utf-8");
12368
+ const filePath = path8__default.join(dir, entry.name);
12369
+ const content = fs8__default.readFileSync(filePath, "utf-8");
12357
12370
  if (useFilename) {
12358
12371
  const toolName = entry.name.replace(/\.ts$/, "");
12359
12372
  if (content.includes("defineTool")) {
@@ -12374,18 +12387,18 @@ function scanForNames(dir, useFilename = false) {
12374
12387
  }
12375
12388
  function scanHooksForIds(dir) {
12376
12389
  const hookIds = [];
12377
- if (!fs7__default.existsSync(dir)) {
12390
+ if (!fs8__default.existsSync(dir)) {
12378
12391
  return hookIds;
12379
12392
  }
12380
12393
  try {
12381
- const entries = fs7__default.readdirSync(dir, { withFileTypes: true });
12394
+ const entries = fs8__default.readdirSync(dir, { withFileTypes: true });
12382
12395
  for (const entry of entries) {
12383
12396
  if (entry.isFile() && entry.name.endsWith(".ts")) {
12384
12397
  if (entry.name === "index.ts") {
12385
12398
  continue;
12386
12399
  }
12387
- const filePath = path7__default.join(dir, entry.name);
12388
- const content = fs7__default.readFileSync(filePath, "utf-8");
12400
+ const filePath = path8__default.join(dir, entry.name);
12401
+ const content = fs8__default.readFileSync(filePath, "utf-8");
12389
12402
  const idMatch = content.match(/defineHook\s*\(\s*\{[^}]*id:\s*['"]([^'"]+)['"]/s);
12390
12403
  if (idMatch) {
12391
12404
  hookIds.push(idMatch[1]);
@@ -12852,6 +12865,34 @@ declare module 'virtual:@standardagents/builder' {
12852
12865
  property: string;
12853
12866
  promptName?: string;
12854
12867
  }): Promise<'text' | 'secret'>;
12868
+ getInstanceEnv(): Promise<Record<string, string>>;
12869
+ getInstanceEnvTypes(): Promise<Record<string, 'text' | 'secret'>>;
12870
+ getInstanceEnvEntries(): Promise<Array<{
12871
+ name: string;
12872
+ value: string;
12873
+ type: 'text' | 'secret';
12874
+ created_at: number;
12875
+ updated_at: number;
12876
+ }>>;
12877
+ patchInstanceEnv(params: {
12878
+ env_patch?: Record<string, unknown> | null;
12879
+ env_type_patch?: Record<string, unknown> | null;
12880
+ env_delete?: string[] | null;
12881
+ }): Promise<void>;
12882
+ getUserEnv(userId: string): Promise<Record<string, string>>;
12883
+ getUserEnvTypes(userId: string): Promise<Record<string, 'text' | 'secret'>>;
12884
+ getUserEnvEntries(userId: string): Promise<Array<{
12885
+ name: string;
12886
+ value: string;
12887
+ type: 'text' | 'secret';
12888
+ created_at: number;
12889
+ updated_at: number;
12890
+ }>>;
12891
+ patchUserEnv(userId: string, params: {
12892
+ env_patch?: Record<string, unknown> | null;
12893
+ env_type_patch?: Record<string, unknown> | null;
12894
+ env_delete?: string[] | null;
12895
+ }): Promise<void>;
12855
12896
  listThreads(params?: {
12856
12897
  agent_name?: string;
12857
12898
  user_id?: string;
@@ -13009,44 +13050,44 @@ declare module 'virtual:@standardagents/router' {
13009
13050
  `;
13010
13051
  }
13011
13052
  function ensureDir(dir) {
13012
- if (!fs7__default.existsSync(dir)) {
13013
- fs7__default.mkdirSync(dir, { recursive: true });
13053
+ if (!fs8__default.existsSync(dir)) {
13054
+ fs8__default.mkdirSync(dir, { recursive: true });
13014
13055
  }
13015
13056
  }
13016
13057
  function writeFileIfChanged(filePath, content) {
13017
- if (fs7__default.existsSync(filePath)) {
13018
- const existing = fs7__default.readFileSync(filePath, "utf-8");
13058
+ if (fs8__default.existsSync(filePath)) {
13059
+ const existing = fs8__default.readFileSync(filePath, "utf-8");
13019
13060
  if (existing === content) {
13020
13061
  return;
13021
13062
  }
13022
13063
  }
13023
- fs7__default.writeFileSync(filePath, content);
13064
+ fs8__default.writeFileSync(filePath, content);
13024
13065
  }
13025
13066
  function generateTypes(config) {
13026
13067
  ensureDir(config.outputDir);
13027
13068
  const typesContent = generateTypesContent(config);
13028
- writeFileIfChanged(path7__default.join(config.outputDir, "types.d.ts"), typesContent);
13069
+ writeFileIfChanged(path8__default.join(config.outputDir, "types.d.ts"), typesContent);
13029
13070
  const virtualModuleContent = generateVirtualModuleContent();
13030
- writeFileIfChanged(path7__default.join(config.outputDir, "virtual-module.d.ts"), virtualModuleContent);
13031
- writeFileIfChanged(path7__default.join(config.outputDir, "tsconfig.json"), TSCONFIG_CONTENT);
13032
- writeFileIfChanged(path7__default.join(config.outputDir, ".gitignore"), "*\n");
13071
+ writeFileIfChanged(path8__default.join(config.outputDir, "virtual-module.d.ts"), virtualModuleContent);
13072
+ writeFileIfChanged(path8__default.join(config.outputDir, "tsconfig.json"), TSCONFIG_CONTENT);
13073
+ writeFileIfChanged(path8__default.join(config.outputDir, ".gitignore"), "*\n");
13033
13074
  }
13034
13075
  function needsRegeneration(config) {
13035
- const typesPath = path7__default.join(config.outputDir, "types.d.ts");
13036
- if (!fs7__default.existsSync(typesPath)) {
13076
+ const typesPath = path8__default.join(config.outputDir, "types.d.ts");
13077
+ if (!fs8__default.existsSync(typesPath)) {
13037
13078
  return true;
13038
13079
  }
13039
- const typesMtime = fs7__default.statSync(typesPath).mtime;
13080
+ const typesMtime = fs8__default.statSync(typesPath).mtime;
13040
13081
  const dirs = [config.modelsDir, config.promptsDir, config.agentsDir, config.toolsDir, config.hooksDir];
13041
13082
  for (const dir of dirs) {
13042
- if (!fs7__default.existsSync(dir)) {
13083
+ if (!fs8__default.existsSync(dir)) {
13043
13084
  continue;
13044
13085
  }
13045
- const entries = fs7__default.readdirSync(dir, { withFileTypes: true });
13086
+ const entries = fs8__default.readdirSync(dir, { withFileTypes: true });
13046
13087
  for (const entry of entries) {
13047
13088
  if (entry.isFile() && entry.name.endsWith(".ts")) {
13048
- const filePath = path7__default.join(dir, entry.name);
13049
- const fileMtime = fs7__default.statSync(filePath).mtime;
13089
+ const filePath = path8__default.join(dir, entry.name);
13090
+ const fileMtime = fs8__default.statSync(filePath).mtime;
13050
13091
  if (fileMtime > typesMtime) {
13051
13092
  return true;
13052
13093
  }
@@ -13233,7 +13274,7 @@ function createHmrReloader() {
13233
13274
  versions,
13234
13275
  invalidateSourceFileModule(server, filePath) {
13235
13276
  if (!filePath) return;
13236
- const absolutePath = path7__default.resolve(filePath);
13277
+ const absolutePath = path8__default.resolve(filePath);
13237
13278
  for (const [envName, env] of Object.entries(server.environments)) {
13238
13279
  const modules = env.moduleGraph.getModulesByFile(absolutePath);
13239
13280
  if (!modules) continue;
@@ -13244,10 +13285,10 @@ function createHmrReloader() {
13244
13285
  }
13245
13286
  },
13246
13287
  invalidateSourceDirectoryModules(server, dirPath) {
13247
- if (!fs7__default.existsSync(dirPath)) return;
13288
+ if (!fs8__default.existsSync(dirPath)) return;
13248
13289
  const scan = (currentDir) => {
13249
- for (const entry of fs7__default.readdirSync(currentDir, { withFileTypes: true })) {
13250
- const nextPath = path7__default.join(currentDir, entry.name);
13290
+ for (const entry of fs8__default.readdirSync(currentDir, { withFileTypes: true })) {
13291
+ const nextPath = path8__default.join(currentDir, entry.name);
13251
13292
  if (entry.isDirectory()) {
13252
13293
  scan(nextPath);
13253
13294
  } else if (entry.isFile() && entry.name.endsWith(".ts")) {
@@ -13399,6 +13440,73 @@ function createHmrReloader() {
13399
13440
  };
13400
13441
  return reloader;
13401
13442
  }
13443
+ var STATE_RELATIVE_PATH = path8__default.join(".agents", "bootstrap-session.json");
13444
+ var PROJECT_ROOT_ENV_KEYS = ["INIT_CWD", "PWD", "npm_config_local_prefix"];
13445
+ function uniquePaths(paths) {
13446
+ return Array.from(
13447
+ new Set(
13448
+ paths.filter((value) => !!value?.trim()).map((value) => path8__default.resolve(value))
13449
+ )
13450
+ );
13451
+ }
13452
+ function isBootstrapSessionRoute(routePath) {
13453
+ return routePath === "/api/platform-auth/me" || routePath === "/api/platform-session" || routePath.startsWith("/api/platform-session/");
13454
+ }
13455
+ function hasSessionCookie(cookieHeader) {
13456
+ const raw = Array.isArray(cookieHeader) ? cookieHeader.join("; ") : cookieHeader || "";
13457
+ return /(?:^|;\s*)session=/.test(raw);
13458
+ }
13459
+ function mergeCookieHeader(cookieHeader, injectedCookie) {
13460
+ const raw = Array.isArray(cookieHeader) ? cookieHeader.join("; ") : cookieHeader || "";
13461
+ return raw ? `${raw}; ${injectedCookie}` : injectedCookie;
13462
+ }
13463
+ function loadLocalBootstrapSession(projectRoot) {
13464
+ const statePath = path8__default.join(projectRoot, STATE_RELATIVE_PATH);
13465
+ if (!fs8__default.existsSync(statePath)) return null;
13466
+ try {
13467
+ const parsed = JSON.parse(
13468
+ fs8__default.readFileSync(statePath, "utf-8")
13469
+ );
13470
+ if (parsed.version !== 1) return null;
13471
+ if (!parsed.endpoint || !parsed.user?.id || !parsed.account?.id) return null;
13472
+ if (!parsed.session_cookie || typeof parsed.session_cookie !== "string") return null;
13473
+ return parsed;
13474
+ } catch {
13475
+ return null;
13476
+ }
13477
+ }
13478
+ function loadLocalBootstrapSessionFromEnv(env) {
13479
+ return null;
13480
+ }
13481
+ function findLocalBootstrapSession(projectRoot, env) {
13482
+ const envSession = loadLocalBootstrapSessionFromEnv();
13483
+ if (envSession) {
13484
+ return {
13485
+ projectRoot: projectRoot ? path8__default.resolve(projectRoot) : process.cwd(),
13486
+ session: envSession
13487
+ };
13488
+ }
13489
+ const candidates = uniquePaths([
13490
+ projectRoot,
13491
+ process.cwd(),
13492
+ ...PROJECT_ROOT_ENV_KEYS.map((key) => process.env[key])
13493
+ ]);
13494
+ for (const candidate of candidates) {
13495
+ const session = loadLocalBootstrapSession(candidate);
13496
+ if (session) {
13497
+ return {
13498
+ projectRoot: candidate,
13499
+ session
13500
+ };
13501
+ }
13502
+ }
13503
+ return null;
13504
+ }
13505
+ function resolveLocalBootstrapCookie(projectRoot, routePath, cookieHeader) {
13506
+ if (!isBootstrapSessionRoute(routePath)) return null;
13507
+ if (hasSessionCookie(cookieHeader)) return null;
13508
+ return findLocalBootstrapSession(projectRoot)?.session.session_cookie ?? null;
13509
+ }
13402
13510
 
13403
13511
  // src/sdk/generators/generateModelFile.ts
13404
13512
  function generateModelFile(data, options) {
@@ -14019,19 +14127,19 @@ function nameToFilename(name) {
14019
14127
  }
14020
14128
  function getModelFilePath(modelsDir, name) {
14021
14129
  const filename = nameToFilename(name);
14022
- return path7__default.join(modelsDir, `${filename}.ts`);
14130
+ return path8__default.join(modelsDir, `${filename}.ts`);
14023
14131
  }
14024
14132
  function modelExists(modelsDir, name) {
14025
14133
  const filePath = getModelFilePath(modelsDir, name);
14026
- return fs7__default.existsSync(filePath);
14134
+ return fs8__default.existsSync(filePath);
14027
14135
  }
14028
14136
  async function saveModel(modelsDir, data, overwrite = false, providerPackageMap = defaultProviderPackageMap) {
14029
14137
  try {
14030
- if (!fs7__default.existsSync(modelsDir)) {
14031
- fs7__default.mkdirSync(modelsDir, { recursive: true });
14138
+ if (!fs8__default.existsSync(modelsDir)) {
14139
+ fs8__default.mkdirSync(modelsDir, { recursive: true });
14032
14140
  }
14033
14141
  const filePath = getModelFilePath(modelsDir, data.name);
14034
- if (!overwrite && fs7__default.existsSync(filePath)) {
14142
+ if (!overwrite && fs8__default.existsSync(filePath)) {
14035
14143
  return {
14036
14144
  success: false,
14037
14145
  error: `Model file already exists: ${filePath}. Use update to modify existing models.`
@@ -14048,7 +14156,7 @@ async function saveModel(modelsDir, data, overwrite = false, providerPackageMap
14048
14156
  providerName: providerInfo.name,
14049
14157
  providerPackage: providerInfo.package
14050
14158
  });
14051
- await fs7__default.promises.writeFile(filePath, content, "utf-8");
14159
+ await fs8__default.promises.writeFile(filePath, content, "utf-8");
14052
14160
  return {
14053
14161
  success: true,
14054
14162
  filePath
@@ -14063,13 +14171,13 @@ async function saveModel(modelsDir, data, overwrite = false, providerPackageMap
14063
14171
  async function deleteModel(modelsDir, name) {
14064
14172
  try {
14065
14173
  const filePath = getModelFilePath(modelsDir, name);
14066
- if (!fs7__default.existsSync(filePath)) {
14174
+ if (!fs8__default.existsSync(filePath)) {
14067
14175
  return {
14068
14176
  success: false,
14069
14177
  error: `Model file not found: ${filePath}`
14070
14178
  };
14071
14179
  }
14072
- await fs7__default.promises.unlink(filePath);
14180
+ await fs8__default.promises.unlink(filePath);
14073
14181
  return {
14074
14182
  success: true,
14075
14183
  filePath
@@ -14330,26 +14438,26 @@ function transformPromptData(data) {
14330
14438
  }
14331
14439
  function getPromptFilePath(promptsDir, name) {
14332
14440
  const filename = nameToFilename(name);
14333
- return path7__default.join(promptsDir, `${filename}.ts`);
14441
+ return path8__default.join(promptsDir, `${filename}.ts`);
14334
14442
  }
14335
14443
  function promptExists(promptsDir, name) {
14336
14444
  const filePath = getPromptFilePath(promptsDir, name);
14337
- return fs7__default.existsSync(filePath);
14445
+ return fs8__default.existsSync(filePath);
14338
14446
  }
14339
14447
  async function savePrompt(promptsDir, data, overwrite = false) {
14340
14448
  try {
14341
- if (!fs7__default.existsSync(promptsDir)) {
14342
- fs7__default.mkdirSync(promptsDir, { recursive: true });
14449
+ if (!fs8__default.existsSync(promptsDir)) {
14450
+ fs8__default.mkdirSync(promptsDir, { recursive: true });
14343
14451
  }
14344
14452
  const filePath = getPromptFilePath(promptsDir, data.name);
14345
- if (!overwrite && fs7__default.existsSync(filePath)) {
14453
+ if (!overwrite && fs8__default.existsSync(filePath)) {
14346
14454
  return {
14347
14455
  success: false,
14348
14456
  error: `Prompt file already exists: ${filePath}. Use update to modify existing prompts.`
14349
14457
  };
14350
14458
  }
14351
14459
  const content = generatePromptFile(data);
14352
- await fs7__default.promises.writeFile(filePath, content, "utf-8");
14460
+ await fs8__default.promises.writeFile(filePath, content, "utf-8");
14353
14461
  return {
14354
14462
  success: true,
14355
14463
  filePath
@@ -14364,13 +14472,13 @@ async function savePrompt(promptsDir, data, overwrite = false) {
14364
14472
  async function deletePrompt(promptsDir, name) {
14365
14473
  try {
14366
14474
  const filePath = getPromptFilePath(promptsDir, name);
14367
- if (!fs7__default.existsSync(filePath)) {
14475
+ if (!fs8__default.existsSync(filePath)) {
14368
14476
  return {
14369
14477
  success: false,
14370
14478
  error: `Prompt file not found: ${filePath}`
14371
14479
  };
14372
14480
  }
14373
- await fs7__default.promises.unlink(filePath);
14481
+ await fs8__default.promises.unlink(filePath);
14374
14482
  return {
14375
14483
  success: true,
14376
14484
  filePath
@@ -14386,25 +14494,25 @@ async function renamePrompt(promptsDir, oldName, newName) {
14386
14494
  try {
14387
14495
  const oldFilePath = getPromptFilePath(promptsDir, oldName);
14388
14496
  const newFilePath = getPromptFilePath(promptsDir, newName);
14389
- if (!fs7__default.existsSync(oldFilePath)) {
14497
+ if (!fs8__default.existsSync(oldFilePath)) {
14390
14498
  return {
14391
14499
  success: false,
14392
14500
  error: `Prompt file not found: ${oldFilePath}`
14393
14501
  };
14394
14502
  }
14395
- if (fs7__default.existsSync(newFilePath)) {
14503
+ if (fs8__default.existsSync(newFilePath)) {
14396
14504
  return {
14397
14505
  success: false,
14398
14506
  error: `Prompt file already exists: ${newFilePath}`
14399
14507
  };
14400
14508
  }
14401
- const content = await fs7__default.promises.readFile(oldFilePath, "utf-8");
14509
+ const content = await fs8__default.promises.readFile(oldFilePath, "utf-8");
14402
14510
  const updatedContent = content.replace(
14403
14511
  /name:\s*['"]([^'"]+)['"]/,
14404
14512
  `name: '${newName}'`
14405
14513
  );
14406
- await fs7__default.promises.writeFile(newFilePath, updatedContent, "utf-8");
14407
- await fs7__default.promises.unlink(oldFilePath);
14514
+ await fs8__default.promises.writeFile(newFilePath, updatedContent, "utf-8");
14515
+ await fs8__default.promises.unlink(oldFilePath);
14408
14516
  return {
14409
14517
  success: true,
14410
14518
  filePath: newFilePath
@@ -14704,15 +14812,15 @@ function transformAgentData(data) {
14704
14812
  }
14705
14813
  function getAgentFilePath(agentsDir, name) {
14706
14814
  const filename = nameToFilename(name);
14707
- return path7__default.join(agentsDir, `${filename}.ts`);
14815
+ return path8__default.join(agentsDir, `${filename}.ts`);
14708
14816
  }
14709
14817
  function agentExists(agentsDir, name) {
14710
14818
  const filePath = getAgentFilePath(agentsDir, name);
14711
- return fs7__default.existsSync(filePath);
14819
+ return fs8__default.existsSync(filePath);
14712
14820
  }
14713
14821
  function extractAgentMetadata(filePath) {
14714
14822
  try {
14715
- const content = fs7__default.readFileSync(filePath, "utf-8");
14823
+ const content = fs8__default.readFileSync(filePath, "utf-8");
14716
14824
  const metadata = {};
14717
14825
  const packageNameMatch = content.match(/packageName:\s*['"]([^'"]+)['"]/);
14718
14826
  if (packageNameMatch) metadata.packageName = packageNameMatch[1];
@@ -14729,17 +14837,17 @@ function extractAgentMetadata(filePath) {
14729
14837
  }
14730
14838
  async function saveAgent(agentsDir, data, overwrite = false) {
14731
14839
  try {
14732
- if (!fs7__default.existsSync(agentsDir)) {
14733
- fs7__default.mkdirSync(agentsDir, { recursive: true });
14840
+ if (!fs8__default.existsSync(agentsDir)) {
14841
+ fs8__default.mkdirSync(agentsDir, { recursive: true });
14734
14842
  }
14735
14843
  const filePath = getAgentFilePath(agentsDir, data.name);
14736
- if (!overwrite && fs7__default.existsSync(filePath)) {
14844
+ if (!overwrite && fs8__default.existsSync(filePath)) {
14737
14845
  return {
14738
14846
  success: false,
14739
14847
  error: `Agent file already exists: ${filePath}. Use update to modify existing agents.`
14740
14848
  };
14741
14849
  }
14742
- if (overwrite && fs7__default.existsSync(filePath)) {
14850
+ if (overwrite && fs8__default.existsSync(filePath)) {
14743
14851
  const existingMetadata = extractAgentMetadata(filePath);
14744
14852
  if (existingMetadata.packageName && !data.packageName) {
14745
14853
  data.packageName = existingMetadata.packageName;
@@ -14755,7 +14863,7 @@ async function saveAgent(agentsDir, data, overwrite = false) {
14755
14863
  }
14756
14864
  }
14757
14865
  const content = generateAgentFile(data);
14758
- await fs7__default.promises.writeFile(filePath, content, "utf-8");
14866
+ await fs8__default.promises.writeFile(filePath, content, "utf-8");
14759
14867
  return {
14760
14868
  success: true,
14761
14869
  filePath
@@ -14770,13 +14878,13 @@ async function saveAgent(agentsDir, data, overwrite = false) {
14770
14878
  async function deleteAgent(agentsDir, name) {
14771
14879
  try {
14772
14880
  const filePath = getAgentFilePath(agentsDir, name);
14773
- if (!fs7__default.existsSync(filePath)) {
14881
+ if (!fs8__default.existsSync(filePath)) {
14774
14882
  return {
14775
14883
  success: false,
14776
14884
  error: `Agent file not found: ${filePath}`
14777
14885
  };
14778
14886
  }
14779
- await fs7__default.promises.unlink(filePath);
14887
+ await fs8__default.promises.unlink(filePath);
14780
14888
  return {
14781
14889
  success: true,
14782
14890
  filePath
@@ -14792,25 +14900,25 @@ async function renameModel(modelsDir, oldName, newName) {
14792
14900
  try {
14793
14901
  const oldFilePath = getModelFilePath(modelsDir, oldName);
14794
14902
  const newFilePath = getModelFilePath(modelsDir, newName);
14795
- if (!fs7__default.existsSync(oldFilePath)) {
14903
+ if (!fs8__default.existsSync(oldFilePath)) {
14796
14904
  return {
14797
14905
  success: false,
14798
14906
  error: `Model file not found: ${oldFilePath}`
14799
14907
  };
14800
14908
  }
14801
- if (fs7__default.existsSync(newFilePath)) {
14909
+ if (fs8__default.existsSync(newFilePath)) {
14802
14910
  return {
14803
14911
  success: false,
14804
14912
  error: `Model file already exists: ${newFilePath}`
14805
14913
  };
14806
14914
  }
14807
- const content = await fs7__default.promises.readFile(oldFilePath, "utf-8");
14915
+ const content = await fs8__default.promises.readFile(oldFilePath, "utf-8");
14808
14916
  const updatedContent = content.replace(
14809
14917
  /name:\s*['"]([^'"]+)['"]/,
14810
14918
  `name: '${newName}'`
14811
14919
  );
14812
- await fs7__default.promises.writeFile(newFilePath, updatedContent, "utf-8");
14813
- await fs7__default.promises.unlink(oldFilePath);
14920
+ await fs8__default.promises.writeFile(newFilePath, updatedContent, "utf-8");
14921
+ await fs8__default.promises.unlink(oldFilePath);
14814
14922
  return {
14815
14923
  success: true,
14816
14924
  filePath: newFilePath
@@ -14824,17 +14932,17 @@ async function renameModel(modelsDir, oldName, newName) {
14824
14932
  }
14825
14933
  async function updateModelReferencesInPrompts(promptsDir, oldModelName, newModelName) {
14826
14934
  const updatedFiles = [];
14827
- if (!fs7__default.existsSync(promptsDir)) {
14935
+ if (!fs8__default.existsSync(promptsDir)) {
14828
14936
  return updatedFiles;
14829
14937
  }
14830
- const files = fs7__default.readdirSync(promptsDir).filter((f) => f.endsWith(".ts"));
14938
+ const files = fs8__default.readdirSync(promptsDir).filter((f) => f.endsWith(".ts"));
14831
14939
  for (const file of files) {
14832
- const filePath = path7__default.join(promptsDir, file);
14833
- let content = await fs7__default.promises.readFile(filePath, "utf-8");
14940
+ const filePath = path8__default.join(promptsDir, file);
14941
+ let content = await fs8__default.promises.readFile(filePath, "utf-8");
14834
14942
  const modelRegex = new RegExp(`model:\\s*['"]${escapeRegExp(oldModelName)}['"]`, "g");
14835
14943
  if (modelRegex.test(content)) {
14836
14944
  content = content.replace(modelRegex, `model: '${newModelName}'`);
14837
- await fs7__default.promises.writeFile(filePath, content, "utf-8");
14945
+ await fs8__default.promises.writeFile(filePath, content, "utf-8");
14838
14946
  updatedFiles.push(filePath);
14839
14947
  }
14840
14948
  }
@@ -14842,13 +14950,13 @@ async function updateModelReferencesInPrompts(promptsDir, oldModelName, newModel
14842
14950
  }
14843
14951
  async function updatePromptReferencesInPrompts(promptsDir, oldPromptName, newPromptName) {
14844
14952
  const updatedFiles = [];
14845
- if (!fs7__default.existsSync(promptsDir)) {
14953
+ if (!fs8__default.existsSync(promptsDir)) {
14846
14954
  return updatedFiles;
14847
14955
  }
14848
- const files = fs7__default.readdirSync(promptsDir).filter((f) => f.endsWith(".ts"));
14956
+ const files = fs8__default.readdirSync(promptsDir).filter((f) => f.endsWith(".ts"));
14849
14957
  for (const file of files) {
14850
- const filePath = path7__default.join(promptsDir, file);
14851
- let content = await fs7__default.promises.readFile(filePath, "utf-8");
14958
+ const filePath = path8__default.join(promptsDir, file);
14959
+ let content = await fs8__default.promises.readFile(filePath, "utf-8");
14852
14960
  let modified = false;
14853
14961
  const toolsArrayRegex = /tools:\s*\[([^\]]*)\]/gs;
14854
14962
  const newContent = content.replace(toolsArrayRegex, (match) => {
@@ -14861,7 +14969,7 @@ async function updatePromptReferencesInPrompts(promptsDir, oldPromptName, newPro
14861
14969
  return replaced;
14862
14970
  });
14863
14971
  if (modified) {
14864
- await fs7__default.promises.writeFile(filePath, newContent, "utf-8");
14972
+ await fs8__default.promises.writeFile(filePath, newContent, "utf-8");
14865
14973
  updatedFiles.push(filePath);
14866
14974
  }
14867
14975
  }
@@ -14869,17 +14977,17 @@ async function updatePromptReferencesInPrompts(promptsDir, oldPromptName, newPro
14869
14977
  }
14870
14978
  async function updatePromptReferencesInAgents(agentsDir, oldPromptName, newPromptName) {
14871
14979
  const updatedFiles = [];
14872
- if (!fs7__default.existsSync(agentsDir)) {
14980
+ if (!fs8__default.existsSync(agentsDir)) {
14873
14981
  return updatedFiles;
14874
14982
  }
14875
- const files = fs7__default.readdirSync(agentsDir).filter((f) => f.endsWith(".ts"));
14983
+ const files = fs8__default.readdirSync(agentsDir).filter((f) => f.endsWith(".ts"));
14876
14984
  for (const file of files) {
14877
- const filePath = path7__default.join(agentsDir, file);
14878
- let content = await fs7__default.promises.readFile(filePath, "utf-8");
14985
+ const filePath = path8__default.join(agentsDir, file);
14986
+ let content = await fs8__default.promises.readFile(filePath, "utf-8");
14879
14987
  const promptRegex = new RegExp(`prompt:\\s*['"]${escapeRegExp(oldPromptName)}['"]`, "g");
14880
14988
  if (promptRegex.test(content)) {
14881
14989
  content = content.replace(promptRegex, `prompt: '${newPromptName}'`);
14882
- await fs7__default.promises.writeFile(filePath, content, "utf-8");
14990
+ await fs8__default.promises.writeFile(filePath, content, "utf-8");
14883
14991
  updatedFiles.push(filePath);
14884
14992
  }
14885
14993
  }
@@ -15006,16 +15114,16 @@ function parseThreadEndpointRouteKey(input) {
15006
15114
  };
15007
15115
  }
15008
15116
  function scanThreadEndpointFiles(dir, options = {}) {
15009
- if (!fs7__default.existsSync(dir)) {
15117
+ if (!fs8__default.existsSync(dir)) {
15010
15118
  return [];
15011
15119
  }
15012
15120
  const extensions = options.extensions ?? [".ts"];
15013
15121
  const routes = [];
15014
15122
  const scan = (currentDir, relativeDir = "") => {
15015
- const entries = fs7__default.readdirSync(currentDir, { withFileTypes: true });
15123
+ const entries = fs8__default.readdirSync(currentDir, { withFileTypes: true });
15016
15124
  for (const entry of entries) {
15017
- const filePath = path7__default.join(currentDir, entry.name);
15018
- const relativePath = relativeDir ? path7__default.posix.join(relativeDir, entry.name) : entry.name;
15125
+ const filePath = path8__default.join(currentDir, entry.name);
15126
+ const relativePath = relativeDir ? path8__default.posix.join(relativeDir, entry.name) : entry.name;
15019
15127
  if (entry.isDirectory()) {
15020
15128
  scan(filePath, relativePath);
15021
15129
  continue;
@@ -15049,7 +15157,7 @@ function scanApiDirectory(dir) {
15049
15157
  try {
15050
15158
  return scanThreadEndpointFiles(dir, {
15051
15159
  extensions: [".ts"],
15052
- importPathForFile: (filePath) => "./" + path7__default.relative(process.cwd(), filePath).replace(/\\/g, "/")
15160
+ importPathForFile: (filePath) => "./" + path8__default.relative(process.cwd(), filePath).replace(/\\/g, "/")
15053
15161
  }).map(({ method, route, importPath }) => ({
15054
15162
  method,
15055
15163
  route,
@@ -15061,26 +15169,26 @@ function scanApiDirectory(dir) {
15061
15169
  }
15062
15170
  }
15063
15171
  function discoverPackedPackageDirectories(packedDir) {
15064
- if (!fs7__default.existsSync(packedDir)) {
15172
+ if (!fs8__default.existsSync(packedDir)) {
15065
15173
  return [];
15066
15174
  }
15067
15175
  const packageDirs = [];
15068
- const entries = fs7__default.readdirSync(packedDir, { withFileTypes: true }).filter((entry) => entry.isDirectory());
15176
+ const entries = fs8__default.readdirSync(packedDir, { withFileTypes: true }).filter((entry) => entry.isDirectory());
15069
15177
  for (const entry of entries) {
15070
- const fullPath = path7__default.join(packedDir, entry.name);
15071
- const packageJsonPath = path7__default.join(fullPath, "package.json");
15072
- if (fs7__default.existsSync(packageJsonPath)) {
15178
+ const fullPath = path8__default.join(packedDir, entry.name);
15179
+ const packageJsonPath = path8__default.join(fullPath, "package.json");
15180
+ if (fs8__default.existsSync(packageJsonPath)) {
15073
15181
  packageDirs.push(fullPath);
15074
15182
  continue;
15075
15183
  }
15076
15184
  if (!entry.name.startsWith("@")) {
15077
15185
  continue;
15078
15186
  }
15079
- const scopedEntries = fs7__default.readdirSync(fullPath, { withFileTypes: true }).filter((scopedEntry) => scopedEntry.isDirectory());
15187
+ const scopedEntries = fs8__default.readdirSync(fullPath, { withFileTypes: true }).filter((scopedEntry) => scopedEntry.isDirectory());
15080
15188
  for (const scopedEntry of scopedEntries) {
15081
- const scopedPackagePath = path7__default.join(fullPath, scopedEntry.name);
15082
- const scopedPackageJson = path7__default.join(scopedPackagePath, "package.json");
15083
- if (fs7__default.existsSync(scopedPackageJson)) {
15189
+ const scopedPackagePath = path8__default.join(fullPath, scopedEntry.name);
15190
+ const scopedPackageJson = path8__default.join(scopedPackagePath, "package.json");
15191
+ if (fs8__default.existsSync(scopedPackageJson)) {
15084
15192
  packageDirs.push(scopedPackagePath);
15085
15193
  }
15086
15194
  }
@@ -15088,26 +15196,26 @@ function discoverPackedPackageDirectories(packedDir) {
15088
15196
  return packageDirs;
15089
15197
  }
15090
15198
  function scanPackedDistDirectory(packagePath, outputDir, subDir) {
15091
- const fullPath = path7__default.join(packagePath, outputDir, subDir);
15092
- if (!fs7__default.existsSync(fullPath)) {
15199
+ const fullPath = path8__default.join(packagePath, outputDir, subDir);
15200
+ if (!fs8__default.existsSync(fullPath)) {
15093
15201
  return [];
15094
15202
  }
15095
- return fs7__default.readdirSync(fullPath).filter((fileName) => fileName.endsWith(".js") || fileName.endsWith(".ts")).map((fileName) => ({
15203
+ return fs8__default.readdirSync(fullPath).filter((fileName) => fileName.endsWith(".js") || fileName.endsWith(".ts")).map((fileName) => ({
15096
15204
  name: fileName.replace(/\.(js|ts)$/, ""),
15097
- path: path7__default.join(fullPath, fileName).replace(/\\/g, "/")
15205
+ path: path8__default.join(fullPath, fileName).replace(/\\/g, "/")
15098
15206
  }));
15099
15207
  }
15100
15208
  function scanPackedThreadEndpoints(packagePath, outputDir) {
15101
- const rootDir = path7__default.join(packagePath, outputDir, "thread-endpoints");
15102
- if (!fs7__default.existsSync(rootDir)) {
15209
+ const rootDir = path8__default.join(packagePath, outputDir, "thread-endpoints");
15210
+ if (!fs8__default.existsSync(rootDir)) {
15103
15211
  return [];
15104
15212
  }
15105
15213
  const endpoints = [];
15106
15214
  const scan = (dir, relativeDir = "") => {
15107
- const entries = fs7__default.readdirSync(dir, { withFileTypes: true });
15215
+ const entries = fs8__default.readdirSync(dir, { withFileTypes: true });
15108
15216
  for (const entry of entries) {
15109
- const nextRelative = relativeDir ? path7__default.posix.join(relativeDir, entry.name) : entry.name;
15110
- const absolutePath = path7__default.join(dir, entry.name);
15217
+ const nextRelative = relativeDir ? path8__default.posix.join(relativeDir, entry.name) : entry.name;
15218
+ const absolutePath = path8__default.join(dir, entry.name);
15111
15219
  if (entry.isDirectory()) {
15112
15220
  scan(absolutePath, nextRelative);
15113
15221
  continue;
@@ -15137,7 +15245,7 @@ function isSnakeCase(str) {
15137
15245
  }
15138
15246
  function validateToolFile(filePath, fileName) {
15139
15247
  try {
15140
- const content = fs7__default.readFileSync(filePath, "utf-8");
15248
+ const content = fs8__default.readFileSync(filePath, "utf-8");
15141
15249
  const hasDefaultExport = /export\s+default\s+defineTool/.test(content);
15142
15250
  if (!hasDefaultExport) {
15143
15251
  return `Tool file '${fileName}.ts' must have a default export using defineTool()`;
@@ -15149,15 +15257,15 @@ function validateToolFile(filePath, fileName) {
15149
15257
  }
15150
15258
  async function scanToolsDirectory(dir) {
15151
15259
  const tools = [];
15152
- if (!fs7__default.existsSync(dir)) {
15260
+ if (!fs8__default.existsSync(dir)) {
15153
15261
  return tools;
15154
15262
  }
15155
- const entries = await fs7__default.promises.readdir(dir, { withFileTypes: true });
15263
+ const entries = await fs8__default.promises.readdir(dir, { withFileTypes: true });
15156
15264
  for (const entry of entries) {
15157
15265
  if (entry.isFile() && entry.name.endsWith(".ts")) {
15158
15266
  const fileName = entry.name.replace(".ts", "");
15159
- const filePath = path7__default.join(dir, entry.name);
15160
- const importPath = "./" + path7__default.relative(process.cwd(), filePath).replace(/\\/g, "/");
15267
+ const filePath = path8__default.join(dir, entry.name);
15268
+ const importPath = "./" + path8__default.relative(process.cwd(), filePath).replace(/\\/g, "/");
15161
15269
  let toolError;
15162
15270
  const validationError = validateToolFile(filePath, fileName);
15163
15271
  if (validationError) {
@@ -15184,18 +15292,18 @@ async function scanToolsDirectory(dir) {
15184
15292
  }
15185
15293
  async function scanHooksDirectory(dir) {
15186
15294
  const hooks = [];
15187
- if (!fs7__default.existsSync(dir)) {
15295
+ if (!fs8__default.existsSync(dir)) {
15188
15296
  return hooks;
15189
15297
  }
15190
- const entries = await fs7__default.promises.readdir(dir, { withFileTypes: true });
15298
+ const entries = await fs8__default.promises.readdir(dir, { withFileTypes: true });
15191
15299
  for (const entry of entries) {
15192
15300
  if (entry.isFile() && entry.name.endsWith(".ts")) {
15193
15301
  const fileName = entry.name.replace(".ts", "");
15194
15302
  if (fileName === "index") continue;
15195
- const filePath = path7__default.join(dir, entry.name);
15196
- const importPath = "./" + path7__default.relative(process.cwd(), filePath).replace(/\\/g, "/");
15303
+ const filePath = path8__default.join(dir, entry.name);
15304
+ const importPath = "./" + path8__default.relative(process.cwd(), filePath).replace(/\\/g, "/");
15197
15305
  try {
15198
- const content = fs7__default.readFileSync(filePath, "utf-8");
15306
+ const content = fs8__default.readFileSync(filePath, "utf-8");
15199
15307
  const idMatch = content.match(/id:\s*['"]([^'"]+)['"]/);
15200
15308
  const hookMatch = content.match(/hook:\s*['"]([^'"]+)['"]/);
15201
15309
  if (idMatch && hookMatch) {
@@ -15218,16 +15326,16 @@ async function scanHooksDirectory(dir) {
15218
15326
  }
15219
15327
  async function scanConfigDirectory(dir, definePattern) {
15220
15328
  const items = [];
15221
- if (!fs7__default.existsSync(dir)) {
15329
+ if (!fs8__default.existsSync(dir)) {
15222
15330
  return items;
15223
15331
  }
15224
- const entries = await fs7__default.promises.readdir(dir, { withFileTypes: true });
15332
+ const entries = await fs8__default.promises.readdir(dir, { withFileTypes: true });
15225
15333
  for (const entry of entries) {
15226
15334
  if (entry.isFile() && entry.name.endsWith(".ts")) {
15227
- const filePath = path7__default.join(dir, entry.name);
15228
- const importPath = "./" + path7__default.relative(process.cwd(), filePath).replace(/\\/g, "/");
15335
+ const filePath = path8__default.join(dir, entry.name);
15336
+ const importPath = "./" + path8__default.relative(process.cwd(), filePath).replace(/\\/g, "/");
15229
15337
  try {
15230
- const content = fs7__default.readFileSync(filePath, "utf-8");
15338
+ const content = fs8__default.readFileSync(filePath, "utf-8");
15231
15339
  const hasDefaultExport = definePattern.test(content);
15232
15340
  if (!hasDefaultExport) {
15233
15341
  items.push({
@@ -15269,20 +15377,20 @@ async function scanAgentsDirectory(dir) {
15269
15377
  }
15270
15378
  async function scanEffectsDirectory(dir) {
15271
15379
  const effects = [];
15272
- if (!fs7__default.existsSync(dir)) {
15380
+ if (!fs8__default.existsSync(dir)) {
15273
15381
  return effects;
15274
15382
  }
15275
- const entries = await fs7__default.promises.readdir(dir, { withFileTypes: true });
15383
+ const entries = await fs8__default.promises.readdir(dir, { withFileTypes: true });
15276
15384
  for (const entry of entries) {
15277
15385
  if (entry.isFile() && entry.name.endsWith(".ts")) {
15278
15386
  const fileName = entry.name.replace(".ts", "");
15279
- const filePath = path7__default.join(dir, entry.name);
15280
- const importPath = "./" + path7__default.relative(process.cwd(), filePath).replace(/\\/g, "/");
15387
+ const filePath = path8__default.join(dir, entry.name);
15388
+ const importPath = "./" + path8__default.relative(process.cwd(), filePath).replace(/\\/g, "/");
15281
15389
  if (fileName === "CLAUDE" || fileName.startsWith("_")) {
15282
15390
  continue;
15283
15391
  }
15284
15392
  try {
15285
- const content = fs7__default.readFileSync(filePath, "utf-8");
15393
+ const content = fs8__default.readFileSync(filePath, "utf-8");
15286
15394
  if (!content.includes("defineEffect")) {
15287
15395
  continue;
15288
15396
  }
@@ -15769,7 +15877,7 @@ var MetadataService = class {
15769
15877
  * @param agentsDir - Path to the agents/ directory
15770
15878
  */
15771
15879
  constructor(agentsDir) {
15772
- this.metadataDir = path7.join(agentsDir, ".standardagent");
15880
+ this.metadataDir = path8.join(agentsDir, ".standardagent");
15773
15881
  }
15774
15882
  /**
15775
15883
  * Read metadata for an agent.
@@ -15779,11 +15887,11 @@ var MetadataService = class {
15779
15887
  */
15780
15888
  async read(agentName) {
15781
15889
  const filePath = this.getMetadataPath(agentName);
15782
- if (!fs7.existsSync(filePath)) {
15890
+ if (!fs8.existsSync(filePath)) {
15783
15891
  return null;
15784
15892
  }
15785
15893
  try {
15786
- const content = fs7.readFileSync(filePath, "utf-8");
15894
+ const content = fs8.readFileSync(filePath, "utf-8");
15787
15895
  return JSON.parse(content);
15788
15896
  } catch {
15789
15897
  return null;
@@ -15796,11 +15904,11 @@ var MetadataService = class {
15796
15904
  * @param metadata - Metadata to write
15797
15905
  */
15798
15906
  async write(agentName, metadata) {
15799
- if (!fs7.existsSync(this.metadataDir)) {
15800
- fs7.mkdirSync(this.metadataDir, { recursive: true });
15907
+ if (!fs8.existsSync(this.metadataDir)) {
15908
+ fs8.mkdirSync(this.metadataDir, { recursive: true });
15801
15909
  }
15802
15910
  const filePath = this.getMetadataPath(agentName);
15803
- fs7.writeFileSync(filePath, JSON.stringify(metadata, null, 2));
15911
+ fs8.writeFileSync(filePath, JSON.stringify(metadata, null, 2));
15804
15912
  }
15805
15913
  /**
15806
15914
  * Delete metadata for an agent.
@@ -15809,8 +15917,8 @@ var MetadataService = class {
15809
15917
  */
15810
15918
  async delete(agentName) {
15811
15919
  const filePath = this.getMetadataPath(agentName);
15812
- if (fs7.existsSync(filePath)) {
15813
- fs7.unlinkSync(filePath);
15920
+ if (fs8.existsSync(filePath)) {
15921
+ fs8.unlinkSync(filePath);
15814
15922
  }
15815
15923
  }
15816
15924
  /**
@@ -15891,7 +15999,7 @@ var MetadataService = class {
15891
15999
  * Get the file path for an agent's metadata.
15892
16000
  */
15893
16001
  getMetadataPath(agentName) {
15894
- return path7.join(this.metadataDir, `${agentName}.json`);
16002
+ return path8.join(this.metadataDir, `${agentName}.json`);
15895
16003
  }
15896
16004
  };
15897
16005
  var _ts;
@@ -16263,9 +16371,9 @@ var PackingService = class {
16263
16371
  * @returns Version specifier (e.g., '^1.2.3') or '*' if not found
16264
16372
  */
16265
16373
  resolvePackageVersion(pkgName, rootDir) {
16266
- const pkgJsonPath = path7.join(rootDir, "node_modules", pkgName, "package.json");
16374
+ const pkgJsonPath = path8.join(rootDir, "node_modules", pkgName, "package.json");
16267
16375
  try {
16268
- const pkgJson = JSON.parse(fs7.readFileSync(pkgJsonPath, "utf-8"));
16376
+ const pkgJson = JSON.parse(fs8.readFileSync(pkgJsonPath, "utf-8"));
16269
16377
  return `^${pkgJson.version}`;
16270
16378
  } catch {
16271
16379
  return "*";
@@ -16282,7 +16390,7 @@ var PackingService = class {
16282
16390
  * @returns Analysis result with all discovered constituents
16283
16391
  */
16284
16392
  async analyzeAgent(agentName, rootDir) {
16285
- const agentsDir = path7.join(rootDir, "agents");
16393
+ const agentsDir = path8.join(rootDir, "agents");
16286
16394
  const analysis = {
16287
16395
  agent: agentName,
16288
16396
  primaryPrompt: "",
@@ -16306,7 +16414,7 @@ var PackingService = class {
16306
16414
  warnings: [],
16307
16415
  errors: []
16308
16416
  };
16309
- const agentFilePath = await this.findFile(path7.join(agentsDir, "agents"), agentName);
16417
+ const agentFilePath = await this.findFile(path8.join(agentsDir, "agents"), agentName);
16310
16418
  if (!agentFilePath) {
16311
16419
  analysis.errors.push(`Agent file not found: ${agentName}`);
16312
16420
  return analysis;
@@ -16317,7 +16425,7 @@ var PackingService = class {
16317
16425
  discoveredVia: "static",
16318
16426
  sharedWith: []
16319
16427
  });
16320
- const agentSource = fs7.readFileSync(agentFilePath, "utf-8");
16428
+ const agentSource = fs8.readFileSync(agentFilePath, "utf-8");
16321
16429
  const agentPrompts = await extractAgentPrompts(agentSource);
16322
16430
  if (agentPrompts.sideA) {
16323
16431
  analysis.primaryPrompt = agentPrompts.sideA;
@@ -16342,13 +16450,13 @@ var PackingService = class {
16342
16450
  * @returns Object with generatedReadme and agentDescription
16343
16451
  */
16344
16452
  async generateReadmeForAnalysis(analysis, rootDir) {
16345
- const agentsDir = path7.join(rootDir, "agents");
16453
+ const agentsDir = path8.join(rootDir, "agents");
16346
16454
  const metadataService = new MetadataService(agentsDir);
16347
16455
  let agentDescription;
16348
16456
  const agentItem = analysis.constituents.agents.find((a) => a.name === analysis.agent);
16349
16457
  if (agentItem?.filePath) {
16350
16458
  try {
16351
- const agentSource = fs7.readFileSync(agentItem.filePath, "utf-8");
16459
+ const agentSource = fs8.readFileSync(agentItem.filePath, "utf-8");
16352
16460
  agentDescription = await extractAgentDescription(agentSource) || void 0;
16353
16461
  } catch {
16354
16462
  }
@@ -16372,7 +16480,7 @@ var PackingService = class {
16372
16480
  * include all endpoint modules discovered under agents/api.
16373
16481
  */
16374
16482
  async analyzeThreadEndpoints(agentsDir, analysis) {
16375
- const apiDir = path7.join(agentsDir, "api");
16483
+ const apiDir = path8.join(agentsDir, "api");
16376
16484
  const endpoints = this.scanThreadEndpointFiles(apiDir);
16377
16485
  for (const endpoint of endpoints) {
16378
16486
  if (analysis.constituents.threadEndpoints.some((item) => item.name === endpoint.name)) {
@@ -16394,15 +16502,15 @@ var PackingService = class {
16394
16502
  * - `admin/users/[userId]/sync.post`
16395
16503
  */
16396
16504
  scanThreadEndpointFiles(apiDir, relativeDir = "") {
16397
- if (!fs7.existsSync(apiDir)) {
16505
+ if (!fs8.existsSync(apiDir)) {
16398
16506
  return [];
16399
16507
  }
16400
16508
  const endpoints = [];
16401
- const currentDir = relativeDir ? path7.join(apiDir, relativeDir) : apiDir;
16402
- if (!fs7.existsSync(currentDir)) {
16509
+ const currentDir = relativeDir ? path8.join(apiDir, relativeDir) : apiDir;
16510
+ if (!fs8.existsSync(currentDir)) {
16403
16511
  return endpoints;
16404
16512
  }
16405
- const entries = fs7.readdirSync(currentDir, { withFileTypes: true });
16513
+ const entries = fs8.readdirSync(currentDir, { withFileTypes: true });
16406
16514
  if (entries.length > 0 && typeof entries[0] === "string") {
16407
16515
  return endpoints;
16408
16516
  }
@@ -16410,8 +16518,8 @@ var PackingService = class {
16410
16518
  const entryName = typeof entry === "string" ? entry : entry.name;
16411
16519
  const isDirectory = typeof entry === "string" ? false : entry.isDirectory();
16412
16520
  const isFile = typeof entry === "string" ? true : entry.isFile();
16413
- const entryRelative = relativeDir ? path7.posix.join(relativeDir.replace(/\\/g, "/"), entryName) : entryName;
16414
- const absolutePath = path7.join(apiDir, entryRelative);
16521
+ const entryRelative = relativeDir ? path8.posix.join(relativeDir.replace(/\\/g, "/"), entryName) : entryName;
16522
+ const absolutePath = path8.join(apiDir, entryRelative);
16415
16523
  if (isDirectory) {
16416
16524
  endpoints.push(...this.scanThreadEndpointFiles(apiDir, entryRelative));
16417
16525
  continue;
@@ -16438,7 +16546,7 @@ var PackingService = class {
16438
16546
  * include all effect modules discovered under agents/effects.
16439
16547
  */
16440
16548
  async analyzeEffects(agentsDir, analysis) {
16441
- const effectsDir = path7.join(agentsDir, "effects");
16549
+ const effectsDir = path8.join(agentsDir, "effects");
16442
16550
  const effects = this.scanEffectFiles(effectsDir);
16443
16551
  for (const effect of effects) {
16444
16552
  if (analysis.constituents.effects.some((item) => item.name === effect.name)) {
@@ -16460,15 +16568,15 @@ var PackingService = class {
16460
16568
  * - `notifications/digest`
16461
16569
  */
16462
16570
  scanEffectFiles(effectsDir, relativeDir = "") {
16463
- if (!fs7.existsSync(effectsDir)) {
16571
+ if (!fs8.existsSync(effectsDir)) {
16464
16572
  return [];
16465
16573
  }
16466
16574
  const effects = [];
16467
- const currentDir = relativeDir ? path7.join(effectsDir, relativeDir) : effectsDir;
16468
- if (!fs7.existsSync(currentDir)) {
16575
+ const currentDir = relativeDir ? path8.join(effectsDir, relativeDir) : effectsDir;
16576
+ if (!fs8.existsSync(currentDir)) {
16469
16577
  return effects;
16470
16578
  }
16471
- const entries = fs7.readdirSync(currentDir, { withFileTypes: true });
16579
+ const entries = fs8.readdirSync(currentDir, { withFileTypes: true });
16472
16580
  if (entries.length > 0 && typeof entries[0] === "string") {
16473
16581
  return effects;
16474
16582
  }
@@ -16476,8 +16584,8 @@ var PackingService = class {
16476
16584
  const entryName = typeof entry === "string" ? entry : entry.name;
16477
16585
  const isDirectory = typeof entry === "string" ? false : entry.isDirectory();
16478
16586
  const isFile = typeof entry === "string" ? true : entry.isFile();
16479
- const entryRelative = relativeDir ? path7.posix.join(relativeDir.replace(/\\/g, "/"), entryName) : entryName;
16480
- const absolutePath = path7.join(effectsDir, entryRelative);
16587
+ const entryRelative = relativeDir ? path8.posix.join(relativeDir.replace(/\\/g, "/"), entryName) : entryName;
16588
+ const absolutePath = path8.join(effectsDir, entryRelative);
16481
16589
  if (isDirectory) {
16482
16590
  effects.push(...this.scanEffectFiles(effectsDir, entryRelative));
16483
16591
  continue;
@@ -16501,7 +16609,7 @@ var PackingService = class {
16501
16609
  * Recursively analyze a prompt and its dependencies.
16502
16610
  */
16503
16611
  async analyzePrompt(promptName, agentsDir, analysis, visited, parentKey) {
16504
- const promptFilePath = await this.findFile(path7.join(agentsDir, "prompts"), promptName);
16612
+ const promptFilePath = await this.findFile(path8.join(agentsDir, "prompts"), promptName);
16505
16613
  if (!promptFilePath) {
16506
16614
  analysis.warnings.push(`Prompt file not found: ${promptName}`);
16507
16615
  return;
@@ -16520,7 +16628,7 @@ var PackingService = class {
16520
16628
  return;
16521
16629
  }
16522
16630
  visited.add(`prompt:${promptName}`);
16523
- const promptSource = fs7.readFileSync(promptFilePath, "utf-8");
16631
+ const promptSource = fs8.readFileSync(promptFilePath, "utf-8");
16524
16632
  const modelName = await extractPromptModel(promptSource);
16525
16633
  if (modelName) {
16526
16634
  await this.analyzeModel(modelName, agentsDir, analysis, visited, thisKey);
@@ -16546,17 +16654,17 @@ var PackingService = class {
16546
16654
  */
16547
16655
  async analyzeTool(toolName, agentsDir, analysis, visited, discoveredVia, parentKey) {
16548
16656
  const thisKey = `tool:${toolName}`;
16549
- const promptFilePath = await this.findFile(path7.join(agentsDir, "prompts"), toolName);
16657
+ const promptFilePath = await this.findFile(path8.join(agentsDir, "prompts"), toolName);
16550
16658
  if (promptFilePath) {
16551
16659
  await this.analyzePrompt(toolName, agentsDir, analysis, visited, parentKey);
16552
16660
  return;
16553
16661
  }
16554
- const agentFilePath = await this.findFile(path7.join(agentsDir, "agents"), toolName);
16662
+ const agentFilePath = await this.findFile(path8.join(agentsDir, "agents"), toolName);
16555
16663
  if (agentFilePath) {
16556
16664
  await this.analyzeNestedAgent(toolName, agentsDir, analysis, visited, parentKey);
16557
16665
  return;
16558
16666
  }
16559
- const toolFilePath = await this.findFile(path7.join(agentsDir, "tools"), toolName);
16667
+ const toolFilePath = await this.findFile(path8.join(agentsDir, "tools"), toolName);
16560
16668
  if (!toolFilePath) {
16561
16669
  analysis.warnings.push(`Tool file not found: ${toolName}`);
16562
16670
  return;
@@ -16574,7 +16682,7 @@ var PackingService = class {
16574
16682
  return;
16575
16683
  }
16576
16684
  visited.add(`tool:${toolName}`);
16577
- const toolSource = fs7.readFileSync(toolFilePath, "utf-8");
16685
+ const toolSource = fs8.readFileSync(toolFilePath, "utf-8");
16578
16686
  const { uses } = await extractToolUses(toolSource);
16579
16687
  for (const usedItem of uses) {
16580
16688
  await this.analyzeTool(usedItem, agentsDir, analysis, visited, "uses", thisKey);
@@ -16584,7 +16692,7 @@ var PackingService = class {
16584
16692
  * Analyze a nested agent (used as a handoff target).
16585
16693
  */
16586
16694
  async analyzeNestedAgent(agentName, agentsDir, analysis, visited, parentKey) {
16587
- const agentFilePath = await this.findFile(path7.join(agentsDir, "agents"), agentName);
16695
+ const agentFilePath = await this.findFile(path8.join(agentsDir, "agents"), agentName);
16588
16696
  if (!agentFilePath) {
16589
16697
  analysis.warnings.push(`Agent file not found: ${agentName}`);
16590
16698
  return;
@@ -16603,7 +16711,7 @@ var PackingService = class {
16603
16711
  return;
16604
16712
  }
16605
16713
  visited.add(`agent:${agentName}`);
16606
- const agentSource = fs7.readFileSync(agentFilePath, "utf-8");
16714
+ const agentSource = fs8.readFileSync(agentFilePath, "utf-8");
16607
16715
  const agentPrompts = await extractAgentPrompts(agentSource);
16608
16716
  if (agentPrompts.sideA) {
16609
16717
  await this.analyzePrompt(agentPrompts.sideA, agentsDir, analysis, visited, thisKey);
@@ -16616,7 +16724,7 @@ var PackingService = class {
16616
16724
  * Analyze a model and its fallbacks.
16617
16725
  */
16618
16726
  async analyzeModel(modelName, agentsDir, analysis, visited, parentKey) {
16619
- const modelFilePath = await this.findFile(path7.join(agentsDir, "models"), modelName);
16727
+ const modelFilePath = await this.findFile(path8.join(agentsDir, "models"), modelName);
16620
16728
  if (!modelFilePath) {
16621
16729
  analysis.warnings.push(`Model file not found: ${modelName}`);
16622
16730
  return;
@@ -16635,7 +16743,7 @@ var PackingService = class {
16635
16743
  return;
16636
16744
  }
16637
16745
  visited.add(`model:${modelName}`);
16638
- const modelSource = fs7.readFileSync(modelFilePath, "utf-8");
16746
+ const modelSource = fs8.readFileSync(modelFilePath, "utf-8");
16639
16747
  const fallbacks = await extractModelFallbacks(modelSource);
16640
16748
  for (const fallbackName of fallbacks) {
16641
16749
  await this.analyzeModel(fallbackName, agentsDir, analysis, visited, thisKey);
@@ -16645,13 +16753,13 @@ var PackingService = class {
16645
16753
  * Check which items are shared with other agents.
16646
16754
  */
16647
16755
  async checkSharedItems(agentsDir, analysis) {
16648
- const agentsPath = path7.join(agentsDir, "agents");
16649
- if (!fs7.existsSync(agentsPath)) return;
16650
- const agentFiles = fs7.readdirSync(agentsPath).filter((f) => f.endsWith(".ts"));
16756
+ const agentsPath = path8.join(agentsDir, "agents");
16757
+ if (!fs8.existsSync(agentsPath)) return;
16758
+ const agentFiles = fs8.readdirSync(agentsPath).filter((f) => f.endsWith(".ts"));
16651
16759
  for (const agentFile of agentFiles) {
16652
16760
  const otherAgentName = agentFile.replace(".ts", "");
16653
16761
  if (otherAgentName === analysis.agent) continue;
16654
- const otherAnalysis = await this.analyzeAgentLight(otherAgentName, path7.dirname(agentsDir));
16762
+ const otherAnalysis = await this.analyzeAgentLight(otherAgentName, path8.dirname(agentsDir));
16655
16763
  for (const prompt of analysis.constituents.prompts) {
16656
16764
  if (otherAnalysis.prompts.includes(prompt.name)) {
16657
16765
  prompt.sharedWith.push(otherAgentName);
@@ -16683,19 +16791,19 @@ var PackingService = class {
16683
16791
  */
16684
16792
  async analyzeAgentLight(agentName, rootDir) {
16685
16793
  const result = { prompts: [], tools: [], models: [] };
16686
- const agentsDir = path7.join(rootDir, "agents");
16794
+ const agentsDir = path8.join(rootDir, "agents");
16687
16795
  const visited = /* @__PURE__ */ new Set();
16688
- const agentFilePath = await this.findFile(path7.join(agentsDir, "agents"), agentName);
16796
+ const agentFilePath = await this.findFile(path8.join(agentsDir, "agents"), agentName);
16689
16797
  if (!agentFilePath) return result;
16690
- const agentSource = fs7.readFileSync(agentFilePath, "utf-8");
16798
+ const agentSource = fs8.readFileSync(agentFilePath, "utf-8");
16691
16799
  const agentPrompts = await extractAgentPrompts(agentSource);
16692
16800
  const analyzePromptLight = async (promptName) => {
16693
16801
  if (visited.has(promptName)) return;
16694
16802
  visited.add(promptName);
16695
16803
  result.prompts.push(promptName);
16696
- const promptFilePath = await this.findFile(path7.join(agentsDir, "prompts"), promptName);
16804
+ const promptFilePath = await this.findFile(path8.join(agentsDir, "prompts"), promptName);
16697
16805
  if (!promptFilePath) return;
16698
- const promptSource = fs7.readFileSync(promptFilePath, "utf-8");
16806
+ const promptSource = fs8.readFileSync(promptFilePath, "utf-8");
16699
16807
  const modelName = await extractPromptModel(promptSource);
16700
16808
  if (modelName && !result.models.includes(modelName)) {
16701
16809
  result.models.push(modelName);
@@ -16768,14 +16876,14 @@ var PackingService = class {
16768
16876
  return result;
16769
16877
  }
16770
16878
  result.warnings = analysis.warnings;
16771
- const pkgOutputDir = path7.join(outputDir, packageId);
16772
- fs7.mkdirSync(path7.join(pkgOutputDir, "dist", "agents"), { recursive: true });
16773
- fs7.mkdirSync(path7.join(pkgOutputDir, "dist", "prompts"), { recursive: true });
16774
- fs7.mkdirSync(path7.join(pkgOutputDir, "dist", "tools"), { recursive: true });
16775
- fs7.mkdirSync(path7.join(pkgOutputDir, "dist", "models"), { recursive: true });
16776
- fs7.mkdirSync(path7.join(pkgOutputDir, "dist", "hooks"), { recursive: true });
16777
- fs7.mkdirSync(path7.join(pkgOutputDir, "dist", "effects"), { recursive: true });
16778
- fs7.mkdirSync(path7.join(pkgOutputDir, "dist", "thread-endpoints"), { recursive: true });
16879
+ const pkgOutputDir = path8.join(outputDir, packageId);
16880
+ fs8.mkdirSync(path8.join(pkgOutputDir, "dist", "agents"), { recursive: true });
16881
+ fs8.mkdirSync(path8.join(pkgOutputDir, "dist", "prompts"), { recursive: true });
16882
+ fs8.mkdirSync(path8.join(pkgOutputDir, "dist", "tools"), { recursive: true });
16883
+ fs8.mkdirSync(path8.join(pkgOutputDir, "dist", "models"), { recursive: true });
16884
+ fs8.mkdirSync(path8.join(pkgOutputDir, "dist", "hooks"), { recursive: true });
16885
+ fs8.mkdirSync(path8.join(pkgOutputDir, "dist", "effects"), { recursive: true });
16886
+ fs8.mkdirSync(path8.join(pkgOutputDir, "dist", "thread-endpoints"), { recursive: true });
16779
16887
  const seenItems = /* @__PURE__ */ new Set();
16780
16888
  const allItems = [];
16781
16889
  for (const a of analysis.constituents.agents) {
@@ -16829,13 +16937,13 @@ var PackingService = class {
16829
16937
  }
16830
16938
  const externalDeps = /* @__PURE__ */ new Map();
16831
16939
  for (const item of allItems) {
16832
- const outputPath = path7.join(
16940
+ const outputPath = path8.join(
16833
16941
  pkgOutputDir,
16834
16942
  "dist",
16835
16943
  this.getTypeDir(item.type),
16836
16944
  `${item.name}.js`
16837
16945
  );
16838
- fs7.mkdirSync(path7.dirname(outputPath), { recursive: true });
16946
+ fs8.mkdirSync(path8.dirname(outputPath), { recursive: true });
16839
16947
  const deps = await this.bundleFile(item.filePath, outputPath, rootDir);
16840
16948
  for (const [depName, depVersion] of deps) {
16841
16949
  if (!externalDeps.has(depName)) {
@@ -16845,12 +16953,12 @@ var PackingService = class {
16845
16953
  result.filesCreated.push(outputPath);
16846
16954
  }
16847
16955
  const indexJs = this.generateReExportIndex(analysis, meta);
16848
- const indexJsPath = path7.join(pkgOutputDir, "dist", "index.js");
16849
- fs7.writeFileSync(indexJsPath, indexJs);
16956
+ const indexJsPath = path8.join(pkgOutputDir, "dist", "index.js");
16957
+ fs8.writeFileSync(indexJsPath, indexJs);
16850
16958
  result.filesCreated.push(indexJsPath);
16851
16959
  const indexDts = this.generateIndexDts(analysis);
16852
- const indexDtsPath = path7.join(pkgOutputDir, "dist", "index.d.ts");
16853
- fs7.writeFileSync(indexDtsPath, indexDts);
16960
+ const indexDtsPath = path8.join(pkgOutputDir, "dist", "index.d.ts");
16961
+ fs8.writeFileSync(indexDtsPath, indexDts);
16854
16962
  result.filesCreated.push(indexDtsPath);
16855
16963
  const pkgJson = this.generatePackageJson(
16856
16964
  finalPackageName,
@@ -16863,13 +16971,13 @@ var PackingService = class {
16863
16971
  license,
16864
16972
  licenseOwner
16865
16973
  );
16866
- const pkgJsonPath = path7.join(pkgOutputDir, "package.json");
16867
- fs7.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2));
16974
+ const pkgJsonPath = path8.join(pkgOutputDir, "package.json");
16975
+ fs8.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2));
16868
16976
  result.filesCreated.push(pkgJsonPath);
16869
16977
  if (license) {
16870
16978
  const licenseContent = this.generateLicenseFile(license, licenseOwner);
16871
- const licensePath = path7.join(pkgOutputDir, "LICENSE");
16872
- fs7.writeFileSync(licensePath, licenseContent);
16979
+ const licensePath = path8.join(pkgOutputDir, "LICENSE");
16980
+ fs8.writeFileSync(licensePath, licenseContent);
16873
16981
  result.filesCreated.push(licensePath);
16874
16982
  }
16875
16983
  let readmeContent = readme;
@@ -16877,7 +16985,7 @@ var PackingService = class {
16877
16985
  const agentItem = analysis.constituents.agents.find((a) => a.name === agentName);
16878
16986
  let agentDescription;
16879
16987
  if (agentItem?.filePath) {
16880
- const agentSource = fs7.readFileSync(agentItem.filePath, "utf-8");
16988
+ const agentSource = fs8.readFileSync(agentItem.filePath, "utf-8");
16881
16989
  agentDescription = await extractAgentDescription(agentSource) || void 0;
16882
16990
  }
16883
16991
  readmeContent = this.generateReadme(
@@ -16888,21 +16996,21 @@ var PackingService = class {
16888
16996
  agentDescription
16889
16997
  );
16890
16998
  }
16891
- const readmePath = path7.join(pkgOutputDir, "README.md");
16892
- fs7.writeFileSync(readmePath, readmeContent);
16999
+ const readmePath = path8.join(pkgOutputDir, "README.md");
17000
+ fs8.writeFileSync(readmePath, readmeContent);
16893
17001
  result.filesCreated.push(readmePath);
16894
17002
  if (removeOriginals || itemSelections) {
16895
17003
  result.filesRemoved = [];
16896
17004
  for (const item of allItems) {
16897
17005
  const selection = itemSelections?.find((s) => s.name === item.name && s.type === item.type);
16898
17006
  const shouldRemove = selection ? selection.mode === "extract" : removeOriginals && item.sharedWith.length === 0 && item.type !== "thread-endpoint" && item.type !== "effect";
16899
- if (shouldRemove && fs7.existsSync(item.filePath)) {
16900
- fs7.unlinkSync(item.filePath);
17007
+ if (shouldRemove && fs8.existsSync(item.filePath)) {
17008
+ fs8.unlinkSync(item.filePath);
16901
17009
  result.filesRemoved.push(item.filePath);
16902
17010
  }
16903
17011
  }
16904
17012
  }
16905
- const agentsDir = path7.join(rootDir, "agents");
17013
+ const agentsDir = path8.join(rootDir, "agents");
16906
17014
  const metadataService = new MetadataService(agentsDir);
16907
17015
  const metadata = {
16908
17016
  packageName: finalPackageName,
@@ -16936,7 +17044,7 @@ var PackingService = class {
16936
17044
  const commonjs = (await import('@rollup/plugin-commonjs')).default;
16937
17045
  const esbuild = (await import('rollup-plugin-esbuild')).default;
16938
17046
  const externalDeps = /* @__PURE__ */ new Map();
16939
- const agentsDir = path7.join(rootDir, "agents");
17047
+ const agentsDir = path8.join(rootDir, "agents");
16940
17048
  const resolveVersion = this.resolvePackageVersion.bind(this);
16941
17049
  const trackExternalsPlugin = {
16942
17050
  name: "track-externals",
@@ -16945,14 +17053,14 @@ var PackingService = class {
16945
17053
  return null;
16946
17054
  }
16947
17055
  if (source.startsWith("./") || source.startsWith("../")) {
16948
- const resolved = path7.resolve(path7.dirname(importer), source);
17056
+ const resolved = path8.resolve(path8.dirname(importer), source);
16949
17057
  let tsResolved = resolved;
16950
17058
  if (!resolved.endsWith(".ts") && !resolved.endsWith(".js")) {
16951
- if (fs7.existsSync(`${resolved}.ts`)) {
17059
+ if (fs8.existsSync(`${resolved}.ts`)) {
16952
17060
  tsResolved = `${resolved}.ts`;
16953
- } else if (fs7.existsSync(`${resolved}.js`)) {
17061
+ } else if (fs8.existsSync(`${resolved}.js`)) {
16954
17062
  tsResolved = `${resolved}.js`;
16955
- } else if (fs7.existsSync(`${resolved}/index.ts`)) {
17063
+ } else if (fs8.existsSync(`${resolved}/index.ts`)) {
16956
17064
  tsResolved = `${resolved}/index.ts`;
16957
17065
  }
16958
17066
  }
@@ -17001,11 +17109,11 @@ var PackingService = class {
17001
17109
  exports: "named"
17002
17110
  });
17003
17111
  const bundledCode = output[0].code;
17004
- const header = `// Bundled from: ${path7.relative(rootDir, inputPath)}
17112
+ const header = `// Bundled from: ${path8.relative(rootDir, inputPath)}
17005
17113
  // Local dependencies have been inlined
17006
17114
 
17007
17115
  `;
17008
- fs7.writeFileSync(outputPath, header + bundledCode);
17116
+ fs8.writeFileSync(outputPath, header + bundledCode);
17009
17117
  await bundle.close();
17010
17118
  } catch (error) {
17011
17119
  await bundle.close();
@@ -17430,30 +17538,30 @@ Copyright (c) ${year} ${copyrightHolder}
17430
17538
  * @returns Package info or null if not found
17431
17539
  */
17432
17540
  getPackedInfo(packageId, rootDir) {
17433
- const packedDir = path7.join(rootDir, "agents", "packed");
17434
- let packageDir = path7.join(packedDir, packageId);
17435
- if (!fs7.existsSync(packageDir)) {
17436
- if (!fs7.existsSync(packedDir)) {
17541
+ const packedDir = path8.join(rootDir, "agents", "packed");
17542
+ let packageDir = path8.join(packedDir, packageId);
17543
+ if (!fs8.existsSync(packageDir)) {
17544
+ if (!fs8.existsSync(packedDir)) {
17437
17545
  return null;
17438
17546
  }
17439
- const dirs = fs7.readdirSync(packedDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
17547
+ const dirs = fs8.readdirSync(packedDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
17440
17548
  const matchingDir = dirs.find(
17441
17549
  (d) => d === packageId || d === `standardagent-${packageId}` || d === `standardagent-${packageId.replace(/_/g, "-")}`
17442
17550
  );
17443
17551
  if (!matchingDir) {
17444
17552
  return null;
17445
17553
  }
17446
- packageDir = path7.join(packedDir, matchingDir);
17554
+ packageDir = path8.join(packedDir, matchingDir);
17447
17555
  }
17448
- const pkgJsonPath = path7.join(packageDir, "package.json");
17449
- if (!fs7.existsSync(pkgJsonPath)) {
17556
+ const pkgJsonPath = path8.join(packageDir, "package.json");
17557
+ if (!fs8.existsSync(pkgJsonPath)) {
17450
17558
  return null;
17451
17559
  }
17452
- const pkgJson = JSON.parse(fs7.readFileSync(pkgJsonPath, "utf-8"));
17560
+ const pkgJson = JSON.parse(fs8.readFileSync(pkgJsonPath, "utf-8"));
17453
17561
  let readme;
17454
- const readmePath = path7.join(packageDir, "README.md");
17455
- if (fs7.existsSync(readmePath)) {
17456
- readme = fs7.readFileSync(readmePath, "utf-8");
17562
+ const readmePath = path8.join(packageDir, "README.md");
17563
+ if (fs8.existsSync(readmePath)) {
17564
+ readme = fs8.readFileSync(readmePath, "utf-8");
17457
17565
  }
17458
17566
  return {
17459
17567
  packageName: pkgJson.name,
@@ -17471,11 +17579,11 @@ Copyright (c) ${year} ${copyrightHolder}
17471
17579
  * @returns Array of package directory names
17472
17580
  */
17473
17581
  listPackedPackages(rootDir) {
17474
- const packedDir = path7.join(rootDir, "agents", "packed");
17475
- if (!fs7.existsSync(packedDir)) {
17582
+ const packedDir = path8.join(rootDir, "agents", "packed");
17583
+ if (!fs8.existsSync(packedDir)) {
17476
17584
  return [];
17477
17585
  }
17478
- return fs7.readdirSync(packedDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
17586
+ return fs8.readdirSync(packedDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
17479
17587
  }
17480
17588
  /**
17481
17589
  * Generate README.md content for a packed agent.
@@ -17522,17 +17630,17 @@ ${license || "See LICENSE file"}
17522
17630
  * Find a file by name in a directory.
17523
17631
  */
17524
17632
  async findFile(dir, name) {
17525
- if (!fs7.existsSync(dir)) {
17633
+ if (!fs8.existsSync(dir)) {
17526
17634
  return null;
17527
17635
  }
17528
- const exactPath = path7.join(dir, `${name}.ts`);
17529
- if (fs7.existsSync(exactPath)) {
17636
+ const exactPath = path8.join(dir, `${name}.ts`);
17637
+ if (fs8.existsSync(exactPath)) {
17530
17638
  return exactPath;
17531
17639
  }
17532
- const files = fs7.readdirSync(dir).filter((f) => f.endsWith(".ts"));
17640
+ const files = fs8.readdirSync(dir).filter((f) => f.endsWith(".ts"));
17533
17641
  for (const file of files) {
17534
- const filePath = path7.join(dir, file);
17535
- const source = fs7.readFileSync(filePath, "utf-8");
17642
+ const filePath = path8.join(dir, file);
17643
+ const source = fs8.readFileSync(filePath, "utf-8");
17536
17644
  const extractedName = await extractDefinitionName(source);
17537
17645
  if (extractedName === name) {
17538
17646
  return filePath;
@@ -17544,15 +17652,15 @@ ${license || "See LICENSE file"}
17544
17652
  * List all agents in the workspace.
17545
17653
  */
17546
17654
  async listAgents(rootDir) {
17547
- const agentsDir = path7.join(rootDir, "agents", "agents");
17548
- if (!fs7.existsSync(agentsDir)) {
17655
+ const agentsDir = path8.join(rootDir, "agents", "agents");
17656
+ if (!fs8.existsSync(agentsDir)) {
17549
17657
  return [];
17550
17658
  }
17551
- const files = fs7.readdirSync(agentsDir).filter((f) => f.endsWith(".ts"));
17659
+ const files = fs8.readdirSync(agentsDir).filter((f) => f.endsWith(".ts"));
17552
17660
  const agents = [];
17553
17661
  for (const file of files) {
17554
- const filePath = path7.join(agentsDir, file);
17555
- const source = fs7.readFileSync(filePath, "utf-8");
17662
+ const filePath = path8.join(agentsDir, file);
17663
+ const source = fs8.readFileSync(filePath, "utf-8");
17556
17664
  const name = await extractDefinitionName(source);
17557
17665
  if (name) {
17558
17666
  agents.push(name);
@@ -17568,7 +17676,7 @@ var PackageDiscoveryService = class {
17568
17676
  constructor(config) {
17569
17677
  this.config = {
17570
17678
  rootDir: config.rootDir,
17571
- packedDir: config.packedDir ?? path7.join(config.rootDir, "agents", "packed"),
17679
+ packedDir: config.packedDir ?? path8.join(config.rootDir, "agents", "packed"),
17572
17680
  scanNpm: config.scanNpm ?? true,
17573
17681
  scanLocal: config.scanLocal ?? true
17574
17682
  };
@@ -17601,19 +17709,19 @@ var PackageDiscoveryService = class {
17601
17709
  */
17602
17710
  async discoverNpmPackages() {
17603
17711
  const packages = [];
17604
- const nodeModulesDir = path7.join(this.config.rootDir, "node_modules");
17605
- if (!fs7.existsSync(nodeModulesDir)) {
17712
+ const nodeModulesDir = path8.join(this.config.rootDir, "node_modules");
17713
+ if (!fs8.existsSync(nodeModulesDir)) {
17606
17714
  return packages;
17607
17715
  }
17608
17716
  const rootEntries = await this.scanDirectory(nodeModulesDir);
17609
17717
  for (const entry of rootEntries) {
17610
17718
  if (entry.startsWith(".")) continue;
17611
17719
  if (entry.startsWith("@")) {
17612
- const scopeDir = path7.join(nodeModulesDir, entry);
17720
+ const scopeDir = path8.join(nodeModulesDir, entry);
17613
17721
  const scopeEntries = await this.scanDirectory(scopeDir);
17614
17722
  for (const scopedPkg of scopeEntries) {
17615
17723
  if (scopedPkg.startsWith(".")) continue;
17616
- const pkgDir = path7.join(scopeDir, scopedPkg);
17724
+ const pkgDir = path8.join(scopeDir, scopedPkg);
17617
17725
  const fullName = `${entry}/${scopedPkg}`;
17618
17726
  const pkg = await this.checkNpmPackage(pkgDir, fullName);
17619
17727
  if (pkg) {
@@ -17621,7 +17729,7 @@ var PackageDiscoveryService = class {
17621
17729
  }
17622
17730
  }
17623
17731
  } else {
17624
- const pkgDir = path7.join(nodeModulesDir, entry);
17732
+ const pkgDir = path8.join(nodeModulesDir, entry);
17625
17733
  const pkg = await this.checkNpmPackage(pkgDir, entry);
17626
17734
  if (pkg) {
17627
17735
  packages.push(pkg);
@@ -17637,12 +17745,12 @@ var PackageDiscoveryService = class {
17637
17745
  * which must contain `entryAgents` array.
17638
17746
  */
17639
17747
  async checkNpmPackage(pkgDir, pkgName) {
17640
- const pkgJsonPath = path7.join(pkgDir, "package.json");
17641
- if (!fs7.existsSync(pkgJsonPath)) {
17748
+ const pkgJsonPath = path8.join(pkgDir, "package.json");
17749
+ if (!fs8.existsSync(pkgJsonPath)) {
17642
17750
  return null;
17643
17751
  }
17644
17752
  try {
17645
- const pkgJson = JSON.parse(fs7.readFileSync(pkgJsonPath, "utf-8"));
17753
+ const pkgJson = JSON.parse(fs8.readFileSync(pkgJsonPath, "utf-8"));
17646
17754
  const isStandardAgent = (
17647
17755
  // Has "standardagent" keyword
17648
17756
  pkgJson.keywords?.includes("standardagent") || // Has "standardagent-*" prefix
@@ -17679,21 +17787,21 @@ var PackageDiscoveryService = class {
17679
17787
  */
17680
17788
  async discoverLocalPackages() {
17681
17789
  const packages = [];
17682
- if (!fs7.existsSync(this.config.packedDir)) {
17790
+ if (!fs8.existsSync(this.config.packedDir)) {
17683
17791
  return packages;
17684
17792
  }
17685
17793
  const entries = await this.scanDirectory(this.config.packedDir);
17686
17794
  for (const entry of entries) {
17687
17795
  if (entry.startsWith(".")) continue;
17688
- const pkgDir = path7.join(this.config.packedDir, entry);
17689
- const stat2 = fs7.statSync(pkgDir);
17796
+ const pkgDir = path8.join(this.config.packedDir, entry);
17797
+ const stat2 = fs8.statSync(pkgDir);
17690
17798
  if (!stat2.isDirectory()) continue;
17691
17799
  if (entry.startsWith("@")) {
17692
17800
  const scopeEntries = await this.scanDirectory(pkgDir);
17693
17801
  for (const scopedPkg of scopeEntries) {
17694
17802
  if (scopedPkg.startsWith(".")) continue;
17695
- const scopedPkgDir = path7.join(pkgDir, scopedPkg);
17696
- const scopedStat = fs7.statSync(scopedPkgDir);
17803
+ const scopedPkgDir = path8.join(pkgDir, scopedPkg);
17804
+ const scopedStat = fs8.statSync(scopedPkgDir);
17697
17805
  if (!scopedStat.isDirectory()) continue;
17698
17806
  const fullName = `${entry}/${scopedPkg}`;
17699
17807
  const pkg = await this.checkLocalPackage(scopedPkgDir, fullName);
@@ -17716,12 +17824,12 @@ var PackageDiscoveryService = class {
17716
17824
  * Detection is based on the `standardagent` field in package.json.
17717
17825
  */
17718
17826
  async checkLocalPackage(pkgDir, dirName) {
17719
- const pkgJsonPath = path7.join(pkgDir, "package.json");
17720
- if (!fs7.existsSync(pkgJsonPath)) {
17827
+ const pkgJsonPath = path8.join(pkgDir, "package.json");
17828
+ if (!fs8.existsSync(pkgJsonPath)) {
17721
17829
  return null;
17722
17830
  }
17723
17831
  try {
17724
- const pkgJson = JSON.parse(fs7.readFileSync(pkgJsonPath, "utf-8"));
17832
+ const pkgJson = JSON.parse(fs8.readFileSync(pkgJsonPath, "utf-8"));
17725
17833
  if (!pkgJson.standardagent?.entryAgents) {
17726
17834
  return null;
17727
17835
  }
@@ -17746,10 +17854,10 @@ var PackageDiscoveryService = class {
17746
17854
  * Scan a directory and return entry names.
17747
17855
  */
17748
17856
  async scanDirectory(dir) {
17749
- if (!fs7.existsSync(dir)) {
17857
+ if (!fs8.existsSync(dir)) {
17750
17858
  return [];
17751
17859
  }
17752
- const entries = fs7.readdirSync(dir);
17860
+ const entries = fs8.readdirSync(dir);
17753
17861
  return entries;
17754
17862
  }
17755
17863
  /**
@@ -17846,29 +17954,29 @@ var UnpackingService = class {
17846
17954
  }
17847
17955
  analysis.version = pkg.version;
17848
17956
  analysis.source = pkg.source;
17849
- const indexPath = path7.join(pkg.path, "dist", "index.js");
17850
- if (!fs7.existsSync(indexPath)) {
17957
+ const indexPath = path8.join(pkg.path, "dist", "index.js");
17958
+ if (!fs8.existsSync(indexPath)) {
17851
17959
  analysis.errors.push(`Package index not found: ${indexPath}`);
17852
17960
  return analysis;
17853
17961
  }
17854
- const indexContent = fs7.readFileSync(indexPath, "utf-8");
17962
+ const indexContent = fs8.readFileSync(indexPath, "utf-8");
17855
17963
  const registryItems = await this.parseIndexExports(indexContent);
17856
17964
  const availableItems = /* @__PURE__ */ new Map();
17857
17965
  for (const item of registryItems) {
17858
17966
  availableItems.set(`${item.type}:${item.name}`, item);
17859
17967
  }
17860
- const agentsDir = path7.join(rootDir, "agents");
17968
+ const agentsDir = path8.join(rootDir, "agents");
17861
17969
  const itemsWithRelations = [];
17862
17970
  for (const item of registryItems) {
17863
- const targetPath = path7.join(agentsDir, TYPE_TO_TARGET_DIR[item.type], `${item.name}.ts`);
17864
- const sourcePath = path7.join(pkg.path, "dist", TYPE_TO_DIR[item.type], `${item.name}.js`);
17971
+ const targetPath = path8.join(agentsDir, TYPE_TO_TARGET_DIR[item.type], `${item.name}.ts`);
17972
+ const sourcePath = path8.join(pkg.path, "dist", TYPE_TO_DIR[item.type], `${item.name}.js`);
17865
17973
  const existsGlobally = this.fileExists(targetPath);
17866
- const sourceExists = fs7.existsSync(sourcePath);
17974
+ const sourceExists = fs8.existsSync(sourcePath);
17867
17975
  if (!sourceExists) {
17868
17976
  analysis.warnings.push(`Source file not found for ${item.type} "${item.name}": ${sourcePath}`);
17869
17977
  continue;
17870
17978
  }
17871
- const bundledCode = fs7.readFileSync(sourcePath, "utf-8");
17979
+ const bundledCode = fs8.readFileSync(sourcePath, "utf-8");
17872
17980
  const children = await this.discoverRelationships(item.type, item.name, bundledCode, availableItems);
17873
17981
  itemsWithRelations.push({
17874
17982
  name: item.name,
@@ -17878,10 +17986,10 @@ var UnpackingService = class {
17878
17986
  action: existsGlobally ? "skip" : "generate"
17879
17987
  });
17880
17988
  for (const child of children) {
17881
- const childTargetPath = path7.join(agentsDir, TYPE_TO_TARGET_DIR[child.type], `${child.name}.ts`);
17882
- const childSourcePath = path7.join(pkg.path, "dist", TYPE_TO_DIR[child.type], `${child.name}.js`);
17989
+ const childTargetPath = path8.join(agentsDir, TYPE_TO_TARGET_DIR[child.type], `${child.name}.ts`);
17990
+ const childSourcePath = path8.join(pkg.path, "dist", TYPE_TO_DIR[child.type], `${child.name}.js`);
17883
17991
  const childExists = this.fileExists(childTargetPath);
17884
- const childSourceExists = fs7.existsSync(childSourcePath);
17992
+ const childSourceExists = fs8.existsSync(childSourcePath);
17885
17993
  if (!childSourceExists) {
17886
17994
  continue;
17887
17995
  }
@@ -17984,8 +18092,8 @@ var UnpackingService = class {
17984
18092
  return result;
17985
18093
  }
17986
18094
  const itemsToProcess = this.applySelections(analysis.items, itemSelections);
17987
- const pkgJsonPath = path7.join(pkg.path, "package.json");
17988
- const pkgJson = JSON.parse(fs7.readFileSync(pkgJsonPath, "utf-8"));
18095
+ const pkgJsonPath = path8.join(pkg.path, "package.json");
18096
+ const pkgJson = JSON.parse(fs8.readFileSync(pkgJsonPath, "utf-8"));
17989
18097
  let author = "";
17990
18098
  if (typeof pkgJson.author === "string") {
17991
18099
  author = pkgJson.author;
@@ -18010,17 +18118,17 @@ var UnpackingService = class {
18010
18118
  continue;
18011
18119
  }
18012
18120
  try {
18013
- const sourcePath = path7.join(pkg.path, "dist", TYPE_TO_DIR[item.type], `${item.name}.js`);
18014
- const bundledCode = fs7.readFileSync(sourcePath, "utf-8");
18121
+ const sourcePath = path8.join(pkg.path, "dist", TYPE_TO_DIR[item.type], `${item.name}.js`);
18122
+ const bundledCode = fs8.readFileSync(sourcePath, "utf-8");
18015
18123
  let tsCode = await transformBundledJs(bundledCode);
18016
18124
  if (item.type === "agent") {
18017
18125
  tsCode = await injectAgentMetadata(tsCode, agentMetadata);
18018
18126
  }
18019
- const dir = path7.dirname(item.targetPath);
18020
- if (!fs7.existsSync(dir)) {
18021
- fs7.mkdirSync(dir, { recursive: true });
18127
+ const dir = path8.dirname(item.targetPath);
18128
+ if (!fs8.existsSync(dir)) {
18129
+ fs8.mkdirSync(dir, { recursive: true });
18022
18130
  }
18023
- fs7.writeFileSync(item.targetPath, tsCode);
18131
+ fs8.writeFileSync(item.targetPath, tsCode);
18024
18132
  result.filesGenerated.push(item.targetPath);
18025
18133
  } catch (error) {
18026
18134
  result.warnings.push(
@@ -18109,14 +18217,14 @@ var UnpackingService = class {
18109
18217
  */
18110
18218
  async resolvePackage(pkgIdentifier, rootDir) {
18111
18219
  if (pkgIdentifier.startsWith("/") || pkgIdentifier.startsWith("./")) {
18112
- const absolutePath = path7.isAbsolute(pkgIdentifier) ? pkgIdentifier : path7.join(rootDir, pkgIdentifier);
18113
- const pkgJsonPath2 = path7.join(absolutePath, "package.json");
18114
- if (fs7.existsSync(pkgJsonPath2)) {
18220
+ const absolutePath = path8.isAbsolute(pkgIdentifier) ? pkgIdentifier : path8.join(rootDir, pkgIdentifier);
18221
+ const pkgJsonPath2 = path8.join(absolutePath, "package.json");
18222
+ if (fs8.existsSync(pkgJsonPath2)) {
18115
18223
  try {
18116
- const pkgJson = JSON.parse(fs7.readFileSync(pkgJsonPath2, "utf-8"));
18224
+ const pkgJson = JSON.parse(fs8.readFileSync(pkgJsonPath2, "utf-8"));
18117
18225
  if (pkgJson.standardagent?.entryAgents) {
18118
18226
  return {
18119
- packageId: pkgJson.name || path7.basename(absolutePath),
18227
+ packageId: pkgJson.name || path8.basename(absolutePath),
18120
18228
  version: pkgJson.version || "0.0.0",
18121
18229
  source: "local",
18122
18230
  path: absolutePath,
@@ -18128,11 +18236,11 @@ var UnpackingService = class {
18128
18236
  }
18129
18237
  return null;
18130
18238
  }
18131
- const packedDir = path7.join(rootDir, "agents", "packed", pkgIdentifier);
18132
- const pkgJsonPath = path7.join(packedDir, "package.json");
18133
- if (fs7.existsSync(pkgJsonPath)) {
18239
+ const packedDir = path8.join(rootDir, "agents", "packed", pkgIdentifier);
18240
+ const pkgJsonPath = path8.join(packedDir, "package.json");
18241
+ if (fs8.existsSync(pkgJsonPath)) {
18134
18242
  try {
18135
- const pkgJson = JSON.parse(fs7.readFileSync(pkgJsonPath, "utf-8"));
18243
+ const pkgJson = JSON.parse(fs8.readFileSync(pkgJsonPath, "utf-8"));
18136
18244
  if (pkgJson.standardagent?.entryAgents) {
18137
18245
  return {
18138
18246
  packageId: pkgJson.name || pkgIdentifier,
@@ -18173,18 +18281,18 @@ var UnpackingService = class {
18173
18281
  * Check if a file exists.
18174
18282
  */
18175
18283
  fileExists(filePath) {
18176
- if (fs7.existsSync(filePath)) {
18284
+ if (fs8.existsSync(filePath)) {
18177
18285
  return true;
18178
18286
  }
18179
18287
  const withoutExt = filePath.replace(/\.(ts|js)$/, "");
18180
- return fs7.existsSync(`${withoutExt}.ts`) || fs7.existsSync(`${withoutExt}.js`);
18288
+ return fs8.existsSync(`${withoutExt}.ts`) || fs8.existsSync(`${withoutExt}.js`);
18181
18289
  }
18182
18290
  /**
18183
18291
  * Recursively delete a directory.
18184
18292
  */
18185
18293
  deleteDirectory(dirPath) {
18186
- if (fs7.existsSync(dirPath)) {
18187
- fs7.rmSync(dirPath, { recursive: true, force: true });
18294
+ if (fs8.existsSync(dirPath)) {
18295
+ fs8.rmSync(dirPath, { recursive: true, force: true });
18188
18296
  }
18189
18297
  }
18190
18298
  /**
@@ -18260,8 +18368,8 @@ var NpmPublishService = class {
18260
18368
  error: "Registry URL must use HTTPS"
18261
18369
  };
18262
18370
  }
18263
- const pkgJsonPath = path7.join(packageDir, "package.json");
18264
- if (!fs7.existsSync(pkgJsonPath)) {
18371
+ const pkgJsonPath = path8.join(packageDir, "package.json");
18372
+ if (!fs8.existsSync(pkgJsonPath)) {
18265
18373
  return {
18266
18374
  success: false,
18267
18375
  output: "",
@@ -18271,7 +18379,7 @@ var NpmPublishService = class {
18271
18379
  let packageName;
18272
18380
  let version;
18273
18381
  try {
18274
- const pkgJson = JSON.parse(fs7.readFileSync(pkgJsonPath, "utf-8"));
18382
+ const pkgJson = JSON.parse(fs8.readFileSync(pkgJsonPath, "utf-8"));
18275
18383
  packageName = pkgJson.name;
18276
18384
  version = pkgJson.version;
18277
18385
  } catch (e) {
@@ -18281,13 +18389,13 @@ var NpmPublishService = class {
18281
18389
  error: `Failed to read package.json: ${e instanceof Error ? e.message : String(e)}`
18282
18390
  };
18283
18391
  }
18284
- const npmrcPath = path7.join(packageDir, ".npmrc");
18392
+ const npmrcPath = path8.join(packageDir, ".npmrc");
18285
18393
  const registryHost = new URL(registry).host;
18286
18394
  const npmrcContent = `//${registryHost}/:_authToken=${token}
18287
18395
  registry=${registry}
18288
18396
  `;
18289
18397
  try {
18290
- fs7.writeFileSync(npmrcPath, npmrcContent, { mode: 384 });
18398
+ fs8.writeFileSync(npmrcPath, npmrcContent, { mode: 384 });
18291
18399
  const args = ["publish"];
18292
18400
  if (dryRun) {
18293
18401
  args.push("--dry-run");
@@ -18319,8 +18427,8 @@ registry=${registry}
18319
18427
  };
18320
18428
  } finally {
18321
18429
  try {
18322
- if (fs7.existsSync(npmrcPath)) {
18323
- fs7.unlinkSync(npmrcPath);
18430
+ if (fs8.existsSync(npmrcPath)) {
18431
+ fs8.unlinkSync(npmrcPath);
18324
18432
  }
18325
18433
  } catch {
18326
18434
  }
@@ -18413,7 +18521,7 @@ async function handlePackingApiRequest(context) {
18413
18521
  const body = await parseRequestBody(req);
18414
18522
  const packingService = new PackingService();
18415
18523
  const rootDir = process.cwd();
18416
- const outputDir = path7__default.join(rootDir, "agents", "packed");
18524
+ const outputDir = path8__default.join(rootDir, "agents", "packed");
18417
18525
  const result = await packingService.pack({
18418
18526
  agentName,
18419
18527
  rootDir,
@@ -18466,8 +18574,8 @@ async function handlePackingApiRequest(context) {
18466
18574
  res.end(JSON.stringify({ error: "Cannot delete npm packages. Use npm uninstall instead." }));
18467
18575
  return true;
18468
18576
  }
18469
- const fs17 = await import('fs');
18470
- fs17.rmSync(pkg.path, { recursive: true, force: true });
18577
+ const fs18 = await import('fs');
18578
+ fs18.rmSync(pkg.path, { recursive: true, force: true });
18471
18579
  await reloadAllAgentModules(context);
18472
18580
  res.statusCode = 200;
18473
18581
  res.setHeader("Content-Type", "application/json");
@@ -18495,8 +18603,8 @@ async function handlePackingApiRequest(context) {
18495
18603
  return true;
18496
18604
  }
18497
18605
  const { spawn } = await import('child_process');
18498
- const parentDir = path7__default.dirname(pkg.path);
18499
- const dirName = path7__default.basename(pkg.path);
18606
+ const parentDir = path8__default.dirname(pkg.path);
18607
+ const dirName = path8__default.basename(pkg.path);
18500
18608
  res.setHeader("Content-Type", "application/gzip");
18501
18609
  res.setHeader("Content-Disposition", `attachment; filename="${packageId}.tar.gz"`);
18502
18610
  const tar = spawn("tar", ["-czf", "-", "-C", parentDir, dirName]);
@@ -18552,16 +18660,16 @@ async function handlePackingApiRequest(context) {
18552
18660
  const packageId = decodeURIComponent(packPublishMatch[1]);
18553
18661
  const body = await parseRequestBody(req);
18554
18662
  const rootDir = process.cwd();
18555
- const packedDir = path7__default.join(rootDir, "agents", "packed");
18556
- let packageDir = path7__default.join(packedDir, packageId);
18557
- if (!fs7__default.existsSync(packageDir)) {
18558
- if (!fs7__default.existsSync(packedDir)) {
18663
+ const packedDir = path8__default.join(rootDir, "agents", "packed");
18664
+ let packageDir = path8__default.join(packedDir, packageId);
18665
+ if (!fs8__default.existsSync(packageDir)) {
18666
+ if (!fs8__default.existsSync(packedDir)) {
18559
18667
  res.statusCode = 400;
18560
18668
  res.setHeader("Content-Type", "application/json");
18561
18669
  res.end(JSON.stringify({ error: "No packed packages found. Pack the agent first." }));
18562
18670
  return true;
18563
18671
  }
18564
- const dirs = fs7__default.readdirSync(packedDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
18672
+ const dirs = fs8__default.readdirSync(packedDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
18565
18673
  const matchingDir = dirs.find(
18566
18674
  (d) => d === packageId || d === `standardagent-${packageId}` || d === `standardagent-${packageId.replace(/_/g, "-")}`
18567
18675
  );
@@ -18573,14 +18681,14 @@ async function handlePackingApiRequest(context) {
18573
18681
  }));
18574
18682
  return true;
18575
18683
  }
18576
- packageDir = path7__default.join(packedDir, matchingDir);
18684
+ packageDir = path8__default.join(packedDir, matchingDir);
18577
18685
  }
18578
18686
  let token = body.token || process.env.NPM_TOKEN;
18579
18687
  let tokenSource = body.token ? "provided" : "environment";
18580
18688
  if (!token) {
18581
- const devVarsPath = path7__default.join(rootDir, ".dev.vars");
18582
- if (fs7__default.existsSync(devVarsPath)) {
18583
- const devVars = fs7__default.readFileSync(devVarsPath, "utf-8");
18689
+ const devVarsPath = path8__default.join(rootDir, ".dev.vars");
18690
+ if (fs8__default.existsSync(devVarsPath)) {
18691
+ const devVars = fs8__default.readFileSync(devVarsPath, "utf-8");
18584
18692
  const match = devVars.match(/^NPM_TOKEN=(.+)$/m);
18585
18693
  if (match) {
18586
18694
  token = match[1].trim();
@@ -18692,6 +18800,23 @@ async function handlePackingApiRequest(context) {
18692
18800
  }
18693
18801
 
18694
18802
  // src/plugin/dev-middleware.ts
18803
+ function readRawRequestBody(req) {
18804
+ return new Promise((resolve2, reject) => {
18805
+ const chunks = [];
18806
+ req.on("data", (chunk) => {
18807
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
18808
+ });
18809
+ req.on("end", () => {
18810
+ resolve2(chunks.length > 0 ? Buffer.concat(chunks) : void 0);
18811
+ });
18812
+ req.on("error", reject);
18813
+ });
18814
+ }
18815
+ function injectUiConfigIntoHtml(htmlContent, mountPoint) {
18816
+ const configScript = `<script>window.__AGENTBUILDER_CONFIG__ = { mountPoint: "${mountPoint}", devMode: true };</script>`;
18817
+ const assetPrefix = mountPoint === "/" ? "/" : `${mountPoint}/`;
18818
+ return htmlContent.replace(/\/agents\//g, assetPrefix).replace("</head>", `${configScript}</head>`);
18819
+ }
18695
18820
  function createDevMiddleware(server, context) {
18696
18821
  const {
18697
18822
  mountPoint,
@@ -18723,6 +18848,19 @@ function createDevMiddleware(server, context) {
18723
18848
  pathWithoutMount = "/" + pathWithoutMount;
18724
18849
  }
18725
18850
  const method = req.method?.toUpperCase();
18851
+ const legacyMountPoint = "/agentbuilder";
18852
+ if (mountPoint === "/" && (pathWithoutMount === legacyMountPoint || pathWithoutMount.startsWith(`${legacyMountPoint}/`))) {
18853
+ const normalizedPath = pathWithoutMount.slice(legacyMountPoint.length) || "/";
18854
+ if (normalizedPath.startsWith("/api/")) {
18855
+ req.url = normalizedPath;
18856
+ pathWithoutMount = normalizedPath;
18857
+ } else if (method === "GET" || method === "HEAD") {
18858
+ res.statusCode = 302;
18859
+ res.setHeader("Location", normalizedPath);
18860
+ res.end();
18861
+ return;
18862
+ }
18863
+ }
18726
18864
  if (await handleConfigApiRequest({
18727
18865
  req,
18728
18866
  res,
@@ -18753,6 +18891,14 @@ function createDevMiddleware(server, context) {
18753
18891
  })) {
18754
18892
  return;
18755
18893
  }
18894
+ const bootstrapCookie = resolveLocalBootstrapCookie(
18895
+ process.cwd(),
18896
+ pathWithoutMount,
18897
+ req.headers.cookie
18898
+ );
18899
+ if (bootstrapCookie) {
18900
+ req.headers.cookie = mergeCookieHeader(req.headers.cookie, bootstrapCookie);
18901
+ }
18756
18902
  if (pathWithoutMount.startsWith("/api/")) {
18757
18903
  next();
18758
18904
  return;
@@ -18761,13 +18907,38 @@ function createDevMiddleware(server, context) {
18761
18907
  if (uiDevServer && !pathWithoutMount.startsWith("/api/")) {
18762
18908
  const targetUrl = `${uiDevServer}${pathWithoutMount}`;
18763
18909
  try {
18764
- const proxyRes = await fetch(targetUrl);
18910
+ const proxyHeaders = new Headers();
18911
+ for (const [key, value] of Object.entries(req.headers)) {
18912
+ if (value === void 0) continue;
18913
+ if (Array.isArray(value)) {
18914
+ for (const item of value) {
18915
+ proxyHeaders.append(key, item);
18916
+ }
18917
+ continue;
18918
+ }
18919
+ proxyHeaders.set(key, value);
18920
+ }
18921
+ proxyHeaders.delete("host");
18922
+ const proxyBody = method === "GET" || method === "HEAD" ? void 0 : await readRawRequestBody(req);
18923
+ const proxyRes = await fetch(targetUrl, {
18924
+ method: method || "GET",
18925
+ headers: proxyHeaders,
18926
+ body: proxyBody
18927
+ });
18765
18928
  res.statusCode = proxyRes.status;
18766
18929
  proxyRes.headers.forEach((value, key) => {
18767
- if (!["content-encoding", "transfer-encoding"].includes(key.toLowerCase())) {
18930
+ if (!["content-encoding", "transfer-encoding", "content-length"].includes(key.toLowerCase())) {
18768
18931
  res.setHeader(key, value);
18769
18932
  }
18770
18933
  });
18934
+ const contentType = proxyRes.headers.get("content-type") || "";
18935
+ if (contentType.includes("text/html")) {
18936
+ const htmlBody = await proxyRes.text();
18937
+ const injectedHtml = Buffer.from(injectUiConfigIntoHtml(htmlBody, mountPoint));
18938
+ res.setHeader("content-length", String(injectedHtml.byteLength));
18939
+ res.end(injectedHtml);
18940
+ return;
18941
+ }
18771
18942
  const body = await proxyRes.arrayBuffer();
18772
18943
  res.end(Buffer.from(body));
18773
18944
  return;
@@ -18778,30 +18949,27 @@ function createDevMiddleware(server, context) {
18778
18949
  const clientPath = mountPoint === "/" && pathWithoutMount.startsWith("/agents/") ? pathWithoutMount.slice("/agents".length) || "/" : pathWithoutMount;
18779
18950
  const isStaticAsset = clientPath.startsWith("/assets/") || clientPath.startsWith("/vendor.js") || clientPath.startsWith("/vue.js") || clientPath.startsWith("/monaco.js") || clientPath.startsWith("/index.js") || clientPath.startsWith("/index.css") || clientPath.match(/\.(js|css|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|ico)$/);
18780
18951
  {
18781
- const currentDir = path7__default.dirname(fileURLToPath(import.meta.url));
18952
+ const currentDir = path8__default.dirname(fileURLToPath(import.meta.url));
18782
18953
  const isInDist = currentDir.endsWith("dist");
18783
- const clientDir = path7__default.resolve(
18954
+ const clientDir = path8__default.resolve(
18784
18955
  currentDir,
18785
18956
  isInDist ? "./client" : "../dist/client"
18786
18957
  );
18787
18958
  let filePath;
18788
18959
  if (isStaticAsset) {
18789
18960
  const cleanUrl = clientPath.split("?")[0];
18790
- filePath = path7__default.join(clientDir, cleanUrl);
18961
+ filePath = path8__default.join(clientDir, cleanUrl);
18791
18962
  } else {
18792
- filePath = path7__default.join(clientDir, "index.html");
18963
+ filePath = path8__default.join(clientDir, "index.html");
18793
18964
  }
18794
18965
  try {
18795
- if (fs7__default.existsSync(filePath)) {
18796
- let content = fs7__default.readFileSync(filePath);
18797
- const ext = path7__default.extname(filePath).toLowerCase();
18966
+ if (fs8__default.existsSync(filePath)) {
18967
+ let content = fs8__default.readFileSync(filePath);
18968
+ const ext = path8__default.extname(filePath).toLowerCase();
18798
18969
  if (ext === ".html") {
18799
- const configScript = `<script>window.__AGENTBUILDER_CONFIG__ = { mountPoint: "${mountPoint}", devMode: true };</script>`;
18800
- let htmlContent = content.toString();
18801
- const assetPrefix = mountPoint === "/" ? "/" : `${mountPoint}/`;
18802
- htmlContent = htmlContent.replace(/\/agents\//g, assetPrefix);
18803
- htmlContent = htmlContent.replace("</head>", `${configScript}</head>`);
18804
- content = Buffer.from(htmlContent);
18970
+ content = Buffer.from(
18971
+ injectUiConfigIntoHtml(content.toString(), mountPoint)
18972
+ );
18805
18973
  }
18806
18974
  const mimeTypes = {
18807
18975
  ".html": "text/html",
@@ -18836,7 +19004,7 @@ async function loadBuilderVirtualModule(context) {
18836
19004
  const effects = await scanEffectsDirectory(effectsDir);
18837
19005
  const toAbsolutePath = (relativePath) => {
18838
19006
  if (relativePath.startsWith("./")) {
18839
- return path7__default.resolve(process.cwd(), relativePath).replace(/\\/g, "/");
19007
+ return path8__default.resolve(process.cwd(), relativePath).replace(/\\/g, "/");
18840
19008
  }
18841
19009
  return relativePath;
18842
19010
  };
@@ -19066,7 +19234,7 @@ async function loadRegistryVirtualModule(context) {
19066
19234
  const effects = await scanEffectsDirectory(effectsDir);
19067
19235
  const toAbsolutePath = (relativePath) => {
19068
19236
  if (relativePath.startsWith("./")) {
19069
- return path7__default.resolve(process.cwd(), relativePath).replace(/\\/g, "/");
19237
+ return path8__default.resolve(process.cwd(), relativePath).replace(/\\/g, "/");
19070
19238
  }
19071
19239
  return relativePath;
19072
19240
  };
@@ -19094,23 +19262,23 @@ async function loadRegistryVirtualModule(context) {
19094
19262
  const absPath = toAbsolutePath(importPath);
19095
19263
  return ` "${name}": async () => (await import("${absPath}")).default,`;
19096
19264
  }).join("\n");
19097
- const packedDir = path7__default.resolve(process.cwd(), "agents/packed");
19265
+ const packedDir = path8__default.resolve(process.cwd(), "agents/packed");
19098
19266
  const packedPackages = [];
19099
- if (fs7__default.existsSync(packedDir)) {
19267
+ if (fs8__default.existsSync(packedDir)) {
19100
19268
  console.log(`[vite-plugin-agent] Scanning packed directory: ${packedDir}`);
19101
19269
  const packageDirs = discoverPackedPackageDirectories(packedDir);
19102
19270
  console.log(`[vite-plugin-agent] Found package dirs: ${packageDirs.join(", ")}`);
19103
19271
  for (const pkgPath of packageDirs) {
19104
- const pkgJsonPath = path7__default.join(pkgPath, "package.json");
19105
- if (fs7__default.existsSync(pkgJsonPath)) {
19272
+ const pkgJsonPath = path8__default.join(pkgPath, "package.json");
19273
+ if (fs8__default.existsSync(pkgJsonPath)) {
19106
19274
  try {
19107
- const pkgJson = JSON.parse(fs7__default.readFileSync(pkgJsonPath, "utf-8"));
19275
+ const pkgJson = JSON.parse(fs8__default.readFileSync(pkgJsonPath, "utf-8"));
19108
19276
  console.log(`[vite-plugin-agent] Loaded ${pkgPath} package.json, standardagent:`, pkgJson.standardagent);
19109
19277
  if (!pkgJson.standardagent) {
19110
19278
  continue;
19111
19279
  }
19112
19280
  const mainEntry = pkgJson.main || "./dist/index.js";
19113
- const outputDir = path7__default.dirname(mainEntry).replace(/^\.\//, "");
19281
+ const outputDir = path8__default.dirname(mainEntry).replace(/^\.\//, "");
19114
19282
  const pkg = {
19115
19283
  packageId: pkgJson.name,
19116
19284
  version: pkgJson.version,
@@ -19228,7 +19396,7 @@ export function getVisibleToolNames() {
19228
19396
  async function loadRoutesVirtualModule(context) {
19229
19397
  const { mountPoint, threadApiDir, rou3Code, hmr } = context;
19230
19398
  const threadRoutes = scanApiDirectory(threadApiDir);
19231
- const toAbsolutePath = (inputPath) => path7__default.resolve(process.cwd(), inputPath).replace(/\\/g, "/");
19399
+ const toAbsolutePath = (inputPath) => path8__default.resolve(process.cwd(), inputPath).replace(/\\/g, "/");
19232
19400
  const threadRouteCode = threadRoutes.map(({ method, route, importPath }) => {
19233
19401
  const apiRoute = `/api/threads/:threadId${route}`;
19234
19402
  return ` addRoute(
@@ -19239,20 +19407,20 @@ async function loadRoutesVirtualModule(context) {
19239
19407
  );`;
19240
19408
  }).join("\n");
19241
19409
  const packedThreadRoutes = [];
19242
- const packedDir = path7__default.resolve(process.cwd(), "agents/packed");
19410
+ const packedDir = path8__default.resolve(process.cwd(), "agents/packed");
19243
19411
  const packedPackageDirs = discoverPackedPackageDirectories(packedDir);
19244
19412
  for (const packagePath of packedPackageDirs) {
19245
- const packageJsonPath = path7__default.join(packagePath, "package.json");
19246
- if (!fs7__default.existsSync(packageJsonPath)) {
19413
+ const packageJsonPath = path8__default.join(packagePath, "package.json");
19414
+ if (!fs8__default.existsSync(packageJsonPath)) {
19247
19415
  continue;
19248
19416
  }
19249
19417
  try {
19250
- const packageJson = JSON.parse(fs7__default.readFileSync(packageJsonPath, "utf-8"));
19418
+ const packageJson = JSON.parse(fs8__default.readFileSync(packageJsonPath, "utf-8"));
19251
19419
  if (!packageJson.standardagent) {
19252
19420
  continue;
19253
19421
  }
19254
19422
  const mainEntry = packageJson.main || "./dist/index.js";
19255
- const outputDir = path7__default.dirname(mainEntry).replace(/^\.\//, "");
19423
+ const outputDir = path8__default.dirname(mainEntry).replace(/^\.\//, "");
19256
19424
  const threadEndpoints = scanPackedThreadEndpoints(packagePath, outputDir);
19257
19425
  for (const endpoint of threadEndpoints) {
19258
19426
  const apiRoute = `/api/threads/:threadId${endpoint.route}`;
@@ -19292,12 +19460,19 @@ const MOUNT_POINT = "${mountPoint}";
19292
19460
 
19293
19461
  // Routes that don't require authentication
19294
19462
  const PUBLIC_ROUTES = [
19463
+ '/api/auth/bootstrap',
19295
19464
  '/api/auth/login',
19465
+ '/api/auth/bootstrap',
19296
19466
  '/api/auth/config',
19467
+ '/api/config',
19297
19468
  '/api/auth/oauth/github',
19298
19469
  '/api/auth/oauth/google',
19299
19470
  '/api/auth/oauth/github/callback',
19300
19471
  '/api/auth/oauth/google/callback',
19472
+ '/api/platform-auth/bootstrap',
19473
+ '/api/platform-auth/login',
19474
+ '/api/platform-auth/logout',
19475
+ '/api/platform-auth/me',
19301
19476
  '/api/hooks' // Hook metadata is safe to expose publicly
19302
19477
  ];
19303
19478
 
@@ -19318,6 +19493,20 @@ function isPublicRoute(routePath) {
19318
19493
  return true;
19319
19494
  }
19320
19495
 
19496
+ // Platform proxy routes handle their own auth.
19497
+ if (routePath.startsWith('/api/platform/') || routePath === '/api/platform') {
19498
+ return true;
19499
+ }
19500
+
19501
+ // Platform session proxy and auth bridge handle auth via platform cookies.
19502
+ if (routePath.startsWith('/api/platform-session/') || routePath === '/api/platform-session') {
19503
+ return true;
19504
+ }
19505
+
19506
+ if (routePath.startsWith('/api/platform-auth/') || routePath === '/api/platform-auth') {
19507
+ return true;
19508
+ }
19509
+
19321
19510
  return false;
19322
19511
  }
19323
19512
 
@@ -19582,12 +19771,12 @@ ${hooksCode}
19582
19771
  };`;
19583
19772
  }
19584
19773
  if (id === RESOLVED_VIRTUAL_CONFIG_ID) {
19585
- const relativeToolsDir = path7__default.relative(process.cwd(), toolsDir).replace(/\\/g, "/");
19586
- const relativeHooksDir = path7__default.relative(process.cwd(), hooksDir).replace(/\\/g, "/");
19587
- const relativeApiDir = path7__default.relative(process.cwd(), threadApiDir).replace(/\\/g, "/");
19588
- const relativeModelsDir = path7__default.relative(process.cwd(), modelsDir).replace(/\\/g, "/");
19589
- const relativePromptsDir = path7__default.relative(process.cwd(), promptsDir).replace(/\\/g, "/");
19590
- const relativeAgentsDir = path7__default.relative(process.cwd(), agentsDir).replace(/\\/g, "/");
19774
+ const relativeToolsDir = path8__default.relative(process.cwd(), toolsDir).replace(/\\/g, "/");
19775
+ const relativeHooksDir = path8__default.relative(process.cwd(), hooksDir).replace(/\\/g, "/");
19776
+ const relativeApiDir = path8__default.relative(process.cwd(), threadApiDir).replace(/\\/g, "/");
19777
+ const relativeModelsDir = path8__default.relative(process.cwd(), modelsDir).replace(/\\/g, "/");
19778
+ const relativePromptsDir = path8__default.relative(process.cwd(), promptsDir).replace(/\\/g, "/");
19779
+ const relativeAgentsDir = path8__default.relative(process.cwd(), agentsDir).replace(/\\/g, "/");
19591
19780
  return `// Virtual agent config module
19592
19781
  export const config = {
19593
19782
  toolsDir: "${relativeToolsDir}",
@@ -19757,14 +19946,14 @@ var packingDeps = [
19757
19946
  "typescript"
19758
19947
  ];
19759
19948
  function createPluginViteConfig(pluginModuleUrl) {
19760
- const currentDir = path7__default.dirname(fileURLToPath(pluginModuleUrl));
19949
+ const currentDir = path8__default.dirname(fileURLToPath(pluginModuleUrl));
19761
19950
  const isInDist = currentDir.endsWith("dist");
19762
- const builderClientDir = path7__default.resolve(
19951
+ const builderClientDir = path8__default.resolve(
19763
19952
  currentDir,
19764
19953
  isInDist ? "./client" : "../dist/client"
19765
19954
  );
19766
19955
  return {
19767
- publicDir: fs7__default.existsSync(builderClientDir) ? builderClientDir : void 0,
19956
+ publicDir: fs8__default.existsSync(builderClientDir) ? builderClientDir : void 0,
19768
19957
  build: {
19769
19958
  rollupOptions: {
19770
19959
  external: [...packingDeps]
@@ -19821,14 +20010,14 @@ function agentbuilder(options = {}) {
19821
20010
  if (mountPoint.endsWith("/") && mountPoint.length > 1) {
19822
20011
  mountPoint = mountPoint.slice(0, -1);
19823
20012
  }
19824
- const toolsDir = options.toolsDir ? path7__default.resolve(process.cwd(), options.toolsDir) : path7__default.resolve(process.cwd(), "agents/tools");
19825
- const hooksDir = options.hooksDir ? path7__default.resolve(process.cwd(), options.hooksDir) : path7__default.resolve(process.cwd(), "agents/hooks");
19826
- const threadApiDir = options.apiDir ? path7__default.resolve(process.cwd(), options.apiDir) : path7__default.resolve(process.cwd(), "agents/api");
19827
- const modelsDir = options.modelsDir ? path7__default.resolve(process.cwd(), options.modelsDir) : path7__default.resolve(process.cwd(), "agents/models");
19828
- const promptsDir = options.promptsDir ? path7__default.resolve(process.cwd(), options.promptsDir) : path7__default.resolve(process.cwd(), "agents/prompts");
19829
- const agentsDir = options.agentsDir ? path7__default.resolve(process.cwd(), options.agentsDir) : path7__default.resolve(process.cwd(), "agents/agents");
19830
- const effectsDir = options.effectsDir ? path7__default.resolve(process.cwd(), options.effectsDir) : path7__default.resolve(process.cwd(), "agents/effects");
19831
- const outputDir = path7__default.resolve(process.cwd(), ".agents");
20013
+ const toolsDir = options.toolsDir ? path8__default.resolve(process.cwd(), options.toolsDir) : path8__default.resolve(process.cwd(), "agents/tools");
20014
+ const hooksDir = options.hooksDir ? path8__default.resolve(process.cwd(), options.hooksDir) : path8__default.resolve(process.cwd(), "agents/hooks");
20015
+ const threadApiDir = options.apiDir ? path8__default.resolve(process.cwd(), options.apiDir) : path8__default.resolve(process.cwd(), "agents/api");
20016
+ const modelsDir = options.modelsDir ? path8__default.resolve(process.cwd(), options.modelsDir) : path8__default.resolve(process.cwd(), "agents/models");
20017
+ const promptsDir = options.promptsDir ? path8__default.resolve(process.cwd(), options.promptsDir) : path8__default.resolve(process.cwd(), "agents/prompts");
20018
+ const agentsDir = options.agentsDir ? path8__default.resolve(process.cwd(), options.agentsDir) : path8__default.resolve(process.cwd(), "agents/agents");
20019
+ const effectsDir = options.effectsDir ? path8__default.resolve(process.cwd(), options.effectsDir) : path8__default.resolve(process.cwd(), "agents/effects");
20020
+ const outputDir = path8__default.resolve(process.cwd(), ".agents");
19832
20021
  const installedProviders = buildInstalledProviderCatalog(options.providers || []);
19833
20022
  const installedProviderPackageMap = buildProviderPackageMap(options.providers || []);
19834
20023
  const typeGenConfig = {
@@ -19845,11 +20034,11 @@ function agentbuilder(options = {}) {
19845
20034
  }
19846
20035
  }
19847
20036
  const __filename = fileURLToPath(import.meta.url);
19848
- const __dirname = path7__default.dirname(__filename);
19849
- const rou3Path = path7__default.join(__dirname, "../dist/rou3.js");
20037
+ const __dirname = path8__default.dirname(__filename);
20038
+ const rou3Path = path8__default.join(__dirname, "../dist/rou3.js");
19850
20039
  let rou3Code = "";
19851
20040
  try {
19852
- rou3Code = fs7__default.readFileSync(rou3Path, "utf-8").replace(/^export \{[^}]+\};?\s*$/gm, "").replace(/\/\/# sourceMappingURL=.+$/gm, "").trim();
20041
+ rou3Code = fs8__default.readFileSync(rou3Path, "utf-8").replace(/^export \{[^}]+\};?\s*$/gm, "").replace(/\/\/# sourceMappingURL=.+$/gm, "").trim();
19853
20042
  } catch (err) {
19854
20043
  console.warn("[vite-plugin-agent] Could not read rou3.js for inlining:", err);
19855
20044
  }
@@ -19959,28 +20148,28 @@ function agentbuilder(options = {}) {
19959
20148
  writeBundle(options2, bundle) {
19960
20149
  const outDir = options2.dir || "dist";
19961
20150
  const mountPath = mountPoint.slice(1);
19962
- const mountDir = mountPath ? path7__default.join(outDir, "../client", mountPath) : path7__default.join(outDir, "../client");
19963
- const currentDir = path7__default.dirname(fileURLToPath(import.meta.url));
20151
+ const mountDir = mountPath ? path8__default.join(outDir, "../client", mountPath) : path8__default.join(outDir, "../client");
20152
+ const currentDir = path8__default.dirname(fileURLToPath(import.meta.url));
19964
20153
  const isInDist = currentDir.endsWith("dist");
19965
- const clientDir = path7__default.resolve(
20154
+ const clientDir = path8__default.resolve(
19966
20155
  currentDir,
19967
20156
  isInDist ? "./client" : "../dist/client"
19968
20157
  );
19969
- if (!fs7__default.existsSync(clientDir)) {
20158
+ if (!fs8__default.existsSync(clientDir)) {
19970
20159
  console.warn(`[agentbuilder] Client directory not found at ${clientDir}`);
19971
20160
  return;
19972
20161
  }
19973
- fs7__default.mkdirSync(mountDir, { recursive: true });
20162
+ fs8__default.mkdirSync(mountDir, { recursive: true });
19974
20163
  function copyRecursive(src, dest) {
19975
- const entries = fs7__default.readdirSync(src, { withFileTypes: true });
20164
+ const entries = fs8__default.readdirSync(src, { withFileTypes: true });
19976
20165
  for (const entry of entries) {
19977
- const srcPath = path7__default.join(src, entry.name);
19978
- const destPath = path7__default.join(dest, entry.name);
20166
+ const srcPath = path8__default.join(src, entry.name);
20167
+ const destPath = path8__default.join(dest, entry.name);
19979
20168
  if (entry.isDirectory()) {
19980
- fs7__default.mkdirSync(destPath, { recursive: true });
20169
+ fs8__default.mkdirSync(destPath, { recursive: true });
19981
20170
  copyRecursive(srcPath, destPath);
19982
20171
  } else {
19983
- let content = fs7__default.readFileSync(srcPath);
20172
+ let content = fs8__default.readFileSync(srcPath);
19984
20173
  if (entry.name === "index.html") {
19985
20174
  const configScript = `<script>window.__AGENTBUILDER_CONFIG__ = { mountPoint: "${mountPoint}" };</script>`;
19986
20175
  let htmlContent = content.toString();
@@ -19989,7 +20178,7 @@ function agentbuilder(options = {}) {
19989
20178
  htmlContent = htmlContent.replace("</head>", `${configScript}</head>`);
19990
20179
  content = Buffer.from(htmlContent);
19991
20180
  }
19992
- fs7__default.writeFileSync(destPath, content);
20181
+ fs8__default.writeFileSync(destPath, content);
19993
20182
  }
19994
20183
  }
19995
20184
  }
@@ -21003,8 +21192,27 @@ var migration29 = {
21003
21192
  }
21004
21193
  };
21005
21194
 
21195
+ // src/durable-objects/migrations/030_add_standard_agents_router_used.ts
21196
+ var migration30 = {
21197
+ version: 30,
21198
+ name: "add_standard_agents_router_used",
21199
+ async up(sql) {
21200
+ const tableInfo = sql.exec(`PRAGMA table_info(logs)`).toArray();
21201
+ const hasRouterUsed = tableInfo.some((col) => col.name === "standard_agents_router_used");
21202
+ if (!hasRouterUsed) {
21203
+ await sql.exec(`
21204
+ ALTER TABLE logs ADD COLUMN standard_agents_router_used INTEGER NOT NULL DEFAULT 0;
21205
+ `);
21206
+ await sql.exec(`
21207
+ CREATE INDEX IF NOT EXISTS idx_logs_standard_agents_router_used
21208
+ ON logs(standard_agents_router_used);
21209
+ `);
21210
+ }
21211
+ }
21212
+ };
21213
+
21006
21214
  // src/durable-objects/migrations/index.ts
21007
- var migrations = [migration, migration2, migration3, migration4, migration5, migration6, migration7, migration8, migration9, migration10, migration11, migration12, migration13, migration14, migration15, migration16, migration17, migration18, migration19, migration20, migration21, migration22, migration23, migration24, migration25, migration26, migration27, migration28, migration29];
21215
+ var migrations = [migration, migration2, migration3, migration4, migration5, migration6, migration7, migration8, migration9, migration10, migration11, migration12, migration13, migration14, migration15, migration16, migration17, migration18, migration19, migration20, migration21, migration22, migration23, migration24, migration25, migration26, migration27, migration28, migration29, migration30];
21008
21216
  var LATEST_SCHEMA_VERSION = migrations.length;
21009
21217
 
21010
21218
  // src/durable-objects/DurableThread.ts
@@ -21773,12 +21981,12 @@ function isQualifiedName(name) {
21773
21981
  init_sessionTools();
21774
21982
  init_code_execution();
21775
21983
  var RUNTIME_STORAGE_PREFIX = "__agentbuilder_runtime_storage__:";
21776
- function normalizeEndpointThreadPath(path19) {
21777
- if (!path19 || /^[A-Za-z][A-Za-z\d+\-.]*:/.test(path19)) {
21984
+ function normalizeEndpointThreadPath(path20) {
21985
+ if (!path20 || /^[A-Za-z][A-Za-z\d+\-.]*:/.test(path20)) {
21778
21986
  throw new Error("Use a relative thread filesystem path");
21779
21987
  }
21780
21988
  const parts = [];
21781
- for (const part of path19.replace(/\\/g, "/").split("/")) {
21989
+ for (const part of path20.replace(/\\/g, "/").split("/")) {
21782
21990
  if (!part || part === ".") continue;
21783
21991
  if (part === "..") {
21784
21992
  if (parts.length === 0) throw new Error("Path cannot escape the thread filesystem root");
@@ -21828,12 +22036,12 @@ function createEndpointFetchBridge() {
21828
22036
  function createEndpointFsBridge(state) {
21829
22037
  const decoder = new TextDecoder();
21830
22038
  return {
21831
- readFile: async (path19) => {
21832
- const data = await state.readFile(normalizeEndpointThreadPath(path19));
22039
+ readFile: async (path20) => {
22040
+ const data = await state.readFile(normalizeEndpointThreadPath(path20));
21833
22041
  return data ? decoder.decode(data) : null;
21834
22042
  },
21835
- writeFile: async (path19, content, mimeType = "text/plain") => {
21836
- return state.writeFile(normalizeEndpointThreadPath(path19), content, mimeType);
22043
+ writeFile: async (path20, content, mimeType = "text/plain") => {
22044
+ return state.writeFile(normalizeEndpointThreadPath(path20), content, mimeType);
21837
22045
  }
21838
22046
  };
21839
22047
  }
@@ -21901,19 +22109,19 @@ function createEndpointThreadStateBridge(state) {
21901
22109
  emit: (event, data) => state.emit(event, data),
21902
22110
  getValue: (key) => state.getValue(key),
21903
22111
  setValue: (key, value) => state.setValue(key, value),
21904
- readFile: (path19) => state.readFile(normalizeEndpointThreadPath(path19)),
21905
- writeFile: (path19, data, mimeType = "application/octet-stream", options) => {
21906
- return state.writeFile(normalizeEndpointThreadPath(path19), data, mimeType, options);
22112
+ readFile: (path20) => state.readFile(normalizeEndpointThreadPath(path20)),
22113
+ writeFile: (path20, data, mimeType = "application/octet-stream", options) => {
22114
+ return state.writeFile(normalizeEndpointThreadPath(path20), data, mimeType, options);
21907
22115
  },
21908
- statFile: (path19) => state.statFile(normalizeEndpointThreadPath(path19)),
21909
- readdirFile: (path19) => state.readdirFile(normalizeEndpointThreadPath(path19)),
21910
- unlinkFile: (path19) => state.unlinkFile(normalizeEndpointThreadPath(path19)),
21911
- mkdirFile: (path19) => state.mkdirFile(normalizeEndpointThreadPath(path19)),
21912
- rmdirFile: (path19) => state.rmdirFile(normalizeEndpointThreadPath(path19)),
22116
+ statFile: (path20) => state.statFile(normalizeEndpointThreadPath(path20)),
22117
+ readdirFile: (path20) => state.readdirFile(normalizeEndpointThreadPath(path20)),
22118
+ unlinkFile: (path20) => state.unlinkFile(normalizeEndpointThreadPath(path20)),
22119
+ mkdirFile: (path20) => state.mkdirFile(normalizeEndpointThreadPath(path20)),
22120
+ rmdirFile: (path20) => state.rmdirFile(normalizeEndpointThreadPath(path20)),
21913
22121
  getFileStats: () => state.getFileStats(),
21914
22122
  grepFiles: (pattern) => state.grepFiles(pattern),
21915
22123
  findFiles: (pattern) => state.findFiles(pattern),
21916
- getFileThumbnail: (path19) => state.getFileThumbnail(normalizeEndpointThreadPath(path19))
22124
+ getFileThumbnail: (path20) => state.getFileThumbnail(normalizeEndpointThreadPath(path20))
21917
22125
  };
21918
22126
  }
21919
22127
  var DurableThread = class extends DurableObject {
@@ -21941,7 +22149,14 @@ var DurableThread = class extends DurableObject {
21941
22149
  );
21942
22150
  break;
21943
22151
  case "processMessage":
21944
- await this.processMessage(args.threadId, args.content, args.role, args.attachments);
22152
+ await this.processMessage(
22153
+ args.threadId,
22154
+ args.content,
22155
+ args.role,
22156
+ args.attachments,
22157
+ args.messageId,
22158
+ args.queuedAt
22159
+ );
21945
22160
  break;
21946
22161
  case "testOperation":
21947
22162
  await this.testOperation(args.id, args.label, args.expectedOrder);
@@ -22456,7 +22671,7 @@ var DurableThread = class extends DurableObject {
22456
22671
  this.assertJsonSerializableThreadValue(value, "$", /* @__PURE__ */ new WeakSet());
22457
22672
  return JSON.stringify(value);
22458
22673
  }
22459
- assertJsonSerializableThreadValue(value, path19, seen) {
22674
+ assertJsonSerializableThreadValue(value, path20, seen) {
22460
22675
  if (value === null) {
22461
22676
  return;
22462
22677
  }
@@ -22466,36 +22681,36 @@ var DurableThread = class extends DurableObject {
22466
22681
  return;
22467
22682
  case "number":
22468
22683
  if (!Number.isFinite(value)) {
22469
- throw new Error(`Thread value at ${path19} must be a finite number`);
22684
+ throw new Error(`Thread value at ${path20} must be a finite number`);
22470
22685
  }
22471
22686
  return;
22472
22687
  case "object": {
22473
22688
  if (seen.has(value)) {
22474
- throw new Error(`Thread value at ${path19} cannot contain circular references`);
22689
+ throw new Error(`Thread value at ${path20} cannot contain circular references`);
22475
22690
  }
22476
22691
  seen.add(value);
22477
22692
  if (Array.isArray(value)) {
22478
22693
  for (let i = 0; i < value.length; i += 1) {
22479
- this.assertJsonSerializableThreadValue(value[i], `${path19}[${i}]`, seen);
22694
+ this.assertJsonSerializableThreadValue(value[i], `${path20}[${i}]`, seen);
22480
22695
  }
22481
22696
  seen.delete(value);
22482
22697
  return;
22483
22698
  }
22484
22699
  const prototype = Object.getPrototypeOf(value);
22485
22700
  if (prototype !== Object.prototype && prototype !== null) {
22486
- throw new Error(`Thread value at ${path19} must be a JSON object, array, or primitive`);
22701
+ throw new Error(`Thread value at ${path20} must be a JSON object, array, or primitive`);
22487
22702
  }
22488
22703
  if (Object.getOwnPropertySymbols(value).length > 0) {
22489
- throw new Error(`Thread value at ${path19} cannot contain symbol keys`);
22704
+ throw new Error(`Thread value at ${path20} cannot contain symbol keys`);
22490
22705
  }
22491
22706
  for (const [entryKey, entryValue] of Object.entries(value)) {
22492
- this.assertJsonSerializableThreadValue(entryValue, `${path19}.${entryKey}`, seen);
22707
+ this.assertJsonSerializableThreadValue(entryValue, `${path20}.${entryKey}`, seen);
22493
22708
  }
22494
22709
  seen.delete(value);
22495
22710
  return;
22496
22711
  }
22497
22712
  default:
22498
- throw new Error(`Thread value at ${path19} must be JSON-serializable`);
22713
+ throw new Error(`Thread value at ${path20} must be JSON-serializable`);
22499
22714
  }
22500
22715
  }
22501
22716
  // ============================================================
@@ -22720,17 +22935,37 @@ var DurableThread = class extends DurableObject {
22720
22935
  await this.assertNotTerminated();
22721
22936
  const id = crypto.randomUUID();
22722
22937
  const now = Date.now() * 1e3;
22938
+ const attachmentsJson = message.attachments ? JSON.stringify(message.attachments) : null;
22939
+ const metadataJson = message.metadata ? JSON.stringify(message.metadata) : null;
22723
22940
  await this.ctx.storage.sql.exec(
22724
22941
  `INSERT INTO message_queue (id, role, content, attachments, silent, metadata, created_at)
22725
22942
  VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)`,
22726
22943
  id,
22727
22944
  message.role,
22728
22945
  message.content,
22729
- message.attachments ? JSON.stringify(message.attachments) : null,
22946
+ attachmentsJson,
22730
22947
  message.silent ? 1 : 0,
22731
- message.metadata ? JSON.stringify(message.metadata) : null,
22948
+ metadataJson,
22732
22949
  now
22733
22950
  );
22951
+ if (this.messageSockets?.size > 0) {
22952
+ await this.broadcastMessageWithSubagentProjection({
22953
+ id,
22954
+ role: message.role,
22955
+ content: message.content,
22956
+ attachments: message.attachments ?? null,
22957
+ silent: !!message.silent,
22958
+ created_at: now,
22959
+ status: "pending",
22960
+ depth: 0,
22961
+ metadata: {
22962
+ ...message.metadata ?? {},
22963
+ queued: true,
22964
+ queue_status: "queued"
22965
+ },
22966
+ subagent_id: this.extractSubagentIdFromMetadata(metadataJson)
22967
+ });
22968
+ }
22734
22969
  const side = message.role === "user" ? "a" : "b";
22735
22970
  await this.ensureQueuedMessageExecution(threadId, side);
22736
22971
  }
@@ -22934,9 +23169,9 @@ var DurableThread = class extends DurableObject {
22934
23169
  * Each migration is run in order, starting from the current version + 1.
22935
23170
  */
22936
23171
  async runMigrations(fromVersion) {
22937
- for (const migration35 of migrations) {
22938
- if (migration35.version > fromVersion) {
22939
- await migration35.up(this.ctx.storage.sql);
23172
+ for (const migration37 of migrations) {
23173
+ if (migration37.version > fromVersion) {
23174
+ await migration37.up(this.ctx.storage.sql);
22940
23175
  }
22941
23176
  }
22942
23177
  }
@@ -23182,21 +23417,42 @@ var DurableThread = class extends DurableObject {
23182
23417
  await this.ensureMigrated();
23183
23418
  try {
23184
23419
  await this.assertNotTerminated();
23420
+ const messageId = crypto.randomUUID();
23421
+ const queuedAt = Date.now() * 1e3;
23185
23422
  const queueId = await this.alarmQueue.enqueue(
23186
23423
  "processMessage",
23187
23424
  {
23188
23425
  threadId,
23189
23426
  content,
23190
23427
  role,
23191
- attachments
23428
+ attachments,
23429
+ messageId,
23430
+ queuedAt
23192
23431
  },
23193
23432
  1
23194
23433
  // Execute almost immediately (1ms)
23195
23434
  );
23435
+ this.broadcastMessage({
23436
+ id: messageId,
23437
+ role,
23438
+ content,
23439
+ attachments: this.parseAttachmentRefsJson(attachments ?? null) ?? null,
23440
+ created_at: queuedAt,
23441
+ status: "pending",
23442
+ depth: 0,
23443
+ silent: false,
23444
+ metadata: {
23445
+ queued: true,
23446
+ queue_status: "queued",
23447
+ queue_source: "alarm_queue",
23448
+ alarm_queue_id: queueId
23449
+ }
23450
+ });
23196
23451
  return Response.json(
23197
23452
  {
23198
23453
  status: "queued",
23199
23454
  queueId,
23455
+ messageId,
23200
23456
  message: "Message queued for processing. Connect via WebSocket for real-time updates."
23201
23457
  },
23202
23458
  { status: 202 }
@@ -23300,6 +23556,78 @@ var DurableThread = class extends DurableObject {
23300
23556
  return void 0;
23301
23557
  }
23302
23558
  }
23559
+ async deleteAttachmentRefsFromJson(raw) {
23560
+ const refs = this.parseAttachmentRefsJson(raw);
23561
+ if (!refs) {
23562
+ return;
23563
+ }
23564
+ for (const ref of refs) {
23565
+ if (ref.path) {
23566
+ await this.unlinkFile(ref.path);
23567
+ }
23568
+ }
23569
+ }
23570
+ async cancelQueuedMessage(messageId) {
23571
+ let cancelled = false;
23572
+ const queuedRows = await this.ctx.storage.sql.exec(
23573
+ `SELECT id, attachments FROM message_queue WHERE id = ?`,
23574
+ messageId
23575
+ ).toArray();
23576
+ for (const row of queuedRows) {
23577
+ await this.deleteAttachmentRefsFromJson(row.attachments);
23578
+ await this.ctx.storage.sql.exec(
23579
+ `DELETE FROM message_queue WHERE id = ?`,
23580
+ row.id
23581
+ );
23582
+ cancelled = true;
23583
+ }
23584
+ const alarmRows = await this.ctx.storage.sql.exec(
23585
+ `
23586
+ SELECT id, args
23587
+ FROM alarm_queue
23588
+ WHERE method = 'processMessage'
23589
+ AND status = 'pending'
23590
+ AND (
23591
+ id = ?
23592
+ OR json_extract(args, '$.messageId') = ?
23593
+ )
23594
+ `,
23595
+ messageId,
23596
+ messageId
23597
+ ).toArray();
23598
+ for (const row of alarmRows) {
23599
+ try {
23600
+ const args = JSON.parse(row.args);
23601
+ if (typeof args.attachments === "string") {
23602
+ await this.deleteAttachmentRefsFromJson(args.attachments);
23603
+ }
23604
+ } catch (error) {
23605
+ console.error("[DurableThread] Failed to parse queued message args:", error);
23606
+ }
23607
+ await this.ctx.storage.sql.exec(
23608
+ `DELETE FROM alarm_queue WHERE id = ? AND status = 'pending'`,
23609
+ row.id
23610
+ );
23611
+ cancelled = true;
23612
+ }
23613
+ return cancelled;
23614
+ }
23615
+ parseMessageMetadata(raw) {
23616
+ if (typeof raw !== "string") {
23617
+ return void 0;
23618
+ }
23619
+ try {
23620
+ const parsed = JSON.parse(raw);
23621
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
23622
+ } catch {
23623
+ return void 0;
23624
+ }
23625
+ }
23626
+ extractSubagentIdFromMetadata(raw) {
23627
+ const metadata = this.parseMessageMetadata(raw);
23628
+ const value = typeof metadata?.subagent_id === "string" ? metadata.subagent_id : typeof metadata?.subagentId === "string" ? metadata.subagentId : null;
23629
+ return value && value.trim().length > 0 ? value.trim() : null;
23630
+ }
23303
23631
  async getLatestTerminalSessionMessageAfter(messageId, terminalToolNames) {
23304
23632
  const toolNames = Array.from(terminalToolNames);
23305
23633
  if (toolNames.length === 0) {
@@ -23330,8 +23658,8 @@ var DurableThread = class extends DurableObject {
23330
23658
  );
23331
23659
  return terminalCursor.toArray()[0] ?? null;
23332
23660
  }
23333
- inferMimeTypeFromPath(path19) {
23334
- const normalized = path19.toLowerCase();
23661
+ inferMimeTypeFromPath(path20) {
23662
+ const normalized = path20.toLowerCase();
23335
23663
  if (normalized.endsWith(".png")) return "image/png";
23336
23664
  if (normalized.endsWith(".jpg") || normalized.endsWith(".jpeg")) return "image/jpeg";
23337
23665
  if (normalized.endsWith(".webp")) return "image/webp";
@@ -23370,7 +23698,7 @@ var DurableThread = class extends DurableObject {
23370
23698
  ext: value.slice(lastDot + 1).toLowerCase()
23371
23699
  };
23372
23700
  }
23373
- resolveAttachmentMimeType(sourceMimeType, fallbackMimeType, path19) {
23701
+ resolveAttachmentMimeType(sourceMimeType, fallbackMimeType, path20) {
23374
23702
  const source = sourceMimeType?.trim();
23375
23703
  if (source && source !== "application/octet-stream") {
23376
23704
  return source;
@@ -23379,7 +23707,7 @@ var DurableThread = class extends DurableObject {
23379
23707
  if (fallback && fallback !== "application/octet-stream") {
23380
23708
  return fallback;
23381
23709
  }
23382
- return this.inferMimeTypeFromPath(path19) ?? source ?? fallback ?? "application/octet-stream";
23710
+ return this.inferMimeTypeFromPath(path20) ?? source ?? fallback ?? "application/octet-stream";
23383
23711
  }
23384
23712
  buildAttachmentTargetPath(preferredName, mimeType, sourcePath) {
23385
23713
  const safeName = this.sanitizeFilename(preferredName);
@@ -23474,8 +23802,8 @@ var DurableThread = class extends DurableObject {
23474
23802
  }
23475
23803
  return copied;
23476
23804
  }
23477
- async readAttachmentDataFromSource(path19, sourceFile) {
23478
- const sourceData = await this.readFile(path19);
23805
+ async readAttachmentDataFromSource(path20, sourceFile) {
23806
+ const sourceData = await this.readFile(path20);
23479
23807
  if (sourceData.success && sourceData.data) {
23480
23808
  return sourceData.data;
23481
23809
  }
@@ -23509,7 +23837,7 @@ var DurableThread = class extends DurableObject {
23509
23837
  if (!attachments || attachments.length === 0) {
23510
23838
  return "";
23511
23839
  }
23512
- const paths = attachments.map((attachment) => attachment.path).filter((path19) => typeof path19 === "string" && path19.length > 0);
23840
+ const paths = attachments.map((attachment) => attachment.path).filter((path20) => typeof path20 === "string" && path20.length > 0);
23513
23841
  if (paths.length === 0) {
23514
23842
  return "";
23515
23843
  }
@@ -23852,22 +24180,163 @@ ${resultContent}${attachmentSummary}`;
23852
24180
  }
23853
24181
  whereClauses.push(`(depth <= ${maxDepth} OR depth IS NULL)`);
23854
24182
  const whereClause = whereClauses.length > 0 ? `WHERE ${whereClauses.join(" AND ")}` : "";
24183
+ const orderDirection = order === "ASC" ? "ASC" : "DESC";
24184
+ const combinedMessagesSql = `
24185
+ WITH combined_messages AS (
24186
+ SELECT
24187
+ rowid AS source_rowid,
24188
+ 0 AS source_order,
24189
+ 'message' AS source,
24190
+ id, role, content, name, tool_calls, tool_call_id, tool_status,
24191
+ log_id, created_at, silent, parent_id, depth, status,
24192
+ reasoning_content, reasoning_details, attachments, metadata,
24193
+ subagent_id
24194
+ FROM messages
24195
+ UNION ALL
24196
+ SELECT
24197
+ rowid AS source_rowid,
24198
+ 1 AS source_order,
24199
+ 'queue' AS source,
24200
+ id, role, content, NULL AS name, NULL AS tool_calls,
24201
+ NULL AS tool_call_id, NULL AS tool_status, NULL AS log_id,
24202
+ created_at, silent, NULL AS parent_id, 0 AS depth,
24203
+ 'pending' AS status, NULL AS reasoning_content,
24204
+ NULL AS reasoning_details, attachments, metadata,
24205
+ NULL AS subagent_id
24206
+ FROM message_queue
24207
+ UNION ALL
24208
+ SELECT
24209
+ rowid AS source_rowid,
24210
+ 2 AS source_order,
24211
+ 'send_queue' AS source,
24212
+ COALESCE(json_extract(args, '$.messageId'), id) AS id,
24213
+ COALESCE(json_extract(args, '$.role'), 'user') AS role,
24214
+ json_extract(args, '$.content') AS content,
24215
+ NULL AS name, NULL AS tool_calls,
24216
+ NULL AS tool_call_id, NULL AS tool_status, NULL AS log_id,
24217
+ created_at, 0 AS silent, NULL AS parent_id, 0 AS depth,
24218
+ 'pending' AS status, NULL AS reasoning_content,
24219
+ NULL AS reasoning_details,
24220
+ json_extract(args, '$.attachments') AS attachments,
24221
+ NULL AS metadata,
24222
+ NULL AS subagent_id
24223
+ FROM alarm_queue
24224
+ WHERE method = 'processMessage'
24225
+ AND status IN ('pending', 'processing')
24226
+ AND (
24227
+ status = 'pending'
24228
+ OR json_extract(args, '$.messageId') IS NOT NULL
24229
+ )
24230
+ AND NOT EXISTS (
24231
+ SELECT 1
24232
+ FROM messages persisted
24233
+ WHERE persisted.id = COALESCE(json_extract(alarm_queue.args, '$.messageId'), alarm_queue.id)
24234
+ )
24235
+ )
24236
+ `;
23855
24237
  const countResult = await this.ctx.storage.sql.exec(
23856
- `SELECT COUNT(*) as total FROM messages ${whereClause}`
24238
+ `
24239
+ ${combinedMessagesSql}
24240
+ SELECT COUNT(*) as total FROM combined_messages ${whereClause}
24241
+ `
23857
24242
  );
23858
24243
  const total = countResult.one().total;
23859
24244
  const result = await this.ctx.storage.sql.exec(
23860
24245
  `
23861
- SELECT id, role, content, name, tool_calls, tool_call_id, tool_status, log_id, created_at, silent, parent_id, depth, status, reasoning_content, reasoning_details, attachments, metadata, subagent_id
23862
- FROM messages
24246
+ ${combinedMessagesSql}
24247
+ SELECT source, id, role, content, name, tool_calls, tool_call_id,
24248
+ tool_status, log_id, created_at, silent, parent_id, depth, status,
24249
+ reasoning_content, reasoning_details, attachments, metadata,
24250
+ subagent_id
24251
+ FROM combined_messages
23863
24252
  ${whereClause}
23864
- ORDER BY created_at ${order === "ASC" ? "ASC" : "DESC"}, rowid ${order === "ASC" ? "ASC" : "DESC"}
24253
+ ORDER BY created_at ${orderDirection}, source_order ${orderDirection}, source_rowid ${orderDirection}
23865
24254
  LIMIT ? OFFSET ?
23866
24255
  `,
23867
24256
  limit,
23868
24257
  offset
23869
24258
  );
23870
24259
  let messages = result.toArray().map((row) => {
24260
+ const metadata = this.parseMessageMetadata(row.metadata);
24261
+ const isQueuedSource = row.source === "queue" || row.source === "send_queue";
24262
+ const messageMetadata = isQueuedSource ? {
24263
+ ...metadata ?? {},
24264
+ queued: true,
24265
+ queue_status: "queued",
24266
+ queue_source: row.source === "send_queue" ? "alarm_queue" : "message_queue"
24267
+ } : metadata;
24268
+ return {
24269
+ id: row.id,
24270
+ role: row.role,
24271
+ content: row.content,
24272
+ name: row.name,
24273
+ tool_calls: row.tool_calls,
24274
+ tool_call_id: row.tool_call_id,
24275
+ tool_status: row.tool_status,
24276
+ log_id: row.log_id,
24277
+ created_at: row.created_at,
24278
+ silent: row.silent === 1,
24279
+ parent_id: row.parent_id,
24280
+ depth: row.depth,
24281
+ status: row.status,
24282
+ reasoning_content: row.reasoning_content,
24283
+ reasoning_details: row.reasoning_details,
24284
+ attachments: row.attachments ? JSON.parse(row.attachments) : null,
24285
+ metadata: messageMetadata,
24286
+ subagent_id: row.subagent_id ?? (row.source === "queue" ? this.extractSubagentIdFromMetadata(row.metadata) : null)
24287
+ };
24288
+ });
24289
+ const subagentIds = Array.from(
24290
+ new Set(
24291
+ messages.map(
24292
+ (message) => typeof message.subagent_id === "string" ? message.subagent_id.trim() : ""
24293
+ ).filter((id) => id.length > 0)
24294
+ )
24295
+ );
24296
+ if (subagentIds.length > 0) {
24297
+ const projectionMap = await this.resolveSubagentMessageProjections(
24298
+ subagentIds
24299
+ );
24300
+ messages = messages.map((message) => {
24301
+ const subagentId = typeof message.subagent_id === "string" ? message.subagent_id.trim() : "";
24302
+ if (!subagentId) {
24303
+ return message;
24304
+ }
24305
+ const projection = projectionMap.get(subagentId);
24306
+ return projection ? { ...message, ...projection } : message;
24307
+ });
24308
+ }
24309
+ if (order === "DESC") {
24310
+ messages = messages.reverse();
24311
+ }
24312
+ const hasMore = offset + messages.length < total;
24313
+ return { messages, total, hasMore };
24314
+ } catch (error) {
24315
+ console.error("Error in getMessages:", error);
24316
+ throw error;
24317
+ }
24318
+ }
24319
+ /**
24320
+ * Get specific messages, optionally expanding any requested tool-call message
24321
+ * to the full contiguous workblock it belongs to.
24322
+ */
24323
+ async getMessagesByIds(ids, includeSilent = false, maxDepth = 0, includeWorkblocks = false) {
24324
+ await this.ensureMigrated();
24325
+ const uniqueIds = Array.from(new Set(ids.map((id) => id.trim()).filter(Boolean)));
24326
+ if (uniqueIds.length === 0) {
24327
+ return { messages: [], total: 0, hasMore: false };
24328
+ }
24329
+ if (uniqueIds.length > 200) {
24330
+ throw new Error("Too many message IDs requested");
24331
+ }
24332
+ const whereClauses = [];
24333
+ if (!includeSilent) {
24334
+ whereClauses.push("silent = 0");
24335
+ }
24336
+ whereClauses.push(`(depth <= ${maxDepth} OR depth IS NULL)`);
24337
+ const baseWhereClause = whereClauses.length > 0 ? whereClauses.join(" AND ") : "1 = 1";
24338
+ const mapRows = async (rows) => {
24339
+ let messages2 = rows.map((row) => {
23871
24340
  let metadata;
23872
24341
  if (typeof row.metadata === "string") {
23873
24342
  try {
@@ -23902,7 +24371,7 @@ ${resultContent}${attachmentSummary}`;
23902
24371
  });
23903
24372
  const subagentIds = Array.from(
23904
24373
  new Set(
23905
- messages.map(
24374
+ messages2.map(
23906
24375
  (message) => typeof message.subagent_id === "string" ? message.subagent_id.trim() : ""
23907
24376
  ).filter((id) => id.length > 0)
23908
24377
  )
@@ -23911,7 +24380,7 @@ ${resultContent}${attachmentSummary}`;
23911
24380
  const projectionMap = await this.resolveSubagentMessageProjections(
23912
24381
  subagentIds
23913
24382
  );
23914
- messages = messages.map((message) => {
24383
+ messages2 = messages2.map((message) => {
23915
24384
  const subagentId = typeof message.subagent_id === "string" ? message.subagent_id.trim() : "";
23916
24385
  if (!subagentId) {
23917
24386
  return message;
@@ -23920,15 +24389,61 @@ ${resultContent}${attachmentSummary}`;
23920
24389
  return projection ? { ...message, ...projection } : message;
23921
24390
  });
23922
24391
  }
23923
- if (order === "DESC") {
23924
- messages = messages.reverse();
24392
+ return messages2;
24393
+ };
24394
+ const selectColumns = `
24395
+ id, role, content, name, tool_calls, tool_call_id, tool_status, log_id,
24396
+ created_at, silent, parent_id, depth, status, reasoning_content,
24397
+ reasoning_details, attachments, metadata, subagent_id
24398
+ `;
24399
+ if (!includeWorkblocks) {
24400
+ const placeholders = uniqueIds.map(() => "?").join(", ");
24401
+ const rows = await this.ctx.storage.sql.exec(
24402
+ `
24403
+ SELECT ${selectColumns}
24404
+ FROM messages
24405
+ WHERE ${baseWhereClause} AND id IN (${placeholders})
24406
+ ORDER BY created_at ASC, rowid ASC
24407
+ `,
24408
+ ...uniqueIds
24409
+ ).toArray();
24410
+ const messages2 = await mapRows(rows);
24411
+ return { messages: messages2, total: messages2.length, hasMore: false };
24412
+ }
24413
+ const allRows = await this.ctx.storage.sql.exec(
24414
+ `
24415
+ SELECT ${selectColumns}
24416
+ FROM messages
24417
+ WHERE ${baseWhereClause}
24418
+ ORDER BY created_at ASC, rowid ASC
24419
+ `
24420
+ ).toArray();
24421
+ const requestedIds = new Set(uniqueIds);
24422
+ const selectedIds = /* @__PURE__ */ new Set();
24423
+ const isWorkblockRow = (row) => row.role === "tool" || row.role === "assistant" && typeof row.tool_calls === "string" && row.tool_calls.length > 0;
24424
+ for (let index = 0; index < allRows.length; index++) {
24425
+ const row = allRows[index];
24426
+ if (!requestedIds.has(row.id)) continue;
24427
+ if (!isWorkblockRow(row)) {
24428
+ selectedIds.add(row.id);
24429
+ continue;
24430
+ }
24431
+ let start = index;
24432
+ while (start > 0 && isWorkblockRow(allRows[start - 1])) {
24433
+ start--;
24434
+ }
24435
+ let end = index;
24436
+ while (end + 1 < allRows.length && isWorkblockRow(allRows[end + 1])) {
24437
+ end++;
24438
+ }
24439
+ for (let i = start; i <= end; i++) {
24440
+ selectedIds.add(allRows[i].id);
23925
24441
  }
23926
- const hasMore = offset + messages.length < total;
23927
- return { messages, total, hasMore };
23928
- } catch (error) {
23929
- console.error("Error in getMessages:", error);
23930
- throw error;
23931
24442
  }
24443
+ const messages = await mapRows(
24444
+ allRows.filter((row) => selectedIds.has(row.id))
24445
+ );
24446
+ return { messages, total: messages.length, hasMore: false };
23932
24447
  }
23933
24448
  /**
23934
24449
  * Delete a message (RPC method)
@@ -23937,6 +24452,9 @@ ${resultContent}${attachmentSummary}`;
23937
24452
  async deleteMessage(messageId) {
23938
24453
  await this.ensureMigrated();
23939
24454
  try {
24455
+ if (await this.cancelQueuedMessage(messageId)) {
24456
+ return { success: true };
24457
+ }
23940
24458
  const rows = await this.ctx.storage.sql.exec(
23941
24459
  `SELECT id, attachments FROM messages WHERE id = ?`,
23942
24460
  messageId
@@ -23947,12 +24465,7 @@ ${resultContent}${attachmentSummary}`;
23947
24465
  const attachmentsJson = rows[0].attachments;
23948
24466
  if (attachmentsJson) {
23949
24467
  try {
23950
- const refs = JSON.parse(attachmentsJson);
23951
- for (const ref of refs) {
23952
- if (ref.path) {
23953
- await this.unlinkFile(ref.path);
23954
- }
23955
- }
24468
+ await this.deleteAttachmentRefsFromJson(attachmentsJson);
23956
24469
  } catch (e) {
23957
24470
  console.error("Failed to cleanup attachments:", e);
23958
24471
  }
@@ -24076,7 +24589,7 @@ ${resultContent}${attachmentSummary}`;
24076
24589
  const result = await this.ctx.storage.sql.exec(
24077
24590
  `
24078
24591
  SELECT
24079
- id, message_id, provider, actual_provider, model, model_name, prompt_name,
24592
+ id, message_id, provider, actual_provider, standard_agents_router_used, model, model_name, prompt_name,
24080
24593
  tools_called, queued_tools, provider_tools, parent_log_id, retry_of_log_id, error, cost_total,
24081
24594
  is_complete, created_at, request_body
24082
24595
  FROM logs
@@ -24091,6 +24604,7 @@ ${resultContent}${attachmentSummary}`;
24091
24604
  message_id: row.message_id,
24092
24605
  provider: row.provider,
24093
24606
  actual_provider: row.actual_provider,
24607
+ standard_agents_router_used: row.standard_agents_router_used === 1,
24094
24608
  model: row.model,
24095
24609
  model_name: row.model_name,
24096
24610
  prompt_name: row.prompt_name,
@@ -24112,6 +24626,203 @@ ${resultContent}${attachmentSummary}`;
24112
24626
  throw error;
24113
24627
  }
24114
24628
  }
24629
+ /**
24630
+ * Get specific logs, optionally including all descendant logs.
24631
+ */
24632
+ async getLogsByIds(ids, includeDescendants = false, order = "ASC") {
24633
+ await this.ensureMigrated();
24634
+ const uniqueIds = Array.from(new Set(ids.map((id) => id.trim()).filter(Boolean)));
24635
+ if (uniqueIds.length === 0) {
24636
+ return { logs: [], total: 0, hasMore: false };
24637
+ }
24638
+ if (uniqueIds.length > 200) {
24639
+ throw new Error("Too many log IDs requested");
24640
+ }
24641
+ const placeholders = uniqueIds.map(() => "?").join(", ");
24642
+ const sourceQuery = includeDescendants ? `
24643
+ WITH RECURSIVE
24644
+ seed_logs(id) AS (
24645
+ SELECT id FROM logs WHERE id IN (${placeholders})
24646
+ ),
24647
+ descendant_logs(id) AS (
24648
+ SELECT id FROM seed_logs
24649
+ UNION
24650
+ SELECT logs.id
24651
+ FROM logs
24652
+ JOIN descendant_logs ON logs.parent_log_id = descendant_logs.id
24653
+ ),
24654
+ selected_logs(id) AS (
24655
+ SELECT id FROM descendant_logs
24656
+ UNION
24657
+ SELECT logs.parent_log_id
24658
+ FROM logs
24659
+ JOIN selected_logs ON logs.id = selected_logs.id
24660
+ WHERE logs.parent_log_id IS NOT NULL
24661
+ )
24662
+ SELECT
24663
+ id, message_id, provider, actual_provider, model, model_name, prompt_name,
24664
+ tools_called, queued_tools, provider_tools, parent_log_id, retry_of_log_id, error, cost_total,
24665
+ is_complete, created_at, request_body
24666
+ FROM logs
24667
+ WHERE id IN (SELECT id FROM selected_logs)
24668
+ ORDER BY created_at ${order}, rowid ${order}
24669
+ ` : `
24670
+ SELECT
24671
+ id, message_id, provider, actual_provider, model, model_name, prompt_name,
24672
+ tools_called, queued_tools, provider_tools, parent_log_id, retry_of_log_id, error, cost_total,
24673
+ is_complete, created_at, request_body
24674
+ FROM logs
24675
+ WHERE id IN (${placeholders})
24676
+ ORDER BY created_at ${order}, rowid ${order}
24677
+ `;
24678
+ const result = await this.ctx.storage.sql.exec(sourceQuery, ...uniqueIds);
24679
+ const logs = result.toArray().map((row) => ({
24680
+ id: row.id,
24681
+ message_id: row.message_id,
24682
+ provider: row.provider,
24683
+ actual_provider: row.actual_provider,
24684
+ model: row.model,
24685
+ model_name: row.model_name,
24686
+ prompt_name: row.prompt_name,
24687
+ tools_called: row.tools_called,
24688
+ queued_tools: row.queued_tools,
24689
+ provider_tools: row.provider_tools,
24690
+ parent_log_id: row.parent_log_id,
24691
+ retry_of_log_id: row.retry_of_log_id,
24692
+ error: row.error,
24693
+ cost_total: row.cost_total,
24694
+ is_complete: row.is_complete === 1,
24695
+ created_at: row.created_at,
24696
+ request_body: row.request_body
24697
+ }));
24698
+ return { logs, total: logs.length, hasMore: false };
24699
+ }
24700
+ /**
24701
+ * Get logs for specific messages, optionally expanding requested messages to
24702
+ * the full contiguous workblock they belong to and including descendant logs.
24703
+ */
24704
+ async getLogsByMessageIds(messageIds, includeWorkblocks = false, includeDescendants = false, order = "ASC") {
24705
+ await this.ensureMigrated();
24706
+ const uniqueMessageIds = Array.from(
24707
+ new Set(messageIds.map((id) => id.trim()).filter(Boolean))
24708
+ );
24709
+ if (uniqueMessageIds.length === 0) {
24710
+ return { logs: [], total: 0, hasMore: false };
24711
+ }
24712
+ if (uniqueMessageIds.length > 200) {
24713
+ throw new Error("Too many message IDs requested");
24714
+ }
24715
+ const selectedMessageIds = /* @__PURE__ */ new Set();
24716
+ if (includeWorkblocks) {
24717
+ const allRows = await this.ctx.storage.sql.exec(
24718
+ `
24719
+ SELECT id, role, tool_calls
24720
+ FROM messages
24721
+ ORDER BY created_at ASC, rowid ASC
24722
+ `
24723
+ ).toArray();
24724
+ const requestedIds = new Set(uniqueMessageIds);
24725
+ const isWorkblockRow = (row) => row.role === "tool" || row.role === "assistant" && typeof row.tool_calls === "string" && row.tool_calls.length > 0;
24726
+ for (let index = 0; index < allRows.length; index++) {
24727
+ const row = allRows[index];
24728
+ if (!requestedIds.has(row.id)) continue;
24729
+ if (!isWorkblockRow(row)) {
24730
+ selectedMessageIds.add(row.id);
24731
+ continue;
24732
+ }
24733
+ let start = index;
24734
+ while (start > 0 && isWorkblockRow(allRows[start - 1])) {
24735
+ start--;
24736
+ }
24737
+ let end = index;
24738
+ while (end + 1 < allRows.length && isWorkblockRow(allRows[end + 1])) {
24739
+ end++;
24740
+ }
24741
+ for (let i = start; i <= end; i++) {
24742
+ selectedMessageIds.add(allRows[i].id);
24743
+ }
24744
+ }
24745
+ } else {
24746
+ uniqueMessageIds.forEach((id) => selectedMessageIds.add(id));
24747
+ }
24748
+ const selectedMessageIdList = Array.from(selectedMessageIds);
24749
+ if (selectedMessageIdList.length === 0) {
24750
+ return { logs: [], total: 0, hasMore: false };
24751
+ }
24752
+ const rowsById = /* @__PURE__ */ new Map();
24753
+ const MESSAGE_ID_CHUNK_SIZE = 80;
24754
+ for (let index = 0; index < selectedMessageIdList.length; index += MESSAGE_ID_CHUNK_SIZE) {
24755
+ const chunk = selectedMessageIdList.slice(index, index + MESSAGE_ID_CHUNK_SIZE);
24756
+ const placeholders = chunk.map(() => "?").join(", ");
24757
+ const sourceQuery = includeDescendants ? `
24758
+ WITH RECURSIVE
24759
+ seed_logs(id) AS (
24760
+ SELECT id FROM logs WHERE message_id IN (${placeholders})
24761
+ ),
24762
+ descendant_logs(id) AS (
24763
+ SELECT id FROM seed_logs
24764
+ UNION
24765
+ SELECT logs.id
24766
+ FROM logs
24767
+ JOIN descendant_logs ON logs.parent_log_id = descendant_logs.id
24768
+ ),
24769
+ selected_logs(id) AS (
24770
+ SELECT id FROM descendant_logs
24771
+ UNION
24772
+ SELECT logs.parent_log_id
24773
+ FROM logs
24774
+ JOIN selected_logs ON logs.id = selected_logs.id
24775
+ WHERE logs.parent_log_id IS NOT NULL
24776
+ )
24777
+ SELECT
24778
+ rowid AS row_index,
24779
+ id, message_id, provider, actual_provider, model, model_name, prompt_name,
24780
+ tools_called, queued_tools, provider_tools, parent_log_id, retry_of_log_id, error, cost_total,
24781
+ is_complete, created_at, request_body
24782
+ FROM logs
24783
+ WHERE id IN (SELECT id FROM selected_logs)
24784
+ ORDER BY created_at ${order}, rowid ${order}
24785
+ ` : `
24786
+ SELECT
24787
+ rowid AS row_index,
24788
+ id, message_id, provider, actual_provider, model, model_name, prompt_name,
24789
+ tools_called, queued_tools, provider_tools, parent_log_id, retry_of_log_id, error, cost_total,
24790
+ is_complete, created_at, request_body
24791
+ FROM logs
24792
+ WHERE message_id IN (${placeholders})
24793
+ ORDER BY created_at ${order}, rowid ${order}
24794
+ `;
24795
+ const result = await this.ctx.storage.sql.exec(sourceQuery, ...chunk);
24796
+ for (const row of result.toArray()) {
24797
+ rowsById.set(row.id, row);
24798
+ }
24799
+ }
24800
+ const rows = Array.from(rowsById.values()).sort((left, right) => {
24801
+ const createdAtDelta = left.created_at - right.created_at;
24802
+ const rowDelta = left.row_index - right.row_index;
24803
+ return order === "ASC" ? createdAtDelta || rowDelta : -createdAtDelta || -rowDelta;
24804
+ });
24805
+ const logs = rows.map((row) => ({
24806
+ id: row.id,
24807
+ message_id: row.message_id,
24808
+ provider: row.provider,
24809
+ actual_provider: row.actual_provider,
24810
+ model: row.model,
24811
+ model_name: row.model_name,
24812
+ prompt_name: row.prompt_name,
24813
+ tools_called: row.tools_called,
24814
+ queued_tools: row.queued_tools,
24815
+ provider_tools: row.provider_tools,
24816
+ parent_log_id: row.parent_log_id,
24817
+ retry_of_log_id: row.retry_of_log_id,
24818
+ error: row.error,
24819
+ cost_total: row.cost_total,
24820
+ is_complete: row.is_complete === 1,
24821
+ created_at: row.created_at,
24822
+ request_body: row.request_body
24823
+ }));
24824
+ return { logs, total: logs.length, hasMore: false };
24825
+ }
24115
24826
  /**
24116
24827
  * Get detailed information for a single log (RPC method)
24117
24828
  * This includes all fields including large ones like request/response bodies
@@ -24122,7 +24833,7 @@ ${resultContent}${attachmentSummary}`;
24122
24833
  const result = await this.ctx.storage.sql.exec(
24123
24834
  `
24124
24835
  SELECT
24125
- l.id, l.message_id, l.provider, l.actual_provider, l.model, l.model_name, l.endpoint,
24836
+ l.id, l.message_id, l.provider, l.actual_provider, l.standard_agents_router_used, l.model, l.model_name, l.endpoint,
24126
24837
  l.request_body, l.request_headers, l.response_body, l.response_headers,
24127
24838
  l.status_code, l.reasoning_content, l.input_tokens, l.cached_tokens, l.output_tokens,
24128
24839
  l.reasoning_tokens, l.total_tokens, l.latency_ms, l.time_to_first_token_ms,
@@ -24194,6 +24905,7 @@ ${resultContent}${attachmentSummary}`;
24194
24905
  message_id: row.message_id,
24195
24906
  provider: row.provider,
24196
24907
  actual_provider: row.actual_provider,
24908
+ standard_agents_router_used: row.standard_agents_router_used === 1,
24197
24909
  model: row.model,
24198
24910
  model_name: row.model_name,
24199
24911
  endpoint: row.endpoint,
@@ -24787,7 +25499,7 @@ ${resultContent}${attachmentSummary}`;
24787
25499
  * Internal method: Process a message (called by alarm queue)
24788
25500
  * This is the actual message processing logic, separate from the public sendMessage() RPC method
24789
25501
  */
24790
- async processMessage(threadId, content, role = "user", attachments) {
25502
+ async processMessage(threadId, content, role = "user", attachments, queuedMessageId, queuedAt) {
24791
25503
  await this.assertNotTerminated();
24792
25504
  if (role === "user") {
24793
25505
  await this.ctx.storage.sql.exec(
@@ -24863,8 +25575,8 @@ ${resultContent}${attachmentSummary}`;
24863
25575
  side_b_session_status_message_property: sideBSession.status.messageProperty,
24864
25576
  side_b_session_status_attachments_property: sideBSession.status.attachmentsProperty
24865
25577
  };
24866
- const messageId = crypto.randomUUID();
24867
- const timestamp = Date.now() * 1e3;
25578
+ const messageId = this.asOptionalString(queuedMessageId) ?? crypto.randomUUID();
25579
+ const timestamp = typeof queuedAt === "number" && Number.isFinite(queuedAt) && queuedAt > 0 ? queuedAt : Date.now() * 1e3;
24868
25580
  let message = {
24869
25581
  id: messageId,
24870
25582
  role,
@@ -25232,11 +25944,11 @@ ${resultContent}${attachmentSummary}`;
25232
25944
  /**
25233
25945
  * Write a file to storage (RPC method)
25234
25946
  */
25235
- async writeFile(path19, data, mimeType, options) {
25947
+ async writeFile(path20, data, mimeType, options) {
25236
25948
  await this.ensureMigrated();
25237
25949
  try {
25238
- const fs17 = this.getFileStorage();
25239
- const existingFile = await fs17.stat(path19);
25950
+ const fs18 = this.getFileStorage();
25951
+ const existingFile = await fs18.stat(path20);
25240
25952
  const isUpdate = existingFile !== null;
25241
25953
  const binaryString = atob(data);
25242
25954
  const dataBuffer = new Uint8Array(binaryString.length);
@@ -25258,12 +25970,12 @@ ${resultContent}${attachmentSummary}`;
25258
25970
  }
25259
25971
  }
25260
25972
  }
25261
- const record = await fs17.writeFile(path19, dataBuffer, mimeType, {
25973
+ const record = await fs18.writeFile(path20, dataBuffer, mimeType, {
25262
25974
  metadata: options?.metadata,
25263
25975
  thumbnail: thumbnailBuffer
25264
25976
  });
25265
25977
  this.broadcastEvent(isUpdate ? "file_updated" : "file_created", {
25266
- path: path19,
25978
+ path: path20,
25267
25979
  file: record
25268
25980
  });
25269
25981
  return { success: true, file: record };
@@ -25275,15 +25987,15 @@ ${resultContent}${attachmentSummary}`;
25275
25987
  /**
25276
25988
  * Write a text file to storage (RPC method)
25277
25989
  */
25278
- async writeTextFile(path19, content, mimeType = "text/plain", options) {
25990
+ async writeTextFile(path20, content, mimeType = "text/plain", options) {
25279
25991
  await this.ensureMigrated();
25280
25992
  try {
25281
- const fs17 = this.getFileStorage();
25282
- const existingFile = await fs17.stat(path19);
25993
+ const fs18 = this.getFileStorage();
25994
+ const existingFile = await fs18.stat(path20);
25283
25995
  const isUpdate = existingFile !== null;
25284
- const record = await fs17.writeFile(path19, content, mimeType, options);
25996
+ const record = await fs18.writeFile(path20, content, mimeType, options);
25285
25997
  this.broadcastEvent(isUpdate ? "file_updated" : "file_created", {
25286
- path: path19,
25998
+ path: path20,
25287
25999
  file: record
25288
26000
  });
25289
26001
  return { success: true, file: record };
@@ -25320,11 +26032,11 @@ ${resultContent}${attachmentSummary}`;
25320
26032
  /**
25321
26033
  * Link to an external file (RPC method)
25322
26034
  */
25323
- async linkFile(path19, location, options) {
26035
+ async linkFile(path20, location, options) {
25324
26036
  await this.ensureMigrated();
25325
26037
  try {
25326
- const fs17 = this.getFileStorage();
25327
- const record = await fs17.linkFile(path19, location, options);
26038
+ const fs18 = this.getFileStorage();
26039
+ const record = await fs18.linkFile(path20, location, options);
25328
26040
  return { success: true, file: record };
25329
26041
  } catch (error) {
25330
26042
  console.error("Error in linkFile:", error);
@@ -25335,11 +26047,11 @@ ${resultContent}${attachmentSummary}`;
25335
26047
  * Read a file from storage (RPC method)
25336
26048
  * Returns base64-encoded data
25337
26049
  */
25338
- async readFile(path19) {
26050
+ async readFile(path20) {
25339
26051
  await this.ensureMigrated();
25340
26052
  try {
25341
- const fs17 = this.getFileStorage();
25342
- const data = await fs17.readFile(path19);
26053
+ const fs18 = this.getFileStorage();
26054
+ const data = await fs18.readFile(path20);
25343
26055
  if (data === null) {
25344
26056
  return { success: false, error: "File not found or external" };
25345
26057
  }
@@ -25358,11 +26070,11 @@ ${resultContent}${attachmentSummary}`;
25358
26070
  /**
25359
26071
  * Read a text file from storage (RPC method)
25360
26072
  */
25361
- async readTextFile(path19) {
26073
+ async readTextFile(path20) {
25362
26074
  await this.ensureMigrated();
25363
26075
  try {
25364
- const fs17 = this.getFileStorage();
25365
- const content = await fs17.readTextFile(path19);
26076
+ const fs18 = this.getFileStorage();
26077
+ const content = await fs18.readTextFile(path20);
25366
26078
  if (content === null) {
25367
26079
  return { success: false, error: "File not found or external" };
25368
26080
  }
@@ -25375,11 +26087,11 @@ ${resultContent}${attachmentSummary}`;
25375
26087
  /**
25376
26088
  * Get file metadata (RPC method)
25377
26089
  */
25378
- async statFile(path19) {
26090
+ async statFile(path20) {
25379
26091
  await this.ensureMigrated();
25380
26092
  try {
25381
- const fs17 = this.getFileStorage();
25382
- const record = await fs17.stat(path19);
26093
+ const fs18 = this.getFileStorage();
26094
+ const record = await fs18.stat(path20);
25383
26095
  if (record === null) {
25384
26096
  return { success: false, error: "File not found" };
25385
26097
  }
@@ -25392,11 +26104,11 @@ ${resultContent}${attachmentSummary}`;
25392
26104
  /**
25393
26105
  * Check if file exists (RPC method)
25394
26106
  */
25395
- async fileExists(path19) {
26107
+ async fileExists(path20) {
25396
26108
  await this.ensureMigrated();
25397
26109
  try {
25398
- const fs17 = this.getFileStorage();
25399
- const exists2 = await fs17.exists(path19);
26110
+ const fs18 = this.getFileStorage();
26111
+ const exists2 = await fs18.exists(path20);
25400
26112
  return { success: true, exists: exists2 };
25401
26113
  } catch (error) {
25402
26114
  console.error("Error in fileExists:", error);
@@ -25406,12 +26118,12 @@ ${resultContent}${attachmentSummary}`;
25406
26118
  /**
25407
26119
  * Delete a file (RPC method)
25408
26120
  */
25409
- async unlinkFile(path19) {
26121
+ async unlinkFile(path20) {
25410
26122
  await this.ensureMigrated();
25411
26123
  try {
25412
- const fs17 = this.getFileStorage();
25413
- await fs17.unlink(path19);
25414
- this.broadcastEvent("file_deleted", { path: path19 });
26124
+ const fs18 = this.getFileStorage();
26125
+ await fs18.unlink(path20);
26126
+ this.broadcastEvent("file_deleted", { path: path20 });
25415
26127
  return { success: true };
25416
26128
  } catch (error) {
25417
26129
  console.error("Error in unlinkFile:", error);
@@ -25421,12 +26133,12 @@ ${resultContent}${attachmentSummary}`;
25421
26133
  /**
25422
26134
  * Create a directory (RPC method)
25423
26135
  */
25424
- async mkdirFile(path19) {
26136
+ async mkdirFile(path20) {
25425
26137
  await this.ensureMigrated();
25426
26138
  try {
25427
- const fs17 = this.getFileStorage();
25428
- const record = await fs17.mkdir(path19);
25429
- this.broadcastEvent("file_created", { path: path19, file: record });
26139
+ const fs18 = this.getFileStorage();
26140
+ const record = await fs18.mkdir(path20);
26141
+ this.broadcastEvent("file_created", { path: path20, file: record });
25430
26142
  return { success: true, directory: record };
25431
26143
  } catch (error) {
25432
26144
  console.error("Error in mkdirFile:", error);
@@ -25436,11 +26148,11 @@ ${resultContent}${attachmentSummary}`;
25436
26148
  /**
25437
26149
  * List directory contents (RPC method)
25438
26150
  */
25439
- async readdirFile(path19) {
26151
+ async readdirFile(path20) {
25440
26152
  await this.ensureMigrated();
25441
26153
  try {
25442
- const fs17 = this.getFileStorage();
25443
- const files = await fs17.readdir(path19);
26154
+ const fs18 = this.getFileStorage();
26155
+ const files = await fs18.readdir(path20);
25444
26156
  return { success: true, files };
25445
26157
  } catch (error) {
25446
26158
  console.error("Error in readdirFile:", error);
@@ -25450,12 +26162,12 @@ ${resultContent}${attachmentSummary}`;
25450
26162
  /**
25451
26163
  * Remove empty directory (RPC method)
25452
26164
  */
25453
- async rmdirFile(path19) {
26165
+ async rmdirFile(path20) {
25454
26166
  await this.ensureMigrated();
25455
26167
  try {
25456
- const fs17 = this.getFileStorage();
25457
- await fs17.rmdir(path19);
25458
- this.broadcastEvent("file_deleted", { path: path19 });
26168
+ const fs18 = this.getFileStorage();
26169
+ await fs18.rmdir(path20);
26170
+ this.broadcastEvent("file_deleted", { path: path20 });
25459
26171
  return { success: true };
25460
26172
  } catch (error) {
25461
26173
  console.error("Error in rmdirFile:", error);
@@ -25468,8 +26180,8 @@ ${resultContent}${attachmentSummary}`;
25468
26180
  async getFileStats() {
25469
26181
  await this.ensureMigrated();
25470
26182
  try {
25471
- const fs17 = this.getFileStorage();
25472
- const stats = await fs17.getFileStats();
26183
+ const fs18 = this.getFileStorage();
26184
+ const stats = await fs18.getFileStats();
25473
26185
  return { success: true, stats };
25474
26186
  } catch (error) {
25475
26187
  console.error("Error in getFileStats:", error);
@@ -25480,11 +26192,11 @@ ${resultContent}${attachmentSummary}`;
25480
26192
  * Get thumbnail for an image (RPC method)
25481
26193
  * Returns base64-encoded data
25482
26194
  */
25483
- async getFileThumbnail(path19) {
26195
+ async getFileThumbnail(path20) {
25484
26196
  await this.ensureMigrated();
25485
26197
  try {
25486
- const fs17 = this.getFileStorage();
25487
- const data = await fs17.getThumbnail(path19);
26198
+ const fs18 = this.getFileStorage();
26199
+ const data = await fs18.getThumbnail(path20);
25488
26200
  if (data === null) {
25489
26201
  return { success: false, error: "Thumbnail not found" };
25490
26202
  }
@@ -25506,8 +26218,8 @@ ${resultContent}${attachmentSummary}`;
25506
26218
  async grepFiles(pattern, options) {
25507
26219
  await this.ensureMigrated();
25508
26220
  try {
25509
- const fs17 = this.getFileStorage();
25510
- const results = await fs17.grep(pattern, options);
26221
+ const fs18 = this.getFileStorage();
26222
+ const results = await fs18.grep(pattern, options);
25511
26223
  return { success: true, results };
25512
26224
  } catch (error) {
25513
26225
  console.error("Error in grepFiles:", error);
@@ -25520,8 +26232,8 @@ ${resultContent}${attachmentSummary}`;
25520
26232
  async findFiles(pattern, options) {
25521
26233
  await this.ensureMigrated();
25522
26234
  try {
25523
- const fs17 = this.getFileStorage();
25524
- const files = await fs17.find(pattern, options);
26235
+ const fs18 = this.getFileStorage();
26236
+ const files = await fs18.find(pattern, options);
25525
26237
  return { success: true, files };
25526
26238
  } catch (error) {
25527
26239
  console.error("Error in findFiles:", error);
@@ -25536,11 +26248,11 @@ ${resultContent}${attachmentSummary}`;
25536
26248
  * Creates file record with is_chunked=1 and chunk_count=null.
25537
26249
  * Caller should then use writeFileChunk() to write chunks.
25538
26250
  */
25539
- async startChunkedUpload(path19, totalSize, mimeType, options) {
26251
+ async startChunkedUpload(path20, totalSize, mimeType, options) {
25540
26252
  await this.ensureMigrated();
25541
26253
  try {
25542
26254
  const { CHUNK_SIZE: CHUNK_SIZE2, normalizePath: normalizePath2, basename: basename3 } = await Promise.resolve().then(() => (init_files(), files_exports));
25543
- const normalizedPath = normalizePath2(path19);
26255
+ const normalizedPath = normalizePath2(path20);
25544
26256
  const name = basename3(normalizedPath);
25545
26257
  const now = Date.now();
25546
26258
  const expectedChunks = Math.ceil(totalSize / CHUNK_SIZE2);
@@ -25577,11 +26289,11 @@ ${resultContent}${attachmentSummary}`;
25577
26289
  * @param chunkIndex - 0-based chunk index
25578
26290
  * @param data - Base64 encoded chunk data
25579
26291
  */
25580
- async writeFileChunk(path19, chunkIndex, data) {
26292
+ async writeFileChunk(path20, chunkIndex, data) {
25581
26293
  await this.ensureMigrated();
25582
26294
  try {
25583
26295
  const { normalizePath: normalizePath2 } = await Promise.resolve().then(() => (init_files(), files_exports));
25584
- const normalizedPath = normalizePath2(path19);
26296
+ const normalizedPath = normalizePath2(path20);
25585
26297
  const binaryString = atob(data);
25586
26298
  const dataBuffer = new Uint8Array(binaryString.length);
25587
26299
  for (let i = 0; i < binaryString.length; i++) {
@@ -25603,12 +26315,12 @@ ${resultContent}${attachmentSummary}`;
25603
26315
  * Complete a chunked file upload.
25604
26316
  * Validates all chunks are present and sets chunk_count.
25605
26317
  */
25606
- async completeChunkedUpload(path19, expectedChunks, options) {
26318
+ async completeChunkedUpload(path20, expectedChunks, options) {
25607
26319
  await this.ensureMigrated();
25608
26320
  try {
25609
26321
  const { normalizePath: normalizePath2 } = await Promise.resolve().then(() => (init_files(), files_exports));
25610
- const fs17 = this.getFileStorage();
25611
- const normalizedPath = normalizePath2(path19);
26322
+ const fs18 = this.getFileStorage();
26323
+ const normalizedPath = normalizePath2(path20);
25612
26324
  const countResult = await this.ctx.storage.sql.exec(
25613
26325
  `SELECT COUNT(*) as count FROM file_chunks WHERE file_path = ?`,
25614
26326
  normalizedPath
@@ -25634,7 +26346,7 @@ ${resultContent}${attachmentSummary}`;
25634
26346
  thumbnailBuffer || null,
25635
26347
  normalizedPath
25636
26348
  );
25637
- const file = await fs17.stat(normalizedPath);
26349
+ const file = await fs18.stat(normalizedPath);
25638
26350
  if (file) {
25639
26351
  this.broadcastEvent("file_created", { path: normalizedPath, file });
25640
26352
  }
@@ -25648,11 +26360,11 @@ ${resultContent}${attachmentSummary}`;
25648
26360
  * Read a single chunk of a file.
25649
26361
  * Use for streaming large files to client.
25650
26362
  */
25651
- async readFileChunk(path19, chunkIndex) {
26363
+ async readFileChunk(path20, chunkIndex) {
25652
26364
  await this.ensureMigrated();
25653
26365
  try {
25654
26366
  const { normalizePath: normalizePath2 } = await Promise.resolve().then(() => (init_files(), files_exports));
25655
- const normalizedPath = normalizePath2(path19);
26367
+ const normalizedPath = normalizePath2(path20);
25656
26368
  const cursor = await this.ctx.storage.sql.exec(
25657
26369
  `SELECT data FROM file_chunks WHERE file_path = ? AND chunk_index = ?`,
25658
26370
  normalizedPath,
@@ -25677,11 +26389,11 @@ ${resultContent}${attachmentSummary}`;
25677
26389
  /**
25678
26390
  * Get file info including chunking metadata.
25679
26391
  */
25680
- async getFileInfo(path19) {
26392
+ async getFileInfo(path20) {
25681
26393
  await this.ensureMigrated();
25682
26394
  try {
25683
- const fs17 = this.getFileStorage();
25684
- const file = await fs17.stat(path19);
26395
+ const fs18 = this.getFileStorage();
26396
+ const file = await fs18.stat(path20);
25685
26397
  if (!file) {
25686
26398
  return { success: false, error: "File not found" };
25687
26399
  }
@@ -25694,7 +26406,7 @@ ${resultContent}${attachmentSummary}`;
25694
26406
  };
25695
26407
 
25696
26408
  // src/durable-objects/agentbuilder-migrations/0001_initial.ts
25697
- var migration30 = {
26409
+ var migration31 = {
25698
26410
  version: 1,
25699
26411
  async up(sql) {
25700
26412
  sql.exec(`
@@ -25793,7 +26505,7 @@ var migration30 = {
25793
26505
  };
25794
26506
 
25795
26507
  // src/durable-objects/agentbuilder-migrations/0002_add_tenvs_properties.ts
25796
- var migration31 = {
26508
+ var migration32 = {
25797
26509
  version: 2,
25798
26510
  async up(sql) {
25799
26511
  sql.exec(`ALTER TABLE threads ADD COLUMN tenvs TEXT`);
@@ -25805,7 +26517,7 @@ var migration31 = {
25805
26517
  };
25806
26518
 
25807
26519
  // src/durable-objects/agentbuilder-migrations/0003_add_parent_and_terminated.ts
25808
- var migration32 = {
26520
+ var migration33 = {
25809
26521
  version: 3,
25810
26522
  async up(sql) {
25811
26523
  sql.exec(`ALTER TABLE threads ADD COLUMN parent TEXT REFERENCES threads(id)`);
@@ -25818,7 +26530,7 @@ var migration32 = {
25818
26530
  };
25819
26531
 
25820
26532
  // src/durable-objects/agentbuilder-migrations/0004_add_env_tables.ts
25821
- var migration33 = {
26533
+ var migration34 = {
25822
26534
  version: 4,
25823
26535
  async up(sql) {
25824
26536
  sql.exec(`ALTER TABLE threads ADD COLUMN env TEXT`);
@@ -25842,7 +26554,7 @@ var migration33 = {
25842
26554
  };
25843
26555
 
25844
26556
  // src/durable-objects/agentbuilder-migrations/0005_add_pending_subagent_env_requests.ts
25845
- var migration34 = {
26557
+ var migration35 = {
25846
26558
  version: 5,
25847
26559
  async up(sql) {
25848
26560
  sql.exec(`
@@ -25867,9 +26579,24 @@ var migration34 = {
25867
26579
  }
25868
26580
  };
25869
26581
 
26582
+ // src/durable-objects/agentbuilder-migrations/0006_add_env_value_types.ts
26583
+ var migration36 = {
26584
+ version: 6,
26585
+ async up(sql) {
26586
+ sql.exec(
26587
+ `ALTER TABLE envs
26588
+ ADD COLUMN value_type TEXT NOT NULL DEFAULT 'secret'
26589
+ CHECK (value_type IN ('text', 'secret'))`
26590
+ );
26591
+ sql.exec(`
26592
+ INSERT OR REPLACE INTO _metadata (key, value) VALUES ('schema_version', '6')
26593
+ `);
26594
+ }
26595
+ };
26596
+
25870
26597
  // src/durable-objects/agentbuilder-migrations/index.ts
25871
- var migrations2 = [migration30, migration31, migration32, migration33, migration34];
25872
- var LATEST_SCHEMA_VERSION2 = 5;
26598
+ var migrations2 = [migration31, migration32, migration33, migration34, migration35, migration36];
26599
+ var LATEST_SCHEMA_VERSION2 = 6;
25873
26600
 
25874
26601
  // src/utils/crypto.ts
25875
26602
  var CryptoUtil = class {
@@ -26209,10 +26936,10 @@ var DurableAgentBuilder = class extends DurableObject {
26209
26936
  for (const entry of value) {
26210
26937
  if (!entry || typeof entry !== "object") continue;
26211
26938
  const attachment = entry;
26212
- const path19 = typeof attachment.path === "string" ? attachment.path.trim() : "";
26213
- if (!path19) continue;
26939
+ const path20 = typeof attachment.path === "string" ? attachment.path.trim() : "";
26940
+ if (!path20) continue;
26214
26941
  output.push({
26215
- path: path19,
26942
+ path: path20,
26216
26943
  name: typeof attachment.name === "string" ? attachment.name : void 0,
26217
26944
  mimeType: typeof attachment.mimeType === "string" ? attachment.mimeType : void 0,
26218
26945
  size: typeof attachment.size === "number" ? attachment.size : void 0,
@@ -26229,8 +26956,8 @@ var DurableAgentBuilder = class extends DurableObject {
26229
26956
  const trimmed = sanitized.replace(/^[-.]+|[-.]+$/g, "");
26230
26957
  return trimmed || "attachment";
26231
26958
  }
26232
- inferMimeTypeFromPath(path19) {
26233
- const normalized = path19.toLowerCase();
26959
+ inferMimeTypeFromPath(path20) {
26960
+ const normalized = path20.toLowerCase();
26234
26961
  if (normalized.endsWith(".png")) return "image/png";
26235
26962
  if (normalized.endsWith(".jpg") || normalized.endsWith(".jpeg")) return "image/jpeg";
26236
26963
  if (normalized.endsWith(".webp")) return "image/webp";
@@ -26268,7 +26995,7 @@ var DurableAgentBuilder = class extends DurableObject {
26268
26995
  if (!attachments || attachments.length === 0) {
26269
26996
  return "";
26270
26997
  }
26271
- const paths = attachments.map((attachment) => attachment.path).filter((path19) => typeof path19 === "string" && path19.length > 0);
26998
+ const paths = attachments.map((attachment) => attachment.path).filter((path20) => typeof path20 === "string" && path20.length > 0);
26272
26999
  if (paths.length === 0) {
26273
27000
  return "";
26274
27001
  }
@@ -26493,9 +27220,9 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
26493
27220
  }
26494
27221
  }
26495
27222
  async runMigrations(fromVersion) {
26496
- for (const migration35 of migrations2) {
26497
- if (migration35.version > fromVersion) {
26498
- await migration35.up(this.ctx.storage.sql);
27223
+ for (const migration37 of migrations2) {
27224
+ if (migration37.version > fromVersion) {
27225
+ await migration37.up(this.ctx.storage.sql);
26499
27226
  }
26500
27227
  }
26501
27228
  }
@@ -26852,23 +27579,49 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
26852
27579
  return CryptoUtil.decrypt(encrypted, this.getEncryptionKey());
26853
27580
  }
26854
27581
  async listScopedEnv(scope, userId = "") {
27582
+ const entries = await this.listScopedEnvEntries(scope, userId);
27583
+ const env = {};
27584
+ for (const entry of entries) {
27585
+ env[entry.name] = entry.value;
27586
+ }
27587
+ return env;
27588
+ }
27589
+ async listScopedEnvEntries(scope, userId = "") {
26855
27590
  await this.ensureMigrated();
26856
27591
  const cursor = await this.ctx.storage.sql.exec(
26857
- `SELECT name, value FROM envs WHERE scope = ? AND user_id = ?`,
27592
+ `SELECT name, value, value_type, created_at, updated_at
27593
+ FROM envs
27594
+ WHERE scope = ? AND user_id = ?`,
26858
27595
  scope,
26859
27596
  userId
26860
27597
  );
26861
- const env = {};
27598
+ const entries = [];
26862
27599
  const rows = cursor.toArray();
26863
27600
  for (const row of rows) {
26864
27601
  try {
26865
- env[row.name] = await this.decryptEnvValue(row.value);
27602
+ entries.push({
27603
+ name: row.name,
27604
+ value: await this.decryptEnvValue(row.value),
27605
+ type: row.value_type === "text" ? "text" : "secret",
27606
+ created_at: row.created_at,
27607
+ updated_at: row.updated_at
27608
+ });
26866
27609
  } catch {
26867
27610
  }
26868
27611
  }
26869
- return env;
27612
+ return entries;
27613
+ }
27614
+ async getScopedEnvTypeRecord(scope, userId = "") {
27615
+ const entries = await this.listScopedEnvEntries(scope, userId);
27616
+ const envTypes = {};
27617
+ for (const entry of entries) {
27618
+ if (entry.type === "text") {
27619
+ envTypes[entry.name] = "text";
27620
+ }
27621
+ }
27622
+ return envTypes;
26870
27623
  }
26871
- async replaceScopedEnv(scope, userId, env) {
27624
+ async replaceScopedEnv(scope, userId, env, envTypes) {
26872
27625
  await this.ensureMigrated();
26873
27626
  await this.ctx.storage.sql.exec(
26874
27627
  `DELETE FROM envs WHERE scope = ? AND user_id = ?`,
@@ -26876,32 +27629,93 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
26876
27629
  userId
26877
27630
  );
26878
27631
  const now = Math.floor(Date.now() / 1e3);
27632
+ const normalizedEnvTypes = this.normalizeEnvTypeRecord(envTypes ?? null, env) ?? {};
26879
27633
  for (const [name, value] of Object.entries(env)) {
26880
27634
  await this.ctx.storage.sql.exec(
26881
- `INSERT INTO envs (scope, user_id, name, value, created_at, updated_at)
26882
- VALUES (?, ?, ?, ?, ?, ?)`,
27635
+ `INSERT INTO envs (scope, user_id, name, value, value_type, created_at, updated_at)
27636
+ VALUES (?, ?, ?, ?, ?, ?, ?)`,
26883
27637
  scope,
26884
27638
  userId,
26885
27639
  name,
26886
27640
  await this.encryptEnvValue(value),
27641
+ normalizedEnvTypes[name] === "text" ? "text" : "secret",
26887
27642
  now,
26888
27643
  now
26889
27644
  );
26890
27645
  }
26891
27646
  }
27647
+ async patchScopedEnv(scope, userId, params) {
27648
+ const currentEnv = await this.listScopedEnv(scope, userId);
27649
+ const currentEnvTypes = await this.getScopedEnvTypeRecord(scope, userId);
27650
+ const nextEnv = { ...currentEnv };
27651
+ const nextEnvTypes = { ...currentEnvTypes };
27652
+ if (params.env_patch) {
27653
+ for (const [key, value] of Object.entries(params.env_patch)) {
27654
+ const property = key.trim();
27655
+ if (!property) {
27656
+ throw new Error("env_patch keys must be non-empty strings");
27657
+ }
27658
+ if (value === void 0 || value === null) {
27659
+ throw new Error(`env_patch.${property} must be a string`);
27660
+ }
27661
+ nextEnv[property] = String(value);
27662
+ }
27663
+ }
27664
+ if (params.env_type_patch) {
27665
+ for (const [key, value] of Object.entries(params.env_type_patch)) {
27666
+ const property = key.trim();
27667
+ if (!property) {
27668
+ throw new Error("env_type_patch keys must be non-empty strings");
27669
+ }
27670
+ if (nextEnv[property] === void 0) {
27671
+ throw new Error(`env_type_patch.${property} has no matching env value`);
27672
+ }
27673
+ if (value === "text") {
27674
+ nextEnvTypes[property] = "text";
27675
+ } else {
27676
+ delete nextEnvTypes[property];
27677
+ }
27678
+ }
27679
+ }
27680
+ for (const key of params.env_delete ?? []) {
27681
+ delete nextEnv[key];
27682
+ delete nextEnvTypes[key];
27683
+ }
27684
+ await this.replaceScopedEnv(scope, userId, nextEnv, nextEnvTypes);
27685
+ }
26892
27686
  async getInstanceEnv() {
26893
27687
  return this.listScopedEnv("instance", "");
26894
27688
  }
26895
- async setInstanceEnv(env) {
27689
+ async getInstanceEnvTypes() {
27690
+ return this.getScopedEnvTypeRecord("instance", "");
27691
+ }
27692
+ async getInstanceEnvEntries() {
27693
+ return this.listScopedEnvEntries("instance", "");
27694
+ }
27695
+ async setInstanceEnv(env, envTypes) {
26896
27696
  const normalized = this.normalizeEnvRecord(env) ?? {};
26897
- await this.replaceScopedEnv("instance", "", normalized);
27697
+ const normalizedTypes = this.normalizeEnvTypeRecord(envTypes ?? null, normalized);
27698
+ await this.replaceScopedEnv("instance", "", normalized, normalizedTypes);
27699
+ }
27700
+ async patchInstanceEnv(params) {
27701
+ await this.patchScopedEnv("instance", "", params);
26898
27702
  }
26899
27703
  async getUserEnv(userId) {
26900
27704
  return this.listScopedEnv("user", userId);
26901
27705
  }
26902
- async setUserEnv(userId, env) {
27706
+ async getUserEnvTypes(userId) {
27707
+ return this.getScopedEnvTypeRecord("user", userId);
27708
+ }
27709
+ async getUserEnvEntries(userId) {
27710
+ return this.listScopedEnvEntries("user", userId);
27711
+ }
27712
+ async setUserEnv(userId, env, envTypes) {
26903
27713
  const normalized = this.normalizeEnvRecord(env) ?? {};
26904
- await this.replaceScopedEnv("user", userId, normalized);
27714
+ const normalizedTypes = this.normalizeEnvTypeRecord(envTypes ?? null, normalized);
27715
+ await this.replaceScopedEnv("user", userId, normalized, normalizedTypes);
27716
+ }
27717
+ async patchUserEnv(userId, params) {
27718
+ await this.patchScopedEnv("user", userId, params);
26905
27719
  }
26906
27720
  async getMissingRequiredScopedSubagentEnv(params) {
26907
27721
  await this.ensureMigrated();
@@ -26947,10 +27761,10 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
26947
27761
  const missing = [];
26948
27762
  for (const property of requiredScoped) {
26949
27763
  if (providedEnv[property] !== void 0) continue;
26950
- if (userEnv[property] !== void 0) continue;
26951
- if (instanceEnv[property] !== void 0) continue;
26952
27764
  if (agentEnv[property] !== void 0) continue;
26953
27765
  if (promptEnv[property] !== void 0) continue;
27766
+ if (userEnv[property] !== void 0) continue;
27767
+ if (instanceEnv[property] !== void 0) continue;
26954
27768
  missing.push(property);
26955
27769
  }
26956
27770
  missing.sort((a, b) => a.localeCompare(b));
@@ -27226,16 +28040,6 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
27226
28040
  if (thread.env && thread.env[params.property] !== void 0) {
27227
28041
  return thread.env[params.property];
27228
28042
  }
27229
- if (thread.user_id) {
27230
- const userEnv = await this.getUserEnv(thread.user_id);
27231
- if (userEnv[params.property] !== void 0) {
27232
- return userEnv[params.property];
27233
- }
27234
- }
27235
- const instanceEnv = await this.getInstanceEnv();
27236
- if (instanceEnv[params.property] !== void 0) {
27237
- return instanceEnv[params.property];
27238
- }
27239
28043
  let agentDef = null;
27240
28044
  try {
27241
28045
  agentDef = await this.loadAgent(thread.agent_name);
@@ -27257,6 +28061,16 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
27257
28061
  } catch {
27258
28062
  }
27259
28063
  }
28064
+ if (thread.user_id) {
28065
+ const userEnv = await this.getUserEnv(thread.user_id);
28066
+ if (userEnv[params.property] !== void 0) {
28067
+ return userEnv[params.property];
28068
+ }
28069
+ }
28070
+ const instanceEnv = await this.getInstanceEnv();
28071
+ if (instanceEnv[params.property] !== void 0) {
28072
+ return instanceEnv[params.property];
28073
+ }
27260
28074
  return null;
27261
28075
  }
27262
28076
  async resolveThreadEnvType(params) {
@@ -27265,12 +28079,39 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
27265
28079
  if (thread.env && thread.env[params.property] !== void 0) {
27266
28080
  return thread.env_types?.[params.property] === "text" ? "text" : "secret";
27267
28081
  }
28082
+ let agentDef = null;
28083
+ try {
28084
+ agentDef = await this.loadAgent(thread.agent_name);
28085
+ } catch {
28086
+ agentDef = null;
28087
+ }
28088
+ const agentEnv = this.normalizeEnvRecord(agentDef?.env ?? agentDef?.tenvs ?? null);
28089
+ if (agentEnv && agentEnv[params.property] !== void 0) {
28090
+ return "secret";
28091
+ }
28092
+ const fallbackPromptName = params.promptName ?? (typeof agentDef?.sideA?.prompt === "string" ? agentDef.sideA.prompt : void 0);
28093
+ if (fallbackPromptName) {
28094
+ try {
28095
+ const promptDef = await this.loadPrompt(fallbackPromptName);
28096
+ const promptEnv = this.normalizeEnvRecord(promptDef?.env ?? promptDef?.tenvs ?? null);
28097
+ if (promptEnv && promptEnv[params.property] !== void 0) {
28098
+ return "secret";
28099
+ }
28100
+ } catch {
28101
+ }
28102
+ }
27268
28103
  if (thread.user_id) {
27269
28104
  const userEnv = await this.getUserEnv(thread.user_id);
27270
- if (userEnv[params.property] !== void 0) return "secret";
28105
+ if (userEnv[params.property] !== void 0) {
28106
+ const userEnvTypes = await this.getUserEnvTypes(thread.user_id);
28107
+ return userEnvTypes[params.property] === "text" ? "text" : "secret";
28108
+ }
27271
28109
  }
27272
28110
  const instanceEnv = await this.getInstanceEnv();
27273
- if (instanceEnv[params.property] !== void 0) return "secret";
28111
+ if (instanceEnv[params.property] !== void 0) {
28112
+ const instanceEnvTypes = await this.getInstanceEnvTypes();
28113
+ return instanceEnvTypes[params.property] === "text" ? "text" : "secret";
28114
+ }
27274
28115
  return "secret";
27275
28116
  }
27276
28117
  async toThreadEventPayload(thread) {
@@ -28289,8 +29130,8 @@ var GitHubClient = class _GitHubClient {
28289
29130
  /**
28290
29131
  * Make an authenticated request to GitHub API.
28291
29132
  */
28292
- async request(method, path19, body) {
28293
- const url = `${GITHUB_API_BASE}${path19}`;
29133
+ async request(method, path20, body) {
29134
+ const url = `${GITHUB_API_BASE}${path20}`;
28294
29135
  const response = await fetch(url, {
28295
29136
  method,
28296
29137
  headers: {
@@ -28446,8 +29287,8 @@ var GitHubClient = class _GitHubClient {
28446
29287
  const headSha = branchRef.object.sha;
28447
29288
  const headCommit = await this.getCommit(headSha);
28448
29289
  const baseTreeSha = headCommit.tree.sha;
28449
- const tree = paths.map((path19) => ({
28450
- path: path19,
29290
+ const tree = paths.map((path20) => ({
29291
+ path: path20,
28451
29292
  mode: "100644",
28452
29293
  type: "blob",
28453
29294
  sha: null