experimental-ash 0.24.0 → 0.24.2

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 (155) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/src/chunks/authored-module-loader-DcCfCiBm.js +4 -0
  3. package/dist/src/chunks/client-DLHAGI2g.js +4 -0
  4. package/dist/src/chunks/dev-authored-source-watcher-CBID_Dwh.js +1 -0
  5. package/dist/src/chunks/{errors-DsO9xmQL.js → errors-HYWjHxV6.js} +1 -1
  6. package/dist/src/chunks/{gray-matter-BxS7ZG-J.js → gray-matter-D-9jHwOT.js} +4 -4
  7. package/dist/src/chunks/host-zBy9FyyX.js +70 -0
  8. package/dist/src/chunks/{jsdist-M7JFZoA4.js → jsdist-BkeWZ7EZ.js} +61 -61
  9. package/dist/src/chunks/package-HUaeub_D.js +1 -0
  10. package/dist/src/chunks/paths-CebY5GCi.js +89 -0
  11. package/dist/src/chunks/{picocolors-Bq-tZK9u.js → picocolors-aAkqW4On.js} +1 -1
  12. package/dist/src/chunks/token-D98SQdvs.js +1 -0
  13. package/dist/src/chunks/{url-BVRhVE2O.js → url-JdCGA634.js} +1 -1
  14. package/dist/src/cli/commands/info.js +1 -1
  15. package/dist/src/cli/dev/environment.d.ts +16 -2
  16. package/dist/src/cli/dev/environment.js +1 -1
  17. package/dist/src/cli/dev/input-requests.js +1 -1
  18. package/dist/src/cli/dev/repl.js +3 -3
  19. package/dist/src/cli/dev/url.js +1 -1
  20. package/dist/src/cli/run.js +1 -1
  21. package/dist/src/cli/ui/output.js +1 -1
  22. package/dist/src/client/index.d.ts +1 -0
  23. package/dist/src/client/index.js +1 -0
  24. package/dist/src/compiled/.vendor-stamp.json +7 -6
  25. package/dist/src/compiled/@ai-sdk/anthropic/index.js +1 -1
  26. package/dist/src/compiled/@ai-sdk/google/index.js +1 -1
  27. package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
  28. package/dist/src/compiled/@ai-sdk/openai/index.js +1 -1
  29. package/dist/src/compiled/@ai-sdk/otel/index.js +1 -1
  30. package/dist/src/compiled/@chat-adapter/slack/_slack-web-api.d.ts +7 -0
  31. package/dist/src/compiled/@chat-adapter/slack/index.d.ts +418 -109
  32. package/dist/src/compiled/@chat-adapter/slack/index.js +31 -27
  33. package/dist/src/compiled/@chat-adapter/slack/package.json +1 -1
  34. package/dist/src/compiled/@chat-adapter/state-memory/index.d.ts +8 -2
  35. package/dist/src/compiled/@chat-adapter/state-memory/index.js +1 -1
  36. package/dist/src/compiled/@chat-adapter/state-memory/package.json +1 -1
  37. package/dist/src/compiled/@opentelemetry/api/index.js +1 -1
  38. package/dist/src/compiled/@vercel/sandbox/index.js +19 -17
  39. package/dist/src/compiled/@vercel/sandbox/package.json +1 -1
  40. package/dist/src/compiled/@workflow/core/index.js +2 -2
  41. package/dist/src/compiled/@workflow/core/runtime.js +22 -22
  42. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  43. package/dist/src/compiled/@workflow/errors/index.js +1 -1
  44. package/dist/src/compiled/_chunks/node/auth-ZhCJAHxl.js +2 -0
  45. package/dist/src/compiled/_chunks/node/{dist-BdWHjlRQ.js → dist-BQYUcBqu.js} +31 -31
  46. package/dist/src/compiled/_chunks/node/{chunk-Dd2tEFlW.js → dist-BdTs18CF.js} +1 -1
  47. package/dist/src/compiled/_chunks/node/retry-DkR2H1Y0.js +1 -0
  48. package/dist/src/compiled/_chunks/node/token-CoIbMZkq.js +1 -0
  49. package/dist/src/compiled/_chunks/node/{version-BMyZn3Y2.js → version-D4IYmfaS.js} +1 -1
  50. package/dist/src/compiled/_chunks/workflow/coerce-BhzIW-Hm.js +1 -0
  51. package/dist/src/compiled/_chunks/workflow/{compat-CIROS3w4.js → compat-DcEvieoj.js} +1 -1
  52. package/dist/src/compiled/_chunks/workflow/{core-DOVmxHH8.js → core-XWIi7wKc.js} +3 -3
  53. package/dist/src/compiled/_chunks/workflow/{dist-C7wPwOI9.js → dist-DO14ZaQj.js} +1 -1
  54. package/dist/src/compiled/_chunks/workflow/{dist-CpUQh3NH.js → dist-DZZY3Zyp.js} +1 -1
  55. package/dist/src/compiled/_chunks/workflow/resume-hook-DOMbNs-S.js +51 -0
  56. package/dist/src/compiled/_chunks/workflow/{schemas-DFZoEyCn.js → schemas-DmgDnhW3.js} +1 -1
  57. package/dist/src/compiled/_chunks/workflow/sleep-CRjce49s.js +1 -0
  58. package/dist/src/compiled/_chunks/workflow/{src-ClRYdO4-.js → src-B54rYDvB.js} +1 -1
  59. package/dist/src/compiled/_chunks/workflow/symbols-D8paKc8P.js +9 -0
  60. package/dist/src/compiled/_chunks/workflow/{token-CsNmv7KW.js → token-D9z1dMB6.js} +1 -1
  61. package/dist/src/compiled/_chunks/workflow/{token-j5Cl4rrs.js → token-DV7rQw_t.js} +1 -1
  62. package/dist/src/compiled/chat/index.d.ts +6 -3143
  63. package/dist/src/compiled/chat/index.js +1 -1
  64. package/dist/src/compiled/chat/{jsx-runtime-DxGwoLu2.d.ts → jsx-runtime-CFq1K_Ve.d.ts} +1 -1
  65. package/dist/src/compiled/chat/package.json +1 -1
  66. package/dist/src/compiled/jose/index.js +2 -2
  67. package/dist/src/compiled/jsonc-parser/LICENSE.md +21 -0
  68. package/dist/src/compiled/jsonc-parser/index.d.ts +13 -0
  69. package/dist/src/compiled/jsonc-parser/index.js +15 -0
  70. package/dist/src/compiled/jsonc-parser/package.json +7 -0
  71. package/dist/src/compiled/just-bash/index.js +773 -773
  72. package/dist/src/compiled/just-bash/package.json +1 -1
  73. package/dist/src/compiled/turndown/index.js +1 -1
  74. package/dist/src/compiled/zod/index.js +1 -1
  75. package/dist/src/compiled/zod-validation-error/index.js +1 -1
  76. package/dist/src/compiler/manifest.d.ts +36 -3
  77. package/dist/src/compiler/manifest.js +5 -1
  78. package/dist/src/compiler/module-map.js +8 -0
  79. package/dist/src/compiler/normalize-manifest.js +1 -0
  80. package/dist/src/compiler/normalize-subagent.d.ts +3 -2
  81. package/dist/src/compiler/normalize-subagent.js +112 -3
  82. package/dist/src/compiler/remote-agent-node.d.ts +20 -0
  83. package/dist/src/compiler/remote-agent-node.js +19 -0
  84. package/dist/src/discover/discover-subagent.js +35 -2
  85. package/dist/src/discover/grammar.d.ts +1 -0
  86. package/dist/src/discover/grammar.js +5 -0
  87. package/dist/src/evals/cli/eval.js +1 -1
  88. package/dist/src/evals/loaders/yaml.js +1 -1
  89. package/dist/src/evals/runner/discover.js +1 -1
  90. package/dist/src/evals/runner/execute-suite.js +1 -1
  91. package/dist/src/evals/runner/reporters/console.js +1 -1
  92. package/dist/src/evals/scorers/autoevals-client.js +1 -1
  93. package/dist/src/evals/scorers/autoevals.js +1 -1
  94. package/dist/src/evals/scorers/json.js +1 -1
  95. package/dist/src/evals/scorers/run.js +1 -1
  96. package/dist/src/evals/scorers/sql.js +1 -1
  97. package/dist/src/evals/scorers/text.js +1 -1
  98. package/dist/src/execution/connection-auth-steps.js +2 -0
  99. package/dist/src/internal/application/package.js +1 -1
  100. package/dist/src/internal/authored-asset-import-plugin.d.ts +5 -0
  101. package/dist/src/internal/authored-asset-import-plugin.js +141 -0
  102. package/dist/src/internal/authored-module-bundle.d.ts +4 -0
  103. package/dist/src/internal/authored-module-bundle.js +19 -0
  104. package/dist/src/internal/authored-module-loader.d.ts +6 -0
  105. package/dist/src/internal/authored-module-loader.js +114 -125
  106. package/dist/src/internal/authored-package-tsconfig-paths.d.ts +9 -0
  107. package/dist/src/internal/authored-package-tsconfig-paths.js +209 -0
  108. package/dist/src/internal/nitro/host/channel-routes.d.ts +9 -2
  109. package/dist/src/internal/nitro/host/dev-authored-source-watcher.d.ts +12 -1
  110. package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +19 -3
  111. package/dist/src/internal/nitro/host/schedule-task-routes.d.ts +7 -3
  112. package/dist/src/internal/nitro/host/start-development-server.js +2 -0
  113. package/dist/src/internal/workflow-bundle/builder-support.js +1 -33
  114. package/dist/src/public/agents/auth.d.ts +30 -0
  115. package/dist/src/public/agents/auth.js +37 -0
  116. package/dist/src/public/definitions/remote-agent.d.ts +25 -0
  117. package/dist/src/public/definitions/remote-agent.js +11 -0
  118. package/dist/src/public/index.d.ts +1 -0
  119. package/dist/src/public/index.js +1 -0
  120. package/dist/src/public/next/index.d.ts +4 -4
  121. package/dist/src/public/next/index.js +16 -25
  122. package/dist/src/runtime/connections/mcp-client.js +3 -2
  123. package/dist/src/runtime/connections/types.d.ts +24 -0
  124. package/dist/src/runtime/resolve-agent-graph.js +57 -0
  125. package/dist/src/runtime/sessions/turn.d.ts +17 -5
  126. package/dist/src/runtime/subagents/registry.d.ts +6 -6
  127. package/dist/src/runtime/subagents/registry.js +1 -1
  128. package/dist/src/runtime/types.d.ts +20 -0
  129. package/package.json +22 -17
  130. package/dist/src/chunks/authored-module-loader-XcFLnl49.js +0 -2
  131. package/dist/src/chunks/client-nshDsWNF.js +0 -4
  132. package/dist/src/chunks/dev-authored-source-watcher-B4PaZGUr.js +0 -7
  133. package/dist/src/chunks/host-DsW72Q-w.js +0 -65
  134. package/dist/src/chunks/package-DmsQgn4v.js +0 -1
  135. package/dist/src/chunks/paths-OknjaYR8.js +0 -89
  136. package/dist/src/chunks/prewarm-B4YblQ5m.js +0 -6
  137. package/dist/src/chunks/token-DtoyQZy2.js +0 -1
  138. package/dist/src/chunks/token-util-CHjOk3A7.js +0 -1
  139. package/dist/src/compiled/_chunks/node/auth-vbe4XEEK.js +0 -2
  140. package/dist/src/compiled/_chunks/node/dist-DMSq2ehP.js +0 -1
  141. package/dist/src/compiled/_chunks/node/retry-BOcy5BbJ.js +0 -1
  142. package/dist/src/compiled/_chunks/node/token-D-BTJHoU.js +0 -1
  143. package/dist/src/compiled/_chunks/workflow/coerce-Dh0wa7P9.js +0 -1
  144. package/dist/src/compiled/_chunks/workflow/context-errors-Bbvvp-li.js +0 -6
  145. package/dist/src/compiled/_chunks/workflow/dist-C_oiE-l7.js +0 -40
  146. package/dist/src/compiled/_chunks/workflow/resume-hook-C3VWUPii.js +0 -12
  147. package/dist/src/compiled/_chunks/workflow/sleep-QTkC1VFe.js +0 -1
  148. package/dist/src/compiled/_chunks/workflow/symbols-QezhMuLg.js +0 -4
  149. package/dist/src/compiled/chat/_workflow-serde.d.ts +0 -5
  150. /package/dist/src/chunks/{chunk-8L7ocgPr.js → chunk-DSjMdhoD.js} +0 -0
  151. /package/dist/src/chunks/{guards-CjJ3lmju.js → guards-26p6sOw3.js} +0 -0
  152. /package/dist/src/chunks/{input-requests-BsBi7_5K.js → input-requests-DJiy6dG9.js} +0 -0
  153. /package/dist/src/chunks/{runtime-model-BWu6M_hq.js → runtime-model-Dh0Nz64z.js} +0 -0
  154. /package/dist/src/chunks/{types-MZUhN0Zy.js → types-DDA2QUED.js} +0 -0
  155. /package/dist/src/compiled/_chunks/workflow/{chunk-DHhdAPOb.js → chunk-DSjMdhoD.js} +0 -0
@@ -0,0 +1,209 @@
1
+ import { readFile, stat } from "node:fs/promises";
2
+ import { dirname, join, resolve, sep } from "node:path";
3
+ import { parse as parseJsonc } from "#compiled/jsonc-parser/index.js";
4
+ const packageTsConfigPathsCache = new Map();
5
+ const nearestPackageRootCache = new Map();
6
+ /**
7
+ * Resolves tsconfig `paths` for authored source imported from linked
8
+ * workspace packages. Rolldown handles the root app tsconfig; this only
9
+ * fills the package-local config gap for sources outside the app root.
10
+ */
11
+ export function createAuthoredPackageTsConfigPathsPlugin(input) {
12
+ return {
13
+ name: "ash-package-tsconfig-paths",
14
+ async resolveId(source, importer, options) {
15
+ if (importer === undefined || !isPackageImport(source)) {
16
+ return undefined;
17
+ }
18
+ const importerPath = resolve(importer);
19
+ if (isPathInsideOrEqual(importerPath, input.appPackageRoot)) {
20
+ return undefined;
21
+ }
22
+ const packageRoot = await resolveNearestPackageRoot(importerPath);
23
+ if (packageRoot === undefined || isPathInsideOrEqual(packageRoot, input.appPackageRoot)) {
24
+ return undefined;
25
+ }
26
+ const config = await loadPackageTsConfigPaths(packageRoot);
27
+ if (config === undefined) {
28
+ return undefined;
29
+ }
30
+ for (const candidate of createTsConfigPathCandidates(source, config)) {
31
+ const resolved = await this.resolve(candidate, importer, {
32
+ kind: options.kind,
33
+ skipSelf: true,
34
+ });
35
+ if (resolved !== null) {
36
+ return resolved;
37
+ }
38
+ const existingPath = await resolveExistingPath(candidate, input.extensions);
39
+ if (existingPath !== undefined) {
40
+ return { id: existingPath };
41
+ }
42
+ }
43
+ return undefined;
44
+ },
45
+ };
46
+ }
47
+ function loadPackageTsConfigPaths(packageRoot) {
48
+ const cached = packageTsConfigPathsCache.get(packageRoot);
49
+ if (cached !== undefined) {
50
+ return cached;
51
+ }
52
+ const promise = readPackageTsConfigPaths(packageRoot);
53
+ packageTsConfigPathsCache.set(packageRoot, promise);
54
+ return promise;
55
+ }
56
+ async function readPackageTsConfigPaths(packageRoot) {
57
+ const configFile = await readPackageConfig(packageRoot);
58
+ if (configFile === undefined) {
59
+ return undefined;
60
+ }
61
+ const errors = [];
62
+ const parsed = parseJsonc(configFile.source, errors, {
63
+ allowTrailingComma: true,
64
+ });
65
+ if (errors.length > 0 || !isObjectRecord(parsed)) {
66
+ return undefined;
67
+ }
68
+ const compilerOptions = parsed.compilerOptions;
69
+ if (!isObjectRecord(compilerOptions) || !isObjectRecord(compilerOptions.paths)) {
70
+ return undefined;
71
+ }
72
+ const configDirectory = dirname(configFile.path);
73
+ const baseDirectory = typeof compilerOptions.baseUrl === "string"
74
+ ? resolve(configDirectory, compilerOptions.baseUrl)
75
+ : configDirectory;
76
+ const entries = Object.entries(compilerOptions.paths)
77
+ .flatMap(([pattern, targets]) => {
78
+ if (!Array.isArray(targets) || !targets.every((target) => typeof target === "string")) {
79
+ return [];
80
+ }
81
+ return [{ pattern, targets }];
82
+ })
83
+ .sort((left, right) => right.pattern.length - left.pattern.length);
84
+ if (entries.length === 0) {
85
+ return undefined;
86
+ }
87
+ return { baseDirectory, entries };
88
+ }
89
+ async function readPackageConfig(packageRoot) {
90
+ for (const fileName of ["tsconfig.json", "jsconfig.json"]) {
91
+ const configPath = join(packageRoot, fileName);
92
+ try {
93
+ return {
94
+ path: configPath,
95
+ source: await readFile(configPath, "utf8"),
96
+ };
97
+ }
98
+ catch (error) {
99
+ if (!isPathNotFoundError(error)) {
100
+ throw error;
101
+ }
102
+ }
103
+ }
104
+ return undefined;
105
+ }
106
+ function createTsConfigPathCandidates(source, config) {
107
+ const candidates = [];
108
+ for (const entry of config.entries) {
109
+ const match = matchTsConfigPathPattern(source, entry.pattern);
110
+ if (match === undefined) {
111
+ continue;
112
+ }
113
+ for (const target of entry.targets) {
114
+ const targetPath = target.includes("*") ? target.replaceAll("*", match) : target;
115
+ candidates.push(resolve(config.baseDirectory, targetPath));
116
+ }
117
+ }
118
+ return candidates;
119
+ }
120
+ function matchTsConfigPathPattern(source, pattern) {
121
+ const wildcardIndex = pattern.indexOf("*");
122
+ if (wildcardIndex === -1) {
123
+ return source === pattern ? "" : undefined;
124
+ }
125
+ const prefix = pattern.slice(0, wildcardIndex);
126
+ const suffix = pattern.slice(wildcardIndex + 1);
127
+ if (!source.startsWith(prefix) || !source.endsWith(suffix)) {
128
+ return undefined;
129
+ }
130
+ return source.slice(prefix.length, source.length - suffix.length);
131
+ }
132
+ async function resolveExistingPath(path, extensions) {
133
+ if (await existsAsFile(path)) {
134
+ return path;
135
+ }
136
+ for (const extension of extensions) {
137
+ const candidate = `${path}${extension}`;
138
+ if (await existsAsFile(candidate)) {
139
+ return candidate;
140
+ }
141
+ }
142
+ for (const extension of extensions) {
143
+ const candidate = join(path, `index${extension}`);
144
+ if (await existsAsFile(candidate)) {
145
+ return candidate;
146
+ }
147
+ }
148
+ return undefined;
149
+ }
150
+ async function existsAsFile(path) {
151
+ try {
152
+ return (await stat(path)).isFile();
153
+ }
154
+ catch {
155
+ return false;
156
+ }
157
+ }
158
+ function resolveNearestPackageRoot(path) {
159
+ const startDirectory = dirname(path);
160
+ const cached = nearestPackageRootCache.get(startDirectory);
161
+ if (cached !== undefined) {
162
+ return cached;
163
+ }
164
+ const promise = findNearestPackageRoot(startDirectory);
165
+ nearestPackageRootCache.set(startDirectory, promise);
166
+ return promise;
167
+ }
168
+ async function findNearestPackageRoot(startDirectory) {
169
+ let currentDirectory = startDirectory;
170
+ while (true) {
171
+ if (await pathExists(join(currentDirectory, "package.json"))) {
172
+ return currentDirectory;
173
+ }
174
+ const parentDirectory = dirname(currentDirectory);
175
+ if (parentDirectory === currentDirectory) {
176
+ return undefined;
177
+ }
178
+ currentDirectory = parentDirectory;
179
+ }
180
+ }
181
+ async function pathExists(path) {
182
+ try {
183
+ await stat(path);
184
+ return true;
185
+ }
186
+ catch {
187
+ return false;
188
+ }
189
+ }
190
+ function isPathNotFoundError(error) {
191
+ return (typeof error === "object" &&
192
+ error !== null &&
193
+ "code" in error &&
194
+ (error.code === "ENOENT" || error.code === "ENOTDIR"));
195
+ }
196
+ function isPackageImport(source) {
197
+ if (source.startsWith(".") || source.startsWith("/") || /^[A-Za-z]:[\\/]/.test(source)) {
198
+ return false;
199
+ }
200
+ return !/^(?:node|data|file):/.test(source);
201
+ }
202
+ function isObjectRecord(value) {
203
+ return typeof value === "object" && value !== null && !Array.isArray(value);
204
+ }
205
+ function isPathInsideOrEqual(path, directory) {
206
+ const resolvedPath = resolve(path);
207
+ const resolvedDirectory = resolve(directory);
208
+ return (resolvedPath === resolvedDirectory || resolvedPath.startsWith(`${resolvedDirectory}${sep}`));
209
+ }
@@ -2,6 +2,12 @@ import type { Nitro } from "nitro/types";
2
2
  import type { ChannelMethod } from "#public/definitions/channel.js";
3
3
  import type { NitroArtifactsConfigInput } from "#internal/nitro/host/artifacts-config.js";
4
4
  import type { PreparedApplicationHost } from "#internal/nitro/host/types.js";
5
+ interface ChannelRouteNitro {
6
+ options: Pick<Nitro["options"], "handlers" | "virtual">;
7
+ routing: {
8
+ sync(): void;
9
+ };
10
+ }
5
11
  /**
6
12
  * One Nitro route registration for an Ash channel.
7
13
  */
@@ -16,7 +22,7 @@ export declare function computeChannelRouteRegistrations(preparedHost: PreparedA
16
22
  /**
17
23
  * Registers virtual Nitro handlers for the provided Ash channel routes.
18
24
  */
19
- export declare function registerChannelVirtualHandlers(nitro: Nitro, input: {
25
+ export declare function registerChannelVirtualHandlers(nitro: Pick<ChannelRouteNitro, "options">, input: {
20
26
  readonly artifactsConfig: NitroArtifactsConfigInput;
21
27
  readonly registrations: readonly NitroChannelRouteRegistration[];
22
28
  }): void;
@@ -24,8 +30,9 @@ export declare function registerChannelVirtualHandlers(nitro: Nitro, input: {
24
30
  * Replaces the currently-mounted Ash channel virtual handlers when the route
25
31
  * set changes.
26
32
  */
27
- export declare function syncChannelVirtualHandlers(nitro: Nitro, input: {
33
+ export declare function syncChannelVirtualHandlers(nitro: ChannelRouteNitro, input: {
28
34
  readonly artifactsConfig: NitroArtifactsConfigInput;
29
35
  readonly next: readonly NitroChannelRouteRegistration[];
30
36
  readonly previous: readonly NitroChannelRouteRegistration[];
31
37
  }): boolean;
38
+ export {};
@@ -1,5 +1,15 @@
1
1
  import type { Nitro } from "nitro/types";
2
2
  import type { PreparedApplicationHost } from "#internal/nitro/host/types.js";
3
+ type DevelopmentWatcherNitroOptions = Pick<Nitro["options"], "experimental" | "handlers" | "scheduledTasks" | "tasks" | "virtual"> & Partial<Pick<Nitro["options"], "dev" | "preset">>;
4
+ interface DevelopmentWatcherNitro {
5
+ hooks: {
6
+ callHook: Nitro["hooks"]["callHook"];
7
+ };
8
+ options: DevelopmentWatcherNitroOptions;
9
+ routing: {
10
+ sync(): void;
11
+ };
12
+ }
3
13
  /**
4
14
  * Handle for the authored-source development watcher.
5
15
  */
@@ -13,7 +23,8 @@ export interface AuthoredSourceWatcherHandle {
13
23
  * triggers Nitro rebuild reloads only when structural runtime wiring changes.
14
24
  */
15
25
  export declare function startAuthoredSourceWatcher(input: {
16
- nitro: Nitro;
26
+ nitro: DevelopmentWatcherNitro;
17
27
  preparedHost: PreparedApplicationHost;
18
28
  schedulesEnabled?: boolean;
19
29
  }): Promise<AuthoredSourceWatcherHandle>;
30
+ export {};
@@ -3,7 +3,7 @@ import { readdir, readFile } from "node:fs/promises";
3
3
  import { createRequire } from "node:module";
4
4
  import { dirname, isAbsolute, join, resolve } from "node:path";
5
5
  import { watch } from "chokidar";
6
- import { parse as parseJsonc } from "jsonc-parser";
6
+ import { parse as parseJsonc } from "#compiled/jsonc-parser/index.js";
7
7
  import { clearCompiledRuntimeAgentBundleCache } from "#runtime/sessions/compiled-agent-cache.js";
8
8
  import { toErrorMessage } from "#shared/errors.js";
9
9
  import { resolvePackageSourceFilePath } from "#internal/application/package.js";
@@ -12,6 +12,7 @@ import { computeChannelRouteRegistrations, syncChannelVirtualHandlers, } from "#
12
12
  import { prepareApplicationHost } from "#internal/nitro/host/prepare-application-host.js";
13
13
  import { prewarmAppSandboxes } from "#execution/sandbox/prewarm.js";
14
14
  import { syncScheduleTaskHandlers } from "#internal/nitro/host/schedule-task-routes.js";
15
+ import { getDevelopmentEnvironmentFilePaths, reloadDevelopmentEnvironmentFiles, } from "#cli/dev/environment.js";
15
16
  const DEBOUNCE_MS = 120;
16
17
  const WATCHED_LOCKFILE_NAMES = [
17
18
  "pnpm-lock.yaml",
@@ -44,6 +45,7 @@ export async function startAuthoredSourceWatcher(input) {
44
45
  let queue = Promise.resolve();
45
46
  let debounceTimer;
46
47
  const pendingEvents = new Set();
48
+ const pendingChangedPaths = new Set();
47
49
  const initialWatchPaths = await resolveAuthoredWatchPaths(currentHost);
48
50
  let currentWatchPathsByKey = createWatchPathMap(initialWatchPaths);
49
51
  const watcher = watch(initialWatchPaths, {
@@ -66,10 +68,16 @@ export async function startAuthoredSourceWatcher(input) {
66
68
  return;
67
69
  }
68
70
  const eventSummary = pendingEvents.size;
71
+ const changedPaths = [...pendingChangedPaths];
69
72
  pendingEvents.clear();
73
+ pendingChangedPaths.clear();
70
74
  const previousHost = currentHost;
75
+ const hasEnvironmentChange = hasDevelopmentEnvironmentFileChange(previousHost.appRoot, changedPaths);
71
76
  console.log(`[ash:dev] change detected (${eventSummary} event${eventSummary === 1 ? "" : "s"}), rebuilding authored artifacts...`);
72
77
  try {
78
+ if (hasEnvironmentChange) {
79
+ reloadDevelopmentEnvironmentFiles(previousHost.appRoot);
80
+ }
73
81
  const nextHost = await prepareApplicationHost(previousHost.appRoot);
74
82
  await prewarmAppSandboxes({
75
83
  appRoot: nextHost.appRoot,
@@ -77,7 +85,7 @@ export async function startAuthoredSourceWatcher(input) {
77
85
  });
78
86
  const artifactsConfig = createNitroArtifactsConfig({
79
87
  appRoot: nextHost.appRoot,
80
- dev: input.nitro.options.dev,
88
+ dev: input.nitro.options.dev === true,
81
89
  });
82
90
  const hasChannelRouteChanged = syncChannelVirtualHandlers(input.nitro, {
83
91
  artifactsConfig,
@@ -92,7 +100,7 @@ export async function startAuthoredSourceWatcher(input) {
92
100
  });
93
101
  clearCompiledRuntimeAgentBundleCache();
94
102
  currentHost = nextHost;
95
- const hasStructuralChange = hasChannelRouteChanged || hasScheduleRegistrationsChanged;
103
+ const hasStructuralChange = hasChannelRouteChanged || hasScheduleRegistrationsChanged || hasEnvironmentChange;
96
104
  if (hasStructuralChange) {
97
105
  console.log("[ash:dev] structural change detected, reloading Nitro worker...");
98
106
  await input.nitro.hooks.callHook("rollup:reload");
@@ -120,6 +128,7 @@ export async function startAuthoredSourceWatcher(input) {
120
128
  return;
121
129
  }
122
130
  pendingEvents.add(`${event}:${changedPath}`);
131
+ pendingChangedPaths.add(changedPath);
123
132
  if (debounceTimer !== undefined) {
124
133
  clearTimeout(debounceTimer);
125
134
  }
@@ -160,6 +169,9 @@ async function resolveAuthoredWatchPaths(host) {
160
169
  join(host.appRoot, TS_CONFIG_GLOB_NAME),
161
170
  ]);
162
171
  const tsconfigPaths = await resolveTsConfigWatchPaths(host.appRoot);
172
+ for (const envFilePath of getDevelopmentEnvironmentFilePaths(host.appRoot)) {
173
+ watchPaths.add(envFilePath);
174
+ }
163
175
  for (const path of tsconfigPaths) {
164
176
  watchPaths.add(path);
165
177
  }
@@ -202,6 +214,10 @@ function syncWatcherPaths(input) {
202
214
  function toWatchPathKey(path) {
203
215
  return path.replaceAll("\\", "/");
204
216
  }
217
+ function hasDevelopmentEnvironmentFileChange(appRoot, changedPaths) {
218
+ const environmentFilePathKeys = new Set(getDevelopmentEnvironmentFilePaths(appRoot).map((path) => toWatchPathKey(resolve(path))));
219
+ return changedPaths.some((path) => environmentFilePathKeys.has(toWatchPathKey(resolve(path))));
220
+ }
205
221
  function resolveLockfileSearchDirectories(appRoot) {
206
222
  const directories = [];
207
223
  let currentDirectory = resolve(appRoot);
@@ -1,6 +1,9 @@
1
1
  import type { Nitro } from "nitro/types";
2
2
  import { type ScheduleRegistration } from "#runtime/schedules/register.js";
3
3
  import type { NitroArtifactsConfigInput } from "#internal/nitro/host/artifacts-config.js";
4
+ interface ScheduleTaskNitro {
5
+ options: Pick<Nitro["options"], "experimental" | "scheduledTasks" | "tasks" | "virtual">;
6
+ }
4
7
  /**
5
8
  * Inputs needed to wire one set of compiled authored schedules into Nitro's
6
9
  * task and cron surfaces.
@@ -39,7 +42,7 @@ export interface SyncScheduleTaskHandlersInput {
39
42
  * adapts it to Nitro's task contract while baking in the artifacts config so
40
43
  * the handler does not depend on a global runtime configuration store.
41
44
  */
42
- export declare function registerScheduleTaskHandlers(nitro: Nitro, input: RegisterScheduleTaskHandlersInput): void;
45
+ export declare function registerScheduleTaskHandlers(nitro: ScheduleTaskNitro, input: RegisterScheduleTaskHandlersInput): void;
43
46
  /**
44
47
  * Replaces the currently-registered Ash schedule task handlers when the
45
48
  * compiled authored schedule set changes.
@@ -47,10 +50,11 @@ export declare function registerScheduleTaskHandlers(nitro: Nitro, input: Regist
47
50
  * Returns `true` when the registration set changed (and the caller should
48
51
  * trigger a Nitro rebuild reload), `false` when it was a structural no-op.
49
52
  */
50
- export declare function syncScheduleTaskHandlers(nitro: Nitro, input: SyncScheduleTaskHandlersInput): boolean;
53
+ export declare function syncScheduleTaskHandlers(nitro: ScheduleTaskNitro, input: SyncScheduleTaskHandlersInput): boolean;
51
54
  /**
52
55
  * Removes every Ash-owned schedule task entry, virtual handler module, and
53
56
  * cron entry from the Nitro options. Used by the dev watcher before
54
57
  * re-registering the latest compiled set.
55
58
  */
56
- export declare function removeScheduleTaskHandlers(nitro: Nitro): void;
59
+ export declare function removeScheduleTaskHandlers(nitro: ScheduleTaskNitro): void;
60
+ export {};
@@ -2,6 +2,7 @@ import { build as buildNitro, createDevServer, prepare } from "nitro/builder";
2
2
  import { createApplicationNitro } from "#internal/nitro/host/create-application-nitro.js";
3
3
  import { prepareApplicationHost } from "#internal/nitro/host/prepare-application-host.js";
4
4
  import { prewarmAppSandboxes } from "#execution/sandbox/prewarm.js";
5
+ import { loadDevelopmentEnvironmentFiles } from "#cli/dev/environment.js";
5
6
  const DEFAULT_DEVELOPMENT_SERVER_PORT = 3000;
6
7
  const MAX_ALLOWED_DEVELOPMENT_SERVER_PORT = 65_535;
7
8
  const MAX_DEVELOPMENT_SERVER_PORT_ATTEMPTS = 10;
@@ -160,6 +161,7 @@ async function listenForDevelopmentServer(input) {
160
161
  */
161
162
  export async function startDevelopmentServer(rootDir, options = {}) {
162
163
  const schedulesEnabled = options.schedules === true;
164
+ loadDevelopmentEnvironmentFiles(rootDir);
163
165
  const preparedHost = await prepareApplicationHost(rootDir);
164
166
  await prewarmAppSandboxes({
165
167
  appRoot: preparedHost.appRoot,
@@ -372,37 +372,5 @@ function isJavaScriptLikePath(path) {
372
372
  export async function atomicWriteFile(targetPath, contents) {
373
373
  const tmpPath = `${targetPath}.tmp-${process.pid}-${Date.now().toString(36)}`;
374
374
  await writeFile(tmpPath, contents);
375
- await renameWithWindowsRetry(tmpPath, targetPath);
376
- }
377
- /*
378
- * POSIX `rename` always succeeds when the target is open, but Windows
379
- * `MoveFileEx` rejects the call with EPERM/EACCES if any handle to the
380
- * target lacks FILE_SHARE_DELETE. Node's `fs.readFile` does not request
381
- * that share mode, so a concurrent reader (e.g. Nitro's Rolldown bundler
382
- * during `ash dev`) racing with this rename will trip the error even
383
- * though its open-read-close cycle releases the handle moments later.
384
- * Retrying with backoff lands the rename in one of those gaps and keeps
385
- * the atomic guarantee intact on Windows. POSIX skips the loop.
386
- */
387
- async function renameWithWindowsRetry(source, target) {
388
- if (process.platform !== "win32") {
389
- await rename(source, target);
390
- return;
391
- }
392
- const maxAttempts = 10;
393
- for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
394
- try {
395
- await rename(source, target);
396
- return;
397
- }
398
- catch (error) {
399
- const isContended = error instanceof Error &&
400
- "code" in error &&
401
- (error.code === "EPERM" || error.code === "EACCES" || error.code === "EBUSY");
402
- if (!isContended || attempt === maxAttempts - 1) {
403
- throw error;
404
- }
405
- await new Promise((resolve) => setTimeout(resolve, 10 * (attempt + 1)));
406
- }
407
- }
375
+ await rename(tmpPath, targetPath);
408
376
  }
@@ -0,0 +1,30 @@
1
+ import type { TokenValue } from "#client/types.js";
2
+ /**
3
+ * Outbound request auth hook used by remote agent dispatch.
4
+ */
5
+ export type OutboundAuthFn = () => Promise<{
6
+ readonly headers: Readonly<Record<string, string>>;
7
+ }>;
8
+ /**
9
+ * Ash-owned subset of `@vercel/oidc` token lookup options.
10
+ */
11
+ export interface VercelOidcOptions {
12
+ readonly expirationBufferMs?: number;
13
+ readonly project?: string;
14
+ readonly team?: string;
15
+ }
16
+ /**
17
+ * Returns a Vercel OIDC bearer token for an outbound remote-agent request.
18
+ */
19
+ export declare function vercelOidc(options?: VercelOidcOptions): OutboundAuthFn;
20
+ /**
21
+ * Returns a static or lazily resolved bearer token auth hook.
22
+ */
23
+ export declare function bearer(token: TokenValue): OutboundAuthFn;
24
+ /**
25
+ * Returns an HTTP Basic auth hook.
26
+ */
27
+ export declare function basic(input: {
28
+ readonly password: TokenValue;
29
+ readonly username: string;
30
+ }): OutboundAuthFn;
@@ -0,0 +1,37 @@
1
+ import { getVercelOidcToken } from "@vercel/oidc";
2
+ /**
3
+ * Returns a Vercel OIDC bearer token for an outbound remote-agent request.
4
+ */
5
+ export function vercelOidc(options = {}) {
6
+ return async () => ({
7
+ headers: {
8
+ authorization: `Bearer ${await getVercelOidcToken(options)}`,
9
+ },
10
+ });
11
+ }
12
+ /**
13
+ * Returns a static or lazily resolved bearer token auth hook.
14
+ */
15
+ export function bearer(token) {
16
+ return async () => ({
17
+ headers: {
18
+ authorization: `Bearer ${await resolveTokenValue(token)}`,
19
+ },
20
+ });
21
+ }
22
+ /**
23
+ * Returns an HTTP Basic auth hook.
24
+ */
25
+ export function basic(input) {
26
+ return async () => {
27
+ const encodedCredentials = btoa(`${input.username}:${await resolveTokenValue(input.password)}`);
28
+ return {
29
+ headers: {
30
+ authorization: `Basic ${encodedCredentials}`,
31
+ },
32
+ };
33
+ };
34
+ }
35
+ async function resolveTokenValue(value) {
36
+ return typeof value === "function" ? await value() : value;
37
+ }
@@ -0,0 +1,25 @@
1
+ import type { HeadersValue } from "#client/types.js";
2
+ import type { OutboundAuthFn } from "#public/agents/auth.js";
3
+ /**
4
+ * Public definition for a remote Ash agent lowered as a subagent tool.
5
+ */
6
+ export interface RemoteAgentDefinition {
7
+ readonly auth?: OutboundAuthFn;
8
+ readonly description: string;
9
+ readonly headers?: HeadersValue;
10
+ readonly kind: "remote";
11
+ readonly path: string;
12
+ readonly url: string;
13
+ }
14
+ /**
15
+ * Authored input accepted by {@link defineRemoteAgent}. Identity is derived
16
+ * from the file path under `agent/subagents/`; authored definitions do not
17
+ * carry a `name` field.
18
+ */
19
+ export type RemoteAgentDefinitionInput = Omit<RemoteAgentDefinition, "kind" | "path"> & {
20
+ readonly path?: string;
21
+ };
22
+ /**
23
+ * Defines a remote Ash agent that the parent can call as a subagent tool.
24
+ */
25
+ export declare function defineRemoteAgent(input: RemoteAgentDefinitionInput): RemoteAgentDefinition;
@@ -0,0 +1,11 @@
1
+ import { ASH_CREATE_SESSION_ROUTE_PATH } from "#protocol/routes.js";
2
+ /**
3
+ * Defines a remote Ash agent that the parent can call as a subagent tool.
4
+ */
5
+ export function defineRemoteAgent(input) {
6
+ return {
7
+ ...input,
8
+ kind: "remote",
9
+ path: input.path ?? ASH_CREATE_SESSION_ROUTE_PATH,
10
+ };
11
+ }
@@ -2,3 +2,4 @@
2
2
  * Core agent authoring helpers for `agent/agent.ts`.
3
3
  */
4
4
  export { type AgentCompactionDefinition, type AgentDefinition, type AgentModelDefinition, type AgentModelOptionsDefinition, defineAgent, } from "#public/definitions/agent.js";
5
+ export { type RemoteAgentDefinition, type RemoteAgentDefinitionInput, defineRemoteAgent, } from "#public/definitions/remote-agent.js";
@@ -2,3 +2,4 @@
2
2
  * Core agent authoring helpers for `agent/agent.ts`.
3
3
  */
4
4
  export { defineAgent, } from "#public/definitions/agent.js";
5
+ export { defineRemoteAgent, } from "#public/definitions/remote-agent.js";
@@ -72,10 +72,10 @@ export interface WithAshOptions {
72
72
  * In development, `withAsh` starts `ash dev --no-repl --port 0` for the Ash
73
73
  * app and rewrites Ash protocol endpoints to that local URL. In production on
74
74
  * Vercel, it rewrites to the private Ash service prefix configured in
75
- * `vercel.json` using the deployment origin from `VERCEL_URL`. Outside Vercel
76
- * production, it serves an existing `.output/server/index.mjs` Ash build on a
77
- * stable local port when present; otherwise set `ASH_NEXT_PRODUCTION_ORIGIN` to
78
- * the origin that serves the Ash service namespace.
75
+ * `vercel.json`. Outside Vercel production, it serves an existing
76
+ * `.output/server/index.mjs` Ash build on a stable local port when present;
77
+ * otherwise set `ASH_NEXT_PRODUCTION_ORIGIN` to the origin that serves the Ash
78
+ * service namespace.
79
79
  */
80
80
  export declare function withAsh<TConfig extends AshNextConfig>(configOrFunction: AshNextConfigInput<TConfig>, options?: WithAshOptions): AshNextConfigFunction<TConfig>;
81
81
  export {};
@@ -32,16 +32,6 @@ function joinRoutePrefix(prefix, path) {
32
32
  function normalizeOrigin(origin) {
33
33
  return new URL(origin.trim()).origin;
34
34
  }
35
- function hasUrlScheme(value) {
36
- return /^[a-z][a-z\d+.-]*:/i.test(value);
37
- }
38
- function resolveVercelDeploymentOrigin() {
39
- const deploymentUrl = process.env.VERCEL_URL;
40
- if (deploymentUrl === undefined || deploymentUrl.trim().length === 0) {
41
- return undefined;
42
- }
43
- return normalizeOrigin(hasUrlScheme(deploymentUrl) ? deploymentUrl : `https://${deploymentUrl}`);
44
- }
45
35
  function readLocalProductionPort() {
46
36
  const configuredPort = process.env[ASH_NEXT_PRODUCTION_PORT_ENV];
47
37
  if (configuredPort === undefined || configuredPort.trim().length === 0) {
@@ -54,16 +44,15 @@ function readLocalProductionPort() {
54
44
  return port;
55
45
  }
56
46
  function resolveProductionDestination(servicePrefix) {
57
- const configuredOrigin = process.env[ASH_NEXT_PRODUCTION_ORIGIN_ENV];
58
- if (configuredOrigin !== undefined && configuredOrigin.trim().length > 0) {
47
+ if (process.env.VERCEL) {
59
48
  return {
60
- destinationPrefix: joinRoutePrefix(normalizeOrigin(configuredOrigin), servicePrefix),
49
+ destinationPrefix: servicePrefix,
61
50
  };
62
51
  }
63
- const vercelOrigin = resolveVercelDeploymentOrigin();
64
- if (vercelOrigin !== undefined) {
52
+ const configuredOrigin = process.env[ASH_NEXT_PRODUCTION_ORIGIN_ENV];
53
+ if (configuredOrigin !== undefined && configuredOrigin.trim().length > 0) {
65
54
  return {
66
- destinationPrefix: joinRoutePrefix(vercelOrigin, servicePrefix),
55
+ destinationPrefix: joinRoutePrefix(normalizeOrigin(configuredOrigin), servicePrefix),
67
56
  };
68
57
  }
69
58
  const localServerOrigin = `http://127.0.0.1:${String(readLocalProductionPort())}`;
@@ -73,11 +62,13 @@ function resolveProductionDestination(servicePrefix) {
73
62
  };
74
63
  }
75
64
  function createAshRewriteRules(destinationPrefix) {
76
- return ASH_PROXY_REWRITE_SOURCES.map((source) => ({
77
- basePath: false,
78
- destination: joinRoutePrefix(destinationPrefix, source),
79
- source,
80
- }));
65
+ return ASH_PROXY_REWRITE_SOURCES.map((source) => {
66
+ const rule = {
67
+ destination: joinRoutePrefix(destinationPrefix, source),
68
+ source,
69
+ };
70
+ return rule;
71
+ });
81
72
  }
82
73
  async function resolveExistingRewrites(rewrites) {
83
74
  return await rewrites?.();
@@ -114,10 +105,10 @@ async function resolveNextConfig(configOrFunction, phase, context) {
114
105
  * In development, `withAsh` starts `ash dev --no-repl --port 0` for the Ash
115
106
  * app and rewrites Ash protocol endpoints to that local URL. In production on
116
107
  * Vercel, it rewrites to the private Ash service prefix configured in
117
- * `vercel.json` using the deployment origin from `VERCEL_URL`. Outside Vercel
118
- * production, it serves an existing `.output/server/index.mjs` Ash build on a
119
- * stable local port when present; otherwise set `ASH_NEXT_PRODUCTION_ORIGIN` to
120
- * the origin that serves the Ash service namespace.
108
+ * `vercel.json`. Outside Vercel production, it serves an existing
109
+ * `.output/server/index.mjs` Ash build on a stable local port when present;
110
+ * otherwise set `ASH_NEXT_PRODUCTION_ORIGIN` to the origin that serves the Ash
111
+ * service namespace.
121
112
  */
122
113
  export function withAsh(configOrFunction, options = {}) {
123
114
  const nextRoot = process.cwd();