@robota-sdk/agent-sdk 3.0.0-beta.31 → 3.0.0-beta.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -0
- package/dist/node/index.cjs +576 -266
- package/dist/node/index.d.cts +195 -8
- package/dist/node/index.d.ts +195 -8
- package/dist/node/index.js +576 -275
- package/package.json +5 -5
package/dist/node/index.js
CHANGED
|
@@ -109,7 +109,7 @@ Respond with JSON: { "ok": boolean, "reason"?: string }`;
|
|
|
109
109
|
};
|
|
110
110
|
|
|
111
111
|
// src/assembly/create-session.ts
|
|
112
|
-
import { Session } from "@robota-sdk/agent-sessions";
|
|
112
|
+
import { Session as Session2 } from "@robota-sdk/agent-sessions";
|
|
113
113
|
|
|
114
114
|
// src/context/system-prompt-builder.ts
|
|
115
115
|
var TRUST_LEVEL_DESCRIPTIONS = {
|
|
@@ -251,11 +251,379 @@ function createProvider(config) {
|
|
|
251
251
|
return new AnthropicProvider({ apiKey });
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
+
// src/tools/agent-tool.ts
|
|
255
|
+
import { z } from "zod";
|
|
256
|
+
import { createZodFunctionTool } from "@robota-sdk/agent-tools";
|
|
257
|
+
|
|
258
|
+
// src/agents/built-in-agents.ts
|
|
259
|
+
var GENERAL_PURPOSE_SYSTEM_PROMPT = `You are a general-purpose task execution agent. You have access to all tools available in the parent session and can perform any task delegated to you.
|
|
260
|
+
|
|
261
|
+
Your role is to complete the assigned task thoroughly and accurately. Follow these guidelines:
|
|
262
|
+
|
|
263
|
+
- Execute the task as described in the prompt. Do not expand scope beyond what is requested.
|
|
264
|
+
- Use the most appropriate tools for each step. Prefer precise tools (Read, Grep, Glob) over broad ones (Bash) when possible.
|
|
265
|
+
- Report your findings clearly and concisely when the task is complete.
|
|
266
|
+
- If a task cannot be completed, explain why and what information is missing.
|
|
267
|
+
- Maintain the same code quality standards as the parent session (strict types, no fallbacks, proper error handling).`;
|
|
268
|
+
var EXPLORE_SYSTEM_PROMPT = `You are a codebase exploration and analysis agent. Your purpose is to search, read, and understand code without making any modifications.
|
|
269
|
+
|
|
270
|
+
You operate in read-only mode. You must NEVER attempt to write or edit files. Your tools are restricted to read-only operations: reading files, searching with grep and glob, and running non-destructive bash commands.
|
|
271
|
+
|
|
272
|
+
Your role is to answer questions about the codebase by:
|
|
273
|
+
|
|
274
|
+
- Searching for relevant files, symbols, and patterns using Glob and Grep.
|
|
275
|
+
- Reading source files, configuration, and documentation to understand structure and behavior.
|
|
276
|
+
- Tracing code paths across modules to understand how components interact.
|
|
277
|
+
- Summarizing findings in a clear, structured format with file paths and line references.
|
|
278
|
+
- Identifying architectural patterns, dependencies, and potential issues.
|
|
279
|
+
|
|
280
|
+
When exploring, prefer targeted searches over broad scans. Start with the most likely locations and narrow down. Always include absolute file paths in your responses so the caller can navigate directly to relevant code.`;
|
|
281
|
+
var PLAN_SYSTEM_PROMPT = `You are a planning, research, and architecture agent. Your purpose is to analyze requirements, research approaches, and produce structured plans without making any code modifications.
|
|
282
|
+
|
|
283
|
+
You operate in read-only mode. You must NEVER attempt to write or edit files. Your tools are restricted to read-only operations.
|
|
284
|
+
|
|
285
|
+
Your role is to:
|
|
286
|
+
|
|
287
|
+
- Analyze the current codebase state relevant to the task by reading specs, source code, and tests.
|
|
288
|
+
- Research implementation approaches by examining existing patterns and architectural conventions in the repository.
|
|
289
|
+
- Identify affected files, modules, and interfaces that a proposed change would touch.
|
|
290
|
+
- Assess risks, dependencies, and potential breaking changes.
|
|
291
|
+
- Produce a structured implementation plan with clear steps, file lists, and ordering.
|
|
292
|
+
- Consider edge cases, error handling, and test coverage requirements.
|
|
293
|
+
|
|
294
|
+
Output your plan in a structured format with numbered steps. For each step, specify which files are involved and what changes are needed. Flag any decisions that require human judgment or clarification.`;
|
|
295
|
+
var BUILT_IN_AGENTS = [
|
|
296
|
+
{
|
|
297
|
+
name: "general-purpose",
|
|
298
|
+
description: "General-purpose task execution agent with full tool access.",
|
|
299
|
+
systemPrompt: GENERAL_PURPOSE_SYSTEM_PROMPT
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
name: "Explore",
|
|
303
|
+
description: "Read-only codebase exploration and analysis agent.",
|
|
304
|
+
systemPrompt: EXPLORE_SYSTEM_PROMPT,
|
|
305
|
+
model: "claude-haiku-4-5",
|
|
306
|
+
disallowedTools: ["Write", "Edit"]
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
name: "Plan",
|
|
310
|
+
description: "Read-only planning, research, and architecture agent.",
|
|
311
|
+
systemPrompt: PLAN_SYSTEM_PROMPT,
|
|
312
|
+
disallowedTools: ["Write", "Edit"]
|
|
313
|
+
}
|
|
314
|
+
];
|
|
315
|
+
function getBuiltInAgent(name) {
|
|
316
|
+
return BUILT_IN_AGENTS.find((agent) => agent.name === name);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// src/assembly/create-subagent-session.ts
|
|
320
|
+
import { Session } from "@robota-sdk/agent-sessions";
|
|
321
|
+
|
|
322
|
+
// src/assembly/subagent-prompts.ts
|
|
323
|
+
function getSubagentSuffix() {
|
|
324
|
+
return `When you complete the task, respond with a concise report covering what was done and any key findings \u2014 the caller will relay this to the user, so it only needs the essentials.
|
|
325
|
+
|
|
326
|
+
In your final response, share file paths (always absolute, never relative) that are relevant to the task. Include code snippets only when the exact text is load-bearing \u2014 do not recap code you merely read.
|
|
327
|
+
|
|
328
|
+
Do not use emojis.`;
|
|
329
|
+
}
|
|
330
|
+
function getForkWorkerSuffix() {
|
|
331
|
+
return `You are a worker subagent executing a specific task. Do NOT spawn sub-agents; execute directly. Keep your report under 500 words. Use this structure:
|
|
332
|
+
- Scope: What was requested
|
|
333
|
+
- Result: What was done
|
|
334
|
+
- Key files: Relevant file paths (absolute)
|
|
335
|
+
- Files changed: List of modifications
|
|
336
|
+
- Issues: Any problems encountered`;
|
|
337
|
+
}
|
|
338
|
+
function assembleSubagentPrompt(options) {
|
|
339
|
+
const parts = [options.agentBody];
|
|
340
|
+
if (options.claudeMd) {
|
|
341
|
+
parts.push(options.claudeMd);
|
|
342
|
+
}
|
|
343
|
+
if (options.agentsMd) {
|
|
344
|
+
parts.push(options.agentsMd);
|
|
345
|
+
}
|
|
346
|
+
const suffix = options.isForkWorker ? getForkWorkerSuffix() : getSubagentSuffix();
|
|
347
|
+
parts.push(suffix);
|
|
348
|
+
return parts.join("\n\n");
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// src/assembly/create-subagent-session.ts
|
|
352
|
+
var MODEL_SHORTCUTS = {
|
|
353
|
+
sonnet: "claude-sonnet-4-6",
|
|
354
|
+
haiku: "claude-haiku-4-5",
|
|
355
|
+
opus: "claude-opus-4-6"
|
|
356
|
+
};
|
|
357
|
+
function resolveModelId(shortName, _parentModel) {
|
|
358
|
+
return MODEL_SHORTCUTS[shortName] ?? shortName;
|
|
359
|
+
}
|
|
360
|
+
function filterTools(parentTools, agentDefinition) {
|
|
361
|
+
let tools = [...parentTools];
|
|
362
|
+
if (agentDefinition.disallowedTools) {
|
|
363
|
+
const denySet = new Set(agentDefinition.disallowedTools);
|
|
364
|
+
tools = tools.filter((t) => !denySet.has(t.getName()));
|
|
365
|
+
}
|
|
366
|
+
if (agentDefinition.tools) {
|
|
367
|
+
const allowSet = new Set(agentDefinition.tools);
|
|
368
|
+
tools = tools.filter((t) => allowSet.has(t.getName()));
|
|
369
|
+
}
|
|
370
|
+
tools = tools.filter((t) => t.getName() !== "Agent");
|
|
371
|
+
return tools;
|
|
372
|
+
}
|
|
373
|
+
function createSubagentSession(options) {
|
|
374
|
+
const { agentDefinition, parentConfig, parentContext, parentTools, terminal } = options;
|
|
375
|
+
const tools = filterTools(parentTools, agentDefinition);
|
|
376
|
+
const model = agentDefinition.model ? resolveModelId(agentDefinition.model, parentConfig.provider.model) : parentConfig.provider.model;
|
|
377
|
+
const systemMessage = assembleSubagentPrompt({
|
|
378
|
+
agentBody: agentDefinition.systemPrompt,
|
|
379
|
+
claudeMd: parentContext.claudeMd,
|
|
380
|
+
agentsMd: parentContext.agentsMd,
|
|
381
|
+
isForkWorker: options.isForkWorker ?? false
|
|
382
|
+
});
|
|
383
|
+
const provider = createProvider(parentConfig);
|
|
384
|
+
return new Session({
|
|
385
|
+
tools,
|
|
386
|
+
provider,
|
|
387
|
+
systemMessage,
|
|
388
|
+
terminal,
|
|
389
|
+
model,
|
|
390
|
+
maxTurns: agentDefinition.maxTurns,
|
|
391
|
+
permissions: parentConfig.permissions,
|
|
392
|
+
permissionMode: options.permissionMode,
|
|
393
|
+
defaultTrustLevel: parentConfig.defaultTrustLevel,
|
|
394
|
+
permissionHandler: options.permissionHandler,
|
|
395
|
+
hooks: options.hooks,
|
|
396
|
+
hookTypeExecutors: options.hookTypeExecutors,
|
|
397
|
+
onTextDelta: options.onTextDelta,
|
|
398
|
+
onToolExecution: options.onToolExecution
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// src/tools/agent-tool.ts
|
|
403
|
+
function asZodSchema(schema) {
|
|
404
|
+
return schema;
|
|
405
|
+
}
|
|
406
|
+
var AgentSchema = z.object({
|
|
407
|
+
prompt: z.string().describe("The task for the subagent to perform"),
|
|
408
|
+
subagent_type: z.string().optional().describe('Agent type: "general-purpose", "Explore", "Plan", or a custom agent name'),
|
|
409
|
+
model: z.string().optional().describe("Optional model override")
|
|
410
|
+
});
|
|
411
|
+
var sessionDepsStore = /* @__PURE__ */ new WeakMap();
|
|
412
|
+
function storeAgentToolDeps(key, deps) {
|
|
413
|
+
sessionDepsStore.set(key, deps);
|
|
414
|
+
}
|
|
415
|
+
function retrieveAgentToolDeps(key) {
|
|
416
|
+
return sessionDepsStore.get(key);
|
|
417
|
+
}
|
|
418
|
+
function resolveAgentDefinition(agentType, customRegistry) {
|
|
419
|
+
const builtIn = getBuiltInAgent(agentType);
|
|
420
|
+
if (builtIn) return builtIn;
|
|
421
|
+
if (customRegistry) return customRegistry(agentType);
|
|
422
|
+
return void 0;
|
|
423
|
+
}
|
|
424
|
+
function generateAgentId() {
|
|
425
|
+
return `agent_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
426
|
+
}
|
|
427
|
+
function createAgentTool(deps) {
|
|
428
|
+
async function runAgent(args) {
|
|
429
|
+
const agentType = args.subagent_type ?? "general-purpose";
|
|
430
|
+
const agentDef = resolveAgentDefinition(agentType, deps.customAgentRegistry);
|
|
431
|
+
if (!agentDef) {
|
|
432
|
+
return JSON.stringify({
|
|
433
|
+
success: false,
|
|
434
|
+
output: "",
|
|
435
|
+
error: `Unknown agent type: ${agentType}`
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
const effectiveDef = args.model ? { ...agentDef, model: args.model } : agentDef;
|
|
439
|
+
const session = createSubagentSession({
|
|
440
|
+
agentDefinition: effectiveDef,
|
|
441
|
+
parentConfig: deps.config,
|
|
442
|
+
parentContext: deps.context,
|
|
443
|
+
parentTools: deps.tools,
|
|
444
|
+
terminal: deps.terminal,
|
|
445
|
+
permissionMode: deps.permissionMode,
|
|
446
|
+
permissionHandler: deps.permissionHandler,
|
|
447
|
+
hooks: deps.hooks,
|
|
448
|
+
hookTypeExecutors: deps.hookTypeExecutors,
|
|
449
|
+
onTextDelta: deps.onTextDelta,
|
|
450
|
+
onToolExecution: deps.onToolExecution
|
|
451
|
+
});
|
|
452
|
+
const agentId = generateAgentId();
|
|
453
|
+
try {
|
|
454
|
+
const response = await session.run(args.prompt);
|
|
455
|
+
return JSON.stringify({
|
|
456
|
+
success: true,
|
|
457
|
+
output: response,
|
|
458
|
+
agentId
|
|
459
|
+
});
|
|
460
|
+
} catch (err) {
|
|
461
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
462
|
+
return JSON.stringify({
|
|
463
|
+
success: false,
|
|
464
|
+
output: "",
|
|
465
|
+
error: `Sub-agent error: ${message}`,
|
|
466
|
+
agentId
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
return createZodFunctionTool(
|
|
471
|
+
"Agent",
|
|
472
|
+
"Launch a subagent to handle a task in an isolated context. The subagent gets its own context window and returns a result when done. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.",
|
|
473
|
+
asZodSchema(AgentSchema),
|
|
474
|
+
async (params) => {
|
|
475
|
+
return runAgent(params);
|
|
476
|
+
}
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// src/agents/agent-definition-loader.ts
|
|
481
|
+
import { readdirSync, readFileSync, existsSync } from "fs";
|
|
482
|
+
import { join, basename } from "path";
|
|
483
|
+
import { homedir } from "os";
|
|
484
|
+
var LIST_KEYS = /* @__PURE__ */ new Set(["tools", "disallowedTools"]);
|
|
485
|
+
var NUMBER_KEYS = /* @__PURE__ */ new Set(["maxTurns"]);
|
|
486
|
+
function parseFrontmatter(content) {
|
|
487
|
+
const lines = content.split("\n");
|
|
488
|
+
if (lines[0]?.trim() !== "---") {
|
|
489
|
+
return { frontmatter: null, body: content };
|
|
490
|
+
}
|
|
491
|
+
let endIndex = -1;
|
|
492
|
+
for (let i = 1; i < lines.length; i++) {
|
|
493
|
+
if (lines[i]?.trim() === "---") {
|
|
494
|
+
endIndex = i;
|
|
495
|
+
break;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
if (endIndex === -1) {
|
|
499
|
+
return { frontmatter: null, body: content };
|
|
500
|
+
}
|
|
501
|
+
const result = {};
|
|
502
|
+
for (let i = 1; i < endIndex; i++) {
|
|
503
|
+
const line = lines[i];
|
|
504
|
+
const match = line.match(/^([a-zA-Z][a-zA-Z0-9]*(?:[A-Z][a-z]*)*):\s*(.+)/);
|
|
505
|
+
if (!match) continue;
|
|
506
|
+
const key = match[1];
|
|
507
|
+
const rawValue = match[2].trim();
|
|
508
|
+
if (LIST_KEYS.has(key)) {
|
|
509
|
+
result[key] = rawValue.split(",").map((s) => s.trim());
|
|
510
|
+
} else if (NUMBER_KEYS.has(key)) {
|
|
511
|
+
result[key] = parseInt(rawValue, 10);
|
|
512
|
+
} else {
|
|
513
|
+
result[key] = rawValue;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
const body = lines.slice(endIndex + 1).join("\n").trim();
|
|
517
|
+
return {
|
|
518
|
+
frontmatter: Object.keys(result).length > 0 ? result : null,
|
|
519
|
+
body
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
function scanAgentsDir(dir) {
|
|
523
|
+
if (!existsSync(dir)) return [];
|
|
524
|
+
const agents = [];
|
|
525
|
+
let entries;
|
|
526
|
+
try {
|
|
527
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
528
|
+
} catch {
|
|
529
|
+
return [];
|
|
530
|
+
}
|
|
531
|
+
for (const entry of entries) {
|
|
532
|
+
if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
|
|
533
|
+
const filePath = join(dir, entry.name);
|
|
534
|
+
const content = readFileSync(filePath, "utf-8");
|
|
535
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
536
|
+
const fallbackName = basename(entry.name, ".md");
|
|
537
|
+
const agent = {
|
|
538
|
+
name: frontmatter?.name ?? fallbackName,
|
|
539
|
+
description: frontmatter?.description ?? "",
|
|
540
|
+
systemPrompt: body
|
|
541
|
+
};
|
|
542
|
+
if (frontmatter?.model !== void 0) agent.model = frontmatter.model;
|
|
543
|
+
if (frontmatter?.maxTurns !== void 0) agent.maxTurns = frontmatter.maxTurns;
|
|
544
|
+
if (frontmatter?.tools !== void 0) agent.tools = frontmatter.tools;
|
|
545
|
+
if (frontmatter?.disallowedTools !== void 0)
|
|
546
|
+
agent.disallowedTools = frontmatter.disallowedTools;
|
|
547
|
+
agents.push(agent);
|
|
548
|
+
}
|
|
549
|
+
return agents;
|
|
550
|
+
}
|
|
551
|
+
var AgentDefinitionLoader = class {
|
|
552
|
+
cwd;
|
|
553
|
+
home;
|
|
554
|
+
constructor(cwd, home) {
|
|
555
|
+
this.cwd = cwd;
|
|
556
|
+
this.home = home ?? homedir();
|
|
557
|
+
}
|
|
558
|
+
/** Load all agent definitions, merged with built-in agents. Custom overrides built-in on name collision. */
|
|
559
|
+
loadAll() {
|
|
560
|
+
const sources = [
|
|
561
|
+
scanAgentsDir(join(this.cwd, ".claude", "agents")),
|
|
562
|
+
scanAgentsDir(join(this.home, ".robota", "agents"))
|
|
563
|
+
];
|
|
564
|
+
const seen = /* @__PURE__ */ new Set();
|
|
565
|
+
const customAgents = [];
|
|
566
|
+
for (const agents of sources) {
|
|
567
|
+
for (const agent of agents) {
|
|
568
|
+
if (!seen.has(agent.name)) {
|
|
569
|
+
seen.add(agent.name);
|
|
570
|
+
customAgents.push(agent);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
const result = [...customAgents];
|
|
575
|
+
for (const builtIn of BUILT_IN_AGENTS) {
|
|
576
|
+
if (!seen.has(builtIn.name)) {
|
|
577
|
+
result.push(builtIn);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
return result;
|
|
581
|
+
}
|
|
582
|
+
/** Get a specific agent by name (custom or built-in). */
|
|
583
|
+
getAgent(name) {
|
|
584
|
+
return this.loadAll().find((agent) => agent.name === name);
|
|
585
|
+
}
|
|
586
|
+
};
|
|
587
|
+
|
|
254
588
|
// src/assembly/create-session.ts
|
|
255
589
|
function createSession(options) {
|
|
256
590
|
const provider = options.provider ?? createProvider(options.config);
|
|
257
591
|
const defaultTools = createDefaultTools();
|
|
258
592
|
const tools = [...defaultTools, ...options.additionalTools ?? []];
|
|
593
|
+
const agentLoader = new AgentDefinitionLoader(process.cwd());
|
|
594
|
+
const hookTypeExecutors = [];
|
|
595
|
+
if (options.providerFactory) {
|
|
596
|
+
hookTypeExecutors.push(
|
|
597
|
+
new PromptExecutor({
|
|
598
|
+
providerFactory: options.providerFactory,
|
|
599
|
+
defaultModel: options.config.provider.model
|
|
600
|
+
})
|
|
601
|
+
);
|
|
602
|
+
}
|
|
603
|
+
if (options.sessionFactory) {
|
|
604
|
+
hookTypeExecutors.push(
|
|
605
|
+
new AgentExecutor({
|
|
606
|
+
sessionFactory: options.sessionFactory
|
|
607
|
+
})
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
if (options.additionalHookExecutors) {
|
|
611
|
+
hookTypeExecutors.push(...options.additionalHookExecutors);
|
|
612
|
+
}
|
|
613
|
+
const agentToolDeps = {
|
|
614
|
+
config: options.config,
|
|
615
|
+
context: options.context,
|
|
616
|
+
tools,
|
|
617
|
+
terminal: options.terminal,
|
|
618
|
+
permissionMode: options.permissionMode,
|
|
619
|
+
permissionHandler: options.permissionHandler,
|
|
620
|
+
hooks: options.config.hooks,
|
|
621
|
+
hookTypeExecutors: hookTypeExecutors.length > 0 ? hookTypeExecutors : void 0,
|
|
622
|
+
onTextDelta: options.onTextDelta,
|
|
623
|
+
onToolExecution: options.onToolExecution,
|
|
624
|
+
customAgentRegistry: (name) => agentLoader.getAgent(name)
|
|
625
|
+
};
|
|
626
|
+
tools.push(createAgentTool(agentToolDeps));
|
|
259
627
|
const buildPrompt = options.systemPromptBuilder ?? buildSystemPrompt;
|
|
260
628
|
const systemMessage = buildPrompt({
|
|
261
629
|
agentsMd: options.context.agentsMd,
|
|
@@ -278,26 +646,7 @@ function createSession(options) {
|
|
|
278
646
|
allow: [...defaultAllow, ...options.config.permissions.allow ?? []],
|
|
279
647
|
deny: options.config.permissions.deny ?? []
|
|
280
648
|
};
|
|
281
|
-
const
|
|
282
|
-
if (options.providerFactory) {
|
|
283
|
-
hookTypeExecutors.push(
|
|
284
|
-
new PromptExecutor({
|
|
285
|
-
providerFactory: options.providerFactory,
|
|
286
|
-
defaultModel: options.config.provider.model
|
|
287
|
-
})
|
|
288
|
-
);
|
|
289
|
-
}
|
|
290
|
-
if (options.sessionFactory) {
|
|
291
|
-
hookTypeExecutors.push(
|
|
292
|
-
new AgentExecutor({
|
|
293
|
-
sessionFactory: options.sessionFactory
|
|
294
|
-
})
|
|
295
|
-
);
|
|
296
|
-
}
|
|
297
|
-
if (options.additionalHookExecutors) {
|
|
298
|
-
hookTypeExecutors.push(...options.additionalHookExecutors);
|
|
299
|
-
}
|
|
300
|
-
return new Session({
|
|
649
|
+
const session = new Session2({
|
|
301
650
|
tools,
|
|
302
651
|
provider,
|
|
303
652
|
systemMessage,
|
|
@@ -318,89 +667,104 @@ function createSession(options) {
|
|
|
318
667
|
sessionLogger: options.sessionLogger,
|
|
319
668
|
hookTypeExecutors: hookTypeExecutors.length > 0 ? hookTypeExecutors : void 0
|
|
320
669
|
});
|
|
670
|
+
storeAgentToolDeps(session, agentToolDeps);
|
|
671
|
+
return session;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
// src/assembly/subagent-logger.ts
|
|
675
|
+
import { mkdirSync } from "fs";
|
|
676
|
+
import { join as join2 } from "path";
|
|
677
|
+
import { FileSessionLogger } from "@robota-sdk/agent-sessions";
|
|
678
|
+
function createSubagentLogger(parentSessionId, _agentId, baseLogsDir) {
|
|
679
|
+
const subagentDir = join2(baseLogsDir, parentSessionId, "subagents");
|
|
680
|
+
mkdirSync(subagentDir, { recursive: true });
|
|
681
|
+
return new FileSessionLogger(subagentDir);
|
|
682
|
+
}
|
|
683
|
+
function resolveSubagentLogDir(parentSessionId, baseLogsDir) {
|
|
684
|
+
return join2(baseLogsDir, parentSessionId, "subagents");
|
|
321
685
|
}
|
|
322
686
|
|
|
323
687
|
// src/index.ts
|
|
324
|
-
import { Session as
|
|
325
|
-
import { FileSessionLogger, SilentSessionLogger } from "@robota-sdk/agent-sessions";
|
|
688
|
+
import { Session as Session3 } from "@robota-sdk/agent-sessions";
|
|
689
|
+
import { FileSessionLogger as FileSessionLogger2, SilentSessionLogger } from "@robota-sdk/agent-sessions";
|
|
326
690
|
import { SessionStore } from "@robota-sdk/agent-sessions";
|
|
327
691
|
|
|
328
692
|
// src/config/config-loader.ts
|
|
329
|
-
import { readFileSync, existsSync } from "fs";
|
|
330
|
-
import { join } from "path";
|
|
693
|
+
import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
|
|
694
|
+
import { join as join3 } from "path";
|
|
331
695
|
|
|
332
696
|
// src/config/config-types.ts
|
|
333
|
-
import { z } from "zod";
|
|
334
|
-
var ProviderSchema =
|
|
335
|
-
name:
|
|
336
|
-
model:
|
|
337
|
-
apiKey:
|
|
697
|
+
import { z as z2 } from "zod";
|
|
698
|
+
var ProviderSchema = z2.object({
|
|
699
|
+
name: z2.string().optional(),
|
|
700
|
+
model: z2.string().optional(),
|
|
701
|
+
apiKey: z2.string().optional()
|
|
338
702
|
});
|
|
339
|
-
var PermissionsSchema =
|
|
703
|
+
var PermissionsSchema = z2.object({
|
|
340
704
|
/** Patterns that are always approved without prompting */
|
|
341
|
-
allow:
|
|
705
|
+
allow: z2.array(z2.string()).optional(),
|
|
342
706
|
/** Patterns that are always denied */
|
|
343
|
-
deny:
|
|
707
|
+
deny: z2.array(z2.string()).optional()
|
|
344
708
|
});
|
|
345
|
-
var EnvSchema =
|
|
346
|
-
var CommandHookDefinitionSchema =
|
|
347
|
-
type:
|
|
348
|
-
command:
|
|
349
|
-
timeout:
|
|
709
|
+
var EnvSchema = z2.record(z2.string()).optional();
|
|
710
|
+
var CommandHookDefinitionSchema = z2.object({
|
|
711
|
+
type: z2.literal("command"),
|
|
712
|
+
command: z2.string(),
|
|
713
|
+
timeout: z2.number().optional()
|
|
350
714
|
});
|
|
351
|
-
var HttpHookDefinitionSchema =
|
|
352
|
-
type:
|
|
353
|
-
url:
|
|
354
|
-
headers:
|
|
355
|
-
timeout:
|
|
715
|
+
var HttpHookDefinitionSchema = z2.object({
|
|
716
|
+
type: z2.literal("http"),
|
|
717
|
+
url: z2.string(),
|
|
718
|
+
headers: z2.record(z2.string()).optional(),
|
|
719
|
+
timeout: z2.number().optional()
|
|
356
720
|
});
|
|
357
|
-
var PromptHookDefinitionSchema =
|
|
358
|
-
type:
|
|
359
|
-
prompt:
|
|
360
|
-
model:
|
|
721
|
+
var PromptHookDefinitionSchema = z2.object({
|
|
722
|
+
type: z2.literal("prompt"),
|
|
723
|
+
prompt: z2.string(),
|
|
724
|
+
model: z2.string().optional()
|
|
361
725
|
});
|
|
362
|
-
var AgentHookDefinitionSchema =
|
|
363
|
-
type:
|
|
364
|
-
agent:
|
|
365
|
-
maxTurns:
|
|
366
|
-
timeout:
|
|
726
|
+
var AgentHookDefinitionSchema = z2.object({
|
|
727
|
+
type: z2.literal("agent"),
|
|
728
|
+
agent: z2.string(),
|
|
729
|
+
maxTurns: z2.number().optional(),
|
|
730
|
+
timeout: z2.number().optional()
|
|
367
731
|
});
|
|
368
|
-
var HookDefinitionSchema =
|
|
732
|
+
var HookDefinitionSchema = z2.discriminatedUnion("type", [
|
|
369
733
|
CommandHookDefinitionSchema,
|
|
370
734
|
HttpHookDefinitionSchema,
|
|
371
735
|
PromptHookDefinitionSchema,
|
|
372
736
|
AgentHookDefinitionSchema
|
|
373
737
|
]);
|
|
374
|
-
var HookGroupSchema =
|
|
375
|
-
matcher:
|
|
376
|
-
hooks:
|
|
738
|
+
var HookGroupSchema = z2.object({
|
|
739
|
+
matcher: z2.string(),
|
|
740
|
+
hooks: z2.array(HookDefinitionSchema)
|
|
377
741
|
});
|
|
378
|
-
var HooksSchema =
|
|
379
|
-
PreToolUse:
|
|
380
|
-
PostToolUse:
|
|
381
|
-
SessionStart:
|
|
382
|
-
Stop:
|
|
383
|
-
PreCompact:
|
|
384
|
-
PostCompact:
|
|
385
|
-
UserPromptSubmit:
|
|
386
|
-
Notification:
|
|
742
|
+
var HooksSchema = z2.object({
|
|
743
|
+
PreToolUse: z2.array(HookGroupSchema).optional(),
|
|
744
|
+
PostToolUse: z2.array(HookGroupSchema).optional(),
|
|
745
|
+
SessionStart: z2.array(HookGroupSchema).optional(),
|
|
746
|
+
Stop: z2.array(HookGroupSchema).optional(),
|
|
747
|
+
PreCompact: z2.array(HookGroupSchema).optional(),
|
|
748
|
+
PostCompact: z2.array(HookGroupSchema).optional(),
|
|
749
|
+
UserPromptSubmit: z2.array(HookGroupSchema).optional(),
|
|
750
|
+
Notification: z2.array(HookGroupSchema).optional()
|
|
387
751
|
}).optional();
|
|
388
|
-
var EnabledPluginsSchema =
|
|
389
|
-
var MarketplaceSourceSchema =
|
|
390
|
-
source:
|
|
391
|
-
type:
|
|
392
|
-
repo:
|
|
393
|
-
url:
|
|
394
|
-
path:
|
|
395
|
-
ref:
|
|
752
|
+
var EnabledPluginsSchema = z2.record(z2.boolean()).optional();
|
|
753
|
+
var MarketplaceSourceSchema = z2.object({
|
|
754
|
+
source: z2.object({
|
|
755
|
+
type: z2.enum(["github", "git", "local", "url"]),
|
|
756
|
+
repo: z2.string().optional(),
|
|
757
|
+
url: z2.string().optional(),
|
|
758
|
+
path: z2.string().optional(),
|
|
759
|
+
ref: z2.string().optional()
|
|
396
760
|
})
|
|
397
761
|
});
|
|
398
|
-
var ExtraKnownMarketplacesSchema =
|
|
399
|
-
var SettingsSchema =
|
|
762
|
+
var ExtraKnownMarketplacesSchema = z2.record(MarketplaceSourceSchema).optional();
|
|
763
|
+
var SettingsSchema = z2.object({
|
|
400
764
|
/** Trust level used when no --permission-mode flag is given */
|
|
401
|
-
defaultTrustLevel:
|
|
765
|
+
defaultTrustLevel: z2.enum(["safe", "moderate", "full"]).optional(),
|
|
402
766
|
/** Response language (e.g., "ko", "en", "ja"). Injected into system prompt. */
|
|
403
|
-
language:
|
|
767
|
+
language: z2.string().optional(),
|
|
404
768
|
provider: ProviderSchema.optional(),
|
|
405
769
|
permissions: PermissionsSchema.optional(),
|
|
406
770
|
env: EnvSchema,
|
|
@@ -429,10 +793,10 @@ var DEFAULTS = {
|
|
|
429
793
|
env: {}
|
|
430
794
|
};
|
|
431
795
|
function readJsonFile(filePath) {
|
|
432
|
-
if (!
|
|
796
|
+
if (!existsSync2(filePath)) {
|
|
433
797
|
return void 0;
|
|
434
798
|
}
|
|
435
|
-
const raw =
|
|
799
|
+
const raw = readFileSync2(filePath, "utf-8").trim();
|
|
436
800
|
if (raw.length === 0) {
|
|
437
801
|
return void 0;
|
|
438
802
|
}
|
|
@@ -503,15 +867,15 @@ function toResolvedConfig(merged) {
|
|
|
503
867
|
function getSettingsPaths(cwd) {
|
|
504
868
|
const home = getHomeDir();
|
|
505
869
|
return [
|
|
506
|
-
|
|
870
|
+
join3(home, ".robota", "settings.json"),
|
|
507
871
|
// 1. user (lowest)
|
|
508
|
-
|
|
872
|
+
join3(cwd, ".robota", "settings.json"),
|
|
509
873
|
// 2. project
|
|
510
|
-
|
|
874
|
+
join3(cwd, ".robota", "settings.local.json"),
|
|
511
875
|
// 3. project-local
|
|
512
|
-
|
|
876
|
+
join3(cwd, ".claude", "settings.json"),
|
|
513
877
|
// 4. project, Claude Code compat
|
|
514
|
-
|
|
878
|
+
join3(cwd, ".claude", "settings.local.json")
|
|
515
879
|
// 5. project-local (highest)
|
|
516
880
|
];
|
|
517
881
|
}
|
|
@@ -536,8 +900,8 @@ async function loadConfig(cwd) {
|
|
|
536
900
|
}
|
|
537
901
|
|
|
538
902
|
// src/context/context-loader.ts
|
|
539
|
-
import { existsSync as
|
|
540
|
-
import { join as
|
|
903
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
|
|
904
|
+
import { join as join4, dirname, resolve } from "path";
|
|
541
905
|
var AGENTS_FILENAME = "AGENTS.md";
|
|
542
906
|
var CLAUDE_FILENAME = "CLAUDE.md";
|
|
543
907
|
function collectFilesWalkingUp(startDir, filename) {
|
|
@@ -545,8 +909,8 @@ function collectFilesWalkingUp(startDir, filename) {
|
|
|
545
909
|
let current = resolve(startDir);
|
|
546
910
|
let atRoot = false;
|
|
547
911
|
while (!atRoot) {
|
|
548
|
-
const candidate =
|
|
549
|
-
if (
|
|
912
|
+
const candidate = join4(current, filename);
|
|
913
|
+
if (existsSync3(candidate)) {
|
|
550
914
|
found.push(candidate);
|
|
551
915
|
}
|
|
552
916
|
const parent = dirname(current);
|
|
@@ -584,47 +948,47 @@ function extractCompactInstructions(content) {
|
|
|
584
948
|
async function loadContext(cwd) {
|
|
585
949
|
const agentsPaths = collectFilesWalkingUp(cwd, AGENTS_FILENAME);
|
|
586
950
|
const claudePaths = collectFilesWalkingUp(cwd, CLAUDE_FILENAME);
|
|
587
|
-
const agentsMd = agentsPaths.map((p) =>
|
|
588
|
-
const claudeMd = claudePaths.map((p) =>
|
|
951
|
+
const agentsMd = agentsPaths.map((p) => readFileSync3(p, "utf-8")).join("\n\n");
|
|
952
|
+
const claudeMd = claudePaths.map((p) => readFileSync3(p, "utf-8")).join("\n\n");
|
|
589
953
|
const compactInstructions = extractCompactInstructions(claudeMd);
|
|
590
954
|
return { agentsMd, claudeMd, compactInstructions };
|
|
591
955
|
}
|
|
592
956
|
|
|
593
957
|
// src/context/project-detector.ts
|
|
594
|
-
import { existsSync as
|
|
595
|
-
import { join as
|
|
958
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
|
|
959
|
+
import { join as join5 } from "path";
|
|
596
960
|
function tryReadJson(filePath) {
|
|
597
|
-
if (!
|
|
961
|
+
if (!existsSync4(filePath)) return void 0;
|
|
598
962
|
try {
|
|
599
|
-
return JSON.parse(
|
|
963
|
+
return JSON.parse(readFileSync4(filePath, "utf-8"));
|
|
600
964
|
} catch {
|
|
601
965
|
return void 0;
|
|
602
966
|
}
|
|
603
967
|
}
|
|
604
968
|
function detectPackageManager(cwd) {
|
|
605
|
-
if (
|
|
969
|
+
if (existsSync4(join5(cwd, "pnpm-workspace.yaml")) || existsSync4(join5(cwd, "pnpm-lock.yaml"))) {
|
|
606
970
|
return "pnpm";
|
|
607
971
|
}
|
|
608
|
-
if (
|
|
972
|
+
if (existsSync4(join5(cwd, "yarn.lock"))) {
|
|
609
973
|
return "yarn";
|
|
610
974
|
}
|
|
611
|
-
if (
|
|
975
|
+
if (existsSync4(join5(cwd, "bun.lockb"))) {
|
|
612
976
|
return "bun";
|
|
613
977
|
}
|
|
614
|
-
if (
|
|
978
|
+
if (existsSync4(join5(cwd, "package-lock.json"))) {
|
|
615
979
|
return "npm";
|
|
616
980
|
}
|
|
617
981
|
return void 0;
|
|
618
982
|
}
|
|
619
983
|
async function detectProject(cwd) {
|
|
620
|
-
const pkgJsonPath =
|
|
621
|
-
const tsconfigPath =
|
|
622
|
-
const pyprojectPath =
|
|
623
|
-
const cargoPath =
|
|
624
|
-
const goModPath =
|
|
625
|
-
if (
|
|
984
|
+
const pkgJsonPath = join5(cwd, "package.json");
|
|
985
|
+
const tsconfigPath = join5(cwd, "tsconfig.json");
|
|
986
|
+
const pyprojectPath = join5(cwd, "pyproject.toml");
|
|
987
|
+
const cargoPath = join5(cwd, "Cargo.toml");
|
|
988
|
+
const goModPath = join5(cwd, "go.mod");
|
|
989
|
+
if (existsSync4(pkgJsonPath)) {
|
|
626
990
|
const pkgJson = tryReadJson(pkgJsonPath);
|
|
627
|
-
const language =
|
|
991
|
+
const language = existsSync4(tsconfigPath) ? "typescript" : "javascript";
|
|
628
992
|
const packageManager = detectPackageManager(cwd);
|
|
629
993
|
return {
|
|
630
994
|
type: "node",
|
|
@@ -633,19 +997,19 @@ async function detectProject(cwd) {
|
|
|
633
997
|
language
|
|
634
998
|
};
|
|
635
999
|
}
|
|
636
|
-
if (
|
|
1000
|
+
if (existsSync4(pyprojectPath) || existsSync4(join5(cwd, "setup.py"))) {
|
|
637
1001
|
return {
|
|
638
1002
|
type: "python",
|
|
639
1003
|
language: "python"
|
|
640
1004
|
};
|
|
641
1005
|
}
|
|
642
|
-
if (
|
|
1006
|
+
if (existsSync4(cargoPath)) {
|
|
643
1007
|
return {
|
|
644
1008
|
type: "rust",
|
|
645
1009
|
language: "rust"
|
|
646
1010
|
};
|
|
647
1011
|
}
|
|
648
|
-
if (
|
|
1012
|
+
if (existsSync4(goModPath)) {
|
|
649
1013
|
return {
|
|
650
1014
|
type: "go",
|
|
651
1015
|
language: "go"
|
|
@@ -722,27 +1086,27 @@ import { evaluatePermission } from "@robota-sdk/agent-core";
|
|
|
722
1086
|
import { runHooks } from "@robota-sdk/agent-core";
|
|
723
1087
|
|
|
724
1088
|
// src/paths.ts
|
|
725
|
-
import { join as
|
|
726
|
-
import { homedir } from "os";
|
|
1089
|
+
import { join as join6 } from "path";
|
|
1090
|
+
import { homedir as homedir2 } from "os";
|
|
727
1091
|
function projectPaths(cwd) {
|
|
728
|
-
const base =
|
|
1092
|
+
const base = join6(cwd, ".robota");
|
|
729
1093
|
return {
|
|
730
|
-
settings:
|
|
731
|
-
settingsLocal:
|
|
732
|
-
logs:
|
|
733
|
-
sessions:
|
|
1094
|
+
settings: join6(base, "settings.json"),
|
|
1095
|
+
settingsLocal: join6(base, "settings.local.json"),
|
|
1096
|
+
logs: join6(base, "logs"),
|
|
1097
|
+
sessions: join6(base, "sessions")
|
|
734
1098
|
};
|
|
735
1099
|
}
|
|
736
1100
|
function userPaths() {
|
|
737
|
-
const base =
|
|
1101
|
+
const base = join6(homedir2(), ".robota");
|
|
738
1102
|
return {
|
|
739
|
-
settings:
|
|
740
|
-
sessions:
|
|
1103
|
+
settings: join6(base, "settings.json"),
|
|
1104
|
+
sessions: join6(base, "sessions")
|
|
741
1105
|
};
|
|
742
1106
|
}
|
|
743
1107
|
|
|
744
1108
|
// src/plugins/plugin-settings-store.ts
|
|
745
|
-
import { existsSync as
|
|
1109
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5, writeFileSync, mkdirSync as mkdirSync2 } from "fs";
|
|
746
1110
|
import { dirname as dirname2 } from "path";
|
|
747
1111
|
var PluginSettingsStore = class {
|
|
748
1112
|
settingsPath;
|
|
@@ -751,11 +1115,11 @@ var PluginSettingsStore = class {
|
|
|
751
1115
|
}
|
|
752
1116
|
/** Read the full settings file from disk. */
|
|
753
1117
|
readAll() {
|
|
754
|
-
if (!
|
|
1118
|
+
if (!existsSync5(this.settingsPath)) {
|
|
755
1119
|
return {};
|
|
756
1120
|
}
|
|
757
1121
|
try {
|
|
758
|
-
const raw =
|
|
1122
|
+
const raw = readFileSync5(this.settingsPath, "utf-8");
|
|
759
1123
|
const data = JSON.parse(raw);
|
|
760
1124
|
if (typeof data === "object" && data !== null) {
|
|
761
1125
|
return data;
|
|
@@ -768,8 +1132,8 @@ var PluginSettingsStore = class {
|
|
|
768
1132
|
/** Write the full settings file to disk. */
|
|
769
1133
|
writeAll(settings) {
|
|
770
1134
|
const dir = dirname2(this.settingsPath);
|
|
771
|
-
if (!
|
|
772
|
-
|
|
1135
|
+
if (!existsSync5(dir)) {
|
|
1136
|
+
mkdirSync2(dir, { recursive: true });
|
|
773
1137
|
}
|
|
774
1138
|
writeFileSync(this.settingsPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
775
1139
|
}
|
|
@@ -843,8 +1207,8 @@ var PluginSettingsStore = class {
|
|
|
843
1207
|
};
|
|
844
1208
|
|
|
845
1209
|
// src/plugins/bundle-plugin-loader.ts
|
|
846
|
-
import { existsSync as
|
|
847
|
-
import { join as
|
|
1210
|
+
import { existsSync as existsSync6, readdirSync as readdirSync2, readFileSync as readFileSync6 } from "fs";
|
|
1211
|
+
import { join as join7 } from "path";
|
|
848
1212
|
function parseSkillFrontmatter(raw) {
|
|
849
1213
|
const trimmed = raw.trimStart();
|
|
850
1214
|
if (!trimmed.startsWith("---")) {
|
|
@@ -893,9 +1257,9 @@ function validateManifest(data) {
|
|
|
893
1257
|
};
|
|
894
1258
|
}
|
|
895
1259
|
function getSortedSubdirs(dirPath) {
|
|
896
|
-
if (!
|
|
1260
|
+
if (!existsSync6(dirPath)) return [];
|
|
897
1261
|
try {
|
|
898
|
-
const entries =
|
|
1262
|
+
const entries = readdirSync2(dirPath, { withFileTypes: true });
|
|
899
1263
|
return entries.filter((e) => e.isDirectory()).map((e) => e.name).sort();
|
|
900
1264
|
} catch {
|
|
901
1265
|
return [];
|
|
@@ -923,23 +1287,23 @@ var BundlePluginLoader = class {
|
|
|
923
1287
|
* For each marketplace/plugin pair, the latest version (lexicographically last) is loaded.
|
|
924
1288
|
*/
|
|
925
1289
|
discoverAndLoad() {
|
|
926
|
-
const cacheDir =
|
|
927
|
-
if (!
|
|
1290
|
+
const cacheDir = join7(this.pluginsDir, "cache");
|
|
1291
|
+
if (!existsSync6(cacheDir)) {
|
|
928
1292
|
return [];
|
|
929
1293
|
}
|
|
930
1294
|
const results = [];
|
|
931
1295
|
const marketplaces = getSortedSubdirs(cacheDir);
|
|
932
1296
|
for (const marketplace of marketplaces) {
|
|
933
|
-
const marketplaceDir =
|
|
1297
|
+
const marketplaceDir = join7(cacheDir, marketplace);
|
|
934
1298
|
const plugins = getSortedSubdirs(marketplaceDir);
|
|
935
1299
|
for (const pluginName of plugins) {
|
|
936
|
-
const pluginDir =
|
|
1300
|
+
const pluginDir = join7(marketplaceDir, pluginName);
|
|
937
1301
|
const versions = getSortedSubdirs(pluginDir);
|
|
938
1302
|
if (versions.length === 0) continue;
|
|
939
1303
|
const latestVersion = versions[versions.length - 1];
|
|
940
|
-
const versionDir =
|
|
941
|
-
const manifestPath =
|
|
942
|
-
if (!
|
|
1304
|
+
const versionDir = join7(pluginDir, latestVersion);
|
|
1305
|
+
const manifestPath = join7(versionDir, ".claude-plugin", "plugin.json");
|
|
1306
|
+
if (!existsSync6(manifestPath)) continue;
|
|
943
1307
|
const manifest = this.readManifest(manifestPath);
|
|
944
1308
|
if (!manifest) continue;
|
|
945
1309
|
const pluginId = `${manifest.name}@${marketplace}`;
|
|
@@ -953,7 +1317,7 @@ var BundlePluginLoader = class {
|
|
|
953
1317
|
/** Read and validate a plugin.json manifest. Returns null on failure. */
|
|
954
1318
|
readManifest(path) {
|
|
955
1319
|
try {
|
|
956
|
-
const raw =
|
|
1320
|
+
const raw = readFileSync6(path, "utf-8");
|
|
957
1321
|
const data = JSON.parse(raw);
|
|
958
1322
|
return validateManifest(data);
|
|
959
1323
|
} catch {
|
|
@@ -988,15 +1352,15 @@ var BundlePluginLoader = class {
|
|
|
988
1352
|
}
|
|
989
1353
|
/** Load skills from the plugin's skills/ directory. */
|
|
990
1354
|
loadSkills(pluginDir, pluginName) {
|
|
991
|
-
const skillsDir =
|
|
992
|
-
if (!
|
|
993
|
-
const entries =
|
|
1355
|
+
const skillsDir = join7(pluginDir, "skills");
|
|
1356
|
+
if (!existsSync6(skillsDir)) return [];
|
|
1357
|
+
const entries = readdirSync2(skillsDir, { withFileTypes: true });
|
|
994
1358
|
const skills = [];
|
|
995
1359
|
for (const entry of entries) {
|
|
996
1360
|
if (!entry.isDirectory()) continue;
|
|
997
|
-
const skillFile =
|
|
998
|
-
if (!
|
|
999
|
-
const raw =
|
|
1361
|
+
const skillFile = join7(skillsDir, entry.name, "SKILL.md");
|
|
1362
|
+
if (!existsSync6(skillFile)) continue;
|
|
1363
|
+
const raw = readFileSync6(skillFile, "utf-8");
|
|
1000
1364
|
const { metadata, content } = parseSkillFrontmatter(raw);
|
|
1001
1365
|
const description = typeof metadata.description === "string" ? metadata.description : "";
|
|
1002
1366
|
const skill = {
|
|
@@ -1011,13 +1375,13 @@ var BundlePluginLoader = class {
|
|
|
1011
1375
|
}
|
|
1012
1376
|
/** Load commands from the plugin's commands/ directory (flat .md files). */
|
|
1013
1377
|
loadCommands(pluginDir, pluginName) {
|
|
1014
|
-
const commandsDir =
|
|
1015
|
-
if (!
|
|
1016
|
-
const entries =
|
|
1378
|
+
const commandsDir = join7(pluginDir, "commands");
|
|
1379
|
+
if (!existsSync6(commandsDir)) return [];
|
|
1380
|
+
const entries = readdirSync2(commandsDir, { withFileTypes: true });
|
|
1017
1381
|
const commands = [];
|
|
1018
1382
|
for (const entry of entries) {
|
|
1019
1383
|
if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
|
|
1020
|
-
const raw =
|
|
1384
|
+
const raw = readFileSync6(join7(commandsDir, entry.name), "utf-8");
|
|
1021
1385
|
const { metadata, content } = parseSkillFrontmatter(raw);
|
|
1022
1386
|
const name = typeof metadata.name === "string" ? metadata.name : entry.name.replace(/\.md$/, "");
|
|
1023
1387
|
const description = typeof metadata.description === "string" ? metadata.description : "";
|
|
@@ -1032,10 +1396,10 @@ var BundlePluginLoader = class {
|
|
|
1032
1396
|
}
|
|
1033
1397
|
/** Load hooks from hooks/hooks.json if present. */
|
|
1034
1398
|
loadHooks(pluginDir) {
|
|
1035
|
-
const hooksPath =
|
|
1036
|
-
if (!
|
|
1399
|
+
const hooksPath = join7(pluginDir, "hooks", "hooks.json");
|
|
1400
|
+
if (!existsSync6(hooksPath)) return {};
|
|
1037
1401
|
try {
|
|
1038
|
-
const raw =
|
|
1402
|
+
const raw = readFileSync6(hooksPath, "utf-8");
|
|
1039
1403
|
const data = JSON.parse(raw);
|
|
1040
1404
|
if (typeof data === "object" && data !== null) {
|
|
1041
1405
|
return data;
|
|
@@ -1047,12 +1411,12 @@ var BundlePluginLoader = class {
|
|
|
1047
1411
|
}
|
|
1048
1412
|
/** Load MCP server configuration if present. Checks `.mcp.json` at plugin root first. */
|
|
1049
1413
|
loadMcpConfig(pluginDir) {
|
|
1050
|
-
const primaryPath =
|
|
1051
|
-
const fallbackPath =
|
|
1052
|
-
const mcpPath =
|
|
1053
|
-
if (!
|
|
1414
|
+
const primaryPath = join7(pluginDir, ".mcp.json");
|
|
1415
|
+
const fallbackPath = join7(pluginDir, ".claude-plugin", "mcp.json");
|
|
1416
|
+
const mcpPath = existsSync6(primaryPath) ? primaryPath : fallbackPath;
|
|
1417
|
+
if (!existsSync6(mcpPath)) return void 0;
|
|
1054
1418
|
try {
|
|
1055
|
-
const raw =
|
|
1419
|
+
const raw = readFileSync6(mcpPath, "utf-8");
|
|
1056
1420
|
return JSON.parse(raw);
|
|
1057
1421
|
} catch {
|
|
1058
1422
|
return void 0;
|
|
@@ -1060,10 +1424,10 @@ var BundlePluginLoader = class {
|
|
|
1060
1424
|
}
|
|
1061
1425
|
/** Load agent definitions from agents/ directory if present. */
|
|
1062
1426
|
loadAgents(pluginDir) {
|
|
1063
|
-
const agentsDir =
|
|
1064
|
-
if (!
|
|
1427
|
+
const agentsDir = join7(pluginDir, "agents");
|
|
1428
|
+
if (!existsSync6(agentsDir)) return [];
|
|
1065
1429
|
try {
|
|
1066
|
-
const entries =
|
|
1430
|
+
const entries = readdirSync2(agentsDir, { withFileTypes: true });
|
|
1067
1431
|
return entries.filter((e) => e.isDirectory() || e.name.endsWith(".md")).map((e) => e.name.replace(/\.md$/, ""));
|
|
1068
1432
|
} catch {
|
|
1069
1433
|
return [];
|
|
@@ -1073,8 +1437,8 @@ var BundlePluginLoader = class {
|
|
|
1073
1437
|
|
|
1074
1438
|
// src/plugins/bundle-plugin-installer.ts
|
|
1075
1439
|
import { execSync } from "child_process";
|
|
1076
|
-
import { cpSync, existsSync as
|
|
1077
|
-
import { join as
|
|
1440
|
+
import { cpSync, existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync7, rmSync, writeFileSync as writeFileSync2 } from "fs";
|
|
1441
|
+
import { join as join8, dirname as dirname3 } from "path";
|
|
1078
1442
|
var GIT_CLONE_TIMEOUT_MS = 6e4;
|
|
1079
1443
|
var BundlePluginInstaller = class {
|
|
1080
1444
|
pluginsDir;
|
|
@@ -1085,8 +1449,8 @@ var BundlePluginInstaller = class {
|
|
|
1085
1449
|
exec;
|
|
1086
1450
|
constructor(options) {
|
|
1087
1451
|
this.pluginsDir = options.pluginsDir;
|
|
1088
|
-
this.cacheDir =
|
|
1089
|
-
this.registryPath =
|
|
1452
|
+
this.cacheDir = join8(this.pluginsDir, "cache");
|
|
1453
|
+
this.registryPath = join8(this.pluginsDir, "installed_plugins.json");
|
|
1090
1454
|
this.settingsStore = options.settingsStore;
|
|
1091
1455
|
this.marketplaceClient = options.marketplaceClient;
|
|
1092
1456
|
this.exec = options.exec ?? this.defaultExec;
|
|
@@ -1106,8 +1470,8 @@ var BundlePluginInstaller = class {
|
|
|
1106
1470
|
throw new Error(`Plugin "${pluginName}" not found in marketplace "${marketplaceName}"`);
|
|
1107
1471
|
}
|
|
1108
1472
|
const version = this.resolveVersion(entry, marketplaceName);
|
|
1109
|
-
const targetDir =
|
|
1110
|
-
if (
|
|
1473
|
+
const targetDir = join8(this.cacheDir, marketplaceName, pluginName, version);
|
|
1474
|
+
if (existsSync7(targetDir)) {
|
|
1111
1475
|
throw new Error(
|
|
1112
1476
|
`Plugin "${pluginName}" version "${version}" is already installed from "${marketplaceName}"`
|
|
1113
1477
|
);
|
|
@@ -1134,7 +1498,7 @@ var BundlePluginInstaller = class {
|
|
|
1134
1498
|
if (!record) {
|
|
1135
1499
|
throw new Error(`Plugin "${pluginId}" is not installed`);
|
|
1136
1500
|
}
|
|
1137
|
-
if (
|
|
1501
|
+
if (existsSync7(record.installPath)) {
|
|
1138
1502
|
rmSync(record.installPath, { recursive: true, force: true });
|
|
1139
1503
|
}
|
|
1140
1504
|
delete registry[pluginId];
|
|
@@ -1181,13 +1545,13 @@ var BundlePluginInstaller = class {
|
|
|
1181
1545
|
}
|
|
1182
1546
|
/** Resolve the source and install the plugin. */
|
|
1183
1547
|
resolveAndInstall(rawSource, marketplaceName, pluginName, targetDir) {
|
|
1184
|
-
|
|
1548
|
+
mkdirSync3(targetDir, { recursive: true });
|
|
1185
1549
|
const source = this.normalizeSource(rawSource);
|
|
1186
1550
|
try {
|
|
1187
1551
|
if (typeof source === "string") {
|
|
1188
1552
|
const marketplaceDir = this.marketplaceClient.getMarketplaceDir(marketplaceName);
|
|
1189
|
-
const sourcePath =
|
|
1190
|
-
if (!
|
|
1553
|
+
const sourcePath = join8(marketplaceDir, source);
|
|
1554
|
+
if (!existsSync7(sourcePath)) {
|
|
1191
1555
|
throw new Error(
|
|
1192
1556
|
`Plugin source path "${source}" not found in marketplace "${marketplaceName}"`
|
|
1193
1557
|
);
|
|
@@ -1204,7 +1568,7 @@ var BundlePluginInstaller = class {
|
|
|
1204
1568
|
throw new Error(`Unknown source type: ${JSON.stringify(source)}`);
|
|
1205
1569
|
}
|
|
1206
1570
|
} catch (err) {
|
|
1207
|
-
if (
|
|
1571
|
+
if (existsSync7(targetDir)) {
|
|
1208
1572
|
rmSync(targetDir, { recursive: true, force: true });
|
|
1209
1573
|
}
|
|
1210
1574
|
throw err;
|
|
@@ -1223,11 +1587,11 @@ var BundlePluginInstaller = class {
|
|
|
1223
1587
|
}
|
|
1224
1588
|
/** Read the installed_plugins.json registry. */
|
|
1225
1589
|
readRegistry() {
|
|
1226
|
-
if (!
|
|
1590
|
+
if (!existsSync7(this.registryPath)) {
|
|
1227
1591
|
return {};
|
|
1228
1592
|
}
|
|
1229
1593
|
try {
|
|
1230
|
-
const raw =
|
|
1594
|
+
const raw = readFileSync7(this.registryPath, "utf-8");
|
|
1231
1595
|
const data = JSON.parse(raw);
|
|
1232
1596
|
if (typeof data === "object" && data !== null) {
|
|
1233
1597
|
return data;
|
|
@@ -1240,8 +1604,8 @@ var BundlePluginInstaller = class {
|
|
|
1240
1604
|
/** Write the installed_plugins.json registry. */
|
|
1241
1605
|
writeRegistry(registry) {
|
|
1242
1606
|
const dir = dirname3(this.registryPath);
|
|
1243
|
-
if (!
|
|
1244
|
-
|
|
1607
|
+
if (!existsSync7(dir)) {
|
|
1608
|
+
mkdirSync3(dir, { recursive: true });
|
|
1245
1609
|
}
|
|
1246
1610
|
writeFileSync2(this.registryPath, JSON.stringify(registry, null, 2), "utf-8");
|
|
1247
1611
|
}
|
|
@@ -1255,14 +1619,14 @@ var BundlePluginInstaller = class {
|
|
|
1255
1619
|
import { execSync as execSync2 } from "child_process";
|
|
1256
1620
|
import {
|
|
1257
1621
|
cpSync as cpSync2,
|
|
1258
|
-
existsSync as
|
|
1259
|
-
mkdirSync as
|
|
1260
|
-
readFileSync as
|
|
1622
|
+
existsSync as existsSync8,
|
|
1623
|
+
mkdirSync as mkdirSync4,
|
|
1624
|
+
readFileSync as readFileSync8,
|
|
1261
1625
|
renameSync,
|
|
1262
1626
|
rmSync as rmSync2,
|
|
1263
1627
|
writeFileSync as writeFileSync3
|
|
1264
1628
|
} from "fs";
|
|
1265
|
-
import { join as
|
|
1629
|
+
import { join as join9, dirname as dirname4 } from "path";
|
|
1266
1630
|
var GIT_TIMEOUT_MS = 6e4;
|
|
1267
1631
|
var MarketplaceClient = class {
|
|
1268
1632
|
pluginsDir;
|
|
@@ -1272,8 +1636,8 @@ var MarketplaceClient = class {
|
|
|
1272
1636
|
constructor(options) {
|
|
1273
1637
|
this.pluginsDir = options.pluginsDir;
|
|
1274
1638
|
this.exec = options.exec ?? this.defaultExec;
|
|
1275
|
-
this.marketplacesDir =
|
|
1276
|
-
this.registryPath =
|
|
1639
|
+
this.marketplacesDir = join9(this.pluginsDir, "marketplaces");
|
|
1640
|
+
this.registryPath = join9(this.pluginsDir, "known_marketplaces.json");
|
|
1277
1641
|
}
|
|
1278
1642
|
/**
|
|
1279
1643
|
* Add a marketplace by cloning its repository.
|
|
@@ -1287,10 +1651,10 @@ var MarketplaceClient = class {
|
|
|
1287
1651
|
*/
|
|
1288
1652
|
addMarketplace(source) {
|
|
1289
1653
|
const tempName = "temp-" + Date.now().toString(36);
|
|
1290
|
-
const tempDir =
|
|
1291
|
-
|
|
1654
|
+
const tempDir = join9(this.marketplacesDir, tempName);
|
|
1655
|
+
mkdirSync4(this.marketplacesDir, { recursive: true });
|
|
1292
1656
|
if (source.type === "local") {
|
|
1293
|
-
if (!
|
|
1657
|
+
if (!existsSync8(source.path)) {
|
|
1294
1658
|
throw new Error(`Local marketplace path does not exist: ${source.path}`);
|
|
1295
1659
|
}
|
|
1296
1660
|
cpSync2(source.path, tempDir, { recursive: true });
|
|
@@ -1304,8 +1668,8 @@ var MarketplaceClient = class {
|
|
|
1304
1668
|
throw new Error(`Failed to clone marketplace: ${message}`);
|
|
1305
1669
|
}
|
|
1306
1670
|
}
|
|
1307
|
-
const manifestPath =
|
|
1308
|
-
if (!
|
|
1671
|
+
const manifestPath = join9(tempDir, ".claude-plugin", "marketplace.json");
|
|
1672
|
+
if (!existsSync8(manifestPath)) {
|
|
1309
1673
|
rmSync2(tempDir, { recursive: true, force: true });
|
|
1310
1674
|
throw new Error(
|
|
1311
1675
|
source.type === "local" ? "Local directory does not contain .claude-plugin/marketplace.json" : "Cloned repository does not contain .claude-plugin/marketplace.json"
|
|
@@ -1322,7 +1686,7 @@ var MarketplaceClient = class {
|
|
|
1322
1686
|
rmSync2(tempDir, { recursive: true, force: true });
|
|
1323
1687
|
throw new Error(`Marketplace "${name}" already exists`);
|
|
1324
1688
|
}
|
|
1325
|
-
const finalDir =
|
|
1689
|
+
const finalDir = join9(this.marketplacesDir, name);
|
|
1326
1690
|
renameSync(tempDir, finalDir);
|
|
1327
1691
|
registry[name] = {
|
|
1328
1692
|
source,
|
|
@@ -1344,7 +1708,7 @@ var MarketplaceClient = class {
|
|
|
1344
1708
|
throw new Error(`Marketplace "${name}" not found`);
|
|
1345
1709
|
}
|
|
1346
1710
|
this.removeInstalledPluginsForMarketplace(name);
|
|
1347
|
-
if (
|
|
1711
|
+
if (existsSync8(entry.installLocation)) {
|
|
1348
1712
|
rmSync2(entry.installLocation, { recursive: true, force: true });
|
|
1349
1713
|
}
|
|
1350
1714
|
delete registry[name];
|
|
@@ -1364,12 +1728,12 @@ var MarketplaceClient = class {
|
|
|
1364
1728
|
if (!entry) {
|
|
1365
1729
|
throw new Error(`Marketplace "${name}" not found`);
|
|
1366
1730
|
}
|
|
1367
|
-
if (!
|
|
1731
|
+
if (!existsSync8(entry.installLocation)) {
|
|
1368
1732
|
throw new Error(`Marketplace directory for "${name}" does not exist`);
|
|
1369
1733
|
}
|
|
1370
1734
|
if (entry.source.type === "local") {
|
|
1371
1735
|
const localSource = entry.source;
|
|
1372
|
-
if (!
|
|
1736
|
+
if (!existsSync8(localSource.path)) {
|
|
1373
1737
|
throw new Error(`Local marketplace path does not exist: ${localSource.path}`);
|
|
1374
1738
|
}
|
|
1375
1739
|
rmSync2(entry.installLocation, { recursive: true, force: true });
|
|
@@ -1404,8 +1768,8 @@ var MarketplaceClient = class {
|
|
|
1404
1768
|
if (!entry) {
|
|
1405
1769
|
throw new Error(`Marketplace "${marketplaceName}" not found`);
|
|
1406
1770
|
}
|
|
1407
|
-
const manifestPath =
|
|
1408
|
-
if (!
|
|
1771
|
+
const manifestPath = join9(entry.installLocation, ".claude-plugin", "marketplace.json");
|
|
1772
|
+
if (!existsSync8(manifestPath)) {
|
|
1409
1773
|
throw new Error(
|
|
1410
1774
|
`Marketplace "${marketplaceName}" does not contain .claude-plugin/marketplace.json`
|
|
1411
1775
|
);
|
|
@@ -1472,11 +1836,11 @@ var MarketplaceClient = class {
|
|
|
1472
1836
|
* and updates the registry.
|
|
1473
1837
|
*/
|
|
1474
1838
|
removeInstalledPluginsForMarketplace(marketplaceName) {
|
|
1475
|
-
const installedPath =
|
|
1476
|
-
if (!
|
|
1839
|
+
const installedPath = join9(this.pluginsDir, "installed_plugins.json");
|
|
1840
|
+
if (!existsSync8(installedPath)) return;
|
|
1477
1841
|
let registry;
|
|
1478
1842
|
try {
|
|
1479
|
-
const raw =
|
|
1843
|
+
const raw = readFileSync8(installedPath, "utf-8");
|
|
1480
1844
|
const data = JSON.parse(raw);
|
|
1481
1845
|
if (typeof data !== "object" || data === null) return;
|
|
1482
1846
|
registry = data;
|
|
@@ -1486,7 +1850,7 @@ var MarketplaceClient = class {
|
|
|
1486
1850
|
let changed = false;
|
|
1487
1851
|
for (const [pluginId, record] of Object.entries(registry)) {
|
|
1488
1852
|
if (record.marketplace === marketplaceName) {
|
|
1489
|
-
if (record.installPath &&
|
|
1853
|
+
if (record.installPath && existsSync8(record.installPath)) {
|
|
1490
1854
|
rmSync2(record.installPath, { recursive: true, force: true });
|
|
1491
1855
|
}
|
|
1492
1856
|
delete registry[pluginId];
|
|
@@ -1495,15 +1859,15 @@ var MarketplaceClient = class {
|
|
|
1495
1859
|
}
|
|
1496
1860
|
if (changed) {
|
|
1497
1861
|
const dir = dirname4(installedPath);
|
|
1498
|
-
if (!
|
|
1499
|
-
|
|
1862
|
+
if (!existsSync8(dir)) {
|
|
1863
|
+
mkdirSync4(dir, { recursive: true });
|
|
1500
1864
|
}
|
|
1501
1865
|
writeFileSync3(installedPath, JSON.stringify(registry, null, 2), "utf-8");
|
|
1502
1866
|
}
|
|
1503
1867
|
}
|
|
1504
1868
|
/** Read and parse a marketplace.json from a file path. */
|
|
1505
1869
|
readManifestFromPath(path) {
|
|
1506
|
-
const raw =
|
|
1870
|
+
const raw = readFileSync8(path, "utf-8");
|
|
1507
1871
|
const data = JSON.parse(raw);
|
|
1508
1872
|
if (typeof data !== "object" || data === null) {
|
|
1509
1873
|
throw new Error("Invalid marketplace manifest: not an object");
|
|
@@ -1516,11 +1880,11 @@ var MarketplaceClient = class {
|
|
|
1516
1880
|
}
|
|
1517
1881
|
/** Read the known_marketplaces.json registry. */
|
|
1518
1882
|
readRegistry() {
|
|
1519
|
-
if (!
|
|
1883
|
+
if (!existsSync8(this.registryPath)) {
|
|
1520
1884
|
return {};
|
|
1521
1885
|
}
|
|
1522
1886
|
try {
|
|
1523
|
-
const raw =
|
|
1887
|
+
const raw = readFileSync8(this.registryPath, "utf-8");
|
|
1524
1888
|
const data = JSON.parse(raw);
|
|
1525
1889
|
if (typeof data === "object" && data !== null) {
|
|
1526
1890
|
return data;
|
|
@@ -1533,8 +1897,8 @@ var MarketplaceClient = class {
|
|
|
1533
1897
|
/** Write the known_marketplaces.json registry. */
|
|
1534
1898
|
writeRegistry(registry) {
|
|
1535
1899
|
const dir = dirname4(this.registryPath);
|
|
1536
|
-
if (!
|
|
1537
|
-
|
|
1900
|
+
if (!existsSync8(dir)) {
|
|
1901
|
+
mkdirSync4(dir, { recursive: true });
|
|
1538
1902
|
}
|
|
1539
1903
|
writeFileSync3(this.registryPath, JSON.stringify(registry, null, 2), "utf-8");
|
|
1540
1904
|
}
|
|
@@ -1544,78 +1908,6 @@ var MarketplaceClient = class {
|
|
|
1544
1908
|
}
|
|
1545
1909
|
};
|
|
1546
1910
|
|
|
1547
|
-
// src/tools/agent-tool.ts
|
|
1548
|
-
import { z as z2 } from "zod";
|
|
1549
|
-
import { createZodFunctionTool } from "@robota-sdk/agent-tools";
|
|
1550
|
-
function asZodSchema(schema) {
|
|
1551
|
-
return schema;
|
|
1552
|
-
}
|
|
1553
|
-
var AgentSchema = z2.object({
|
|
1554
|
-
prompt: z2.string().describe("Task description for the sub-agent"),
|
|
1555
|
-
description: z2.string().optional().describe("Short description of what the sub-agent will do (3-5 words)")
|
|
1556
|
-
});
|
|
1557
|
-
var agentToolDeps;
|
|
1558
|
-
function setAgentToolDeps(deps) {
|
|
1559
|
-
agentToolDeps = deps;
|
|
1560
|
-
}
|
|
1561
|
-
async function runAgent(args) {
|
|
1562
|
-
if (!agentToolDeps) {
|
|
1563
|
-
const result = {
|
|
1564
|
-
success: false,
|
|
1565
|
-
output: "",
|
|
1566
|
-
error: "Agent tool not initialized \u2014 missing dependencies"
|
|
1567
|
-
};
|
|
1568
|
-
return JSON.stringify(result);
|
|
1569
|
-
}
|
|
1570
|
-
const noopTerminal = {
|
|
1571
|
-
write: () => {
|
|
1572
|
-
},
|
|
1573
|
-
writeLine: () => {
|
|
1574
|
-
},
|
|
1575
|
-
writeMarkdown: () => {
|
|
1576
|
-
},
|
|
1577
|
-
writeError: () => {
|
|
1578
|
-
},
|
|
1579
|
-
prompt: () => Promise.resolve(""),
|
|
1580
|
-
select: () => Promise.resolve(0),
|
|
1581
|
-
spinner: () => ({ stop: () => {
|
|
1582
|
-
}, update: () => {
|
|
1583
|
-
} })
|
|
1584
|
-
};
|
|
1585
|
-
const subSession = createSession({
|
|
1586
|
-
config: agentToolDeps.config,
|
|
1587
|
-
context: agentToolDeps.context,
|
|
1588
|
-
projectInfo: agentToolDeps.projectInfo,
|
|
1589
|
-
terminal: noopTerminal,
|
|
1590
|
-
// Sub-agents bypass permissions — they inherit parent's trust
|
|
1591
|
-
permissionMode: "bypassPermissions"
|
|
1592
|
-
});
|
|
1593
|
-
try {
|
|
1594
|
-
const response = await subSession.run(args.prompt);
|
|
1595
|
-
const result = {
|
|
1596
|
-
success: true,
|
|
1597
|
-
output: response
|
|
1598
|
-
};
|
|
1599
|
-
return JSON.stringify(result);
|
|
1600
|
-
} catch (err) {
|
|
1601
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
1602
|
-
const result = {
|
|
1603
|
-
success: false,
|
|
1604
|
-
output: "",
|
|
1605
|
-
error: `Sub-agent error: ${message}`
|
|
1606
|
-
};
|
|
1607
|
-
return JSON.stringify(result);
|
|
1608
|
-
}
|
|
1609
|
-
}
|
|
1610
|
-
var agentTool = createZodFunctionTool(
|
|
1611
|
-
"Agent",
|
|
1612
|
-
"Spawn a sub-agent with isolated context to handle a task. The sub-agent has its own conversation history and can use all tools.",
|
|
1613
|
-
asZodSchema(AgentSchema),
|
|
1614
|
-
async (params) => {
|
|
1615
|
-
return runAgent(params);
|
|
1616
|
-
}
|
|
1617
|
-
);
|
|
1618
|
-
|
|
1619
1911
|
// src/index.ts
|
|
1620
1912
|
import { bashTool as bashTool2 } from "@robota-sdk/agent-tools";
|
|
1621
1913
|
import { readTool as readTool2 } from "@robota-sdk/agent-tools";
|
|
@@ -1625,26 +1917,33 @@ import { globTool as globTool2 } from "@robota-sdk/agent-tools";
|
|
|
1625
1917
|
import { grepTool as grepTool2 } from "@robota-sdk/agent-tools";
|
|
1626
1918
|
export {
|
|
1627
1919
|
AgentExecutor,
|
|
1920
|
+
BUILT_IN_AGENTS,
|
|
1628
1921
|
BundlePluginInstaller,
|
|
1629
1922
|
BundlePluginLoader,
|
|
1630
1923
|
DEFAULT_TOOL_DESCRIPTIONS,
|
|
1631
|
-
FileSessionLogger,
|
|
1924
|
+
FileSessionLogger2 as FileSessionLogger,
|
|
1632
1925
|
MarketplaceClient,
|
|
1633
1926
|
PluginSettingsStore,
|
|
1634
1927
|
PromptExecutor,
|
|
1635
|
-
|
|
1928
|
+
Session3 as Session,
|
|
1636
1929
|
SessionStore,
|
|
1637
1930
|
SilentSessionLogger,
|
|
1638
1931
|
TRUST_TO_MODE,
|
|
1639
|
-
|
|
1932
|
+
assembleSubagentPrompt,
|
|
1640
1933
|
bashTool2 as bashTool,
|
|
1641
1934
|
buildSystemPrompt,
|
|
1935
|
+
createAgentTool,
|
|
1642
1936
|
createDefaultTools,
|
|
1643
1937
|
createProvider,
|
|
1644
1938
|
createSession,
|
|
1939
|
+
createSubagentLogger,
|
|
1940
|
+
createSubagentSession,
|
|
1645
1941
|
detectProject,
|
|
1646
1942
|
editTool2 as editTool,
|
|
1647
1943
|
evaluatePermission,
|
|
1944
|
+
getBuiltInAgent,
|
|
1945
|
+
getForkWorkerSuffix,
|
|
1946
|
+
getSubagentSuffix,
|
|
1648
1947
|
globTool2 as globTool,
|
|
1649
1948
|
grepTool2 as grepTool,
|
|
1650
1949
|
loadConfig,
|
|
@@ -1653,8 +1952,10 @@ export {
|
|
|
1653
1952
|
promptForApproval,
|
|
1654
1953
|
query,
|
|
1655
1954
|
readTool2 as readTool,
|
|
1955
|
+
resolveSubagentLogDir,
|
|
1956
|
+
retrieveAgentToolDeps,
|
|
1656
1957
|
runHooks,
|
|
1657
|
-
|
|
1958
|
+
storeAgentToolDeps,
|
|
1658
1959
|
userPaths,
|
|
1659
1960
|
writeTool2 as writeTool
|
|
1660
1961
|
};
|