@dexto/agent-management 1.6.13 → 1.6.15

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 (49) hide show
  1. package/dist/config/config-enrichment.cjs +24 -7
  2. package/dist/config/config-enrichment.d.ts +5 -0
  3. package/dist/config/config-enrichment.d.ts.map +1 -1
  4. package/dist/config/config-enrichment.js +24 -7
  5. package/dist/config/discover-prompts.cjs +7 -7
  6. package/dist/config/discover-prompts.d.ts +5 -3
  7. package/dist/config/discover-prompts.d.ts.map +1 -1
  8. package/dist/config/discover-prompts.js +7 -7
  9. package/dist/config/error-codes.cjs +1 -0
  10. package/dist/config/error-codes.d.ts +1 -0
  11. package/dist/config/error-codes.d.ts.map +1 -1
  12. package/dist/config/error-codes.js +1 -0
  13. package/dist/config/errors.cjs +12 -2
  14. package/dist/config/errors.d.ts +5 -0
  15. package/dist/config/errors.d.ts.map +1 -1
  16. package/dist/config/errors.js +12 -2
  17. package/dist/index.cjs +37 -0
  18. package/dist/index.d.ts +1 -0
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +38 -0
  21. package/dist/plugins/discover-skills.cjs +2 -0
  22. package/dist/plugins/discover-skills.d.ts +7 -5
  23. package/dist/plugins/discover-skills.d.ts.map +1 -1
  24. package/dist/plugins/discover-skills.js +2 -0
  25. package/dist/project-registry.cjs +380 -0
  26. package/dist/project-registry.d.ts +153 -0
  27. package/dist/project-registry.d.ts.map +1 -0
  28. package/dist/project-registry.js +329 -0
  29. package/dist/resolver.cjs +23 -2
  30. package/dist/resolver.d.ts.map +1 -1
  31. package/dist/resolver.js +26 -2
  32. package/dist/tool-factories/agent-spawner/factory.cjs +12 -0
  33. package/dist/tool-factories/agent-spawner/factory.d.ts.map +1 -1
  34. package/dist/tool-factories/agent-spawner/factory.js +12 -0
  35. package/dist/tool-factories/agent-spawner/runtime.cjs +189 -27
  36. package/dist/tool-factories/agent-spawner/runtime.d.ts +7 -1
  37. package/dist/tool-factories/agent-spawner/runtime.d.ts.map +1 -1
  38. package/dist/tool-factories/agent-spawner/runtime.js +189 -27
  39. package/dist/tool-factories/agent-spawner/schemas.cjs +6 -3
  40. package/dist/tool-factories/agent-spawner/schemas.d.ts +3 -2
  41. package/dist/tool-factories/agent-spawner/schemas.d.ts.map +1 -1
  42. package/dist/tool-factories/agent-spawner/schemas.js +6 -3
  43. package/dist/tool-factories/agent-spawner/spawn-agent-tool.cjs +4 -3
  44. package/dist/tool-factories/agent-spawner/spawn-agent-tool.d.ts.map +1 -1
  45. package/dist/tool-factories/agent-spawner/spawn-agent-tool.js +4 -3
  46. package/dist/utils/execution-context.cjs +61 -16
  47. package/dist/utils/execution-context.d.ts.map +1 -1
  48. package/dist/utils/execution-context.js +62 -17
  49. package/package.json +5 -5
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-registry.d.ts","sourceRoot":"","sources":["../src/project-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,329 @@
1
+ import { existsSync, readFileSync, statSync } from "fs";
2
+ import { promises as fs } from "fs";
3
+ import path from "path";
4
+ import { z } from "zod";
5
+ const NonEmptyStringSchema = z.string().trim().min(1);
6
+ const ProjectRegistryEntrySchema = z.object({
7
+ id: NonEmptyStringSchema,
8
+ name: NonEmptyStringSchema,
9
+ description: NonEmptyStringSchema,
10
+ configPath: NonEmptyStringSchema,
11
+ author: NonEmptyStringSchema.optional(),
12
+ tags: z.array(NonEmptyStringSchema).optional(),
13
+ parentAgentId: NonEmptyStringSchema.optional()
14
+ }).strict();
15
+ const ProjectRegistrySchema = z.object({
16
+ primaryAgent: NonEmptyStringSchema.optional(),
17
+ allowGlobalAgents: z.boolean().default(false),
18
+ agents: z.array(ProjectRegistryEntrySchema)
19
+ }).strict().superRefine((registry, ctx) => {
20
+ const seenIds = /* @__PURE__ */ new Set();
21
+ for (const [index, agent] of registry.agents.entries()) {
22
+ if (seenIds.has(agent.id)) {
23
+ ctx.addIssue({
24
+ code: z.ZodIssueCode.custom,
25
+ path: ["agents", index, "id"],
26
+ message: `Duplicate agent id '${agent.id}'.`
27
+ });
28
+ continue;
29
+ }
30
+ seenIds.add(agent.id);
31
+ }
32
+ if (registry.primaryAgent && !registry.agents.some((agent) => agent.id === registry.primaryAgent)) {
33
+ ctx.addIssue({
34
+ code: z.ZodIssueCode.custom,
35
+ path: ["primaryAgent"],
36
+ message: `Primary agent '${registry.primaryAgent}' must match an agent id in 'agents'.`
37
+ });
38
+ }
39
+ });
40
+ class ProjectRegistryError extends Error {
41
+ code;
42
+ registryPath;
43
+ agentId;
44
+ configPath;
45
+ constructor(options) {
46
+ super(options.message, options.cause ? { cause: options.cause } : void 0);
47
+ this.name = "ProjectRegistryError";
48
+ this.code = options.code;
49
+ this.registryPath = options.registryPath;
50
+ this.agentId = options.agentId;
51
+ this.configPath = options.configPath;
52
+ }
53
+ static invalidRegistry(registryPath, message, cause) {
54
+ return new ProjectRegistryError({
55
+ code: "PROJECT_REGISTRY_INVALID",
56
+ message,
57
+ registryPath,
58
+ cause
59
+ });
60
+ }
61
+ static invalidPrimaryAgent(registryPath, primaryAgent) {
62
+ return new ProjectRegistryError({
63
+ code: "PROJECT_REGISTRY_INVALID_PRIMARY",
64
+ message: `Primary agent '${primaryAgent}' not found in ${registryPath}.`,
65
+ registryPath,
66
+ agentId: primaryAgent
67
+ });
68
+ }
69
+ static invalidConfigPath(options) {
70
+ return new ProjectRegistryError({
71
+ code: "PROJECT_REGISTRY_INVALID_CONFIG_PATH",
72
+ message: `Agent '${options.agentId}' in ${options.registryPath} has invalid configPath '${options.configPath}': ${options.reason}.`,
73
+ registryPath: options.registryPath,
74
+ agentId: options.agentId,
75
+ configPath: options.configPath
76
+ });
77
+ }
78
+ }
79
+ function isProjectRegistryError(error) {
80
+ return error instanceof ProjectRegistryError;
81
+ }
82
+ const PROJECT_REGISTRY_RELATIVE_PATHS = [
83
+ path.join("agents", "registry.json"),
84
+ path.join("agents", "agent-registry.json")
85
+ ];
86
+ function getProjectRegistryPath(projectRoot) {
87
+ return path.join(projectRoot, "agents", "registry.json");
88
+ }
89
+ function getProjectRegistryCandidatePaths(projectRoot) {
90
+ return PROJECT_REGISTRY_RELATIVE_PATHS.map(
91
+ (relativePath) => path.join(projectRoot, relativePath)
92
+ );
93
+ }
94
+ async function findProjectRegistryPath(projectRoot) {
95
+ for (const registryPath of getProjectRegistryCandidatePaths(projectRoot)) {
96
+ try {
97
+ if ((await fs.stat(registryPath)).isFile()) {
98
+ return registryPath;
99
+ }
100
+ } catch (error) {
101
+ if (error.code === "ENOENT" || error.code === "ENOTDIR") {
102
+ continue;
103
+ }
104
+ throw error;
105
+ }
106
+ }
107
+ return null;
108
+ }
109
+ function findProjectRegistryPathSync(projectRoot) {
110
+ for (const registryPath of getProjectRegistryCandidatePaths(projectRoot)) {
111
+ try {
112
+ if (existsSync(registryPath) && statSync(registryPath).isFile()) {
113
+ return registryPath;
114
+ }
115
+ } catch (error) {
116
+ if (error.code === "EISDIR" || error.code === "ENOTDIR") {
117
+ continue;
118
+ }
119
+ throw error;
120
+ }
121
+ }
122
+ return null;
123
+ }
124
+ function parseProjectRegistryContent(content, registryPath) {
125
+ let parsed;
126
+ try {
127
+ parsed = JSON.parse(content);
128
+ } catch (error) {
129
+ if (error instanceof SyntaxError) {
130
+ throw ProjectRegistryError.invalidRegistry(
131
+ registryPath,
132
+ `Invalid workspace registry at ${registryPath}: ${error.message}`,
133
+ error
134
+ );
135
+ }
136
+ throw error;
137
+ }
138
+ try {
139
+ return ProjectRegistrySchema.parse(parsed);
140
+ } catch (error) {
141
+ if (error instanceof z.ZodError) {
142
+ const rawPrimaryAgent = parsed && typeof parsed === "object" && typeof parsed.primaryAgent === "string" ? parsed.primaryAgent : void 0;
143
+ const hasPrimaryAgentIssue = error.issues.some(
144
+ (issue) => issue.path[0] === "primaryAgent"
145
+ );
146
+ if (hasPrimaryAgentIssue && rawPrimaryAgent) {
147
+ throw ProjectRegistryError.invalidPrimaryAgent(registryPath, rawPrimaryAgent);
148
+ }
149
+ throw ProjectRegistryError.invalidRegistry(
150
+ registryPath,
151
+ `Invalid workspace registry at ${registryPath}: ${error.message}`,
152
+ error
153
+ );
154
+ }
155
+ throw error;
156
+ }
157
+ }
158
+ async function readProjectRegistry(registryPath) {
159
+ const content = await fs.readFile(registryPath, "utf-8");
160
+ return parseProjectRegistryContent(content, registryPath);
161
+ }
162
+ function readProjectRegistrySync(registryPath) {
163
+ return parseProjectRegistryContent(readFileSync(registryPath, "utf-8"), registryPath);
164
+ }
165
+ async function loadProjectRegistry(projectRoot) {
166
+ const registryPath = await findProjectRegistryPath(projectRoot);
167
+ if (!registryPath) {
168
+ return null;
169
+ }
170
+ return {
171
+ registryPath,
172
+ registry: await readProjectRegistry(registryPath)
173
+ };
174
+ }
175
+ function loadProjectRegistrySync(projectRoot) {
176
+ const registryPath = findProjectRegistryPathSync(projectRoot);
177
+ if (!registryPath) {
178
+ return null;
179
+ }
180
+ return {
181
+ registryPath,
182
+ registry: readProjectRegistrySync(registryPath)
183
+ };
184
+ }
185
+ async function resolveProjectRegistryEntry(projectRoot, agentId) {
186
+ const loaded = await loadProjectRegistry(projectRoot);
187
+ if (!loaded) {
188
+ return null;
189
+ }
190
+ const entry = loaded.registry.agents.find((agent) => agent.id === agentId);
191
+ if (!entry) {
192
+ return null;
193
+ }
194
+ return {
195
+ registryPath: loaded.registryPath,
196
+ entry
197
+ };
198
+ }
199
+ function getDefaultProjectRegistryEntry(registry, registryPath) {
200
+ if (registry.primaryAgent) {
201
+ const primaryEntry = registry.agents.find((agent) => agent.id === registry.primaryAgent);
202
+ if (!primaryEntry) {
203
+ throw ProjectRegistryError.invalidPrimaryAgent(registryPath, registry.primaryAgent);
204
+ }
205
+ return primaryEntry;
206
+ }
207
+ if (registry.agents.length === 1) {
208
+ return registry.agents[0] ?? null;
209
+ }
210
+ return null;
211
+ }
212
+ function assertProjectRegistryConfigPathSync(options) {
213
+ const absolutePath = path.resolve(path.dirname(options.registryPath), options.entry.configPath);
214
+ const relativeToProject = path.relative(options.projectRoot, absolutePath);
215
+ if (relativeToProject.startsWith("..") || path.isAbsolute(relativeToProject) || relativeToProject === "") {
216
+ throw ProjectRegistryError.invalidConfigPath({
217
+ registryPath: options.registryPath,
218
+ agentId: options.entry.id,
219
+ configPath: options.entry.configPath,
220
+ reason: "path must stay within the workspace root"
221
+ });
222
+ }
223
+ let stat;
224
+ try {
225
+ stat = statSync(absolutePath);
226
+ } catch (error) {
227
+ if (error.code === "ENOENT") {
228
+ throw ProjectRegistryError.invalidConfigPath({
229
+ registryPath: options.registryPath,
230
+ agentId: options.entry.id,
231
+ configPath: options.entry.configPath,
232
+ reason: "file does not exist"
233
+ });
234
+ }
235
+ throw error;
236
+ }
237
+ if (!stat.isFile()) {
238
+ throw ProjectRegistryError.invalidConfigPath({
239
+ registryPath: options.registryPath,
240
+ agentId: options.entry.id,
241
+ configPath: options.entry.configPath,
242
+ reason: "path must point to a file"
243
+ });
244
+ }
245
+ return absolutePath;
246
+ }
247
+ async function assertProjectRegistryConfigPath(options) {
248
+ const absolutePath = path.resolve(path.dirname(options.registryPath), options.entry.configPath);
249
+ const relativeToProject = path.relative(options.projectRoot, absolutePath);
250
+ if (relativeToProject.startsWith("..") || path.isAbsolute(relativeToProject) || relativeToProject === "") {
251
+ throw ProjectRegistryError.invalidConfigPath({
252
+ registryPath: options.registryPath,
253
+ agentId: options.entry.id,
254
+ configPath: options.entry.configPath,
255
+ reason: "path must stay within the workspace root"
256
+ });
257
+ }
258
+ let stat;
259
+ try {
260
+ stat = await fs.stat(absolutePath);
261
+ } catch (error) {
262
+ if (error.code === "ENOENT") {
263
+ throw ProjectRegistryError.invalidConfigPath({
264
+ registryPath: options.registryPath,
265
+ agentId: options.entry.id,
266
+ configPath: options.entry.configPath,
267
+ reason: "file does not exist"
268
+ });
269
+ }
270
+ throw error;
271
+ }
272
+ if (!stat.isFile()) {
273
+ throw ProjectRegistryError.invalidConfigPath({
274
+ registryPath: options.registryPath,
275
+ agentId: options.entry.id,
276
+ configPath: options.entry.configPath,
277
+ reason: "path must point to a file"
278
+ });
279
+ }
280
+ return absolutePath;
281
+ }
282
+ async function resolveProjectRegistryEntryConfigPath(projectRoot, registryPath, entry) {
283
+ return await assertProjectRegistryConfigPath({ projectRoot, registryPath, entry });
284
+ }
285
+ function resolveProjectRegistryEntryConfigPathSync(projectRoot, registryPath, entry) {
286
+ return assertProjectRegistryConfigPathSync({ projectRoot, registryPath, entry });
287
+ }
288
+ async function resolveProjectRegistryAgentPath(projectRoot, agentId) {
289
+ const resolved = await resolveProjectRegistryEntry(projectRoot, agentId);
290
+ if (!resolved) {
291
+ return null;
292
+ }
293
+ return await resolveProjectRegistryEntryConfigPath(
294
+ projectRoot,
295
+ resolved.registryPath,
296
+ resolved.entry
297
+ );
298
+ }
299
+ async function resolveDefaultProjectRegistryAgentPath(projectRoot) {
300
+ const loaded = await loadProjectRegistry(projectRoot);
301
+ if (!loaded) {
302
+ return null;
303
+ }
304
+ const entry = getDefaultProjectRegistryEntry(loaded.registry, loaded.registryPath);
305
+ if (!entry) {
306
+ return null;
307
+ }
308
+ return await resolveProjectRegistryEntryConfigPath(projectRoot, loaded.registryPath, entry);
309
+ }
310
+ export {
311
+ ProjectRegistryEntrySchema,
312
+ ProjectRegistryError,
313
+ ProjectRegistrySchema,
314
+ findProjectRegistryPath,
315
+ findProjectRegistryPathSync,
316
+ getDefaultProjectRegistryEntry,
317
+ getProjectRegistryCandidatePaths,
318
+ getProjectRegistryPath,
319
+ isProjectRegistryError,
320
+ loadProjectRegistry,
321
+ loadProjectRegistrySync,
322
+ readProjectRegistry,
323
+ readProjectRegistrySync,
324
+ resolveDefaultProjectRegistryAgentPath,
325
+ resolveProjectRegistryAgentPath,
326
+ resolveProjectRegistryEntry,
327
+ resolveProjectRegistryEntryConfigPath,
328
+ resolveProjectRegistryEntryConfigPathSync
329
+ };
package/dist/resolver.cjs CHANGED
@@ -42,6 +42,7 @@ var import_config = require("./config/index.js");
42
42
  var import_errors = require("./registry/errors.js");
43
43
  var import_AgentManager = require("./AgentManager.js");
44
44
  var import_installation = require("./installation.js");
45
+ var import_project_registry = require("./project-registry.js");
45
46
  async function resolveAgentPath(nameOrPath, autoInstall = true) {
46
47
  if (nameOrPath && (0, import_path2.isPath)(nameOrPath)) {
47
48
  const resolved = import_path.default.resolve(nameOrPath);
@@ -153,10 +154,30 @@ async function resolveDefaultAgentForDextoProject(autoInstall = true) {
153
154
  if (!projectRoot) {
154
155
  throw import_config.ConfigError.unknownContext("dexto-project: project root not found");
155
156
  }
157
+ try {
158
+ const projectRegistryAgentPath = await (0, import_project_registry.resolveDefaultProjectRegistryAgentPath)(projectRoot);
159
+ if (projectRegistryAgentPath) {
160
+ return projectRegistryAgentPath;
161
+ }
162
+ } catch (error) {
163
+ if ((0, import_project_registry.isProjectRegistryError)(error) && error.code === "PROJECT_REGISTRY_INVALID_PRIMARY") {
164
+ throw import_config.ConfigError.invalidProjectPrimary(
165
+ error.registryPath,
166
+ error.agentId ?? "",
167
+ error.message
168
+ );
169
+ }
170
+ throw error;
171
+ }
156
172
  const candidatePaths = [
173
+ import_path.default.join(projectRoot, "agents", "coding-agent", "coding-agent.yml"),
174
+ import_path.default.join(projectRoot, "agents", "coding-agent", "coding-agent.yaml"),
157
175
  import_path.default.join(projectRoot, "coding-agent.yml"),
176
+ import_path.default.join(projectRoot, "coding-agent.yaml"),
158
177
  import_path.default.join(projectRoot, "agents", "coding-agent.yml"),
159
- import_path.default.join(projectRoot, "src", "dexto", "agents", "coding-agent.yml")
178
+ import_path.default.join(projectRoot, "agents", "coding-agent.yaml"),
179
+ import_path.default.join(projectRoot, "src", "dexto", "agents", "coding-agent.yml"),
180
+ import_path.default.join(projectRoot, "src", "dexto", "agents", "coding-agent.yaml")
160
181
  ];
161
182
  for (const p of candidatePaths) {
162
183
  try {
@@ -165,7 +186,7 @@ async function resolveDefaultAgentForDextoProject(autoInstall = true) {
165
186
  } catch {
166
187
  }
167
188
  }
168
- import_core.logger.debug(`No project-local coding-agent.yml found in ${projectRoot}`);
189
+ import_core.logger.debug(`No project-local coding-agent found in ${projectRoot}`);
169
190
  if (!(0, import_loader.globalPreferencesExist)()) {
170
191
  throw import_config.ConfigError.noProjectDefault(projectRoot);
171
192
  }
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAoCA;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAClC,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,GAAE,OAAc,GAC5B,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAiMD;;;;GAIG;AACH,wBAAsB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BnF"}
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAwCA;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAClC,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,GAAE,OAAc,GAC5B,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAuND;;;;GAIG;AACH,wBAAsB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BnF"}
package/dist/resolver.js CHANGED
@@ -12,6 +12,10 @@ import { ConfigError } from "./config/index.js";
12
12
  import { RegistryError } from "./registry/errors.js";
13
13
  import { AgentManager } from "./AgentManager.js";
14
14
  import { installBundledAgent } from "./installation.js";
15
+ import {
16
+ isProjectRegistryError,
17
+ resolveDefaultProjectRegistryAgentPath
18
+ } from "./project-registry.js";
15
19
  async function resolveAgentPath(nameOrPath, autoInstall = true) {
16
20
  if (nameOrPath && isPath(nameOrPath)) {
17
21
  const resolved = path.resolve(nameOrPath);
@@ -123,10 +127,30 @@ async function resolveDefaultAgentForDextoProject(autoInstall = true) {
123
127
  if (!projectRoot) {
124
128
  throw ConfigError.unknownContext("dexto-project: project root not found");
125
129
  }
130
+ try {
131
+ const projectRegistryAgentPath = await resolveDefaultProjectRegistryAgentPath(projectRoot);
132
+ if (projectRegistryAgentPath) {
133
+ return projectRegistryAgentPath;
134
+ }
135
+ } catch (error) {
136
+ if (isProjectRegistryError(error) && error.code === "PROJECT_REGISTRY_INVALID_PRIMARY") {
137
+ throw ConfigError.invalidProjectPrimary(
138
+ error.registryPath,
139
+ error.agentId ?? "",
140
+ error.message
141
+ );
142
+ }
143
+ throw error;
144
+ }
126
145
  const candidatePaths = [
146
+ path.join(projectRoot, "agents", "coding-agent", "coding-agent.yml"),
147
+ path.join(projectRoot, "agents", "coding-agent", "coding-agent.yaml"),
127
148
  path.join(projectRoot, "coding-agent.yml"),
149
+ path.join(projectRoot, "coding-agent.yaml"),
128
150
  path.join(projectRoot, "agents", "coding-agent.yml"),
129
- path.join(projectRoot, "src", "dexto", "agents", "coding-agent.yml")
151
+ path.join(projectRoot, "agents", "coding-agent.yaml"),
152
+ path.join(projectRoot, "src", "dexto", "agents", "coding-agent.yml"),
153
+ path.join(projectRoot, "src", "dexto", "agents", "coding-agent.yaml")
130
154
  ];
131
155
  for (const p of candidatePaths) {
132
156
  try {
@@ -135,7 +159,7 @@ async function resolveDefaultAgentForDextoProject(autoInstall = true) {
135
159
  } catch {
136
160
  }
137
161
  }
138
- logger.debug(`No project-local coding-agent.yml found in ${projectRoot}`);
162
+ logger.debug(`No project-local coding-agent found in ${projectRoot}`);
139
163
  if (!globalPreferencesExist()) {
140
164
  throw ConfigError.noProjectDefault(projectRoot);
141
165
  }
@@ -54,9 +54,13 @@ const agentSpawnerToolsFactory = {
54
54
  );
55
55
  }
56
56
  };
57
+ const updateWorkspaceRootHint = (runtime, context) => {
58
+ runtime.setWorkspaceRootHint(context.workspace?.path);
59
+ };
57
60
  const ensureToolsInitialized = (context) => {
58
61
  const { agent, logger, toolServices } = requireAgentContext(context);
59
62
  if (state && state.agent === agent && !state.abortController.signal.aborted) {
63
+ updateWorkspaceRootHint(state.runtime, context);
60
64
  attachTaskForker({ toolServices, taskForker: state.runtime, logger });
61
65
  return state.tools;
62
66
  }
@@ -71,6 +75,7 @@ const agentSpawnerToolsFactory = {
71
75
  const taskRegistry = new import_orchestration.TaskRegistry(signalBus);
72
76
  const conditionEngine = new import_orchestration.ConditionEngine(taskRegistry, signalBus, logger);
73
77
  const spawnerRuntime = new import_runtime.AgentSpawnerRuntime(agent, config, logger);
78
+ updateWorkspaceRootHint(spawnerRuntime, context);
74
79
  attachTaskForker({ toolServices, taskForker: spawnerRuntime, logger });
75
80
  const taskSessions = /* @__PURE__ */ new Map();
76
81
  const emitTasksUpdate = (sessionId) => {
@@ -229,6 +234,13 @@ const agentSpawnerToolsFactory = {
229
234
  {
230
235
  id: "spawn_agent",
231
236
  description: "Spawn a sub-agent to handle a task and return its result.",
237
+ getDescription: async (context) => {
238
+ const tool = ensureToolsInitialized(context).spawnAgent;
239
+ if (tool.getDescription) {
240
+ return await tool.getDescription(context);
241
+ }
242
+ return tool.description;
243
+ },
232
244
  inputSchema: import_schemas.SpawnAgentInputSchema,
233
245
  execute: (input, context) => ensureToolsInitialized(context).spawnAgent.execute(input, context),
234
246
  presentation: {
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/tool-factories/agent-spawner/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAiBvD,OAAO,EAGH,KAAK,kBAAkB,EAC1B,MAAM,cAAc,CAAC;AAqCtB,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,kBAAkB,CA8VpE,CAAC"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/tool-factories/agent-spawner/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAiBvD,OAAO,EAGH,KAAK,kBAAkB,EAC1B,MAAM,cAAc,CAAC;AAqCtB,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,kBAAkB,CA8WpE,CAAC"}
@@ -44,9 +44,13 @@ const agentSpawnerToolsFactory = {
44
44
  );
45
45
  }
46
46
  };
47
+ const updateWorkspaceRootHint = (runtime, context) => {
48
+ runtime.setWorkspaceRootHint(context.workspace?.path);
49
+ };
47
50
  const ensureToolsInitialized = (context) => {
48
51
  const { agent, logger, toolServices } = requireAgentContext(context);
49
52
  if (state && state.agent === agent && !state.abortController.signal.aborted) {
53
+ updateWorkspaceRootHint(state.runtime, context);
50
54
  attachTaskForker({ toolServices, taskForker: state.runtime, logger });
51
55
  return state.tools;
52
56
  }
@@ -61,6 +65,7 @@ const agentSpawnerToolsFactory = {
61
65
  const taskRegistry = new TaskRegistry(signalBus);
62
66
  const conditionEngine = new ConditionEngine(taskRegistry, signalBus, logger);
63
67
  const spawnerRuntime = new AgentSpawnerRuntime(agent, config, logger);
68
+ updateWorkspaceRootHint(spawnerRuntime, context);
64
69
  attachTaskForker({ toolServices, taskForker: spawnerRuntime, logger });
65
70
  const taskSessions = /* @__PURE__ */ new Map();
66
71
  const emitTasksUpdate = (sessionId) => {
@@ -219,6 +224,13 @@ const agentSpawnerToolsFactory = {
219
224
  {
220
225
  id: "spawn_agent",
221
226
  description: "Spawn a sub-agent to handle a task and return its result.",
227
+ getDescription: async (context) => {
228
+ const tool = ensureToolsInitialized(context).spawnAgent;
229
+ if (tool.getDescription) {
230
+ return await tool.getDescription(context);
231
+ }
232
+ return tool.description;
233
+ },
222
234
  inputSchema: SpawnAgentInputSchema,
223
235
  execute: (input, context) => ensureToolsInitialized(context).spawnAgent.execute(input, context),
224
236
  presentation: {