@kb-labs/agent-tools 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,729 @@
1
+ import * as _kb_labs_agent_contracts from '@kb-labs/agent-contracts';
2
+ import { RepositoryModel, SpawnAgentRequest, AsyncTask, SpawnAgentResult, KernelState, EvidenceRequirements, ToolCapability, ToolDefinition, ToolResult, ToolResultArtifact } from '@kb-labs/agent-contracts';
3
+ import { ICache } from '@kb-labs/core-platform';
4
+
5
+ /**
6
+ * IWorkspaceProvider — abstraction for workspace operations.
7
+ *
8
+ * When agent runs on Platform but workspace is on Workspace Agent,
9
+ * this interface proxies fs/search/git/shell operations through Gateway.
10
+ *
11
+ * When agent runs locally (same machine as workspace), LocalWorkspaceProvider
12
+ * delegates to native fs/child_process (current behavior).
13
+ *
14
+ * Tools check `context.workspaceProvider`:
15
+ * - If set → use provider methods (remote or local)
16
+ * - If not set → use native fs directly (backwards compatible)
17
+ *
18
+ * @see ADR-0017: Workspace Agent Architecture (Phase 3)
19
+ */
20
+ interface FileReadResult {
21
+ content: string;
22
+ totalLines: number;
23
+ truncated: boolean;
24
+ }
25
+ interface FileStatResult {
26
+ size: number;
27
+ isFile: boolean;
28
+ isDir: boolean;
29
+ mtime: number;
30
+ }
31
+ interface GrepMatch {
32
+ file: string;
33
+ line: number;
34
+ content: string;
35
+ }
36
+ interface GrepResult {
37
+ matches: GrepMatch[];
38
+ truncated: boolean;
39
+ totalMatches: number;
40
+ }
41
+ interface GlobResult {
42
+ files: string[];
43
+ truncated: boolean;
44
+ totalFiles: number;
45
+ }
46
+ interface ShellResult {
47
+ stdout: string;
48
+ stderr: string;
49
+ exitCode: number;
50
+ }
51
+ interface IWorkspaceProvider {
52
+ /** Read file content with offset/limit */
53
+ readFile(path: string, offset?: number, limit?: number): Promise<FileReadResult>;
54
+ /** Write file content */
55
+ writeFile(path: string, content: string): Promise<void>;
56
+ /** List directory contents */
57
+ listDir(path: string, limit?: number): Promise<string[]>;
58
+ /** Get file/dir stats */
59
+ stat(path: string): Promise<FileStatResult>;
60
+ /** Check if path exists */
61
+ exists(path: string): Promise<boolean>;
62
+ /** Search file contents (grep) */
63
+ grep(pattern: string, directory: string, options?: {
64
+ includes?: string[];
65
+ excludes?: string[];
66
+ maxResults?: number;
67
+ contextLines?: number;
68
+ }): Promise<GrepResult>;
69
+ /** Find files by glob pattern */
70
+ glob(pattern: string, directory: string, options?: {
71
+ excludes?: string[];
72
+ maxResults?: number;
73
+ }): Promise<GlobResult>;
74
+ /** Execute shell command */
75
+ shellExec(command: string, options?: {
76
+ cwd?: string;
77
+ timeoutMs?: number;
78
+ env?: Record<string, string>;
79
+ }): Promise<ShellResult>;
80
+ }
81
+
82
+ /**
83
+ * Tool types and interfaces
84
+ */
85
+
86
+ /**
87
+ * Tool executor function
88
+ */
89
+ type ToolExecutor = (input: Record<string, unknown>) => Promise<ToolResult> | ToolResult;
90
+ /**
91
+ * Tool registration
92
+ */
93
+ interface Tool {
94
+ definition: ToolDefinition;
95
+ executor: ToolExecutor;
96
+ }
97
+ interface ToolPolicy {
98
+ id: string;
99
+ allows(toolName: string, context: ToolContext): boolean;
100
+ allowsCapability?(capability: ToolCapability, context: ToolContext, toolName: string): boolean;
101
+ }
102
+ interface ToolExecutionEnvelope {
103
+ result: ToolResult;
104
+ artifact: ToolResultArtifact;
105
+ }
106
+ interface SessionMemoryBridge {
107
+ loadKernelState(): Promise<KernelState | null>;
108
+ recordConstraint(content: string): Promise<KernelState>;
109
+ recordCorrection(input: {
110
+ content: string;
111
+ invalidates?: string[];
112
+ asConstraint?: boolean;
113
+ }): Promise<KernelState>;
114
+ }
115
+ interface ToolResponseRequirements {
116
+ requirements: EvidenceRequirements;
117
+ rationale: string;
118
+ }
119
+ /**
120
+ * Interface for ArchiveMemory (Tier 2: Cold Storage).
121
+ * Defined here to avoid circular dependency: agent-tools cannot import agent-core.
122
+ */
123
+ interface IArchiveMemory {
124
+ recallByFilePath(filePath: string): {
125
+ fullOutput: string;
126
+ iteration: number;
127
+ toolName: string;
128
+ } | null;
129
+ recallByToolName(toolName: string, limit?: number): Array<{
130
+ fullOutput: string;
131
+ iteration: number;
132
+ toolName: string;
133
+ filePath?: string;
134
+ }>;
135
+ recallByIteration(iteration: number): Array<{
136
+ fullOutput: string;
137
+ iteration: number;
138
+ toolName: string;
139
+ filePath?: string;
140
+ }>;
141
+ search(keyword: string, limit?: number): Array<{
142
+ fullOutput: string;
143
+ toolName: string;
144
+ iteration: number;
145
+ filePath?: string;
146
+ }>;
147
+ getArchivedFilePaths(): string[];
148
+ hasFile(filePath: string): boolean;
149
+ getSummaryHint(): string;
150
+ }
151
+ /**
152
+ * Tool context (working directory, etc.)
153
+ */
154
+ interface ToolContext {
155
+ workingDir: string;
156
+ repositoryModel?: RepositoryModel;
157
+ currentTask?: string;
158
+ sessionId?: string;
159
+ verbose?: boolean;
160
+ /** Shared platform cache adapter (optional) */
161
+ cache?: ICache;
162
+ /** Files that were read in this session (for edit protection) */
163
+ filesRead?: Set<string>;
164
+ /** File content hashes from when files were read (for change detection) */
165
+ filesReadHash?: Map<string, string>;
166
+ /** Agent ID for attribution */
167
+ agentId?: string;
168
+ /** Archive memory for cold storage recall (Tier 2) */
169
+ archiveMemory?: IArchiveMemory;
170
+ /**
171
+ * If set, only tools whose names are in this set will be registered.
172
+ * Used by plan mode to restrict both the plan-writer and any sub-agents
173
+ * it spawns to read-only tools — without touching AgentConfig.
174
+ */
175
+ allowedTools?: Set<string>;
176
+ /** Async task manager for sub-agent delegation (submit/status/collect). */
177
+ taskManager?: ITaskManager;
178
+ /**
179
+ * Set to true by plan_validate tool when the plan passes the quality gate.
180
+ * Checked by report tool in plan mode — report is blocked until this is set.
181
+ */
182
+ planValidationPassed?: boolean;
183
+ /**
184
+ * Workspace provider for remote fs/search/shell operations (Cursor-model).
185
+ * When set, workspace tools proxy through this provider instead of native fs.
186
+ * When not set, tools use native fs directly (backwards compatible).
187
+ *
188
+ * @see ADR-0017: Workspace Agent Architecture (Phase 3)
189
+ */
190
+ workspaceProvider?: IWorkspaceProvider;
191
+ /** Canonical session memory bridge backed by kernel/store artifacts. */
192
+ sessionMemory?: SessionMemoryBridge;
193
+ /** Optional resolver for answer-time evidence requirements. */
194
+ responseRequirementsResolver?: (input: {
195
+ task?: string;
196
+ answer: string;
197
+ kernel: KernelState | null;
198
+ }) => Promise<ToolResponseRequirements> | ToolResponseRequirements;
199
+ /** Optional capability map for internal or external tool providers. */
200
+ toolCapabilitiesByName?: Map<string, ToolCapability[]>;
201
+ }
202
+ /**
203
+ * Interface for async task management.
204
+ * Defined here to avoid circular dependency: agent-tools cannot import agent-core.
205
+ * Implemented by TaskMiddleware in agent-core.
206
+ */
207
+ interface ITaskManager {
208
+ submit(description: string, request: SpawnAgentRequest): Promise<AsyncTask>;
209
+ getStatus(taskId?: string): AsyncTask | AsyncTask[] | null;
210
+ collect(taskId: string): Promise<SpawnAgentResult>;
211
+ }
212
+
213
+ declare class ToolRegistry {
214
+ private tools;
215
+ private context;
216
+ constructor(context: ToolContext);
217
+ /**
218
+ * Register a tool
219
+ */
220
+ register(tool: Tool): void;
221
+ /**
222
+ * Get tool by name
223
+ */
224
+ get(name: string): Tool | undefined;
225
+ /**
226
+ * Get all tool definitions for LLM
227
+ */
228
+ getDefinitions(): _kb_labs_agent_contracts.ToolDefinition[];
229
+ /**
230
+ * Execute a tool with automatic required-argument validation.
231
+ * Returns a structured error if required args are missing/null/undefined,
232
+ * so the agent understands what went wrong and can correct its call.
233
+ */
234
+ execute(name: string, input: Record<string, unknown>): Promise<_kb_labs_agent_contracts.ToolResult>;
235
+ /**
236
+ * Get sorted list of registered tool names
237
+ */
238
+ getToolNames(): string[];
239
+ /**
240
+ * Get context
241
+ */
242
+ getContext(): ToolContext;
243
+ }
244
+
245
+ declare class ToolGateway {
246
+ private readonly context;
247
+ private readonly policies;
248
+ private readonly registry;
249
+ constructor(context: ToolContext, policies?: ToolPolicy[]);
250
+ getDefinitions(): _kb_labs_agent_contracts.ToolDefinition[];
251
+ getToolNames(): string[];
252
+ execute(name: string, input: Record<string, unknown>): Promise<ToolExecutionEnvelope>;
253
+ private isAllowed;
254
+ private getToolCapabilities;
255
+ }
256
+
257
+ /**
258
+ * Filesystem tools for agent operations
259
+ *
260
+ * Features:
261
+ * - Atomic operations with offset/limit for large files
262
+ * - Path traversal protection
263
+ * - Clear error messages for agent understanding
264
+ * - Size limits to prevent context overflow
265
+ */
266
+
267
+ /**
268
+ * Read file contents with optional line range
269
+ */
270
+ declare function createFsReadTool(context: ToolContext): Tool;
271
+ /**
272
+ * Write content to a file
273
+ */
274
+ declare function createFsWriteTool(context: ToolContext): Tool;
275
+ /**
276
+ * Edit file by replacing a range of lines
277
+ */
278
+ declare function createFsPatchTool(context: ToolContext): Tool;
279
+ /**
280
+ * Edit a file by matching text content and replacing it.
281
+ * More reliable than line-number-based fs_patch because LLMs
282
+ * can copy exact text from fs_read output.
283
+ */
284
+ declare function createFsReplaceTool(context: ToolContext): Tool;
285
+ /**
286
+ * List files in a directory
287
+ */
288
+ declare function createFsListTool(context: ToolContext): Tool;
289
+
290
+ /**
291
+ * Mass replace tool for batch text replacement across multiple files
292
+ *
293
+ * Features:
294
+ * - Supports literal string or regex patterns
295
+ * - Glob-based file selection
296
+ * - File history tracking for rollback
297
+ * - Dry-run mode for preview
298
+ * - Safe: validates paths, checks file sizes
299
+ */
300
+
301
+ declare function createMassReplaceTool(context: ToolContext): Tool;
302
+
303
+ /**
304
+ * Search tools for finding files and content
305
+ */
306
+
307
+ /**
308
+ * Search for files by pattern (glob)
309
+ */
310
+ declare function createGlobSearchTool(context: ToolContext): Tool;
311
+ /**
312
+ * Search for text in files (grep)
313
+ */
314
+ declare function createGrepSearchTool(context: ToolContext): Tool;
315
+ /**
316
+ * List files in directory
317
+ */
318
+ declare function createListFilesTool(context: ToolContext): Tool;
319
+ /**
320
+ * Find files containing specific code pattern (semantic search)
321
+ * Language-agnostic - works with any programming language
322
+ */
323
+ declare function createFindDefinitionTool(context: ToolContext): Tool;
324
+ /**
325
+ * Count lines of code - language agnostic
326
+ */
327
+ declare function createCodeStatsTool(context: ToolContext): Tool;
328
+
329
+ /**
330
+ * Memory tools for persistent context and session management
331
+ *
332
+ * ARCHITECTURE:
333
+ * - Shared memory (.kb/memory/shared/) - persistent across sessions
334
+ * - preferences: user preferences (e.g., "use TypeScript strict mode")
335
+ * - constraints: project rules (e.g., "never modify /legacy/")
336
+ *
337
+ * - Session memory (.kb/memory/session-xxx/) - handled by FileMemory
338
+ * - corrections: user corrections for current session
339
+ * - findings: agent discoveries
340
+ * - blockers: current blockers
341
+ */
342
+
343
+ /**
344
+ * Get shared memory (preferences, constraints, project context)
345
+ */
346
+ declare function createMemoryGetTool(context: ToolContext): Tool;
347
+ /**
348
+ * Add user preference to shared memory (persistent)
349
+ */
350
+ declare function createMemoryPreferenceTool(context: ToolContext): Tool;
351
+ /**
352
+ * Add constraint to shared memory (persistent)
353
+ */
354
+ declare function createMemoryConstraintTool(context: ToolContext): Tool;
355
+ /**
356
+ * Add user correction to session memory
357
+ * Session-scoped - only valid for current session
358
+ */
359
+ declare function createMemoryCorrectionTool(context: ToolContext): Tool;
360
+ /**
361
+ * Add finding to session memory
362
+ */
363
+ declare function createMemoryFindingTool(context: ToolContext): Tool;
364
+ /**
365
+ * Add blocker to session memory
366
+ */
367
+ declare function createMemoryBlockerTool(context: ToolContext): Tool;
368
+ /**
369
+ * Save session summary (shared)
370
+ */
371
+ declare function createSessionSaveTool(context: ToolContext): Tool;
372
+
373
+ /**
374
+ * archive_recall tool - Retrieve full content from previously-read files
375
+ * or tool outputs WITHOUT re-reading them.
376
+ *
377
+ * This is the agent's interface to Tier 2 (Cold Storage / ArchiveMemory).
378
+ */
379
+
380
+ declare function createArchiveRecallTool(context: ToolContext): Tool;
381
+
382
+ /**
383
+ * TODO tools for task planning and progress tracking
384
+ */
385
+
386
+ /**
387
+ * Create TODO list with tasks
388
+ */
389
+ declare function createTodoCreateTool(context: ToolContext): Tool;
390
+ /**
391
+ * Update TODO item status
392
+ */
393
+ declare function createTodoUpdateTool(context: ToolContext): Tool;
394
+ /**
395
+ * Get TODO list status
396
+ */
397
+ declare function createTodoGetTool(context: ToolContext): Tool;
398
+
399
+ /**
400
+ * plan_validate tool — LLM-based plan quality gate.
401
+ *
402
+ * Called by the plan-writer agent after drafting a plan to get structured
403
+ * feedback before reporting it as ready. The LLM evaluator receives:
404
+ * - The original user task (so it can judge relevance)
405
+ * - The full plan markdown
406
+ * - The requested evaluation tier (default: small)
407
+ *
408
+ * Returns a human+agent-readable string with:
409
+ * - passed: yes/no
410
+ * - score: 0.0–1.0
411
+ * - Per-dimension breakdown (specificity, actionability, completeness, verification)
412
+ * - Concrete, actionable feedback for each failing dimension
413
+ *
414
+ * The agent uses this output to decide:
415
+ * 1. passed=yes → call report() with the plan
416
+ * 2. passed=no → revise the plan based on feedback and call plan_validate again
417
+ * 3. After 3 failed attempts → call ask_user() with the plan + issues
418
+ */
419
+
420
+ declare function createPlanValidateTool(context: ToolContext): Tool;
421
+
422
+ /**
423
+ * plan_write tool — write/update the session plan file on disk.
424
+ *
425
+ * Enables iterative plan building: agent writes plan incrementally during
426
+ * exploration, rather than generating everything at the end in one shot.
427
+ * The plan survives context compaction because it lives on disk.
428
+ *
429
+ * Plan file location: .kb/agents/sessions/{sessionId}/plan.md
430
+ * (resolved from context.sessionId and context.workingDir)
431
+ */
432
+
433
+ declare function createPlanWriteTool(context: ToolContext): Tool;
434
+
435
+ /**
436
+ * Shell execution tool
437
+ */
438
+
439
+ /**
440
+ * Execute shell command
441
+ */
442
+ declare function createShellExecTool(context: ToolContext): Tool;
443
+
444
+ /**
445
+ * Async task tools — fire-and-forget sub-agent operations.
446
+ *
447
+ * - task_submit: Start a sub-agent in the background, get a task ID immediately
448
+ * - task_status: Check status of one or all async tasks
449
+ * - task_collect: Wait for a specific task to complete and get its result
450
+ */
451
+
452
+ /**
453
+ * Submit an async task (fire-and-forget sub-agent).
454
+ */
455
+ declare function createTaskSubmitTool(context: ToolContext): Tool;
456
+ /**
457
+ * Check status of async tasks.
458
+ */
459
+ declare function createTaskStatusTool(context: ToolContext): Tool;
460
+ /**
461
+ * Wait for a specific async task to complete and get its full result.
462
+ */
463
+ declare function createTaskCollectTool(context: ToolContext): Tool;
464
+
465
+ /**
466
+ * User interaction tools
467
+ */
468
+
469
+ /**
470
+ * Ask user a question (interactive mode only)
471
+ */
472
+ declare function createAskUserTool(_context: ToolContext): Tool;
473
+
474
+ /**
475
+ * Reporting tools - for sub-agents to communicate with parent agent
476
+ */
477
+
478
+ /**
479
+ * Ask parent agent for help when stuck or uncertain.
480
+ * Sub-agents use this to escalate to the main agent for guidance.
481
+ */
482
+ declare function createAskParentTool(_context: ToolContext): Tool;
483
+ /**
484
+ * Report findings and exit. Used by agents to provide synthesized answer
485
+ * and signal early exit when task is complete.
486
+ */
487
+ declare function createReportTool(context: ToolContext): Tool;
488
+
489
+ /**
490
+ * Tool registration and exports
491
+ *
492
+ * Tools are organized by category:
493
+ * filesystem/ — fs_read, fs_write, fs_patch, fs_replace, fs_list, mass_replace
494
+ * search/ — glob_search, grep_search, find_definition, code_stats
495
+ * memory/ — memory_*, archive_recall, session_save
496
+ * planning/ — plan_validate, plan_write, todo_*
497
+ * execution/ — shell_exec, task_submit/status/collect
498
+ * interaction/ — ask_user, ask_parent, report
499
+ * shared/ — tool-error (utilities)
500
+ */
501
+
502
+ /**
503
+ * Create and register all tools
504
+ */
505
+ declare function createToolRegistry(context: ToolContext): ToolRegistry;
506
+
507
+ /**
508
+ * Centralized configuration constants for agent tools.
509
+ *
510
+ * All magic numbers and default values live here — tool implementations
511
+ * import from this module instead of defining inline constants.
512
+ */
513
+ declare const FILESYSTEM_CONFIG: {
514
+ /** Hard cap on file size to read (500KB) — prevents context overflow */
515
+ readonly maxFileSize: 500000;
516
+ /** Hard cap on lines returned per read — prevents context overflow */
517
+ readonly maxLinesPerRead: 2000;
518
+ /** Default lines to return when not specified — read whole file up to maxLinesPerRead */
519
+ readonly defaultLines: 2000;
520
+ /** Hard cap on content size for write operations (1MB) */
521
+ readonly maxWriteSize: 1000000;
522
+ /** Default limit for directory listing */
523
+ readonly defaultListLimit: 50;
524
+ /** Maximum limit for directory listing */
525
+ readonly maxListLimit: 200;
526
+ /** Max output characters before trimming (prevents context explosion) */
527
+ readonly maxOutputChars: 12000;
528
+ };
529
+ declare const SEARCH_CONFIG: {
530
+ /** Timeout for search commands (15s) — fail fast, don't burn iterations */
531
+ readonly timeoutMs: 15000;
532
+ /** Max stdout buffer for search commands (8MB) */
533
+ readonly maxBuffer: number;
534
+ /** Default result limit — enough for actionable results */
535
+ readonly defaultResultLimit: 50;
536
+ /** Maximum result limit */
537
+ readonly maxResultLimit: 200;
538
+ /** Max output characters before trimming */
539
+ readonly maxOutputChars: 8000;
540
+ /**
541
+ * Directories excluded from search by default.
542
+ * These are never useful for code understanding and often huge.
543
+ * Pass exclude=[] to override entirely, or exclude=[...custom] to replace the list.
544
+ */
545
+ readonly defaultExcludes: string[];
546
+ };
547
+ declare const SHELL_CONFIG: {
548
+ /** Max stdout buffer — aligned with SEARCH_CONFIG (16MB) */
549
+ readonly maxBuffer: number;
550
+ };
551
+ declare const TODO_CONFIG: {
552
+ /** Cache key prefix for todo lists */
553
+ readonly cachePrefix: "agent:todo:";
554
+ /** TTL for cached todo lists (7 days) */
555
+ readonly cacheTtlMs: number;
556
+ };
557
+ declare const DELEGATION_CONFIG: {
558
+ /** Default max iterations for spawned sub-agents (safety net — token budget is primary control) */
559
+ readonly defaultMaxIterations: 100;
560
+ /** Default budget fraction (50% of parent remaining — sub-agents need real budget) */
561
+ readonly defaultBudgetFraction: 0.5;
562
+ };
563
+ /**
564
+ * Sub-agent tool allowlists and iteration defaults per preset.
565
+ *
566
+ * Single source of truth: lives in agent-tools because it knows tool names.
567
+ * agent-core receives these as `allowedTools: string[]` data via SpawnAgentRequest
568
+ * (no import from agent-tools needed — correct dependency direction).
569
+ */
570
+ declare const SUB_AGENT_PRESETS: {
571
+ /** Read-only exploration and evidence gathering. */
572
+ readonly research: {
573
+ readonly tools: Set<string>;
574
+ readonly maxIterations: 50;
575
+ };
576
+ /** Full read/write capabilities for implementation tasks. */
577
+ readonly execute: {
578
+ readonly tools: Set<string>;
579
+ readonly maxIterations: 100;
580
+ };
581
+ /** Code review and verification: read + shell (linters, tests). */
582
+ readonly review: {
583
+ readonly tools: Set<string>;
584
+ readonly maxIterations: 50;
585
+ };
586
+ /**
587
+ * Adversarial verification: independent agent that checks another agent's work.
588
+ * Has read + shell access to run tests, check imports, verify builds.
589
+ * Reports PASS/FAIL verdict with evidence.
590
+ */
591
+ readonly verification: {
592
+ readonly tools: Set<string>;
593
+ readonly maxIterations: 25;
594
+ };
595
+ };
596
+ declare const MASS_REPLACE_CONFIG: {
597
+ /** Hard cap on file size to process (1MB) — same as maxWriteSize */
598
+ readonly maxFileSize: 1000000;
599
+ /** Maximum number of files to process in one operation */
600
+ readonly maxFiles: 100;
601
+ };
602
+ /**
603
+ * Tools available in plan mode — read-only exploration + async task delegation.
604
+ * Used as `allowedTools` in ToolContext for both the plan-writer and any
605
+ * research sub-agents it spawns via task_submit. Single source of truth:
606
+ * lives in agent-tools so both agent-core and tests can import it without
607
+ * creating a circular dependency.
608
+ */
609
+ declare const PLAN_READ_ONLY_TOOL_NAMES: Set<string>;
610
+ /**
611
+ * Source file extensions grouped by language.
612
+ * Use ALL_SOURCE_EXTENSIONS or the helper functions for CLI flags.
613
+ */
614
+ declare const SOURCE_FILE_EXTENSIONS: {
615
+ readonly typescript: readonly ["ts", "tsx"];
616
+ readonly javascript: readonly ["js", "jsx"];
617
+ readonly python: readonly ["py"];
618
+ readonly csharp: readonly ["cs"];
619
+ readonly java: readonly ["java"];
620
+ readonly go: readonly ["go"];
621
+ readonly rust: readonly ["rs"];
622
+ readonly ruby: readonly ["rb"];
623
+ readonly php: readonly ["php"];
624
+ readonly swift: readonly ["swift"];
625
+ readonly kotlin: readonly ["kt"];
626
+ readonly scala: readonly ["scala"];
627
+ readonly cpp: readonly ["cpp", "c", "h", "cc", "cxx"];
628
+ };
629
+ /** Flat list of all source file extensions */
630
+ declare const ALL_SOURCE_EXTENSIONS: readonly string[];
631
+ /**
632
+ * Build `--include="*.ext"` flags for ripgrep / grep.
633
+ * @example toRgIncludes(ALL_SOURCE_EXTENSIONS)
634
+ * // → '--include="*.ts" --include="*.tsx" ...'
635
+ */
636
+ declare function toRgIncludes(exts: readonly string[]): string;
637
+ /**
638
+ * Build `-name "*.ext"` flags for `find` (joined with ` -o `).
639
+ * @example toFindNames(ALL_SOURCE_EXTENSIONS)
640
+ * // → '-name "*.ts" -o -name "*.tsx" ...'
641
+ */
642
+ declare function toFindNames(exts: readonly string[]): string;
643
+
644
+ /**
645
+ * Shared utilities for agent tool implementations.
646
+ */
647
+ /**
648
+ * Normalize offset and limit parameters from tool input.
649
+ *
650
+ * Handles NaN, negative values, and enforces configured max/default limits.
651
+ * Previously duplicated in filesystem.ts and search.ts.
652
+ *
653
+ * @example
654
+ * const { offset, limit } = normalizeOffsetLimit(input, {
655
+ * defaultLimit: FILESYSTEM_CONFIG.defaultLines,
656
+ * maxLimit: FILESYSTEM_CONFIG.maxLinesPerRead,
657
+ * });
658
+ */
659
+ declare function normalizeOffsetLimit(input: Record<string, unknown>, config: {
660
+ defaultLimit: number;
661
+ maxLimit: number;
662
+ }): {
663
+ offset: number;
664
+ limit: number;
665
+ };
666
+ /**
667
+ * Validate that a file path stays within the working directory.
668
+ *
669
+ * Resolves symlinks to prevent symlink-based traversal bypasses.
670
+ * Uses path.relative() which is more robust than startsWith().
671
+ *
672
+ * Previously duplicated in filesystem.ts and mass-replace.ts.
673
+ */
674
+ declare function validatePath(workingDir: string, filePath: string): {
675
+ valid: boolean;
676
+ resolved: string;
677
+ error?: string;
678
+ };
679
+ /**
680
+ * Suggest a similar directory when the requested one doesn't exist.
681
+ *
682
+ * Handles common agent mistakes like nested paths (e.g. "foo/bar" when "foo-bar/" exists).
683
+ * Returns null if no good suggestion found.
684
+ */
685
+ declare function suggestDirectory(workingDir: string, requestedDir: string): string | null;
686
+
687
+ /**
688
+ * RemoteWorkspaceProvider — proxies workspace operations to Workspace Agent via Gateway.
689
+ *
690
+ * Used when Agent Runner runs on Platform but needs to access files
691
+ * on a remote Workspace Agent (Cursor-model: "brain" on server, "hands" on client).
692
+ *
693
+ * Uses Gateway dispatcher to send capability calls to connected Workspace Agent.
694
+ *
695
+ * @see ADR-0017: Workspace Agent Architecture (Phase 3)
696
+ */
697
+
698
+ /** Gateway dispatcher call function (injected, avoids direct dependency on Gateway) */
699
+ type DispatchFn = (adapter: string, method: string, args: unknown[]) => Promise<unknown>;
700
+ interface RemoteWorkspaceProviderOptions {
701
+ /** Function to dispatch capability calls via Gateway */
702
+ dispatch: DispatchFn;
703
+ }
704
+ declare class RemoteWorkspaceProvider implements IWorkspaceProvider {
705
+ private readonly opts;
706
+ constructor(opts: RemoteWorkspaceProviderOptions);
707
+ readFile(path: string, offset?: number, limit?: number): Promise<FileReadResult>;
708
+ writeFile(path: string, content: string): Promise<void>;
709
+ listDir(path: string, limit?: number): Promise<string[]>;
710
+ stat(path: string): Promise<FileStatResult>;
711
+ exists(path: string): Promise<boolean>;
712
+ grep(pattern: string, directory: string, options?: {
713
+ includes?: string[];
714
+ excludes?: string[];
715
+ maxResults?: number;
716
+ contextLines?: number;
717
+ }): Promise<GrepResult>;
718
+ glob(pattern: string, directory: string, options?: {
719
+ excludes?: string[];
720
+ maxResults?: number;
721
+ }): Promise<GlobResult>;
722
+ shellExec(command: string, options?: {
723
+ cwd?: string;
724
+ timeoutMs?: number;
725
+ env?: Record<string, string>;
726
+ }): Promise<ShellResult>;
727
+ }
728
+
729
+ export { ALL_SOURCE_EXTENSIONS, DELEGATION_CONFIG, type DispatchFn, FILESYSTEM_CONFIG, type FileReadResult, type FileStatResult, type GlobResult, type GrepMatch, type GrepResult, type IArchiveMemory, type ITaskManager, type IWorkspaceProvider, MASS_REPLACE_CONFIG, PLAN_READ_ONLY_TOOL_NAMES, RemoteWorkspaceProvider, SEARCH_CONFIG, SHELL_CONFIG, SOURCE_FILE_EXTENSIONS, SUB_AGENT_PRESETS, type SessionMemoryBridge, type ShellResult, TODO_CONFIG, type Tool, type ToolContext, type ToolExecutionEnvelope, type ToolExecutor, ToolGateway, type ToolPolicy, ToolRegistry, type ToolResponseRequirements, createArchiveRecallTool, createAskParentTool, createAskUserTool, createCodeStatsTool, createFindDefinitionTool, createFsListTool, createFsPatchTool, createFsReadTool, createFsReplaceTool, createFsWriteTool, createGlobSearchTool, createGrepSearchTool, createListFilesTool, createMassReplaceTool, createMemoryBlockerTool, createMemoryConstraintTool, createMemoryCorrectionTool, createMemoryFindingTool, createMemoryGetTool, createMemoryPreferenceTool, createPlanValidateTool, createPlanWriteTool, createReportTool, createSessionSaveTool, createShellExecTool, createTaskCollectTool, createTaskStatusTool, createTaskSubmitTool, createTodoCreateTool, createTodoGetTool, createTodoUpdateTool, createToolRegistry, normalizeOffsetLimit, suggestDirectory, toFindNames, toRgIncludes, validatePath };