qlogicagent 0.2.1 → 0.4.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.
Files changed (226) hide show
  1. package/README.md +45 -45
  2. package/package.json +56 -42
  3. package/dist/agent/agent.d.ts +0 -43
  4. package/dist/agent/agent.js +0 -113
  5. package/dist/agent/tool-loop.d.ts +0 -64
  6. package/dist/agent/tool-loop.js +0 -575
  7. package/dist/agent/types.d.ts +0 -175
  8. package/dist/agent/types.js +0 -14
  9. package/dist/cli/main.d.ts +0 -11
  10. package/dist/cli/main.js +0 -23
  11. package/dist/cli/stdio-server.d.ts +0 -45
  12. package/dist/cli/stdio-server.js +0 -463
  13. package/dist/config/config.d.ts +0 -17
  14. package/dist/config/config.js +0 -21
  15. package/dist/contracts/hooks.d.ts +0 -120
  16. package/dist/contracts/hooks.js +0 -7
  17. package/dist/contracts/index.d.ts +0 -10
  18. package/dist/contracts/index.js +0 -10
  19. package/dist/contracts/planner.d.ts +0 -35
  20. package/dist/contracts/planner.js +0 -2
  21. package/dist/contracts/skill-candidate.d.ts +0 -63
  22. package/dist/contracts/skill-candidate.js +0 -195
  23. package/dist/contracts/todo.d.ts +0 -14
  24. package/dist/contracts/todo.js +0 -9
  25. package/dist/index.d.ts +0 -13
  26. package/dist/index.js +0 -15
  27. package/dist/llm/builtin-providers.d.ts +0 -10
  28. package/dist/llm/builtin-providers.js +0 -531
  29. package/dist/llm/index.d.ts +0 -15
  30. package/dist/llm/index.js +0 -14
  31. package/dist/llm/llm-client.d.ts +0 -43
  32. package/dist/llm/llm-client.js +0 -67
  33. package/dist/llm/model-catalog.d.ts +0 -53
  34. package/dist/llm/model-catalog.js +0 -191
  35. package/dist/llm/provider-def.d.ts +0 -59
  36. package/dist/llm/provider-def.js +0 -12
  37. package/dist/llm/provider-registry.d.ts +0 -54
  38. package/dist/llm/provider-registry.js +0 -147
  39. package/dist/llm/transport.d.ts +0 -62
  40. package/dist/llm/transport.js +0 -27
  41. package/dist/llm/transports/anthropic-messages.d.ts +0 -31
  42. package/dist/llm/transports/anthropic-messages.js +0 -293
  43. package/dist/llm/transports/openai-chat.d.ts +0 -36
  44. package/dist/llm/transports/openai-chat.js +0 -165
  45. package/dist/orchestration/agent-registry.d.ts +0 -41
  46. package/dist/orchestration/agent-registry.js +0 -116
  47. package/dist/orchestration/approval-aware-tool-plan.d.ts +0 -32
  48. package/dist/orchestration/approval-aware-tool-plan.js +0 -87
  49. package/dist/orchestration/context-compression.d.ts +0 -220
  50. package/dist/orchestration/context-compression.js +0 -583
  51. package/dist/orchestration/conversation-repair.d.ts +0 -61
  52. package/dist/orchestration/conversation-repair.js +0 -429
  53. package/dist/orchestration/curator-scheduler.d.ts +0 -119
  54. package/dist/orchestration/curator-scheduler.js +0 -135
  55. package/dist/orchestration/embedded-failover-policy.d.ts +0 -110
  56. package/dist/orchestration/embedded-failover-policy.js +0 -168
  57. package/dist/orchestration/error-classification.d.ts +0 -12
  58. package/dist/orchestration/error-classification.js +0 -77
  59. package/dist/orchestration/failover-classification.d.ts +0 -8
  60. package/dist/orchestration/failover-classification.js +0 -381
  61. package/dist/orchestration/failover-error.d.ts +0 -33
  62. package/dist/orchestration/failover-error.js +0 -198
  63. package/dist/orchestration/fork-subagent.d.ts +0 -100
  64. package/dist/orchestration/fork-subagent.js +0 -98
  65. package/dist/orchestration/index.d.ts +0 -120
  66. package/dist/orchestration/index.js +0 -267
  67. package/dist/orchestration/memory-flush-policy.d.ts +0 -57
  68. package/dist/orchestration/memory-flush-policy.js +0 -85
  69. package/dist/orchestration/memory-provider.d.ts +0 -14
  70. package/dist/orchestration/memory-provider.js +0 -2
  71. package/dist/orchestration/parallel-tool-calls.d.ts +0 -41
  72. package/dist/orchestration/parallel-tool-calls.js +0 -59
  73. package/dist/orchestration/prompt-cache-strategy.d.ts +0 -126
  74. package/dist/orchestration/prompt-cache-strategy.js +0 -228
  75. package/dist/orchestration/reactive-compact.d.ts +0 -73
  76. package/dist/orchestration/reactive-compact.js +0 -78
  77. package/dist/orchestration/retry-loop.d.ts +0 -22
  78. package/dist/orchestration/retry-loop.js +0 -24
  79. package/dist/orchestration/skill-candidate.d.ts +0 -52
  80. package/dist/orchestration/skill-candidate.js +0 -141
  81. package/dist/orchestration/skill-consolidation.d.ts +0 -123
  82. package/dist/orchestration/skill-consolidation.js +0 -220
  83. package/dist/orchestration/skill-improvement.d.ts +0 -59
  84. package/dist/orchestration/skill-improvement.js +0 -66
  85. package/dist/orchestration/skill-similarity.d.ts +0 -98
  86. package/dist/orchestration/skill-similarity.js +0 -131
  87. package/dist/orchestration/streaming-tool-executor.d.ts +0 -73
  88. package/dist/orchestration/streaming-tool-executor.js +0 -96
  89. package/dist/orchestration/team-orchestration.d.ts +0 -195
  90. package/dist/orchestration/team-orchestration.js +0 -369
  91. package/dist/orchestration/team-tool-loop-wiring.d.ts +0 -92
  92. package/dist/orchestration/team-tool-loop-wiring.js +0 -147
  93. package/dist/orchestration/tool-choice-policy.d.ts +0 -54
  94. package/dist/orchestration/tool-choice-policy.js +0 -164
  95. package/dist/orchestration/tool-loop-state.d.ts +0 -50
  96. package/dist/orchestration/tool-loop-state.js +0 -133
  97. package/dist/orchestration/tool-schema.d.ts +0 -39
  98. package/dist/orchestration/tool-schema.js +0 -297
  99. package/dist/orchestration/transcript-repair.d.ts +0 -42
  100. package/dist/orchestration/transcript-repair.js +0 -426
  101. package/dist/orchestration/turn-loop-guard.d.ts +0 -86
  102. package/dist/orchestration/turn-loop-guard.js +0 -92
  103. package/dist/orchestration/web-browser-policy.d.ts +0 -17
  104. package/dist/orchestration/web-browser-policy.js +0 -39
  105. package/dist/runtime/context-compression.d.ts +0 -61
  106. package/dist/runtime/context-compression.js +0 -274
  107. package/dist/runtime/hook-registry.d.ts +0 -12
  108. package/dist/runtime/hook-registry.js +0 -53
  109. package/dist/runtime/memory-hooks.d.ts +0 -23
  110. package/dist/runtime/memory-hooks.js +0 -65
  111. package/dist/runtime/tool-eligibility.d.ts +0 -59
  112. package/dist/runtime/tool-eligibility.js +0 -111
  113. package/dist/skills/index.d.ts +0 -108
  114. package/dist/skills/index.js +0 -82
  115. package/dist/skills/memory-extractor.d.ts +0 -64
  116. package/dist/skills/memory-extractor.js +0 -173
  117. package/dist/skills/memory-query-tool.d.ts +0 -43
  118. package/dist/skills/memory-query-tool.js +0 -127
  119. package/dist/skills/memory-store.d.ts +0 -66
  120. package/dist/skills/memory-store.js +0 -228
  121. package/dist/skills/memory-tool.d.ts +0 -67
  122. package/dist/skills/memory-tool.js +0 -192
  123. package/dist/skills/portable-tool.d.ts +0 -71
  124. package/dist/skills/portable-tool.js +0 -14
  125. package/dist/skills/qmemory-adapter.d.ts +0 -52
  126. package/dist/skills/qmemory-adapter.js +0 -165
  127. package/dist/skills/skill-frontmatter.d.ts +0 -19
  128. package/dist/skills/skill-frontmatter.js +0 -344
  129. package/dist/skills/skill-guard.d.ts +0 -23
  130. package/dist/skills/skill-guard.js +0 -229
  131. package/dist/skills/skill-loader.d.ts +0 -16
  132. package/dist/skills/skill-loader.js +0 -303
  133. package/dist/skills/skill-source.d.ts +0 -119
  134. package/dist/skills/skill-source.js +0 -126
  135. package/dist/skills/skill-types.d.ts +0 -199
  136. package/dist/skills/skill-types.js +0 -6
  137. package/dist/skills/think-tool.d.ts +0 -16
  138. package/dist/skills/think-tool.js +0 -59
  139. package/dist/skills/todo-tool.d.ts +0 -63
  140. package/dist/skills/todo-tool.js +0 -114
  141. package/dist/skills/tools/agent-tool.d.ts +0 -91
  142. package/dist/skills/tools/agent-tool.js +0 -142
  143. package/dist/skills/tools/apply-patch-tool.d.ts +0 -29
  144. package/dist/skills/tools/apply-patch-tool.js +0 -184
  145. package/dist/skills/tools/ask-user-tool.d.ts +0 -80
  146. package/dist/skills/tools/ask-user-tool.js +0 -121
  147. package/dist/skills/tools/brief-tool.d.ts +0 -74
  148. package/dist/skills/tools/brief-tool.js +0 -95
  149. package/dist/skills/tools/browser-tool.d.ts +0 -114
  150. package/dist/skills/tools/browser-tool.js +0 -155
  151. package/dist/skills/tools/checkpoint-tool.d.ts +0 -66
  152. package/dist/skills/tools/checkpoint-tool.js +0 -102
  153. package/dist/skills/tools/config-tool.d.ts +0 -63
  154. package/dist/skills/tools/config-tool.js +0 -143
  155. package/dist/skills/tools/cron-tool.d.ts +0 -116
  156. package/dist/skills/tools/cron-tool.js +0 -175
  157. package/dist/skills/tools/edit-tool.d.ts +0 -43
  158. package/dist/skills/tools/edit-tool.js +0 -70
  159. package/dist/skills/tools/exec-tool.d.ts +0 -102
  160. package/dist/skills/tools/exec-tool.js +0 -133
  161. package/dist/skills/tools/image-generate-tool.d.ts +0 -62
  162. package/dist/skills/tools/image-generate-tool.js +0 -67
  163. package/dist/skills/tools/instructions-tool.d.ts +0 -103
  164. package/dist/skills/tools/instructions-tool.js +0 -187
  165. package/dist/skills/tools/lsp-tool.d.ts +0 -153
  166. package/dist/skills/tools/lsp-tool.js +0 -227
  167. package/dist/skills/tools/mcp-client-types.d.ts +0 -269
  168. package/dist/skills/tools/mcp-client-types.js +0 -53
  169. package/dist/skills/tools/mcp-tool.d.ts +0 -249
  170. package/dist/skills/tools/mcp-tool.js +0 -503
  171. package/dist/skills/tools/memory-tool.d.ts +0 -74
  172. package/dist/skills/tools/memory-tool.js +0 -88
  173. package/dist/skills/tools/monitor-tool.d.ts +0 -113
  174. package/dist/skills/tools/monitor-tool.js +0 -131
  175. package/dist/skills/tools/music-generate-tool.d.ts +0 -55
  176. package/dist/skills/tools/music-generate-tool.js +0 -62
  177. package/dist/skills/tools/notify-tool.d.ts +0 -53
  178. package/dist/skills/tools/notify-tool.js +0 -62
  179. package/dist/skills/tools/patch-tool.d.ts +0 -45
  180. package/dist/skills/tools/patch-tool.js +0 -505
  181. package/dist/skills/tools/pdf-tool.d.ts +0 -66
  182. package/dist/skills/tools/pdf-tool.js +0 -88
  183. package/dist/skills/tools/plan-mode-tool.d.ts +0 -59
  184. package/dist/skills/tools/plan-mode-tool.js +0 -122
  185. package/dist/skills/tools/read-tool.d.ts +0 -51
  186. package/dist/skills/tools/read-tool.js +0 -84
  187. package/dist/skills/tools/repl-tool.d.ts +0 -70
  188. package/dist/skills/tools/repl-tool.js +0 -69
  189. package/dist/skills/tools/search-tool.d.ts +0 -112
  190. package/dist/skills/tools/search-tool.js +0 -225
  191. package/dist/skills/tools/send-message-tool.d.ts +0 -51
  192. package/dist/skills/tools/send-message-tool.js +0 -76
  193. package/dist/skills/tools/skill-list-tool.d.ts +0 -33
  194. package/dist/skills/tools/skill-list-tool.js +0 -54
  195. package/dist/skills/tools/skill-manage-tool.d.ts +0 -73
  196. package/dist/skills/tools/skill-manage-tool.js +0 -153
  197. package/dist/skills/tools/skill-view-tool.d.ts +0 -37
  198. package/dist/skills/tools/skill-view-tool.js +0 -72
  199. package/dist/skills/tools/sleep-tool.d.ts +0 -49
  200. package/dist/skills/tools/sleep-tool.js +0 -81
  201. package/dist/skills/tools/structured-output-tool.d.ts +0 -116
  202. package/dist/skills/tools/structured-output-tool.js +0 -176
  203. package/dist/skills/tools/task-tool.d.ts +0 -104
  204. package/dist/skills/tools/task-tool.js +0 -161
  205. package/dist/skills/tools/team-tool.d.ts +0 -89
  206. package/dist/skills/tools/team-tool.js +0 -105
  207. package/dist/skills/tools/tool-search-tool.d.ts +0 -51
  208. package/dist/skills/tools/tool-search-tool.js +0 -110
  209. package/dist/skills/tools/tts-tool.d.ts +0 -38
  210. package/dist/skills/tools/tts-tool.js +0 -45
  211. package/dist/skills/tools/video-edit-tool.d.ts +0 -69
  212. package/dist/skills/tools/video-edit-tool.js +0 -74
  213. package/dist/skills/tools/video-generate-tool.d.ts +0 -62
  214. package/dist/skills/tools/video-generate-tool.js +0 -66
  215. package/dist/skills/tools/video-merge-tool.d.ts +0 -105
  216. package/dist/skills/tools/video-merge-tool.js +0 -92
  217. package/dist/skills/tools/video-upscale-tool.d.ts +0 -45
  218. package/dist/skills/tools/video-upscale-tool.js +0 -52
  219. package/dist/skills/tools/web-fetch-tool.d.ts +0 -78
  220. package/dist/skills/tools/web-fetch-tool.js +0 -92
  221. package/dist/skills/tools/web-search-tool.d.ts +0 -57
  222. package/dist/skills/tools/web-search-tool.js +0 -86
  223. package/dist/skills/tools/worktree-tool.d.ts +0 -69
  224. package/dist/skills/tools/worktree-tool.js +0 -147
  225. package/dist/skills/tools/write-tool.d.ts +0 -45
  226. package/dist/skills/tools/write-tool.js +0 -81
@@ -1,59 +0,0 @@
1
- import type { PortableTool } from "../portable-tool.js";
2
- export declare const PLAN_MODE_TOOL_NAME: "plan_mode";
3
- export type PlanModeAction = "enter" | "exit";
4
- export interface PlanModeToolParams {
5
- /** Action: enter or exit plan mode */
6
- action: PlanModeAction;
7
- /** Plan text (for exit — the finalized plan to present for approval) */
8
- plan?: string;
9
- /** File path where plan was saved (optional) */
10
- planFilePath?: string;
11
- }
12
- export declare const PLAN_MODE_TOOL_SCHEMA: {
13
- readonly type: "object";
14
- readonly properties: {
15
- readonly action: {
16
- readonly type: "string";
17
- readonly enum: readonly ["enter", "exit"];
18
- readonly description: string;
19
- };
20
- readonly plan: {
21
- readonly type: "string";
22
- readonly description: string;
23
- };
24
- readonly planFilePath: {
25
- readonly type: "string";
26
- readonly description: "Optional file path where the plan was saved for reference.";
27
- };
28
- };
29
- readonly required: readonly ["action"];
30
- };
31
- /** Tools allowed during plan mode (read-only + reasoning) */
32
- export declare const PLAN_MODE_ALLOWED_TOOLS: readonly string[];
33
- export interface PlanModeState {
34
- active: boolean;
35
- enteredAt?: string;
36
- plan?: string;
37
- planFilePath?: string;
38
- }
39
- export interface PlanModeResult {
40
- success: boolean;
41
- state: PlanModeState;
42
- allowedTools?: readonly string[];
43
- error?: string;
44
- }
45
- /**
46
- * Host-provided plan mode backend.
47
- * The host is responsible for filtering tool availability based on mode state.
48
- */
49
- export interface PlanModeToolDeps {
50
- /** Get current plan mode state */
51
- getState(): PlanModeState;
52
- /** Enter plan mode — host should restrict tool availability */
53
- enterPlanMode(): Promise<PlanModeResult>;
54
- /** Exit plan mode — host restores full tool availability */
55
- exitPlanMode(plan?: string, planFilePath?: string): Promise<PlanModeResult>;
56
- /** Check if in agent/sub-agent context (plan mode not allowed in sub-agents) */
57
- isAgentContext?(): boolean;
58
- }
59
- export declare function createPlanModeTool(deps: PlanModeToolDeps): PortableTool<PlanModeToolParams>;
@@ -1,122 +0,0 @@
1
- // ============================================================
2
- // Plan Mode Tool — enter/exit plan mode for safer exploration.
3
- // Reference: claude-code-haha/src/tools/EnterPlanModeTool/EnterPlanModeTool.ts
4
- // claude-code-haha/src/tools/ExitPlanModeTool/ExitPlanModeV2Tool.ts
5
- // Category: system (mode switch)
6
- // ============================================================
7
- export const PLAN_MODE_TOOL_NAME = "plan_mode";
8
- export const PLAN_MODE_TOOL_SCHEMA = {
9
- type: "object",
10
- properties: {
11
- action: {
12
- type: "string",
13
- enum: ["enter", "exit"],
14
- description: "enter: Switch to plan mode (only read/search/think tools available).\n" +
15
- "exit: Leave plan mode and submit plan for approval (restores full tool access).",
16
- },
17
- plan: {
18
- type: "string",
19
- description: "The finalized plan text to present for user approval (used with 'exit' action). " +
20
- "Write a clear, structured plan of what will be done.",
21
- },
22
- planFilePath: {
23
- type: "string",
24
- description: "Optional file path where the plan was saved for reference.",
25
- },
26
- },
27
- required: ["action"],
28
- };
29
- /** Tools allowed during plan mode (read-only + reasoning) */
30
- export const PLAN_MODE_ALLOWED_TOOLS = [
31
- "read",
32
- "search",
33
- "think",
34
- "lsp",
35
- "web_search",
36
- "web_fetch",
37
- "memory_query",
38
- "memory_search",
39
- "skill_list",
40
- "skill_view",
41
- "tool_search",
42
- "plan_mode",
43
- ];
44
- export function createPlanModeTool(deps) {
45
- return {
46
- name: PLAN_MODE_TOOL_NAME,
47
- label: "Plan Mode",
48
- description: "Switch between plan mode and execution mode. In plan mode, only " +
49
- "read-only tools (read, search, think, lsp) are available — no file writes or commands. " +
50
- "Use plan mode to safely explore a problem before committing to changes. " +
51
- "Exit plan mode with a finalized plan for user approval.",
52
- parameters: PLAN_MODE_TOOL_SCHEMA,
53
- execute: async (_toolCallId, params) => {
54
- // Plan mode not allowed in sub-agent context
55
- if (deps.isAgentContext?.()) {
56
- return {
57
- content: [{ type: "text", text: "Error: plan mode is not available in sub-agent context." }],
58
- details: { type: "plan_mode", error: "agent_context" },
59
- };
60
- }
61
- switch (params.action) {
62
- case "enter": {
63
- const state = deps.getState();
64
- if (state.active) {
65
- return {
66
- content: [{ type: "text", text: "Already in plan mode. Use action='exit' with a plan to leave." }],
67
- details: { type: "plan_mode", error: "already_active" },
68
- };
69
- }
70
- const result = await deps.enterPlanMode();
71
- if (!result.success) {
72
- return {
73
- content: [{ type: "text", text: `Error: ${result.error || "failed to enter plan mode"}` }],
74
- details: { type: "plan_mode", error: result.error },
75
- };
76
- }
77
- const lines = [
78
- "Entered plan mode.",
79
- "",
80
- "Available tools: " + PLAN_MODE_ALLOWED_TOOLS.join(", "),
81
- "",
82
- "All write/execute tools are disabled. Explore the problem, then exit with a plan.",
83
- 'Use action="exit" with a plan parameter when ready.',
84
- ];
85
- return {
86
- content: [{ type: "text", text: lines.join("\n") }],
87
- details: { type: "plan_mode", action: "enter", allowedTools: PLAN_MODE_ALLOWED_TOOLS },
88
- };
89
- }
90
- case "exit": {
91
- const state = deps.getState();
92
- if (!state.active) {
93
- return {
94
- content: [{ type: "text", text: "Not in plan mode. Nothing to exit." }],
95
- details: { type: "plan_mode", error: "not_active" },
96
- };
97
- }
98
- const result = await deps.exitPlanMode(params.plan, params.planFilePath);
99
- if (!result.success) {
100
- return {
101
- content: [{ type: "text", text: `Error: ${result.error || "failed to exit plan mode"}` }],
102
- details: { type: "plan_mode", error: result.error },
103
- };
104
- }
105
- const lines = ["Exited plan mode. Full tool access restored."];
106
- if (params.plan) {
107
- lines.push("", "Submitted plan for approval:", "", params.plan);
108
- }
109
- return {
110
- content: [{ type: "text", text: lines.join("\n") }],
111
- details: { type: "plan_mode", action: "exit", hasPlan: !!params.plan },
112
- };
113
- }
114
- default:
115
- return {
116
- content: [{ type: "text", text: `Error: unknown action "${params.action}". Use "enter" or "exit".` }],
117
- details: { type: "plan_mode", error: "unknown_action" },
118
- };
119
- }
120
- },
121
- };
122
- }
@@ -1,51 +0,0 @@
1
- import type { PortableTool } from "../portable-tool.js";
2
- export declare const READ_TOOL_NAME: "read";
3
- export interface ReadToolParams {
4
- path: string;
5
- offset?: number;
6
- limit?: number;
7
- }
8
- export declare const READ_TOOL_SCHEMA: {
9
- readonly type: "object";
10
- readonly properties: {
11
- readonly path: {
12
- readonly type: "string";
13
- readonly description: "Absolute path to the file to read.";
14
- };
15
- readonly offset: {
16
- readonly type: "number";
17
- readonly description: "Line number to start reading from (1-indexed). Default: 1.";
18
- };
19
- readonly limit: {
20
- readonly type: "number";
21
- readonly description: "Maximum number of lines to read. Default/max: 2000.";
22
- };
23
- };
24
- readonly required: readonly ["path"];
25
- };
26
- export type ReadResultType = "text" | "image" | "binary_rejected";
27
- /** Deps injected by the host runtime for file reading. */
28
- export interface ReadToolDeps {
29
- /** Read file content. Return string for text, base64 for images, or rejection. */
30
- readFile(path: string): Promise<{
31
- type: "text";
32
- text: string;
33
- } | {
34
- type: "image";
35
- base64: string;
36
- mimeType: string;
37
- } | {
38
- type: "binary";
39
- mimeType: string;
40
- }>;
41
- /** Resolve a relative path to absolute. */
42
- resolvePath(input: string): string;
43
- /**
44
- * Validate read access for the given path.
45
- * Returns null if allowed, or an error message if blocked.
46
- * Blocks device paths (/dev/zero, /dev/random, etc.) and
47
- * paths outside the allowed workspace.
48
- */
49
- validatePath?(path: string): string | null;
50
- }
51
- export declare function createReadTool(deps: ReadToolDeps): PortableTool<ReadToolParams>;
@@ -1,84 +0,0 @@
1
- // ============================================================
2
- // File Read Tool — read file contents with offset/limit.
3
- // Reference: claude-code-haha/src/tools/FileReadTool/FileReadTool.ts
4
- // Category: coding
5
- // ============================================================
6
- export const READ_TOOL_NAME = "read";
7
- export const READ_TOOL_SCHEMA = {
8
- type: "object",
9
- properties: {
10
- path: {
11
- type: "string",
12
- description: "Absolute path to the file to read.",
13
- },
14
- offset: {
15
- type: "number",
16
- description: "Line number to start reading from (1-indexed). Default: 1.",
17
- },
18
- limit: {
19
- type: "number",
20
- description: "Maximum number of lines to read. Default/max: 2000.",
21
- },
22
- },
23
- required: ["path"],
24
- };
25
- export function createReadTool(deps) {
26
- const MAX_LINES = 2000;
27
- const MAX_BYTES = 50_000;
28
- return {
29
- name: READ_TOOL_NAME,
30
- label: "Read File",
31
- description: "Read the contents of a file. Supports text files and images (jpg, png, gif, webp). " +
32
- "For text files, output is truncated to 2000 lines or 50KB. " +
33
- "Binary files are rejected with a hint. " +
34
- "Use offset/limit for pagination of large files.",
35
- parameters: READ_TOOL_SCHEMA,
36
- execute: async (_toolCallId, params) => {
37
- const resolved = deps.resolvePath(params.path);
38
- // Validate path access
39
- if (deps.validatePath) {
40
- const blocked = deps.validatePath(resolved);
41
- if (blocked) {
42
- return {
43
- content: [{ type: "text", text: `Access denied: ${blocked}` }],
44
- details: { type: "read", path: resolved, error: "access_denied" },
45
- };
46
- }
47
- }
48
- const result = await deps.readFile(resolved);
49
- // Image
50
- if (result.type === "image") {
51
- return {
52
- content: [{ type: "image", data: result.base64, mimeType: result.mimeType }],
53
- details: { type: "read", path: resolved, isImage: true },
54
- };
55
- }
56
- // Binary rejection
57
- if (result.type === "binary") {
58
- return {
59
- content: [{
60
- type: "text",
61
- text: `Cannot read binary file (${result.mimeType}). ` +
62
- "Use a specific tool for this file type (e.g. pdf tool for PDFs).",
63
- }],
64
- details: { type: "read", path: resolved, error: "binary_file", mimeType: result.mimeType },
65
- };
66
- }
67
- // Text file
68
- const lines = result.text.split("\n");
69
- const offset = Math.max(0, (params.offset ?? 1) - 1);
70
- const limit = Math.min(params.limit ?? MAX_LINES, MAX_LINES);
71
- const sliced = lines.slice(offset, offset + limit);
72
- let text = sliced.join("\n");
73
- if (text.length > MAX_BYTES)
74
- text = text.slice(0, MAX_BYTES) + "\n... (truncated)";
75
- const totalLines = lines.length;
76
- const endLine = offset + sliced.length;
77
- const hasMore = endLine < totalLines;
78
- return {
79
- content: [{ type: "text", text }],
80
- details: { type: "read", path: resolved, totalLines, startLine: offset + 1, endLine, hasMore },
81
- };
82
- },
83
- };
84
- }
@@ -1,70 +0,0 @@
1
- import type { PortableTool } from "../portable-tool.js";
2
- export declare const REPL_TOOL_NAME: "repl";
3
- export interface ReplToolParams {
4
- /** JavaScript code to execute in the persistent VM context */
5
- code: string;
6
- }
7
- export declare const REPL_TOOL_SCHEMA: {
8
- readonly type: "object";
9
- readonly properties: {
10
- readonly code: {
11
- readonly type: "string";
12
- readonly description: string;
13
- };
14
- };
15
- readonly required: readonly ["code"];
16
- };
17
- export interface ReplExecResult {
18
- output: string;
19
- error?: string;
20
- duration: number;
21
- }
22
- /** Primitive operations injected into the VM context. */
23
- export interface ReplPrimitives {
24
- readFile(path: string): Promise<string>;
25
- writeFile(path: string, content: string): Promise<void>;
26
- editFile(path: string, edits: Array<{
27
- oldText: string;
28
- newText: string;
29
- }>): Promise<string>;
30
- exec(command: string): Promise<{
31
- stdout: string;
32
- stderr: string;
33
- exitCode: number;
34
- }>;
35
- glob(pattern: string): Promise<string[]>;
36
- grep(pattern: string, path?: string): Promise<Array<{
37
- file: string;
38
- line: number;
39
- text: string;
40
- }>>;
41
- }
42
- /**
43
- * Host-provided REPL execution backend.
44
- */
45
- export interface ReplToolDeps {
46
- /**
47
- * Execute JavaScript code within a persistent VM context.
48
- * The VM is pre-initialized with the primitive functions above.
49
- * Each tool invocation reuses the same VM (preserving variable state).
50
- */
51
- executeInVm(code: string): Promise<ReplExecResult>;
52
- /**
53
- * Reset the VM context (clear state). Optional hook called on errors.
54
- */
55
- resetVm?(): void;
56
- /**
57
- * The host-provided primitives injected into the VM.
58
- * When provided, the tool validates that the host has set up all required primitives.
59
- */
60
- primitives?: ReplPrimitives;
61
- /**
62
- * Permission check for individual primitive operations.
63
- * Called before each primitive executes inside the VM.
64
- * Returns null if allowed, or an error message if denied.
65
- */
66
- checkPermission?(operation: string, args: unknown[]): Promise<string | null>;
67
- }
68
- /** Tool names that should be hidden from direct LLM access when REPL is active. */
69
- export declare const REPL_HIDES_TOOLS: readonly string[];
70
- export declare function createReplTool(deps: ReplToolDeps): PortableTool<ReplToolParams>;
@@ -1,69 +0,0 @@
1
- // ============================================================
2
- // REPL Tool — execute JavaScript in a persistent VM context
3
- // with injected tool primitives for batch operations.
4
- // Reference: claude-code-haha/src/tools/REPLTool/primitiveTools.ts
5
- // Category: system
6
- // ============================================================
7
- export const REPL_TOOL_NAME = "repl";
8
- export const REPL_TOOL_SCHEMA = {
9
- type: "object",
10
- properties: {
11
- code: {
12
- type: "string",
13
- description: "JavaScript code to execute. The VM has access to these built-in primitives:\n" +
14
- "- readFile(path): Promise<string> — read a file\n" +
15
- "- writeFile(path, content): Promise<void> — write a file\n" +
16
- "- editFile(path, edits): Promise<string> — apply edits [{oldText, newText}]\n" +
17
- "- exec(command): Promise<{stdout, stderr, exitCode}> — run shell command\n" +
18
- "- glob(pattern): Promise<string[]> — find files by glob\n" +
19
- "- grep(pattern, path?): Promise<{file,line,text}[]> — search files\n" +
20
- "Use this for batch operations (rename many files, transform data, etc) " +
21
- "to reduce tool call round-trips.",
22
- },
23
- },
24
- required: ["code"],
25
- };
26
- /** Tool names that should be hidden from direct LLM access when REPL is active. */
27
- export const REPL_HIDES_TOOLS = ["read", "write", "edit", "exec", "search"];
28
- const MAX_CODE_LENGTH = 100_000;
29
- const MAX_OUTPUT_LENGTH = 50_000;
30
- export function createReplTool(deps) {
31
- return {
32
- name: REPL_TOOL_NAME,
33
- label: "REPL",
34
- description: "Execute JavaScript in a persistent VM with built-in file/shell primitives. " +
35
- "Use for batch operations that would otherwise require many individual tool calls. " +
36
- "The VM persists variables between calls within the same session. " +
37
- "Each primitive (readFile, writeFile, exec, etc.) still goes through permission checks.",
38
- parameters: REPL_TOOL_SCHEMA,
39
- execute: async (_toolCallId, params) => {
40
- if (!params.code || params.code.trim().length === 0) {
41
- return {
42
- content: [{ type: "text", text: "Error: code is required." }],
43
- details: { type: "repl", error: "empty_code" },
44
- };
45
- }
46
- if (params.code.length > MAX_CODE_LENGTH) {
47
- return {
48
- content: [{ type: "text", text: `Error: code too large (${params.code.length} chars, max ${MAX_CODE_LENGTH}).` }],
49
- details: { type: "repl", error: "code_too_large" },
50
- };
51
- }
52
- const result = await deps.executeInVm(params.code);
53
- let output = result.output || "";
54
- if (output.length > MAX_OUTPUT_LENGTH) {
55
- output = output.slice(0, MAX_OUTPUT_LENGTH) + "\n... (truncated)";
56
- }
57
- if (result.error) {
58
- return {
59
- content: [{ type: "text", text: `Error: ${result.error}\n\nOutput:\n${output}` }],
60
- details: { type: "repl", error: result.error, duration: result.duration },
61
- };
62
- }
63
- return {
64
- content: [{ type: "text", text: output || "(no output)" }],
65
- details: { type: "repl", duration: result.duration, outputLength: output.length },
66
- };
67
- },
68
- };
69
- }
@@ -1,112 +0,0 @@
1
- import type { PortableTool } from "../portable-tool.js";
2
- export declare const SEARCH_TOOL_NAME: "search";
3
- export type SearchMode = "filename" | "content" | "both";
4
- export interface SearchToolParams {
5
- mode: SearchMode;
6
- pattern: string;
7
- path?: string;
8
- fileGlob?: string;
9
- contextLines?: number;
10
- caseInsensitive?: boolean;
11
- headLimit?: number;
12
- offset?: number;
13
- }
14
- export declare const SEARCH_TOOL_SCHEMA: {
15
- readonly type: "object";
16
- readonly properties: {
17
- readonly mode: {
18
- readonly type: "string";
19
- readonly enum: readonly ["filename", "content", "both"];
20
- readonly description: string;
21
- };
22
- readonly pattern: {
23
- readonly type: "string";
24
- readonly description: string;
25
- };
26
- readonly path: {
27
- readonly type: "string";
28
- readonly description: "Directory to search in. Defaults to workdir/cwd if omitted.";
29
- };
30
- readonly fileGlob: {
31
- readonly type: "string";
32
- readonly description: string;
33
- };
34
- readonly contextLines: {
35
- readonly type: "number";
36
- readonly description: string;
37
- };
38
- readonly caseInsensitive: {
39
- readonly type: "boolean";
40
- readonly description: "Case insensitive search (content/both modes). Default: false.";
41
- };
42
- readonly headLimit: {
43
- readonly type: "number";
44
- readonly description: string;
45
- };
46
- readonly offset: {
47
- readonly type: "number";
48
- readonly description: "Skip first N results before applying headLimit. Default: 0.";
49
- };
50
- };
51
- readonly required: readonly ["mode", "pattern"];
52
- };
53
- export interface SearchFileResult {
54
- path: string;
55
- }
56
- export interface SearchContentResult {
57
- path: string;
58
- line: number;
59
- text: string;
60
- contextBefore?: string[];
61
- contextAfter?: string[];
62
- }
63
- export interface SearchOutput {
64
- mode: SearchMode;
65
- totalMatches: number;
66
- truncated: boolean;
67
- fileResults?: SearchFileResult[];
68
- contentResults?: SearchContentResult[];
69
- }
70
- /** Host-provided search backend. */
71
- export interface SearchToolDeps {
72
- /**
73
- * Find files matching a glob pattern.
74
- * Returns array of relative file paths.
75
- * The host SHOULD auto-exclude VCS directories (.git, .svn, .hg, .bzr)
76
- * unless the user explicitly includes them.
77
- */
78
- glob(pattern: string, options: {
79
- cwd: string;
80
- limit: number;
81
- }): Promise<{
82
- files: string[];
83
- truncated: boolean;
84
- }>;
85
- /**
86
- * Search file contents using regex.
87
- * The implementation may use ripgrep, native grep, or a custom engine.
88
- * Returns match records.
89
- * The host SHOULD auto-exclude VCS directories (.git, .svn, .hg, .bzr)
90
- * and enforce --max-columns 500 to avoid minified file noise.
91
- */
92
- grep(pattern: string, options: {
93
- cwd: string;
94
- fileGlob?: string;
95
- caseInsensitive?: boolean;
96
- contextLines?: number;
97
- headLimit?: number;
98
- offset?: number;
99
- }): Promise<{
100
- matches: Array<{
101
- path: string;
102
- line: number;
103
- text: string;
104
- contextBefore?: string[];
105
- contextAfter?: string[];
106
- }>;
107
- truncated: boolean;
108
- }>;
109
- /** Resolve relative path to absolute. If omitted, cwd is used. */
110
- resolvePath?(input: string): string;
111
- }
112
- export declare function createSearchTool(deps: SearchToolDeps): PortableTool<SearchToolParams>;