joonecli 0.1.1 → 0.2.1

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 (235) hide show
  1. package/dist/__tests__/config.test.js +1 -0
  2. package/dist/__tests__/config.test.js.map +1 -1
  3. package/dist/__tests__/installHostDeps.test.js +45 -0
  4. package/dist/__tests__/installHostDeps.test.js.map +1 -0
  5. package/dist/__tests__/whitelistedBackend.test.js +18 -0
  6. package/dist/__tests__/whitelistedBackend.test.js.map +1 -0
  7. package/dist/cli/config.d.ts +2 -0
  8. package/dist/cli/config.js +1 -0
  9. package/dist/cli/config.js.map +1 -1
  10. package/dist/cli/index.js +84 -97
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/commands/builtinCommands.js +6 -6
  13. package/dist/commands/builtinCommands.js.map +1 -1
  14. package/dist/commands/commandRegistry.d.ts +3 -1
  15. package/dist/commands/commandRegistry.js.map +1 -1
  16. package/dist/core/agentLoop.d.ts +11 -28
  17. package/dist/core/agentLoop.js +68 -229
  18. package/dist/core/agentLoop.js.map +1 -1
  19. package/dist/core/compactor.js +2 -2
  20. package/dist/core/compactor.js.map +1 -1
  21. package/dist/core/contextGuard.d.ts +5 -0
  22. package/dist/core/contextGuard.js +30 -3
  23. package/dist/core/contextGuard.js.map +1 -1
  24. package/dist/core/events.d.ts +45 -0
  25. package/dist/core/events.js +8 -0
  26. package/dist/core/events.js.map +1 -0
  27. package/dist/core/promptBuilder.js.map +1 -1
  28. package/dist/core/sessionStore.js +3 -2
  29. package/dist/core/sessionStore.js.map +1 -1
  30. package/dist/core/tokenCounter.d.ts +8 -1
  31. package/dist/core/tokenCounter.js +28 -0
  32. package/dist/core/tokenCounter.js.map +1 -1
  33. package/dist/hitl/bridge.js +1 -27
  34. package/dist/hitl/bridge.js.map +1 -1
  35. package/dist/middleware/loopDetection.d.ts +7 -23
  36. package/dist/middleware/loopDetection.js +38 -42
  37. package/dist/middleware/loopDetection.js.map +1 -1
  38. package/dist/sandbox/whitelistedBackend.d.ts +5 -0
  39. package/dist/sandbox/whitelistedBackend.js +27 -0
  40. package/dist/sandbox/whitelistedBackend.js.map +1 -0
  41. package/dist/tools/askUser.d.ts +12 -3
  42. package/dist/tools/askUser.js +16 -28
  43. package/dist/tools/askUser.js.map +1 -1
  44. package/dist/tools/bashTool.d.ts +11 -0
  45. package/dist/tools/bashTool.js +51 -0
  46. package/dist/tools/bashTool.js.map +1 -0
  47. package/dist/tools/index.d.ts +15 -27
  48. package/dist/tools/index.js +9 -181
  49. package/dist/tools/index.js.map +1 -1
  50. package/dist/tools/installHostDeps.d.ts +8 -0
  51. package/dist/tools/installHostDeps.js +44 -0
  52. package/dist/tools/installHostDeps.js.map +1 -0
  53. package/dist/tracing/sessionTracer.d.ts +1 -0
  54. package/dist/tracing/sessionTracer.js +4 -1
  55. package/dist/tracing/sessionTracer.js.map +1 -1
  56. package/dist/ui/App.js +116 -55
  57. package/dist/ui/App.js.map +1 -1
  58. package/dist/ui/components/ActionLog.d.ts +7 -0
  59. package/dist/ui/components/ActionLog.js +63 -0
  60. package/dist/ui/components/ActionLog.js.map +1 -0
  61. package/dist/ui/components/FileBrowser.d.ts +2 -0
  62. package/dist/ui/components/FileBrowser.js +41 -0
  63. package/dist/ui/components/FileBrowser.js.map +1 -0
  64. package/dist/ui/components/MessageBubble.js +1 -1
  65. package/dist/ui/components/MessageBubble.js.map +1 -1
  66. package/package.json +8 -5
  67. package/AGENTS.md +0 -56
  68. package/Handover.md +0 -115
  69. package/PROGRESS.md +0 -160
  70. package/dist/__tests__/m55.test.js +0 -160
  71. package/dist/__tests__/m55.test.js.map +0 -1
  72. package/dist/__tests__/middleware.test.js +0 -169
  73. package/dist/__tests__/middleware.test.js.map +0 -1
  74. package/dist/__tests__/optimizations.test.d.ts +0 -1
  75. package/dist/__tests__/optimizations.test.js +0 -136
  76. package/dist/__tests__/optimizations.test.js.map +0 -1
  77. package/dist/__tests__/security.test.d.ts +0 -1
  78. package/dist/__tests__/security.test.js +0 -86
  79. package/dist/__tests__/security.test.js.map +0 -1
  80. package/dist/__tests__/streaming.test.d.ts +0 -1
  81. package/dist/__tests__/streaming.test.js +0 -71
  82. package/dist/__tests__/streaming.test.js.map +0 -1
  83. package/dist/__tests__/toolRouter.test.d.ts +0 -1
  84. package/dist/__tests__/toolRouter.test.js +0 -37
  85. package/dist/__tests__/toolRouter.test.js.map +0 -1
  86. package/dist/__tests__/tools.test.d.ts +0 -1
  87. package/dist/__tests__/tools.test.js +0 -112
  88. package/dist/__tests__/tools.test.js.map +0 -1
  89. package/dist/core/subAgent.d.ts +0 -56
  90. package/dist/core/subAgent.js +0 -240
  91. package/dist/core/subAgent.js.map +0 -1
  92. package/dist/debug_google.d.ts +0 -1
  93. package/dist/debug_google.js +0 -23
  94. package/dist/debug_google.js.map +0 -1
  95. package/dist/middleware/commandSanitizer.d.ts +0 -18
  96. package/dist/middleware/commandSanitizer.js +0 -50
  97. package/dist/middleware/commandSanitizer.js.map +0 -1
  98. package/dist/middleware/permission.d.ts +0 -17
  99. package/dist/middleware/permission.js +0 -59
  100. package/dist/middleware/permission.js.map +0 -1
  101. package/dist/middleware/pipeline.d.ts +0 -31
  102. package/dist/middleware/pipeline.js +0 -62
  103. package/dist/middleware/pipeline.js.map +0 -1
  104. package/dist/middleware/preCompletion.d.ts +0 -29
  105. package/dist/middleware/preCompletion.js +0 -82
  106. package/dist/middleware/preCompletion.js.map +0 -1
  107. package/dist/middleware/types.d.ts +0 -40
  108. package/dist/middleware/types.js +0 -8
  109. package/dist/middleware/types.js.map +0 -1
  110. package/dist/skills/loader.d.ts +0 -55
  111. package/dist/skills/loader.js +0 -132
  112. package/dist/skills/loader.js.map +0 -1
  113. package/dist/skills/tools.d.ts +0 -5
  114. package/dist/skills/tools.js +0 -78
  115. package/dist/skills/tools.js.map +0 -1
  116. package/dist/test_cache.d.ts +0 -1
  117. package/dist/test_cache.js +0 -55
  118. package/dist/test_cache.js.map +0 -1
  119. package/dist/test_google.d.ts +0 -1
  120. package/dist/test_google.js +0 -36
  121. package/dist/test_google.js.map +0 -1
  122. package/dist/tools/browser.d.ts +0 -19
  123. package/dist/tools/browser.js +0 -111
  124. package/dist/tools/browser.js.map +0 -1
  125. package/dist/tools/registry.d.ts +0 -31
  126. package/dist/tools/registry.js +0 -168
  127. package/dist/tools/registry.js.map +0 -1
  128. package/dist/tools/router.d.ts +0 -34
  129. package/dist/tools/router.js +0 -75
  130. package/dist/tools/router.js.map +0 -1
  131. package/dist/tools/security.d.ts +0 -28
  132. package/dist/tools/security.js +0 -183
  133. package/dist/tools/security.js.map +0 -1
  134. package/dist/tools/spawnAgent.d.ts +0 -19
  135. package/dist/tools/spawnAgent.js +0 -130
  136. package/dist/tools/spawnAgent.js.map +0 -1
  137. package/dist/tools/webSearch.d.ts +0 -6
  138. package/dist/tools/webSearch.js +0 -120
  139. package/dist/tools/webSearch.js.map +0 -1
  140. package/docs/01_insights_and_patterns.md +0 -27
  141. package/docs/02_edge_cases_and_mitigations.md +0 -143
  142. package/docs/03_initial_implementation_plan.md +0 -66
  143. package/docs/04_tech_stack_proposal.md +0 -20
  144. package/docs/05_prd.md +0 -87
  145. package/docs/06_user_stories.md +0 -72
  146. package/docs/07_system_architecture.md +0 -138
  147. package/docs/08_roadmap.md +0 -200
  148. package/e2b/Dockerfile +0 -26
  149. package/src/__tests__/bootstrap.test.ts +0 -111
  150. package/src/__tests__/config.test.ts +0 -97
  151. package/src/__tests__/m55.test.ts +0 -238
  152. package/src/__tests__/middleware.test.ts +0 -219
  153. package/src/__tests__/modelFactory.test.ts +0 -63
  154. package/src/__tests__/optimizations.test.ts +0 -201
  155. package/src/__tests__/promptBuilder.test.ts +0 -141
  156. package/src/__tests__/sandbox.test.ts +0 -102
  157. package/src/__tests__/security.test.ts +0 -122
  158. package/src/__tests__/streaming.test.ts +0 -82
  159. package/src/__tests__/toolRouter.test.ts +0 -52
  160. package/src/__tests__/tools.test.ts +0 -146
  161. package/src/__tests__/tracing.test.ts +0 -196
  162. package/src/agents/agentRegistry.ts +0 -69
  163. package/src/agents/agentSpec.ts +0 -67
  164. package/src/agents/builtinAgents.ts +0 -142
  165. package/src/cli/config.ts +0 -124
  166. package/src/cli/index.ts +0 -742
  167. package/src/cli/modelFactory.ts +0 -174
  168. package/src/cli/postinstall.ts +0 -28
  169. package/src/cli/providers.ts +0 -107
  170. package/src/commands/builtinCommands.ts +0 -293
  171. package/src/commands/commandRegistry.ts +0 -194
  172. package/src/core/agentLoop.d.ts.map +0 -1
  173. package/src/core/agentLoop.ts +0 -312
  174. package/src/core/autoSave.ts +0 -95
  175. package/src/core/compactor.ts +0 -252
  176. package/src/core/contextGuard.ts +0 -129
  177. package/src/core/errors.ts +0 -202
  178. package/src/core/promptBuilder.d.ts.map +0 -1
  179. package/src/core/promptBuilder.ts +0 -139
  180. package/src/core/reasoningRouter.ts +0 -121
  181. package/src/core/retry.ts +0 -75
  182. package/src/core/sessionResumer.ts +0 -90
  183. package/src/core/sessionStore.ts +0 -216
  184. package/src/core/subAgent.ts +0 -339
  185. package/src/core/tokenCounter.ts +0 -64
  186. package/src/evals/dataset.ts +0 -67
  187. package/src/evals/evaluator.ts +0 -81
  188. package/src/hitl/bridge.ts +0 -160
  189. package/src/middleware/commandSanitizer.ts +0 -60
  190. package/src/middleware/loopDetection.ts +0 -63
  191. package/src/middleware/permission.ts +0 -72
  192. package/src/middleware/pipeline.ts +0 -75
  193. package/src/middleware/preCompletion.ts +0 -94
  194. package/src/middleware/types.ts +0 -45
  195. package/src/sandbox/bootstrap.ts +0 -121
  196. package/src/sandbox/manager.ts +0 -239
  197. package/src/sandbox/sync.ts +0 -157
  198. package/src/skills/loader.ts +0 -143
  199. package/src/skills/tools.ts +0 -99
  200. package/src/skills/types.ts +0 -13
  201. package/src/test_cache.ts +0 -72
  202. package/src/tools/askUser.ts +0 -47
  203. package/src/tools/browser.ts +0 -137
  204. package/src/tools/index.d.ts.map +0 -1
  205. package/src/tools/index.ts +0 -237
  206. package/src/tools/registry.ts +0 -198
  207. package/src/tools/router.ts +0 -78
  208. package/src/tools/security.ts +0 -220
  209. package/src/tools/spawnAgent.ts +0 -158
  210. package/src/tools/webSearch.ts +0 -142
  211. package/src/tracing/analyzer.ts +0 -265
  212. package/src/tracing/langsmith.ts +0 -63
  213. package/src/tracing/sessionTracer.ts +0 -202
  214. package/src/tracing/types.ts +0 -49
  215. package/src/types/valyu.d.ts +0 -37
  216. package/src/ui/App.tsx +0 -404
  217. package/src/ui/components/HITLPrompt.tsx +0 -119
  218. package/src/ui/components/Header.tsx +0 -51
  219. package/src/ui/components/MessageBubble.tsx +0 -46
  220. package/src/ui/components/StatusBar.tsx +0 -138
  221. package/src/ui/components/StreamingText.tsx +0 -48
  222. package/src/ui/components/ToolCallPanel.tsx +0 -80
  223. package/tests/commands/commands.test.ts +0 -356
  224. package/tests/core/compactor.test.ts +0 -217
  225. package/tests/core/retryAndErrors.test.ts +0 -164
  226. package/tests/core/sessionResumer.test.ts +0 -95
  227. package/tests/core/sessionStore.test.ts +0 -84
  228. package/tests/core/stability.test.ts +0 -165
  229. package/tests/core/subAgent.test.ts +0 -238
  230. package/tests/hitl/hitlBridge.test.ts +0 -115
  231. package/tsconfig.json +0 -16
  232. package/vitest.config.ts +0 -10
  233. package/vitest.out +0 -48
  234. /package/dist/__tests__/{m55.test.d.ts → installHostDeps.test.d.ts} +0 -0
  235. /package/dist/__tests__/{middleware.test.d.ts → whitelistedBackend.test.d.ts} +0 -0
@@ -1,160 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
- import * as fs from "node:fs";
3
- import * as path from "node:path";
4
- import * as os from "node:os";
5
- import { BrowserTool } from "../tools/browser.js";
6
- import { WebSearchTool, bindValyuApiKey } from "../tools/webSearch.js";
7
- import { SkillLoader } from "../skills/loader.js";
8
- import { SearchSkillsTool, LoadSkillTool, bindSkillLoader, } from "../skills/tools.js";
9
- import { ToolRouter, ToolTarget } from "../tools/router.js";
10
- // ═══════════════════════════════════════════════════════════════════════════════
11
- // 5.5a: Browser Tool
12
- // ═══════════════════════════════════════════════════════════════════════════════
13
- describe("BrowserTool", () => {
14
- // ─── Test #70: Builds navigate command ───
15
- it("has the correct schema with all supported actions", () => {
16
- expect(BrowserTool.name).toBe("browser");
17
- expect(BrowserTool.schema.properties.action.enum).toContain("navigate");
18
- expect(BrowserTool.schema.properties.action.enum).toContain("snapshot");
19
- expect(BrowserTool.schema.properties.action.enum).toContain("click");
20
- expect(BrowserTool.schema.properties.action.enum).toContain("type");
21
- expect(BrowserTool.schema.properties.action.enum).toContain("screenshot");
22
- expect(BrowserTool.schema.properties.action.enum).toContain("scroll");
23
- });
24
- // ─── Test #71: Rejects without sandbox ───
25
- it("throws when sandbox is not active", async () => {
26
- const result = await BrowserTool.execute({ action: "navigate", url: "https://example.com" });
27
- expect(result.isError).toBe(true);
28
- expect(result.content).toMatch(/sandbox/i);
29
- });
30
- });
31
- // ═══════════════════════════════════════════════════════════════════════════════
32
- // 5.5b: Web Search Tool
33
- // ═══════════════════════════════════════════════════════════════════════════════
34
- describe("WebSearchTool", () => {
35
- // ─── Test #72: Returns error if no API key ───
36
- it("returns error when API key is not configured", async () => {
37
- bindValyuApiKey(undefined);
38
- const result = await WebSearchTool.execute({ query: "test" });
39
- expect(result.content).toMatch(/api key not configured/i);
40
- });
41
- // ─── Test #73: Schema includes all sources ───
42
- it("schema includes all search sources", () => {
43
- const sources = WebSearchTool.schema.properties.source.enum;
44
- expect(sources).toContain("web");
45
- expect(sources).toContain("papers");
46
- expect(sources).toContain("finance");
47
- expect(sources).toContain("patents");
48
- expect(sources).toContain("sec");
49
- expect(sources).toContain("companies");
50
- });
51
- });
52
- // ═══════════════════════════════════════════════════════════════════════════════
53
- // 5.5c: Skills System
54
- // ═══════════════════════════════════════════════════════════════════════════════
55
- describe("SkillLoader", () => {
56
- let tmpDir;
57
- beforeEach(() => {
58
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "joone-skills-test-"));
59
- });
60
- afterEach(() => {
61
- fs.rmSync(tmpDir, { recursive: true, force: true });
62
- });
63
- const createSkill = (dir, name, content) => {
64
- const skillDir = path.join(dir, name);
65
- fs.mkdirSync(skillDir, { recursive: true });
66
- fs.writeFileSync(path.join(skillDir, "SKILL.md"), content);
67
- };
68
- // ─── Test #74: Discovers skills from project root ───
69
- it("discovers skills from a directory", () => {
70
- const skillsDir = path.join(tmpDir, "skills");
71
- createSkill(skillsDir, "deploy", "---\nname: deploy\ndescription: Deploy to Vercel\n---\n## Steps\n1. Run vercel deploy");
72
- const loader = new SkillLoader(tmpDir);
73
- const skills = loader.discoverSkills();
74
- expect(skills.length).toBeGreaterThanOrEqual(1);
75
- const deploy = skills.find((s) => s.name === "deploy");
76
- expect(deploy).toBeDefined();
77
- expect(deploy.description).toBe("Deploy to Vercel");
78
- expect(deploy.source).toBe("project");
79
- });
80
- // ─── Test #75: Parses YAML frontmatter ───
81
- it("parses YAML frontmatter correctly", () => {
82
- const loader = new SkillLoader(tmpDir);
83
- const result = loader.parseFrontmatter("---\nname: test-skill\ndescription: A test skill\n---\n# Instructions");
84
- expect(result.name).toBe("test-skill");
85
- expect(result.description).toBe("A test skill");
86
- });
87
- // ─── Test #76: Project skills override user skills with same name ───
88
- it("project skills override user-level skills with the same name", () => {
89
- // Create user-level skill in the mocked home directory (tmpDir)
90
- const userSkillsDir = path.join(tmpDir, ".joone", "skills");
91
- createSkill(userSkillsDir, "deploy", "---\nname: deploy\ndescription: User deploy\n---\n");
92
- // Create project-level skill
93
- const projectSkillsDir = path.join(tmpDir, "skills");
94
- createSkill(projectSkillsDir, "deploy", "---\nname: deploy\ndescription: Project deploy\n---\n");
95
- // Pass tmpDir as both projectRoot and userHome
96
- const loader = new SkillLoader(tmpDir, tmpDir);
97
- const skills = loader.discoverSkills();
98
- const deploy = skills.find((s) => s.name === "deploy");
99
- expect(deploy).toBeDefined();
100
- expect(deploy.source).toBe("project");
101
- expect(deploy.description).toBe("Project deploy");
102
- // Ensure we only discovered one deploy skill
103
- const deployCount = skills.filter((s) => s.name === "deploy").length;
104
- expect(deployCount).toBe(1);
105
- });
106
- // ─── Test #77: loadSkill reads full content ───
107
- it("loads the full content of a skill", () => {
108
- const skillsDir = path.join(tmpDir, "skills");
109
- const content = "---\nname: tdd\ndescription: Test-driven development\n---\n## Red-Green-Refactor\n1. Write failing test";
110
- createSkill(skillsDir, "tdd", content);
111
- const loader = new SkillLoader(tmpDir);
112
- const loaded = loader.loadSkill("tdd");
113
- expect(loaded).toBe(content);
114
- });
115
- });
116
- describe("Skills Tools", () => {
117
- let tmpDir;
118
- beforeEach(() => {
119
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "joone-skills-tools-test-"));
120
- const skillsDir = path.join(tmpDir, "skills");
121
- const skillDir = path.join(skillsDir, "deploy");
122
- fs.mkdirSync(skillDir, { recursive: true });
123
- fs.writeFileSync(path.join(skillDir, "SKILL.md"), "---\nname: deploy\ndescription: Deploy to production\n---\n## Steps");
124
- bindSkillLoader(new SkillLoader(tmpDir));
125
- });
126
- afterEach(() => {
127
- fs.rmSync(tmpDir, { recursive: true, force: true });
128
- });
129
- // ─── Test #78: search_skills returns matching skills ───
130
- it("search_skills finds matching skills", async () => {
131
- const result = await SearchSkillsTool.execute({ query: "deploy" });
132
- expect(result.content).toContain("deploy");
133
- expect(result.content).toContain("production");
134
- });
135
- // ─── Test #79: load_skill reads full content ───
136
- it("load_skill returns the full SKILL.md content", async () => {
137
- const result = await LoadSkillTool.execute({ name: "deploy" });
138
- expect(result.content).toContain("## Steps");
139
- });
140
- });
141
- // ═══════════════════════════════════════════════════════════════════════════════
142
- // Routing
143
- // ═══════════════════════════════════════════════════════════════════════════════
144
- describe("ToolRouter (M5.5 additions)", () => {
145
- const router = new ToolRouter();
146
- // ─── Test #80: Browser routes to sandbox ───
147
- it("routes browser to sandbox", () => {
148
- expect(router.getTarget("browser")).toBe(ToolTarget.SANDBOX);
149
- });
150
- // ─── Test #81: web_search routes to host ───
151
- it("routes web_search to host", () => {
152
- expect(router.getTarget("web_search")).toBe(ToolTarget.HOST);
153
- });
154
- // ─── Test #82: skills tools route to host ───
155
- it("routes search_skills and load_skill to host", () => {
156
- expect(router.getTarget("search_skills")).toBe(ToolTarget.HOST);
157
- expect(router.getTarget("load_skill")).toBe(ToolTarget.HOST);
158
- });
159
- });
160
- //# sourceMappingURL=m55.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"m55.test.js","sourceRoot":"","sources":["../../src/__tests__/m55.test.ts"],"names":[],"mappings":"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"}
@@ -1,169 +0,0 @@
1
- import { describe, it, expect, vi } from "vitest";
2
- import { MiddlewarePipeline } from "../middleware/pipeline.js";
3
- import { LoopDetectionMiddleware } from "../middleware/loopDetection.js";
4
- import { CommandSanitizerMiddleware } from "../middleware/commandSanitizer.js";
5
- import { PreCompletionMiddleware } from "../middleware/preCompletion.js";
6
- // ═══════════════════════════════════════════════════════════════════════════════
7
- // Pipeline Core
8
- // ═══════════════════════════════════════════════════════════════════════════════
9
- describe("MiddlewarePipeline", () => {
10
- const makeCtx = (overrides) => ({
11
- toolName: "bash",
12
- args: { command: "echo hello" },
13
- callId: "call-1",
14
- ...overrides,
15
- });
16
- // ─── Test #44: Runs before/after hooks in order ───
17
- it("runs before hooks in registration order and after hooks in reverse", async () => {
18
- const order = [];
19
- const pipeline = new MiddlewarePipeline();
20
- pipeline.use({
21
- name: "A",
22
- before: (ctx) => { order.push("A:before"); return ctx; },
23
- after: (_ctx, r) => { order.push("A:after"); return r; },
24
- });
25
- pipeline.use({
26
- name: "B",
27
- before: (ctx) => { order.push("B:before"); return ctx; },
28
- after: (_ctx, r) => { order.push("B:after"); return r; },
29
- });
30
- const executeFn = vi.fn(async () => ({ content: "result" }));
31
- await pipeline.run(makeCtx(), executeFn);
32
- expect(order).toEqual(["A:before", "B:before", "B:after", "A:after"]);
33
- expect(executeFn).toHaveBeenCalledOnce();
34
- });
35
- // ─── Test #45: Short-circuits when before returns string ───
36
- it("short-circuits and does NOT execute the tool when before returns a string", async () => {
37
- const pipeline = new MiddlewarePipeline();
38
- pipeline.use({
39
- name: "Blocker",
40
- before: () => "⚠ Blocked!",
41
- });
42
- const executeFn = vi.fn(async () => ({ content: "should not reach this" }));
43
- const result = await pipeline.run(makeCtx(), executeFn);
44
- expect(result).toBe("⚠ Blocked!");
45
- expect(executeFn).not.toHaveBeenCalled();
46
- });
47
- // ─── Test #46: After hooks can transform the result ───
48
- it("after hooks can transform the tool result", async () => {
49
- const pipeline = new MiddlewarePipeline();
50
- pipeline.use({
51
- name: "Uppercaser",
52
- after: (_ctx, result) => { result.content = result.content.toUpperCase(); return result; },
53
- });
54
- const result = await pipeline.run(makeCtx(), async () => ({ content: "hello" }));
55
- expect(result).toBe("HELLO");
56
- });
57
- });
58
- // ═══════════════════════════════════════════════════════════════════════════════
59
- // LoopDetectionMiddleware
60
- // ═══════════════════════════════════════════════════════════════════════════════
61
- describe("LoopDetectionMiddleware", () => {
62
- const makeCtx = (cmd = "echo hello") => ({
63
- toolName: "bash",
64
- args: { command: cmd },
65
- callId: "call-x",
66
- });
67
- // ─── Test #47: Allows first 2 identical calls ───
68
- it("allows calls below the threshold", () => {
69
- const mw = new LoopDetectionMiddleware(3);
70
- expect(mw.before(makeCtx())).toEqual(makeCtx());
71
- expect(mw.before(makeCtx())).toEqual(makeCtx());
72
- });
73
- // ─── Test #48: Blocks on 3rd identical call ───
74
- it("blocks on the Nth identical consecutive call", () => {
75
- const mw = new LoopDetectionMiddleware(3);
76
- mw.before(makeCtx());
77
- mw.before(makeCtx());
78
- const result = mw.before(makeCtx());
79
- expect(typeof result).toBe("string");
80
- expect(result).toMatch(/loop detected/i);
81
- });
82
- // ─── Test #49: Resets when args change ───
83
- it("resets the count when a different call is made", () => {
84
- const mw = new LoopDetectionMiddleware(3);
85
- mw.before(makeCtx("echo a"));
86
- mw.before(makeCtx("echo a"));
87
- // Different call breaks the streak
88
- mw.before(makeCtx("echo b"));
89
- // Back to "echo a" — only 1 in a row now
90
- const result = mw.before(makeCtx("echo a"));
91
- expect(typeof result).not.toBe("string");
92
- });
93
- });
94
- // ═══════════════════════════════════════════════════════════════════════════════
95
- // CommandSanitizerMiddleware
96
- // ═══════════════════════════════════════════════════════════════════════════════
97
- describe("CommandSanitizerMiddleware", () => {
98
- const mw = new CommandSanitizerMiddleware();
99
- const makeCtx = (cmd) => ({
100
- toolName: "bash",
101
- args: { command: cmd },
102
- callId: "call-x",
103
- });
104
- // ─── Test #50: Blocks rm -rf / ───
105
- it("blocks rm -rf /", () => {
106
- const result = mw.before(makeCtx("rm -rf /"));
107
- expect(typeof result).toBe("string");
108
- expect(result).toMatch(/blocked/i);
109
- });
110
- // ─── Test #51: Blocks interactive commands ───
111
- it("blocks interactive commands like vim", () => {
112
- const result = mw.before(makeCtx("vim src/index.ts"));
113
- expect(typeof result).toBe("string");
114
- expect(result).toMatch(/interactive/i);
115
- });
116
- // ─── Test #52: Allows safe commands ───
117
- it("allows safe commands through", () => {
118
- const result = mw.before(makeCtx("npm test"));
119
- expect(result).toEqual(makeCtx("npm test"));
120
- });
121
- // ─── Test #53: Ignores non-bash tools ───
122
- it("ignores non-bash tool calls entirely", () => {
123
- const ctx = {
124
- toolName: "read_file",
125
- args: { path: "/etc/passwd" },
126
- callId: "call-x",
127
- };
128
- expect(mw.before(ctx)).toEqual(ctx);
129
- });
130
- });
131
- // ═══════════════════════════════════════════════════════════════════════════════
132
- // PreCompletionMiddleware
133
- // ═══════════════════════════════════════════════════════════════════════════════
134
- describe("PreCompletionMiddleware", () => {
135
- // ─── Test #54: Blocks completion without tests ───
136
- it("blocks task_complete when no tests have been run", () => {
137
- const mw = new PreCompletionMiddleware();
138
- const ctx = {
139
- toolName: "task_complete",
140
- args: {},
141
- callId: "call-x",
142
- };
143
- const result = mw.before(ctx);
144
- expect(typeof result).toBe("string");
145
- expect(result).toMatch(/must run tests/i);
146
- });
147
- // ─── Test #55: Allows completion after tests ───
148
- it("allows task_complete after a test command has been run", () => {
149
- const mw = new PreCompletionMiddleware();
150
- // Simulate running tests
151
- const testCtx = {
152
- toolName: "bash",
153
- args: { command: "npm test" },
154
- callId: "call-1",
155
- };
156
- mw.before(testCtx);
157
- mw.after(testCtx, { content: "tests passed", metadata: { exitCode: 0 }, isError: false });
158
- expect(mw.hasPassedTests()).toBe(true);
159
- // Now try completion
160
- const completeCtx = {
161
- toolName: "task_complete",
162
- args: {},
163
- callId: "call-2",
164
- };
165
- const result = mw.before(completeCtx);
166
- expect(result).toEqual(completeCtx);
167
- });
168
- });
169
- //# sourceMappingURL=middleware.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"middleware.test.js","sourceRoot":"","sources":["../../src/__tests__/middleware.test.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- export {};
@@ -1,136 +0,0 @@
1
- import { describe, it, expect, beforeEach } from "vitest";
2
- import { HumanMessage, AIMessage } from "@langchain/core/messages";
3
- import { SearchToolsTool, ActivateToolTool, activateTool, getActivatedTools, resetActivatedTools, } from "../tools/registry.js";
4
- import { estimateTokens, countMessageTokens, isNearCapacity, } from "../core/tokenCounter.js";
5
- import { CacheOptimizedPromptBuilder } from "../core/promptBuilder.js";
6
- import { ReasoningRouter, ReasoningLevel, } from "../core/reasoningRouter.js";
7
- // ═══════════════════════════════════════════════════════════════════════════════
8
- // 5a: Enhanced Tool Registry
9
- // ═══════════════════════════════════════════════════════════════════════════════
10
- describe("Enhanced Tool Registry", () => {
11
- beforeEach(() => {
12
- resetActivatedTools();
13
- });
14
- // ─── Test #56: Fuzzy search matches by description keyword ───
15
- it("fuzzy search matches tools by description keyword", async () => {
16
- const result = await SearchToolsTool.execute({ query: "commit" });
17
- expect(result.content).toContain("git_commit");
18
- });
19
- // ─── Test #57: Fuzzy search matches by name ───
20
- it("fuzzy search matches tools by name", async () => {
21
- const result = await SearchToolsTool.execute({ query: "grep" });
22
- expect(result.content).toContain("grep_search");
23
- });
24
- // ─── Test #58: activateTool adds tool to the active set ───
25
- it("activateTool adds a tool to the active set", () => {
26
- expect(getActivatedTools()).toHaveLength(0);
27
- const tool = activateTool("git_commit");
28
- expect(tool).toBeDefined();
29
- expect(tool.name).toBe("git_commit");
30
- expect(getActivatedTools()).toHaveLength(1);
31
- });
32
- // ─── Test #59: ActivateToolTool returns schema on activation ───
33
- it("ActivateToolTool returns the schema on successful activation", async () => {
34
- const result = await ActivateToolTool.execute({ name: "git_diff" });
35
- expect(result.content).toContain("activated");
36
- expect(result.content).toContain("Schema");
37
- expect(getActivatedTools()).toHaveLength(1);
38
- });
39
- // ─── Test #60: ActivateToolTool returns error for unknown tool ───
40
- it("ActivateToolTool returns error for unknown tool", async () => {
41
- const result = await ActivateToolTool.execute({ name: "nonexistent" });
42
- expect(result.content).toMatch(/not found/i);
43
- });
44
- });
45
- // ═══════════════════════════════════════════════════════════════════════════════
46
- // 5b: Token Counter & Context Compaction
47
- // ═══════════════════════════════════════════════════════════════════════════════
48
- describe("Token Counter", () => {
49
- // ─── Test #61: Estimates tokens for short string ───
50
- it("estimates tokens using ~4 chars per token", () => {
51
- const tokens = estimateTokens("Hello world!"); // 12 chars → 3 tokens
52
- expect(tokens).toBe(3);
53
- });
54
- // ─── Test #62: Counts tokens across messages ───
55
- it("counts tokens across multiple messages", () => {
56
- const messages = [
57
- new HumanMessage("Hello"), // 5 chars → 2 tokens + 4 overhead = 6
58
- new AIMessage("Hi there"), // 8 chars → 2 tokens + 4 overhead = 6
59
- ];
60
- const total = countMessageTokens(messages);
61
- expect(total).toBeGreaterThan(0);
62
- expect(total).toBe(12); // (2+4) + (2+4)
63
- });
64
- // ─── Test #63: isNearCapacity detects threshold ───
65
- it("returns true when messages exceed 80% of capacity", () => {
66
- // Create a big message ~320 chars → ~80 tokens
67
- const bigMsg = new HumanMessage("x".repeat(320));
68
- const messages = [bigMsg];
69
- // maxTokens=100, threshold=0.8 → trigger at 80 tokens
70
- // 320/4=80 + 4 overhead = 84 > 80
71
- expect(isNearCapacity(messages, 100, 0.8)).toBe(true);
72
- });
73
- // ─── Test #64: isNearCapacity returns false below threshold ───
74
- it("returns false when well below capacity", () => {
75
- const messages = [new HumanMessage("short")];
76
- expect(isNearCapacity(messages, 100000, 0.8)).toBe(false);
77
- });
78
- });
79
- describe("Context Compaction", () => {
80
- // ─── Test #65: compactHistory preserves last N messages ───
81
- it("preserves the last N messages and prepends summary", () => {
82
- const builder = new CacheOptimizedPromptBuilder();
83
- const history = [
84
- new HumanMessage("msg 1"),
85
- new AIMessage("response 1"),
86
- new HumanMessage("msg 2"),
87
- new AIMessage("response 2"),
88
- new HumanMessage("msg 3"),
89
- new AIMessage("response 3"),
90
- ];
91
- const compacted = builder.compactHistory(history, "Summary of turns 1-2.", 4);
92
- // Should have: 1 summary + 4 preserved
93
- expect(compacted).toHaveLength(5);
94
- expect(compacted[0].content).toContain("compacted");
95
- expect(compacted[0].content).toContain("Summary of turns 1-2.");
96
- });
97
- });
98
- // ═══════════════════════════════════════════════════════════════════════════════
99
- // 5c: Reasoning Sandwich
100
- // ═══════════════════════════════════════════════════════════════════════════════
101
- describe("ReasoningRouter", () => {
102
- // ─── Test #66: First turns are HIGH (planning) ───
103
- it("returns HIGH for the first turn (planning phase)", () => {
104
- const router = new ReasoningRouter();
105
- router.advanceTurn(false, false);
106
- const level = router.getLevel();
107
- expect(level).toBe(ReasoningLevel.HIGH);
108
- });
109
- // ─── Test #67: Tool-heavy turns are MEDIUM ───
110
- it("returns MEDIUM for tool-heavy turns after planning", () => {
111
- const router = new ReasoningRouter({ planningTurns: 1 });
112
- router.advanceTurn(false, false); // turn 1
113
- router.getLevel(); // HIGH (planning)
114
- router.advanceTurn(true, false); // turn 2
115
- const level = router.getLevel(); // tool call shouldn't be high
116
- expect(level).toBe(ReasoningLevel.MEDIUM);
117
- });
118
- // ─── Test #68: Post-error turns are HIGH (recovery) ───
119
- it("returns HIGH for recovery after an error", () => {
120
- const router = new ReasoningRouter({ planningTurns: 1 });
121
- router.advanceTurn(false, false); // turn 1
122
- router.getLevel(); // planning
123
- router.advanceTurn(true, false); // turn 2
124
- router.getLevel(); // tool call (MEDIUM)
125
- router.advanceTurn(false, true); // turn 3
126
- const level = router.getLevel(); // error!
127
- expect(level).toBe(ReasoningLevel.HIGH);
128
- });
129
- // ─── Test #69: Temperature mapping ───
130
- it("maps reasoning levels to correct temperatures", () => {
131
- const router = new ReasoningRouter({ highTemp: 0, mediumTemp: 0.3 });
132
- expect(router.getTemperature(ReasoningLevel.HIGH)).toBe(0);
133
- expect(router.getTemperature(ReasoningLevel.MEDIUM)).toBe(0.3);
134
- });
135
- });
136
- //# sourceMappingURL=optimizations.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"optimizations.test.js","sourceRoot":"","sources":["../../src/__tests__/optimizations.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,SAAS,EAAiB,MAAM,0BAA0B,CAAC;AAClF,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,cAAc,GACf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EACL,eAAe,EACf,cAAc,GACf,MAAM,4BAA4B,CAAC;AAEpC,kFAAkF;AAClF,6BAA6B;AAC7B,kFAAkF;AAElF,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,UAAU,CAAC,GAAG,EAAE;QACd,mBAAmB,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,gEAAgE;IAEhE,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAElE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,iDAAiD;IAEjD,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAEhE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,6DAA6D;IAE7D,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAE5C,MAAM,IAAI,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;QAExC,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACtC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,kEAAkE;IAElE,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QAEpE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC3C,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,oEAAoE;IAEpE,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;QAEvE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,kFAAkF;AAClF,yCAAyC;AACzC,kFAAkF;AAElF,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,sDAAsD;IAEtD,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,MAAM,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC,sBAAsB;QACrE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,kDAAkD;IAElD,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,QAAQ,GAAG;YACf,IAAI,YAAY,CAAC,OAAO,CAAC,EAAM,sCAAsC;YACrE,IAAI,SAAS,CAAC,UAAU,CAAC,EAAM,sCAAsC;SACtE,CAAC;QACF,MAAM,KAAK,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAE3C,MAAM,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB;IAC1C,CAAC,CAAC,CAAC;IAEH,qDAAqD;IAErD,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,+CAA+C;QAC/C,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,CAAC,MAAM,CAAC,CAAC;QAE1B,sDAAsD;QACtD,kCAAkC;QAClC,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,iEAAiE;IAEjE,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,QAAQ,GAAG,CAAC,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;QAE7C,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,6DAA6D;IAE7D,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,OAAO,GAAG,IAAI,2BAA2B,EAAE,CAAC;QAClD,MAAM,OAAO,GAAG;YACd,IAAI,YAAY,CAAC,OAAO,CAAC;YACzB,IAAI,SAAS,CAAC,YAAY,CAAC;YAC3B,IAAI,YAAY,CAAC,OAAO,CAAC;YACzB,IAAI,SAAS,CAAC,YAAY,CAAC;YAC3B,IAAI,YAAY,CAAC,OAAO,CAAC;YACzB,IAAI,SAAS,CAAC,YAAY,CAAC;SAC5B,CAAC;QAEF,MAAM,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,uBAAuB,EAAE,CAAC,CAAC,CAAC;QAE9E,uCAAuC;QACvC,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,CAAE,SAAS,CAAC,CAAC,CAAkB,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACtE,MAAM,CAAE,SAAS,CAAC,CAAC,CAAkB,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;IACpF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,kFAAkF;AAClF,yBAAyB;AACzB,kFAAkF;AAElF,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,oDAAoD;IAEpD,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QAErC,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAEhC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,gDAAgD;IAEhD,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC,CAAC;QAEzD,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,SAAS;QAC3C,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,kBAAkB;QAErC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,SAAS;QAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,8BAA8B;QAE/D,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,yDAAyD;IAEzD,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC,CAAC;QAEzD,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,SAAS;QAC3C,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,WAAW;QAE9B,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAE,SAAS;QAC3C,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,qBAAqB;QAExC,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS;QAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,SAAS;QAE1C,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,wCAAwC;IAExC,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1 +0,0 @@
1
- export {};
@@ -1,86 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from "vitest";
2
- import { SecurityScanTool, DepScanTool, bindSecuritySandbox, } from "../tools/security.js";
3
- import { LazyInstaller } from "../sandbox/bootstrap.js";
4
- // Helpers
5
- const createMockSandbox = (active = true) => ({
6
- exec: vi.fn(),
7
- isActive: vi.fn().mockReturnValue(active),
8
- create: vi.fn(),
9
- destroy: vi.fn(),
10
- uploadFile: vi.fn(),
11
- getSandbox: vi.fn(),
12
- });
13
- describe("SecurityScanTool", () => {
14
- let mockSandbox;
15
- let installer;
16
- beforeEach(() => {
17
- vi.clearAllMocks();
18
- mockSandbox = createMockSandbox();
19
- // Use custom template mode so ensureGeminiCli is instant
20
- installer = new LazyInstaller(true);
21
- bindSecuritySandbox(mockSandbox, installer);
22
- });
23
- // ─── Test #39: Runs security:analyze and returns report ───
24
- it("runs gemini security:analyze and returns the report", async () => {
25
- mockSandbox.exec.mockResolvedValueOnce({
26
- exitCode: 0,
27
- stdout: "## Security Report\n\nNo critical vulnerabilities found.",
28
- stderr: "",
29
- });
30
- const result = await SecurityScanTool.execute({ target: "changes" });
31
- expect(result.content).toContain("Security Report");
32
- expect(mockSandbox.exec).toHaveBeenCalledWith(expect.stringContaining("security:analyze"));
33
- });
34
- // ─── Test #40: Returns error for file scan without path ───
35
- it("returns error when target is 'file' but no path provided", async () => {
36
- const result = await SecurityScanTool.execute({ target: "file" });
37
- expect(result.content).toMatch(/path.*required/i);
38
- });
39
- // ─── Test #41: Handles failed scans gracefully ───
40
- it("returns failure info when scan exits with non-zero code", async () => {
41
- mockSandbox.exec.mockResolvedValueOnce({
42
- exitCode: 1,
43
- stdout: "",
44
- stderr: "Some error occurred",
45
- });
46
- const result = await SecurityScanTool.execute({ target: "changes" });
47
- expect(result.content).toContain("failed");
48
- expect(result.content).toContain("Some error occurred");
49
- });
50
- });
51
- describe("DepScanTool", () => {
52
- let mockSandbox;
53
- let installer;
54
- beforeEach(() => {
55
- vi.clearAllMocks();
56
- mockSandbox = createMockSandbox();
57
- installer = new LazyInstaller(true); // pre-baked template
58
- bindSecuritySandbox(mockSandbox, installer);
59
- });
60
- // ─── Test #42: OSV-Scanner returns vulnerability report ───
61
- it("runs osv-scanner and returns the report", async () => {
62
- mockSandbox.exec.mockResolvedValueOnce({
63
- exitCode: 0,
64
- stdout: "Found 2 vulnerabilities:\n- CVE-2024-1234\n- CVE-2024-5678",
65
- stderr: "",
66
- });
67
- const result = await DepScanTool.execute({ format: "summary" });
68
- expect(result.content).toContain("CVE-2024-1234");
69
- expect(result.content).toContain("CVE-2024-5678");
70
- });
71
- // ─── Test #43: Falls back to npm audit when OSV-Scanner fails ───
72
- it("falls back to npm audit if osv-scanner returns empty output", async () => {
73
- // OSV-Scanner: empty output
74
- mockSandbox.exec
75
- .mockResolvedValueOnce({ exitCode: 1, stdout: "", stderr: "error" })
76
- // npm audit fallback
77
- .mockResolvedValueOnce({
78
- exitCode: 0,
79
- stdout: "found 0 vulnerabilities",
80
- stderr: "",
81
- });
82
- const result = await DepScanTool.execute({ format: "summary" });
83
- expect(result.content).toContain("0 vulnerabilities");
84
- });
85
- });
86
- //# sourceMappingURL=security.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"security.test.js","sourceRoot":"","sources":["../../src/__tests__/security.test.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- export {};