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,57 +0,0 @@
1
- import type { PortableTool } from "../portable-tool.js";
2
- export declare const WEB_SEARCH_TOOL_NAME: "web_search";
3
- export interface WebSearchToolParams {
4
- query: string;
5
- allowedDomains?: string[];
6
- blockedDomains?: string[];
7
- }
8
- export declare const WEB_SEARCH_TOOL_SCHEMA: {
9
- readonly type: "object";
10
- readonly properties: {
11
- readonly query: {
12
- readonly type: "string";
13
- readonly description: "Search query string. Be specific and concise for best results.";
14
- };
15
- readonly allowedDomains: {
16
- readonly type: "array";
17
- readonly items: {
18
- readonly type: "string";
19
- };
20
- readonly description: string;
21
- };
22
- readonly blockedDomains: {
23
- readonly type: "array";
24
- readonly items: {
25
- readonly type: "string";
26
- };
27
- readonly description: "Exclude results from these domains. Cannot be used together with allowedDomains.";
28
- };
29
- };
30
- readonly required: readonly ["query"];
31
- };
32
- export interface WebSearchResult {
33
- title: string;
34
- url: string;
35
- snippet: string;
36
- }
37
- export interface WebSearchOutput {
38
- query: string;
39
- results: WebSearchResult[];
40
- totalResults?: number;
41
- }
42
- /**
43
- * Host-provided web search backend.
44
- * The host may use any search engine (SearXNG, Brave, Tavily, etc.).
45
- */
46
- export interface WebSearchToolDeps {
47
- /**
48
- * Execute a web search and return results.
49
- * The host is responsible for API key management and rate limiting.
50
- */
51
- search(query: string, options?: {
52
- allowedDomains?: string[];
53
- blockedDomains?: string[];
54
- maxResults?: number;
55
- }): Promise<WebSearchOutput>;
56
- }
57
- export declare function createWebSearchTool(deps: WebSearchToolDeps): PortableTool<WebSearchToolParams>;
@@ -1,86 +0,0 @@
1
- // ============================================================
2
- // Web Search Tool — search the web for information.
3
- // Reference: claude-code-haha/src/tools/WebSearchTool/WebSearchTool.ts
4
- // hermes-agent-2026.4.30/tools/web_tools.py
5
- // Category: web
6
- // ============================================================
7
- export const WEB_SEARCH_TOOL_NAME = "web_search";
8
- export const WEB_SEARCH_TOOL_SCHEMA = {
9
- type: "object",
10
- properties: {
11
- query: {
12
- type: "string",
13
- description: "Search query string. Be specific and concise for best results.",
14
- },
15
- allowedDomains: {
16
- type: "array",
17
- items: { type: "string" },
18
- description: "Only include results from these domains (e.g. ['docs.python.org', 'stackoverflow.com']). " +
19
- "Cannot be used together with blockedDomains.",
20
- },
21
- blockedDomains: {
22
- type: "array",
23
- items: { type: "string" },
24
- description: "Exclude results from these domains. Cannot be used together with allowedDomains.",
25
- },
26
- },
27
- required: ["query"],
28
- };
29
- const MAX_RESULTS = 10;
30
- export function createWebSearchTool(deps) {
31
- return {
32
- name: WEB_SEARCH_TOOL_NAME,
33
- label: "Web Search",
34
- description: "Search the web for current information. Returns top results with title, URL, and snippet. " +
35
- "Use this when you need up-to-date information that may not be in your training data. " +
36
- "You MUST include source URLs as markdown links when citing search results.",
37
- parameters: WEB_SEARCH_TOOL_SCHEMA,
38
- execute: async (_toolCallId, params) => {
39
- // Validate mutual exclusivity
40
- if (params.allowedDomains?.length && params.blockedDomains?.length) {
41
- return {
42
- content: [{ type: "text", text: "Error: allowedDomains and blockedDomains cannot both be specified." }],
43
- details: { type: "web_search", error: "mutual_exclusion" },
44
- };
45
- }
46
- // Validate query
47
- if (!params.query || params.query.trim().length < 2) {
48
- return {
49
- content: [{ type: "text", text: "Error: query must be at least 2 characters." }],
50
- details: { type: "web_search", error: "invalid_query" },
51
- };
52
- }
53
- const output = await deps.search(params.query.trim(), {
54
- allowedDomains: params.allowedDomains,
55
- blockedDomains: params.blockedDomains,
56
- maxResults: MAX_RESULTS,
57
- });
58
- if (output.results.length === 0) {
59
- return {
60
- content: [{ type: "text", text: `No results found for: "${params.query}"` }],
61
- details: { type: "web_search", query: params.query, resultCount: 0 },
62
- };
63
- }
64
- const lines = [
65
- `Web search results for: "${output.query}"`,
66
- "",
67
- "REMINDER: You MUST include source URLs as markdown links when referencing these results.",
68
- "",
69
- ];
70
- for (let i = 0; i < output.results.length; i++) {
71
- const r = output.results[i];
72
- lines.push(`${i + 1}. [${r.title}](${r.url})`);
73
- lines.push(` ${r.snippet}`);
74
- lines.push("");
75
- }
76
- return {
77
- content: [{ type: "text", text: lines.join("\n") }],
78
- details: {
79
- type: "web_search",
80
- query: output.query,
81
- resultCount: output.results.length,
82
- },
83
- };
84
- },
85
- };
86
- }
@@ -1,69 +0,0 @@
1
- import type { PortableTool } from "../portable-tool.js";
2
- export declare const WORKTREE_TOOL_NAME: "worktree";
3
- export type WorktreeAction = "enter" | "exit" | "list";
4
- export interface WorktreeToolParams {
5
- /** Action: enter (create worktree), exit (leave worktree), list (show all) */
6
- action: WorktreeAction;
7
- /** Branch/worktree name (for enter). kebab-case, max 64 chars. */
8
- name?: string;
9
- /** For exit: 'keep' retains the worktree, 'remove' deletes it */
10
- exitAction?: "keep" | "remove";
11
- /** Required true to discard uncommitted changes on exit with remove */
12
- discardChanges?: boolean;
13
- }
14
- export declare const WORKTREE_TOOL_SCHEMA: {
15
- readonly type: "object";
16
- readonly properties: {
17
- readonly action: {
18
- readonly type: "string";
19
- readonly enum: readonly ["enter", "exit", "list"];
20
- readonly description: string;
21
- };
22
- readonly name: {
23
- readonly type: "string";
24
- readonly description: string;
25
- };
26
- readonly exitAction: {
27
- readonly type: "string";
28
- readonly enum: readonly ["keep", "remove"];
29
- readonly description: "For exit: 'keep' retains the worktree for later use; 'remove' deletes it.";
30
- };
31
- readonly discardChanges: {
32
- readonly type: "boolean";
33
- readonly description: string;
34
- };
35
- };
36
- readonly required: readonly ["action"];
37
- };
38
- export interface WorktreeInfo {
39
- name: string;
40
- path: string;
41
- branch: string;
42
- isCurrent: boolean;
43
- hasChanges: boolean;
44
- unpushedCommits: number;
45
- }
46
- export interface WorktreeResult {
47
- success: boolean;
48
- worktree?: WorktreeInfo;
49
- worktrees?: WorktreeInfo[];
50
- previousCwd?: string;
51
- error?: string;
52
- }
53
- /**
54
- * Host-provided git worktree backend.
55
- * Manages worktree creation, switching, and cleanup.
56
- */
57
- export interface WorktreeToolDeps {
58
- /** Create a new worktree and switch session cwd */
59
- enterWorktree(name?: string): Promise<WorktreeResult>;
60
- /** Exit worktree (keep or remove) */
61
- exitWorktree(action: "keep" | "remove", discardChanges?: boolean): Promise<WorktreeResult>;
62
- /** List all worktrees */
63
- listWorktrees(): Promise<WorktreeResult>;
64
- /** Check if currently in a worktree */
65
- isInWorktree(): boolean;
66
- /** Get current worktree info */
67
- currentWorktree?(): WorktreeInfo | null;
68
- }
69
- export declare function createWorktreeTool(deps: WorktreeToolDeps): PortableTool<WorktreeToolParams>;
@@ -1,147 +0,0 @@
1
- // ============================================================
2
- // Worktree Tool — git worktree isolation for parallel development.
3
- // Reference: claude-code-haha/src/tools/EnterWorktreeTool/EnterWorktreeTool.ts
4
- // claude-code-haha/src/tools/ExitWorktreeTool/ExitWorktreeTool.ts
5
- // Category: system (git)
6
- // Dependency: #13 AgentTool
7
- // ============================================================
8
- export const WORKTREE_TOOL_NAME = "worktree";
9
- export const WORKTREE_TOOL_SCHEMA = {
10
- type: "object",
11
- properties: {
12
- action: {
13
- type: "string",
14
- enum: ["enter", "exit", "list"],
15
- description: "enter: Create and switch to an isolated git worktree branch.\n" +
16
- "exit: Leave worktree (keep or remove it).\n" +
17
- "list: Show all active worktrees.",
18
- },
19
- name: {
20
- type: "string",
21
- description: "Worktree/branch name (for enter). Must be kebab-case, max 64 characters. " +
22
- "If omitted, auto-generated from task context.",
23
- },
24
- exitAction: {
25
- type: "string",
26
- enum: ["keep", "remove"],
27
- description: "For exit: 'keep' retains the worktree for later use; 'remove' deletes it.",
28
- },
29
- discardChanges: {
30
- type: "boolean",
31
- description: "Required true to confirm discarding uncommitted changes when exitAction='remove'. " +
32
- "Safety mechanism to prevent data loss.",
33
- },
34
- },
35
- required: ["action"],
36
- };
37
- const NAME_PATTERN = /^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]?$/;
38
- export function createWorktreeTool(deps) {
39
- return {
40
- name: WORKTREE_TOOL_NAME,
41
- label: "Git Worktree",
42
- description: "Create isolated git worktree branches for parallel development. " +
43
- "Each worktree has its own working directory independent of the main branch. " +
44
- "Use for: parallel features, safe experimentation, sub-agent isolation. " +
45
- "Exit to keep or remove the worktree when done.",
46
- parameters: WORKTREE_TOOL_SCHEMA,
47
- execute: async (_toolCallId, params) => {
48
- switch (params.action) {
49
- case "enter": {
50
- if (deps.isInWorktree()) {
51
- return {
52
- content: [{ type: "text", text: "Error: already in a worktree. Exit first before entering another." }],
53
- details: { type: "worktree", error: "already_in_worktree" },
54
- };
55
- }
56
- if (params.name && !NAME_PATTERN.test(params.name)) {
57
- return {
58
- content: [{ type: "text", text: "Error: name must be kebab-case (a-z, 0-9, hyphens), 2-64 characters." }],
59
- details: { type: "worktree", error: "invalid_name" },
60
- };
61
- }
62
- const result = await deps.enterWorktree(params.name);
63
- if (!result.success) {
64
- return {
65
- content: [{ type: "text", text: `Error: ${result.error || "failed to create worktree"}` }],
66
- details: { type: "worktree", error: result.error },
67
- };
68
- }
69
- const wt = result.worktree;
70
- const lines = [
71
- `Entered worktree: ${wt.name}`,
72
- ` Branch: ${wt.branch}`,
73
- ` Path: ${wt.path}`,
74
- "",
75
- "Working in isolated branch. Changes here do not affect the main branch.",
76
- "Use action='exit' when done (keep or remove).",
77
- ];
78
- return {
79
- content: [{ type: "text", text: lines.join("\n") }],
80
- details: { type: "worktree", action: "enter", name: wt.name, branch: wt.branch, path: wt.path },
81
- };
82
- }
83
- case "exit": {
84
- if (!deps.isInWorktree()) {
85
- return {
86
- content: [{ type: "text", text: "Error: not in a worktree." }],
87
- details: { type: "worktree", error: "not_in_worktree" },
88
- };
89
- }
90
- const exitAction = params.exitAction || "keep";
91
- // Safety: require explicit discard confirmation for remove with changes
92
- if (exitAction === "remove") {
93
- const current = deps.currentWorktree?.();
94
- if (current && (current.hasChanges || current.unpushedCommits > 0) && !params.discardChanges) {
95
- const warnings = [];
96
- if (current.hasChanges)
97
- warnings.push("uncommitted changes");
98
- if (current.unpushedCommits > 0)
99
- warnings.push(`${current.unpushedCommits} unpushed commit(s)`);
100
- return {
101
- content: [{ type: "text", text: `Error: worktree has ${warnings.join(" and ")}. Set discardChanges=true to confirm removal, or use exitAction='keep'.` }],
102
- details: { type: "worktree", error: "has_changes", hasChanges: current.hasChanges, unpushedCommits: current.unpushedCommits },
103
- };
104
- }
105
- }
106
- const result = await deps.exitWorktree(exitAction, params.discardChanges);
107
- if (!result.success) {
108
- return {
109
- content: [{ type: "text", text: `Error: ${result.error || "failed to exit worktree"}` }],
110
- details: { type: "worktree", error: result.error },
111
- };
112
- }
113
- const action = exitAction === "keep" ? "Worktree kept for later use." : "Worktree removed.";
114
- return {
115
- content: [{ type: "text", text: `Exited worktree. ${action}\nRestored to: ${result.previousCwd || "main workspace"}` }],
116
- details: { type: "worktree", action: "exit", exitAction, previousCwd: result.previousCwd },
117
- };
118
- }
119
- case "list": {
120
- const result = await deps.listWorktrees();
121
- if (!result.worktrees || result.worktrees.length === 0) {
122
- return {
123
- content: [{ type: "text", text: "No worktrees (only the main working tree)." }],
124
- details: { type: "worktree", action: "list", count: 0 },
125
- };
126
- }
127
- const lines = [`Worktrees (${result.worktrees.length}):`, ""];
128
- for (const wt of result.worktrees) {
129
- const current = wt.isCurrent ? " ← current" : "";
130
- const status = wt.hasChanges ? " (has changes)" : "";
131
- lines.push(` ${wt.name} [${wt.branch}]${current}${status}`);
132
- lines.push(` path: ${wt.path}`);
133
- }
134
- return {
135
- content: [{ type: "text", text: lines.join("\n") }],
136
- details: { type: "worktree", action: "list", count: result.worktrees.length },
137
- };
138
- }
139
- default:
140
- return {
141
- content: [{ type: "text", text: `Error: unknown action "${params.action}".` }],
142
- details: { type: "worktree", error: "unknown_action" },
143
- };
144
- }
145
- },
146
- };
147
- }
@@ -1,45 +0,0 @@
1
- import type { PortableTool } from "../portable-tool.js";
2
- export declare const WRITE_TOOL_NAME: "write";
3
- export interface WriteToolParams {
4
- path: string;
5
- content: string;
6
- }
7
- export declare const WRITE_TOOL_SCHEMA: {
8
- readonly type: "object";
9
- readonly properties: {
10
- readonly path: {
11
- readonly type: "string";
12
- readonly description: "Absolute path to the file to write.";
13
- };
14
- readonly content: {
15
- readonly type: "string";
16
- readonly description: "Content to write to the file.";
17
- };
18
- };
19
- readonly required: readonly ["path", "content"];
20
- };
21
- /** Deps injected by the host runtime for file writing. */
22
- export interface WriteToolDeps {
23
- /** Write content to a file. Create parent dirs as needed. */
24
- writeFile(path: string, content: string): Promise<void>;
25
- /** Resolve a relative path to absolute. */
26
- resolvePath(input: string): string;
27
- /**
28
- * Check if file has been read before writing (first-read-then-write protection).
29
- * Returns null if write is allowed, or a warning message.
30
- * If not provided, no protection is applied.
31
- */
32
- checkReadBeforeWrite?(path: string): string | null;
33
- /**
34
- * Validate write access for the given path.
35
- * Returns null if allowed, or an error message if blocked.
36
- */
37
- validatePath?(path: string): string | null;
38
- /**
39
- * Check for concurrent modification before overwriting an existing file.
40
- * Returns null if safe to write, or a warning if modified since last read.
41
- * If not provided, no concurrent modification check is performed.
42
- */
43
- checkConcurrentModification?(path: string): string | null;
44
- }
45
- export declare function createWriteTool(deps: WriteToolDeps): PortableTool<WriteToolParams>;
@@ -1,81 +0,0 @@
1
- // ============================================================
2
- // File Write Tool — create/overwrite files.
3
- // Reference: claude-code-haha/src/tools/FileWriteTool/FileWriteTool.ts
4
- // Category: coding
5
- // ============================================================
6
- export const WRITE_TOOL_NAME = "write";
7
- export const WRITE_TOOL_SCHEMA = {
8
- type: "object",
9
- properties: {
10
- path: {
11
- type: "string",
12
- description: "Absolute path to the file to write.",
13
- },
14
- content: {
15
- type: "string",
16
- description: "Content to write to the file.",
17
- },
18
- },
19
- required: ["path", "content"],
20
- };
21
- const MAX_WRITE_SIZE = 500_000; // 500KB safety limit
22
- export function createWriteTool(deps) {
23
- return {
24
- name: WRITE_TOOL_NAME,
25
- label: "Write File",
26
- description: "Write content to a file. Creates the file if it doesn't exist, overwrites if it does. " +
27
- "Automatically creates parent directories. " +
28
- "Prefer edit/patch for modifying existing files (safer than full overwrite).",
29
- parameters: WRITE_TOOL_SCHEMA,
30
- execute: async (_toolCallId, params) => {
31
- const resolved = deps.resolvePath(params.path);
32
- // Validate path access
33
- if (deps.validatePath) {
34
- const blocked = deps.validatePath(resolved);
35
- if (blocked) {
36
- return {
37
- content: [{ type: "text", text: `Access denied: ${blocked}` }],
38
- details: { type: "write", path: resolved, error: "access_denied" },
39
- };
40
- }
41
- }
42
- // Large file protection
43
- if (params.content.length > MAX_WRITE_SIZE) {
44
- return {
45
- content: [{
46
- type: "text",
47
- text: `Content too large (${params.content.length} chars, max ${MAX_WRITE_SIZE}). ` +
48
- "Split into multiple writes or use a different approach.",
49
- }],
50
- details: { type: "write", path: resolved, error: "content_too_large" },
51
- };
52
- }
53
- // First-read-then-write protection
54
- if (deps.checkReadBeforeWrite) {
55
- const warning = deps.checkReadBeforeWrite(resolved);
56
- if (warning) {
57
- return {
58
- content: [{ type: "text", text: warning }],
59
- details: { type: "write", path: resolved, error: "not_read_first" },
60
- };
61
- }
62
- }
63
- // Concurrent modification detection
64
- if (deps.checkConcurrentModification) {
65
- const conflict = deps.checkConcurrentModification(resolved);
66
- if (conflict) {
67
- return {
68
- content: [{ type: "text", text: `Concurrent modification detected: ${conflict}. Re-read the file first.` }],
69
- details: { type: "write", path: resolved, error: "concurrent_modification" },
70
- };
71
- }
72
- }
73
- await deps.writeFile(resolved, params.content);
74
- const lineCount = params.content.split("\n").length;
75
- return {
76
- content: [{ type: "text", text: `Wrote ${lineCount} lines to ${resolved}` }],
77
- details: { type: "write", path: resolved, lineCount },
78
- };
79
- },
80
- };
81
- }