joonecli 0.1.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.
- package/AGENTS.md +56 -0
- package/Handover.md +115 -0
- package/LICENSE +201 -0
- package/PROGRESS.md +160 -0
- package/README.md +114 -0
- package/dist/__tests__/bootstrap.test.d.ts +1 -0
- package/dist/__tests__/bootstrap.test.js +76 -0
- package/dist/__tests__/bootstrap.test.js.map +1 -0
- package/dist/__tests__/config.test.d.ts +1 -0
- package/dist/__tests__/config.test.js +84 -0
- package/dist/__tests__/config.test.js.map +1 -0
- package/dist/__tests__/m55.test.d.ts +1 -0
- package/dist/__tests__/m55.test.js +160 -0
- package/dist/__tests__/m55.test.js.map +1 -0
- package/dist/__tests__/middleware.test.d.ts +1 -0
- package/dist/__tests__/middleware.test.js +169 -0
- package/dist/__tests__/middleware.test.js.map +1 -0
- package/dist/__tests__/modelFactory.test.d.ts +1 -0
- package/dist/__tests__/modelFactory.test.js +50 -0
- package/dist/__tests__/modelFactory.test.js.map +1 -0
- package/dist/__tests__/optimizations.test.d.ts +1 -0
- package/dist/__tests__/optimizations.test.js +136 -0
- package/dist/__tests__/optimizations.test.js.map +1 -0
- package/dist/__tests__/promptBuilder.test.d.ts +1 -0
- package/dist/__tests__/promptBuilder.test.js +108 -0
- package/dist/__tests__/promptBuilder.test.js.map +1 -0
- package/dist/__tests__/sandbox.test.d.ts +1 -0
- package/dist/__tests__/sandbox.test.js +78 -0
- package/dist/__tests__/sandbox.test.js.map +1 -0
- package/dist/__tests__/security.test.d.ts +1 -0
- package/dist/__tests__/security.test.js +86 -0
- package/dist/__tests__/security.test.js.map +1 -0
- package/dist/__tests__/streaming.test.d.ts +1 -0
- package/dist/__tests__/streaming.test.js +71 -0
- package/dist/__tests__/streaming.test.js.map +1 -0
- package/dist/__tests__/toolRouter.test.d.ts +1 -0
- package/dist/__tests__/toolRouter.test.js +37 -0
- package/dist/__tests__/toolRouter.test.js.map +1 -0
- package/dist/__tests__/tools.test.d.ts +1 -0
- package/dist/__tests__/tools.test.js +112 -0
- package/dist/__tests__/tools.test.js.map +1 -0
- package/dist/__tests__/tracing.test.d.ts +1 -0
- package/dist/__tests__/tracing.test.js +147 -0
- package/dist/__tests__/tracing.test.js.map +1 -0
- package/dist/cli/config.d.ts +49 -0
- package/dist/cli/config.js +86 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +625 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/modelFactory.d.ts +9 -0
- package/dist/cli/modelFactory.js +154 -0
- package/dist/cli/modelFactory.js.map +1 -0
- package/dist/cli/providers.d.ts +18 -0
- package/dist/cli/providers.js +94 -0
- package/dist/cli/providers.js.map +1 -0
- package/dist/core/agentLoop.d.ts +43 -0
- package/dist/core/agentLoop.js +245 -0
- package/dist/core/agentLoop.js.map +1 -0
- package/dist/core/errors.d.ts +62 -0
- package/dist/core/errors.js +139 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/promptBuilder.d.ts +49 -0
- package/dist/core/promptBuilder.js +84 -0
- package/dist/core/promptBuilder.js.map +1 -0
- package/dist/core/reasoningRouter.d.ts +62 -0
- package/dist/core/reasoningRouter.js +102 -0
- package/dist/core/reasoningRouter.js.map +1 -0
- package/dist/core/retry.d.ts +25 -0
- package/dist/core/retry.js +49 -0
- package/dist/core/retry.js.map +1 -0
- package/dist/core/sessionResumer.d.ts +17 -0
- package/dist/core/sessionResumer.js +78 -0
- package/dist/core/sessionResumer.js.map +1 -0
- package/dist/core/sessionStore.d.ts +45 -0
- package/dist/core/sessionStore.js +167 -0
- package/dist/core/sessionStore.js.map +1 -0
- package/dist/core/tokenCounter.d.ts +17 -0
- package/dist/core/tokenCounter.js +54 -0
- package/dist/core/tokenCounter.js.map +1 -0
- package/dist/evals/dataset.d.ts +4 -0
- package/dist/evals/dataset.js +61 -0
- package/dist/evals/dataset.js.map +1 -0
- package/dist/evals/evaluator.d.ts +21 -0
- package/dist/evals/evaluator.js +68 -0
- package/dist/evals/evaluator.js.map +1 -0
- package/dist/hitl/bridge.d.ts +65 -0
- package/dist/hitl/bridge.js +120 -0
- package/dist/hitl/bridge.js.map +1 -0
- package/dist/middleware/commandSanitizer.d.ts +18 -0
- package/dist/middleware/commandSanitizer.js +50 -0
- package/dist/middleware/commandSanitizer.js.map +1 -0
- package/dist/middleware/loopDetection.d.ts +28 -0
- package/dist/middleware/loopDetection.js +49 -0
- package/dist/middleware/loopDetection.js.map +1 -0
- package/dist/middleware/permission.d.ts +17 -0
- package/dist/middleware/permission.js +59 -0
- package/dist/middleware/permission.js.map +1 -0
- package/dist/middleware/pipeline.d.ts +31 -0
- package/dist/middleware/pipeline.js +62 -0
- package/dist/middleware/pipeline.js.map +1 -0
- package/dist/middleware/preCompletion.d.ts +29 -0
- package/dist/middleware/preCompletion.js +82 -0
- package/dist/middleware/preCompletion.js.map +1 -0
- package/dist/middleware/types.d.ts +40 -0
- package/dist/middleware/types.js +8 -0
- package/dist/middleware/types.js.map +1 -0
- package/dist/sandbox/bootstrap.d.ts +38 -0
- package/dist/sandbox/bootstrap.js +107 -0
- package/dist/sandbox/bootstrap.js.map +1 -0
- package/dist/sandbox/manager.d.ts +72 -0
- package/dist/sandbox/manager.js +180 -0
- package/dist/sandbox/manager.js.map +1 -0
- package/dist/sandbox/sync.d.ts +55 -0
- package/dist/sandbox/sync.js +135 -0
- package/dist/sandbox/sync.js.map +1 -0
- package/dist/skills/loader.d.ts +55 -0
- package/dist/skills/loader.js +132 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/skills/tools.d.ts +5 -0
- package/dist/skills/tools.js +78 -0
- package/dist/skills/tools.js.map +1 -0
- package/dist/skills/types.d.ts +13 -0
- package/dist/skills/types.js +2 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/test_cache.d.ts +1 -0
- package/dist/test_cache.js +55 -0
- package/dist/test_cache.js.map +1 -0
- package/dist/test_google.js +93 -0
- package/dist/tools/askUser.d.ts +10 -0
- package/dist/tools/askUser.js +42 -0
- package/dist/tools/askUser.js.map +1 -0
- package/dist/tools/browser.d.ts +19 -0
- package/dist/tools/browser.js +111 -0
- package/dist/tools/browser.js.map +1 -0
- package/dist/tools/index.d.ts +27 -0
- package/dist/tools/index.js +184 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/registry.d.ts +31 -0
- package/dist/tools/registry.js +168 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/router.d.ts +34 -0
- package/dist/tools/router.js +73 -0
- package/dist/tools/router.js.map +1 -0
- package/dist/tools/security.d.ts +28 -0
- package/dist/tools/security.js +183 -0
- package/dist/tools/security.js.map +1 -0
- package/dist/tools/webSearch.d.ts +6 -0
- package/dist/tools/webSearch.js +120 -0
- package/dist/tools/webSearch.js.map +1 -0
- package/dist/tracing/analyzer.d.ts +58 -0
- package/dist/tracing/analyzer.js +190 -0
- package/dist/tracing/analyzer.js.map +1 -0
- package/dist/tracing/langsmith.d.ts +38 -0
- package/dist/tracing/langsmith.js +50 -0
- package/dist/tracing/langsmith.js.map +1 -0
- package/dist/tracing/sessionTracer.d.ts +73 -0
- package/dist/tracing/sessionTracer.js +157 -0
- package/dist/tracing/sessionTracer.js.map +1 -0
- package/dist/tracing/types.d.ts +46 -0
- package/dist/tracing/types.js +5 -0
- package/dist/tracing/types.js.map +1 -0
- package/dist/ui/App.d.ts +24 -0
- package/dist/ui/App.js +172 -0
- package/dist/ui/App.js.map +1 -0
- package/dist/ui/components/HITLPrompt.d.ts +15 -0
- package/dist/ui/components/HITLPrompt.js +35 -0
- package/dist/ui/components/HITLPrompt.js.map +1 -0
- package/dist/ui/components/Header.d.ts +8 -0
- package/dist/ui/components/Header.js +6 -0
- package/dist/ui/components/Header.js.map +1 -0
- package/dist/ui/components/MessageBubble.d.ts +13 -0
- package/dist/ui/components/MessageBubble.js +17 -0
- package/dist/ui/components/MessageBubble.js.map +1 -0
- package/dist/ui/components/StatusBar.d.ts +21 -0
- package/dist/ui/components/StatusBar.js +34 -0
- package/dist/ui/components/StatusBar.js.map +1 -0
- package/dist/ui/components/StreamingText.d.ts +13 -0
- package/dist/ui/components/StreamingText.js +24 -0
- package/dist/ui/components/StreamingText.js.map +1 -0
- package/dist/ui/components/ToolCallPanel.d.ts +15 -0
- package/dist/ui/components/ToolCallPanel.js +18 -0
- package/dist/ui/components/ToolCallPanel.js.map +1 -0
- package/docs/01_insights_and_patterns.md +27 -0
- package/docs/02_edge_cases_and_mitigations.md +143 -0
- package/docs/03_initial_implementation_plan.md +66 -0
- package/docs/04_tech_stack_proposal.md +20 -0
- package/docs/05_prd.md +87 -0
- package/docs/06_user_stories.md +72 -0
- package/docs/07_system_architecture.md +138 -0
- package/docs/08_roadmap.md +200 -0
- package/e2b/Dockerfile +26 -0
- package/package.json +57 -0
- package/src/__tests__/bootstrap.test.ts +111 -0
- package/src/__tests__/config.test.ts +97 -0
- package/src/__tests__/m55.test.ts +238 -0
- package/src/__tests__/middleware.test.ts +219 -0
- package/src/__tests__/modelFactory.test.ts +63 -0
- package/src/__tests__/optimizations.test.ts +201 -0
- package/src/__tests__/promptBuilder.test.ts +141 -0
- package/src/__tests__/sandbox.test.ts +102 -0
- package/src/__tests__/security.test.ts +122 -0
- package/src/__tests__/streaming.test.ts +82 -0
- package/src/__tests__/toolRouter.test.ts +52 -0
- package/src/__tests__/tools.test.ts +146 -0
- package/src/__tests__/tracing.test.ts +196 -0
- package/src/agents/agentRegistry.ts +69 -0
- package/src/agents/agentSpec.ts +67 -0
- package/src/agents/builtinAgents.ts +142 -0
- package/src/cli/config.ts +124 -0
- package/src/cli/index.ts +730 -0
- package/src/cli/modelFactory.ts +174 -0
- package/src/cli/providers.ts +107 -0
- package/src/commands/builtinCommands.ts +293 -0
- package/src/commands/commandRegistry.ts +194 -0
- package/src/core/agentLoop.d.ts.map +1 -0
- package/src/core/agentLoop.ts +312 -0
- package/src/core/autoSave.ts +95 -0
- package/src/core/compactor.ts +252 -0
- package/src/core/contextGuard.ts +129 -0
- package/src/core/errors.ts +202 -0
- package/src/core/promptBuilder.d.ts.map +1 -0
- package/src/core/promptBuilder.ts +139 -0
- package/src/core/reasoningRouter.ts +121 -0
- package/src/core/retry.ts +75 -0
- package/src/core/sessionResumer.ts +90 -0
- package/src/core/sessionStore.ts +215 -0
- package/src/core/subAgent.ts +339 -0
- package/src/core/tokenCounter.ts +64 -0
- package/src/evals/dataset.ts +67 -0
- package/src/evals/evaluator.ts +81 -0
- package/src/hitl/bridge.ts +160 -0
- package/src/middleware/commandSanitizer.ts +60 -0
- package/src/middleware/loopDetection.ts +63 -0
- package/src/middleware/permission.ts +72 -0
- package/src/middleware/pipeline.ts +75 -0
- package/src/middleware/preCompletion.ts +94 -0
- package/src/middleware/types.ts +45 -0
- package/src/sandbox/bootstrap.ts +121 -0
- package/src/sandbox/manager.ts +239 -0
- package/src/sandbox/sync.ts +157 -0
- package/src/skills/loader.ts +143 -0
- package/src/skills/tools.ts +99 -0
- package/src/skills/types.ts +13 -0
- package/src/test_cache.ts +72 -0
- package/src/test_google.js +40 -0
- package/src/test_google.ts +40 -0
- package/src/tools/askUser.ts +47 -0
- package/src/tools/browser.ts +137 -0
- package/src/tools/index.d.ts.map +1 -0
- package/src/tools/index.ts +237 -0
- package/src/tools/registry.ts +198 -0
- package/src/tools/router.ts +78 -0
- package/src/tools/security.ts +220 -0
- package/src/tools/spawnAgent.ts +158 -0
- package/src/tools/webSearch.ts +142 -0
- package/src/tracing/analyzer.ts +265 -0
- package/src/tracing/langsmith.ts +63 -0
- package/src/tracing/sessionTracer.ts +202 -0
- package/src/tracing/types.ts +49 -0
- package/src/types/valyu.d.ts +37 -0
- package/src/ui/App.tsx +404 -0
- package/src/ui/components/HITLPrompt.tsx +119 -0
- package/src/ui/components/Header.tsx +51 -0
- package/src/ui/components/MessageBubble.tsx +46 -0
- package/src/ui/components/StatusBar.tsx +138 -0
- package/src/ui/components/StreamingText.tsx +48 -0
- package/src/ui/components/ToolCallPanel.tsx +80 -0
- package/tests/commands/commands.test.ts +356 -0
- package/tests/core/compactor.test.ts +217 -0
- package/tests/core/retryAndErrors.test.ts +164 -0
- package/tests/core/sessionResumer.test.ts +95 -0
- package/tests/core/sessionStore.test.ts +84 -0
- package/tests/core/stability.test.ts +165 -0
- package/tests/core/subAgent.test.ts +238 -0
- package/tests/hitl/hitlBridge.test.ts +115 -0
- package/tsconfig.json +16 -0
- package/vitest.config.ts +10 -0
- package/vitest.out +48 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// ─── Sandbox + Installer references (set at session start) ──────────────────
|
|
2
|
+
let _sandboxManager = null;
|
|
3
|
+
let _installer = null;
|
|
4
|
+
/**
|
|
5
|
+
* Binds the security tools to the sandbox and installer.
|
|
6
|
+
* Must be called at session start.
|
|
7
|
+
*/
|
|
8
|
+
export function bindSecuritySandbox(sandbox, installer) {
|
|
9
|
+
_sandboxManager = sandbox;
|
|
10
|
+
_installer = installer;
|
|
11
|
+
}
|
|
12
|
+
// ─── Security Helpers ───────────────────────────────────────────────────────────
|
|
13
|
+
/**
|
|
14
|
+
* Escapes a string so it can be safely used as an argument in a Bash shell command.
|
|
15
|
+
*/
|
|
16
|
+
function escapeBashArg(arg) {
|
|
17
|
+
return `'${arg.replace(/'/g, "'\\''")}'`;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Validates a file path to prevent directory traversal out of the workspace.
|
|
21
|
+
*/
|
|
22
|
+
function isSafePath(pathStr) {
|
|
23
|
+
if (!pathStr || pathStr.trim() === "")
|
|
24
|
+
return false;
|
|
25
|
+
if (pathStr.includes("..") || pathStr.startsWith("/"))
|
|
26
|
+
return false;
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
// ─── SecurityScanTool ───────────────────────────────────────────────────────────
|
|
30
|
+
/**
|
|
31
|
+
* Scans code for security vulnerabilities using the Gemini CLI Security Extension.
|
|
32
|
+
*
|
|
33
|
+
* Execution flow:
|
|
34
|
+
* 1. LazyInstaller ensures Gemini CLI + security extension are in the sandbox.
|
|
35
|
+
* 2. Runs `gemini -x security:analyze` in the sandbox.
|
|
36
|
+
* 3. Returns the generated security report.
|
|
37
|
+
*
|
|
38
|
+
* If Gemini CLI installation fails, returns a descriptive fallback message
|
|
39
|
+
* suggesting manual review or alternative tools.
|
|
40
|
+
*/
|
|
41
|
+
export const SecurityScanTool = {
|
|
42
|
+
name: "security_scan",
|
|
43
|
+
description: "Scans code changes for security vulnerabilities using the Gemini CLI Security Extension. " +
|
|
44
|
+
"Analyzes the current branch diff for common vulnerabilities and generates a security report.",
|
|
45
|
+
schema: {
|
|
46
|
+
type: "object",
|
|
47
|
+
properties: {
|
|
48
|
+
target: {
|
|
49
|
+
type: "string",
|
|
50
|
+
enum: ["changes", "file", "deps"],
|
|
51
|
+
description: 'What to scan: "changes" (branch diff), "file" (specific file), "deps" (dependencies only)',
|
|
52
|
+
},
|
|
53
|
+
path: {
|
|
54
|
+
type: "string",
|
|
55
|
+
description: "File path for single-file scan (required when target is 'file')",
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
required: ["target"],
|
|
59
|
+
},
|
|
60
|
+
execute: async (args) => {
|
|
61
|
+
if (!_sandboxManager || !_sandboxManager.isActive()) {
|
|
62
|
+
return { content: "Sandbox is not active. Cannot run security scan.", isError: true };
|
|
63
|
+
}
|
|
64
|
+
if (!_installer) {
|
|
65
|
+
return { content: "LazyInstaller not initialized. Call bindSecuritySandbox() first.", isError: true };
|
|
66
|
+
}
|
|
67
|
+
// Ensure Gemini CLI is available
|
|
68
|
+
const cliReady = await _installer.ensureGeminiCli(_sandboxManager);
|
|
69
|
+
if (!cliReady) {
|
|
70
|
+
return {
|
|
71
|
+
content: ("⚠ Gemini CLI could not be installed in the sandbox.\n" +
|
|
72
|
+
"Suggestions:\n" +
|
|
73
|
+
' - Use `dep_scan` tool for dependency vulnerability scanning (uses npm audit)\n' +
|
|
74
|
+
" - Manually review code for OWASP Top 10 vulnerabilities\n" +
|
|
75
|
+
" - Set sandboxTemplate to a pre-baked template with Gemini CLI installed"),
|
|
76
|
+
isError: true
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// Build the command based on target
|
|
80
|
+
let command;
|
|
81
|
+
switch (args.target) {
|
|
82
|
+
case "changes":
|
|
83
|
+
command = "cd /workspace && gemini -x security:analyze 2>&1";
|
|
84
|
+
break;
|
|
85
|
+
case "file":
|
|
86
|
+
if (!args.path) {
|
|
87
|
+
return { content: "Error: 'path' is required when target is 'file'.", isError: true };
|
|
88
|
+
}
|
|
89
|
+
if (!isSafePath(args.path)) {
|
|
90
|
+
return { content: "Error: Invalid file path. Path must be relative and cannot contain traversal characters ('..').", isError: true };
|
|
91
|
+
}
|
|
92
|
+
command = `cd /workspace && gemini -x security:analyze --file ${escapeBashArg(args.path)} 2>&1`;
|
|
93
|
+
break;
|
|
94
|
+
case "deps":
|
|
95
|
+
command = "cd /workspace && gemini -x security:analyze --deps-only 2>&1";
|
|
96
|
+
break;
|
|
97
|
+
default:
|
|
98
|
+
return { content: `Error: Unknown target "${args.target}". Use "changes", "file", or "deps".`, isError: true };
|
|
99
|
+
}
|
|
100
|
+
const result = await _sandboxManager.exec(command);
|
|
101
|
+
if (result.exitCode !== 0) {
|
|
102
|
+
return {
|
|
103
|
+
content: `Security scan failed (exit code ${result.exitCode}):\n${result.stdout}\n${result.stderr}`,
|
|
104
|
+
metadata: { exitCode: result.exitCode },
|
|
105
|
+
isError: true
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
content: result.stdout || "Security scan completed — no issues found.",
|
|
110
|
+
metadata: { exitCode: result.exitCode },
|
|
111
|
+
isError: false
|
|
112
|
+
};
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
// ─── DepScanTool ────────────────────────────────────────────────────────────────
|
|
116
|
+
/**
|
|
117
|
+
* Scans project dependencies for known vulnerabilities.
|
|
118
|
+
*
|
|
119
|
+
* Execution flow:
|
|
120
|
+
* 1. Try OSV-Scanner (more comprehensive, covers multiple ecosystems).
|
|
121
|
+
* 2. Fall back to `npm audit --json` (always available in Node sandboxes).
|
|
122
|
+
*/
|
|
123
|
+
export const DepScanTool = {
|
|
124
|
+
name: "dep_scan",
|
|
125
|
+
description: "Scans project dependencies for known vulnerabilities (CVEs). " +
|
|
126
|
+
"Uses OSV-Scanner when available, falls back to npm audit.",
|
|
127
|
+
schema: {
|
|
128
|
+
type: "object",
|
|
129
|
+
properties: {
|
|
130
|
+
format: {
|
|
131
|
+
type: "string",
|
|
132
|
+
enum: ["summary", "json"],
|
|
133
|
+
description: 'Output format: "summary" (human readable) or "json" (raw)',
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
execute: async (args) => {
|
|
138
|
+
if (!_sandboxManager || !_sandboxManager.isActive()) {
|
|
139
|
+
return { content: "Sandbox is not active. Cannot run dependency scan.", isError: true };
|
|
140
|
+
}
|
|
141
|
+
if (!_installer) {
|
|
142
|
+
return { content: "LazyInstaller not initialized.", isError: true };
|
|
143
|
+
}
|
|
144
|
+
const format = args?.format ?? "summary";
|
|
145
|
+
// Try OSV-Scanner first
|
|
146
|
+
const osvReady = await _installer.ensureOsvScanner(_sandboxManager);
|
|
147
|
+
if (osvReady) {
|
|
148
|
+
const osvCmd = format === "json"
|
|
149
|
+
? "cd /workspace && osv-scanner --json . 2>&1"
|
|
150
|
+
: "cd /workspace && osv-scanner . 2>&1";
|
|
151
|
+
const result = await _sandboxManager.exec(osvCmd);
|
|
152
|
+
if (result.exitCode === 0) {
|
|
153
|
+
return {
|
|
154
|
+
content: result.stdout || "No known vulnerabilities found in dependencies.",
|
|
155
|
+
metadata: { exitCode: result.exitCode },
|
|
156
|
+
isError: false
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
// Exit code 1 from OSV-Scanner means vulnerabilities found — still valid output
|
|
160
|
+
if (result.exitCode === 1 && result.stdout) {
|
|
161
|
+
return {
|
|
162
|
+
content: result.stdout,
|
|
163
|
+
metadata: { exitCode: result.exitCode },
|
|
164
|
+
isError: false
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
// If we reach here, OSV-Scanner failed for another reason (e.g. exit > 1)
|
|
168
|
+
console.warn(`⚠ OSV-Scanner failed (exit code ${result.exitCode}). Falling back to npm audit.\nDetails: ${result.stdout}\n${result.stderr}`);
|
|
169
|
+
}
|
|
170
|
+
// Fallback: npm audit
|
|
171
|
+
const auditCmd = format === "json"
|
|
172
|
+
? "cd /workspace && npm audit --json 2>&1"
|
|
173
|
+
: "cd /workspace && npm audit 2>&1";
|
|
174
|
+
const auditResult = await _sandboxManager.exec(auditCmd);
|
|
175
|
+
// npm audit returns 1 when vulnerabilities are found — that's valid output
|
|
176
|
+
return {
|
|
177
|
+
content: auditResult.stdout || "No known vulnerabilities found in dependencies.",
|
|
178
|
+
metadata: { exitCode: auditResult.exitCode },
|
|
179
|
+
isError: false
|
|
180
|
+
};
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
//# sourceMappingURL=security.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/tools/security.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web Search Tool — wraps the Valyu AI Search SDK.
|
|
3
|
+
*
|
|
4
|
+
* Provides AI-optimized web search and domain-specific search
|
|
5
|
+
* (papers, finance, patents, SEC filings, etc.). Runs on the Host
|
|
6
|
+
* (API call, not a shell command).
|
|
7
|
+
*
|
|
8
|
+
* Requires a Valyu API key in config (`valyuApiKey`).
|
|
9
|
+
*/
|
|
10
|
+
let _valyuApiKey;
|
|
11
|
+
/**
|
|
12
|
+
* Bind the Valyu API key at session start.
|
|
13
|
+
*/
|
|
14
|
+
export function bindValyuApiKey(key) {
|
|
15
|
+
_valyuApiKey = key;
|
|
16
|
+
}
|
|
17
|
+
export const WebSearchTool = {
|
|
18
|
+
name: "web_search",
|
|
19
|
+
description: "Search the web for information. Supports general web search and specialized sources: " +
|
|
20
|
+
"papers (arXiv/PubMed), finance, patents, SEC filings, companies. " +
|
|
21
|
+
"Returns AI-optimized structured results.",
|
|
22
|
+
schema: {
|
|
23
|
+
type: "object",
|
|
24
|
+
properties: {
|
|
25
|
+
query: {
|
|
26
|
+
type: "string",
|
|
27
|
+
description: "The search query",
|
|
28
|
+
},
|
|
29
|
+
source: {
|
|
30
|
+
type: "string",
|
|
31
|
+
enum: ["web", "papers", "finance", "patents", "sec", "companies"],
|
|
32
|
+
description: 'Search source (default: "web"). Use "papers" for academic, "finance" for financial data, etc.',
|
|
33
|
+
},
|
|
34
|
+
maxResults: {
|
|
35
|
+
type: "number",
|
|
36
|
+
description: "Maximum number of results to return (default: 5)",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
required: ["query"],
|
|
40
|
+
},
|
|
41
|
+
execute: async (args) => {
|
|
42
|
+
if (!_valyuApiKey) {
|
|
43
|
+
return {
|
|
44
|
+
content: "Error: Valyu API key not configured.\n" +
|
|
45
|
+
'Run `joone config` and set your Valyu API key, or add "valyuApiKey" to ~/.joone/config.json.',
|
|
46
|
+
isError: true
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
const source = args.source ?? "web";
|
|
50
|
+
const maxResults = args.maxResults ?? 5;
|
|
51
|
+
try {
|
|
52
|
+
// Dynamic import to avoid requiring the dependency at startup
|
|
53
|
+
const { Valyu } = await import("@valyu/ai-sdk");
|
|
54
|
+
const valyu = new Valyu({ apiKey: _valyuApiKey });
|
|
55
|
+
let results;
|
|
56
|
+
switch (source) {
|
|
57
|
+
case "web":
|
|
58
|
+
results = await valyu.search({
|
|
59
|
+
query: args.query,
|
|
60
|
+
maxResults,
|
|
61
|
+
});
|
|
62
|
+
break;
|
|
63
|
+
case "papers":
|
|
64
|
+
results = await valyu.paperSearch({
|
|
65
|
+
query: args.query,
|
|
66
|
+
maxResults,
|
|
67
|
+
});
|
|
68
|
+
break;
|
|
69
|
+
case "finance":
|
|
70
|
+
results = await valyu.financeSearch({
|
|
71
|
+
query: args.query,
|
|
72
|
+
maxResults,
|
|
73
|
+
});
|
|
74
|
+
break;
|
|
75
|
+
case "patents":
|
|
76
|
+
results = await valyu.patentSearch({
|
|
77
|
+
query: args.query,
|
|
78
|
+
maxResults,
|
|
79
|
+
});
|
|
80
|
+
break;
|
|
81
|
+
case "sec":
|
|
82
|
+
results = await valyu.secSearch({
|
|
83
|
+
query: args.query,
|
|
84
|
+
maxResults,
|
|
85
|
+
});
|
|
86
|
+
break;
|
|
87
|
+
case "companies":
|
|
88
|
+
results = await valyu.companyResearch({
|
|
89
|
+
query: args.query,
|
|
90
|
+
maxResults,
|
|
91
|
+
});
|
|
92
|
+
break;
|
|
93
|
+
default:
|
|
94
|
+
return {
|
|
95
|
+
content: `Error: Unknown source "${source}". Use: web, papers, finance, patents, sec, companies.`,
|
|
96
|
+
isError: true
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
// Format results for the LLM
|
|
100
|
+
if (!results || !results.results || results.results.length === 0) {
|
|
101
|
+
return { content: `No results found for "${args.query}" in ${source} source.` };
|
|
102
|
+
}
|
|
103
|
+
const formatted = results.results
|
|
104
|
+
.map((r, i) => `${i + 1}. **${r.title || "Untitled"}**\n ${r.url || ""}\n ${r.snippet || r.content || ""}`)
|
|
105
|
+
.join("\n\n");
|
|
106
|
+
return { content: `Search results for "${args.query}" (${source}):\n\n${formatted}` };
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
if (error.code === "ERR_MODULE_NOT_FOUND" || error.code === "MODULE_NOT_FOUND") {
|
|
110
|
+
return {
|
|
111
|
+
content: "Error: @valyu/ai-sdk is not installed.\n" +
|
|
112
|
+
"Run: npm install @valyu/ai-sdk",
|
|
113
|
+
isError: true
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
return { content: `Search error: ${error.message}`, isError: true };
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
//# sourceMappingURL=webSearch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webSearch.js","sourceRoot":"","sources":["../../src/tools/webSearch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { SessionTrace } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* TraceAnalyzer — reads a SessionTrace and produces actionable insight reports.
|
|
4
|
+
*
|
|
5
|
+
* Analysis capabilities:
|
|
6
|
+
* - Loop detection: Identifies repeated tool call patterns
|
|
7
|
+
* - Cost hotspots: Flags turns that consumed >20% of total tokens
|
|
8
|
+
* - Error clustering: Groups errors by tool
|
|
9
|
+
* - Cache efficiency: Warns if cache hit rate < 70%
|
|
10
|
+
* - Recommendations: Human-readable suggestions for improvement
|
|
11
|
+
*/
|
|
12
|
+
export interface AnalysisReport {
|
|
13
|
+
/** Human-readable title. */
|
|
14
|
+
title: string;
|
|
15
|
+
/** Key metrics. */
|
|
16
|
+
metrics: Record<string, string | number>;
|
|
17
|
+
/** Detected issues. */
|
|
18
|
+
issues: AnalysisIssue[];
|
|
19
|
+
/** Actionable recommendations. */
|
|
20
|
+
recommendations: string[];
|
|
21
|
+
}
|
|
22
|
+
export interface AnalysisIssue {
|
|
23
|
+
severity: "info" | "warning" | "critical";
|
|
24
|
+
category: "loop" | "cost" | "error" | "cache" | "performance";
|
|
25
|
+
message: string;
|
|
26
|
+
}
|
|
27
|
+
export declare class TraceAnalyzer {
|
|
28
|
+
private trace;
|
|
29
|
+
constructor(trace: SessionTrace);
|
|
30
|
+
/**
|
|
31
|
+
* Run all analysis checks and produce a full report.
|
|
32
|
+
*/
|
|
33
|
+
analyze(): AnalysisReport;
|
|
34
|
+
/**
|
|
35
|
+
* Detect repeated identical tool call patterns (potential doom-loops).
|
|
36
|
+
*/
|
|
37
|
+
detectLoops(): AnalysisIssue[];
|
|
38
|
+
/**
|
|
39
|
+
* Find LLM calls that consumed >20% of total tokens (cost hotspots).
|
|
40
|
+
*/
|
|
41
|
+
detectCostHotspots(): AnalysisIssue[];
|
|
42
|
+
/**
|
|
43
|
+
* Warn if cache hit rate is below 70%.
|
|
44
|
+
*/
|
|
45
|
+
detectCacheIssues(): AnalysisIssue[];
|
|
46
|
+
/**
|
|
47
|
+
* Group errors by tool and report clusters.
|
|
48
|
+
*/
|
|
49
|
+
clusterErrors(): AnalysisIssue[];
|
|
50
|
+
/**
|
|
51
|
+
* Generate actionable recommendations from detected issues.
|
|
52
|
+
*/
|
|
53
|
+
generateRecommendations(issues: AnalysisIssue[]): string[];
|
|
54
|
+
/**
|
|
55
|
+
* Format the report as a human-readable string (for CLI output).
|
|
56
|
+
*/
|
|
57
|
+
static formatReport(report: AnalysisReport): string;
|
|
58
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
export class TraceAnalyzer {
|
|
2
|
+
trace;
|
|
3
|
+
constructor(trace) {
|
|
4
|
+
this.trace = trace;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Run all analysis checks and produce a full report.
|
|
8
|
+
*/
|
|
9
|
+
analyze() {
|
|
10
|
+
const issues = [
|
|
11
|
+
...this.detectLoops(),
|
|
12
|
+
...this.detectCostHotspots(),
|
|
13
|
+
...this.detectCacheIssues(),
|
|
14
|
+
...this.clusterErrors(),
|
|
15
|
+
];
|
|
16
|
+
const recommendations = this.generateRecommendations(issues);
|
|
17
|
+
const { summary } = this.trace;
|
|
18
|
+
return {
|
|
19
|
+
title: `Session Analysis: ${this.trace.sessionId}`,
|
|
20
|
+
metrics: {
|
|
21
|
+
"Total Tokens": summary.totalTokens,
|
|
22
|
+
"Prompt Tokens": summary.promptTokens,
|
|
23
|
+
"Completion Tokens": summary.completionTokens,
|
|
24
|
+
"Estimated Cost": `$${summary.totalCost.toFixed(4)}`,
|
|
25
|
+
"Cache Hit Rate": `${(summary.cacheHitRate * 100).toFixed(1)}%`,
|
|
26
|
+
"Tool Calls": summary.toolCallCount,
|
|
27
|
+
"Errors": summary.errorCount,
|
|
28
|
+
"Turns": summary.turnCount,
|
|
29
|
+
"Duration": `${(summary.totalDuration / 1000).toFixed(1)}s`,
|
|
30
|
+
},
|
|
31
|
+
issues,
|
|
32
|
+
recommendations,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Detect repeated identical tool call patterns (potential doom-loops).
|
|
37
|
+
*/
|
|
38
|
+
detectLoops() {
|
|
39
|
+
const issues = [];
|
|
40
|
+
const toolCalls = this.trace.events.filter((e) => e.type === "tool_call");
|
|
41
|
+
let consecutiveCount = 1;
|
|
42
|
+
let loopToolName = null;
|
|
43
|
+
for (let i = 1; i < toolCalls.length; i++) {
|
|
44
|
+
const prev = toolCalls[i - 1];
|
|
45
|
+
const curr = toolCalls[i];
|
|
46
|
+
if (prev.data.name === curr.data.name &&
|
|
47
|
+
JSON.stringify(prev.data.args) === JSON.stringify(curr.data.args)) {
|
|
48
|
+
consecutiveCount++;
|
|
49
|
+
loopToolName = curr.data.name;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
if (consecutiveCount >= 3 && loopToolName) {
|
|
53
|
+
issues.push({
|
|
54
|
+
severity: "critical",
|
|
55
|
+
category: "loop",
|
|
56
|
+
message: `Doom-loop detected: "${loopToolName}" called ${consecutiveCount} times consecutively with identical args.`,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
consecutiveCount = 1;
|
|
60
|
+
loopToolName = null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Handle loop at end of array
|
|
64
|
+
if (consecutiveCount >= 3 && loopToolName) {
|
|
65
|
+
issues.push({
|
|
66
|
+
severity: "critical",
|
|
67
|
+
category: "loop",
|
|
68
|
+
message: `Doom-loop detected: "${loopToolName}" called ${consecutiveCount} times consecutively with identical args.`,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return issues;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Find LLM calls that consumed >20% of total tokens (cost hotspots).
|
|
75
|
+
*/
|
|
76
|
+
detectCostHotspots() {
|
|
77
|
+
const issues = [];
|
|
78
|
+
const { totalTokens } = this.trace.summary;
|
|
79
|
+
if (totalTokens === 0)
|
|
80
|
+
return issues;
|
|
81
|
+
const llmCalls = this.trace.events.filter((e) => e.type === "llm_call");
|
|
82
|
+
llmCalls.forEach((event, index) => {
|
|
83
|
+
const callTokens = (event.data.promptTokens || 0) + (event.data.completionTokens || 0);
|
|
84
|
+
const ratio = callTokens / totalTokens;
|
|
85
|
+
if (ratio > 0.2) {
|
|
86
|
+
issues.push({
|
|
87
|
+
severity: "warning",
|
|
88
|
+
category: "cost",
|
|
89
|
+
message: `Turn ${index + 1} consumed ${(ratio * 100).toFixed(0)}% of total tokens (${callTokens} tokens).`,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
return issues;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Warn if cache hit rate is below 70%.
|
|
97
|
+
*/
|
|
98
|
+
detectCacheIssues() {
|
|
99
|
+
const issues = [];
|
|
100
|
+
const { cacheHitRate, turnCount } = this.trace.summary;
|
|
101
|
+
// Only relevant if we have enough turns
|
|
102
|
+
if (turnCount >= 3 && cacheHitRate < 0.7) {
|
|
103
|
+
issues.push({
|
|
104
|
+
severity: "warning",
|
|
105
|
+
category: "cache",
|
|
106
|
+
message: `Cache hit rate is ${(cacheHitRate * 100).toFixed(1)}% (below 70% target). This increases cost significantly.`,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return issues;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Group errors by tool and report clusters.
|
|
113
|
+
*/
|
|
114
|
+
clusterErrors() {
|
|
115
|
+
const issues = [];
|
|
116
|
+
const errors = this.trace.events.filter((e) => e.type === "error");
|
|
117
|
+
if (errors.length === 0)
|
|
118
|
+
return issues;
|
|
119
|
+
const byTool = new Map();
|
|
120
|
+
for (const error of errors) {
|
|
121
|
+
const tool = error.data.tool || "unknown";
|
|
122
|
+
byTool.set(tool, (byTool.get(tool) || 0) + 1);
|
|
123
|
+
}
|
|
124
|
+
for (const [tool, count] of byTool) {
|
|
125
|
+
if (count >= 2) {
|
|
126
|
+
issues.push({
|
|
127
|
+
severity: "warning",
|
|
128
|
+
category: "error",
|
|
129
|
+
message: `${count} errors from tool "${tool}" — may indicate a systemic issue.`,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return issues;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Generate actionable recommendations from detected issues.
|
|
137
|
+
*/
|
|
138
|
+
generateRecommendations(issues) {
|
|
139
|
+
const recs = [];
|
|
140
|
+
const hasLoops = issues.some((i) => i.category === "loop");
|
|
141
|
+
const hasCostHotspots = issues.some((i) => i.category === "cost");
|
|
142
|
+
const hasCacheIssues = issues.some((i) => i.category === "cache");
|
|
143
|
+
const hasErrors = issues.some((i) => i.category === "error");
|
|
144
|
+
if (hasLoops) {
|
|
145
|
+
recs.push("Consider lowering the LoopDetectionMiddleware threshold or adding argument variation hints to the system prompt.");
|
|
146
|
+
}
|
|
147
|
+
if (hasCostHotspots) {
|
|
148
|
+
recs.push("Consider compacting context earlier — some turns consumed a large share of the token budget.");
|
|
149
|
+
}
|
|
150
|
+
if (hasCacheIssues) {
|
|
151
|
+
recs.push("Review the static system prompt prefix — cache misses often indicate the prompt prefix is being mutated between turns.");
|
|
152
|
+
}
|
|
153
|
+
if (hasErrors) {
|
|
154
|
+
recs.push("Investigate recurring tool errors — consider adding fallback strategies or better error messages in tool implementations.");
|
|
155
|
+
}
|
|
156
|
+
if (issues.length === 0) {
|
|
157
|
+
recs.push("Session looks healthy! No issues detected.");
|
|
158
|
+
}
|
|
159
|
+
return recs;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Format the report as a human-readable string (for CLI output).
|
|
163
|
+
*/
|
|
164
|
+
static formatReport(report) {
|
|
165
|
+
const lines = [];
|
|
166
|
+
lines.push(`\n ◆ ${report.title}`);
|
|
167
|
+
lines.push(" ─────────────────────────────────────");
|
|
168
|
+
// Metrics
|
|
169
|
+
lines.push("\n 📊 Metrics:");
|
|
170
|
+
for (const [key, value] of Object.entries(report.metrics)) {
|
|
171
|
+
lines.push(` ${key.padEnd(20)} ${value}`);
|
|
172
|
+
}
|
|
173
|
+
// Issues
|
|
174
|
+
if (report.issues.length > 0) {
|
|
175
|
+
lines.push("\n ⚠ Issues:");
|
|
176
|
+
for (const issue of report.issues) {
|
|
177
|
+
const icon = issue.severity === "critical" ? "🔴" : issue.severity === "warning" ? "🟡" : "🔵";
|
|
178
|
+
lines.push(` ${icon} [${issue.category}] ${issue.message}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Recommendations
|
|
182
|
+
lines.push("\n 💡 Recommendations:");
|
|
183
|
+
for (const rec of report.recommendations) {
|
|
184
|
+
lines.push(` • ${rec}`);
|
|
185
|
+
}
|
|
186
|
+
lines.push("");
|
|
187
|
+
return lines.join("\n");
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../src/tracing/analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LangSmith Integration — thin configuration layer.
|
|
3
|
+
*
|
|
4
|
+
* LangChain has built-in LangSmith tracing via environment variables.
|
|
5
|
+
* This module reads from JooneConfig and sets the required env vars
|
|
6
|
+
* so LangChain auto-traces to LangSmith when enabled.
|
|
7
|
+
*
|
|
8
|
+
* Required env vars for LangSmith:
|
|
9
|
+
* LANGCHAIN_TRACING_V2=true
|
|
10
|
+
* LANGCHAIN_API_KEY=<key>
|
|
11
|
+
* LANGCHAIN_PROJECT=<project> (optional, defaults to "joone")
|
|
12
|
+
*/
|
|
13
|
+
interface LangSmithConfig {
|
|
14
|
+
apiKey: string;
|
|
15
|
+
project?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Enables LangSmith tracing by setting the required environment variables.
|
|
19
|
+
* LangChain will automatically detect these and send traces.
|
|
20
|
+
*/
|
|
21
|
+
export declare function enableLangSmith(config: LangSmithConfig): void;
|
|
22
|
+
/**
|
|
23
|
+
* Disables LangSmith tracing.
|
|
24
|
+
*/
|
|
25
|
+
export declare function disableLangSmith(): void;
|
|
26
|
+
/**
|
|
27
|
+
* Checks if LangSmith tracing is currently enabled.
|
|
28
|
+
*/
|
|
29
|
+
export declare function isLangSmithEnabled(): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Attempts to enable LangSmith from JooneConfig values.
|
|
32
|
+
* Returns true if successfully enabled.
|
|
33
|
+
*/
|
|
34
|
+
export declare function tryEnableLangSmithFromConfig(config: {
|
|
35
|
+
langsmithApiKey?: string;
|
|
36
|
+
langsmithProject?: string;
|
|
37
|
+
}): boolean;
|
|
38
|
+
export {};
|