clippy-test 1.0.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/bin/clippy.js +43 -0
- package/dist/api.d.ts +1 -0
- package/dist/api.js +14 -0
- package/dist/api.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +91 -0
- package/dist/cli.js.map +1 -0
- package/dist/code_hierarchy.d.ts +4 -0
- package/dist/code_hierarchy.js +92 -0
- package/dist/code_hierarchy.js.map +1 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.js +12 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +440 -0
- package/dist/index.js.map +1 -0
- package/dist/ui-graph.d.ts +1 -0
- package/dist/ui-graph.js +125 -0
- package/dist/ui-graph.js.map +1 -0
- package/dist/useWebSocket.d.ts +12 -0
- package/dist/useWebSocket.js +202 -0
- package/dist/useWebSocket.js.map +1 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +22 -0
- package/dist/utils.js.map +1 -0
- package/package.json +56 -0
package/bin/clippy.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Simple flag handler and launcher for the compiled CLI
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
|
|
10
|
+
const pkgPath = path.resolve(__dirname, '../package.json');
|
|
11
|
+
const pkgJson = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
12
|
+
|
|
13
|
+
const args = process.argv.slice(2);
|
|
14
|
+
|
|
15
|
+
const printHelp = () => {
|
|
16
|
+
console.log(`
|
|
17
|
+
Clippy - Your AI-powered CLI Debugger
|
|
18
|
+
|
|
19
|
+
Usage:
|
|
20
|
+
clippy init Create the configuration file (~/.clippy/config)
|
|
21
|
+
clippy login <your-auth-key> Login to Clippy using your auth key
|
|
22
|
+
Flags:
|
|
23
|
+
-h, --help Show help
|
|
24
|
+
-v, --version Show version
|
|
25
|
+
`);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
|
|
29
|
+
printHelp();
|
|
30
|
+
process.exit(0);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
34
|
+
console.log(pkgJson.version || '0.0.0');
|
|
35
|
+
process.exit(0);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Defer to compiled app (index bootstraps the TUI / routing)
|
|
39
|
+
import('../dist/index.js').catch((err) => {
|
|
40
|
+
console.error(err);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
});
|
|
43
|
+
|
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const toolFunctionCall: (tool_call_id: any, resultArgs: any, args: any, function_name: any) => Promise<any>;
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { config } from "./config.js";
|
|
3
|
+
//api end point
|
|
4
|
+
const BASE_URL = config.api_base_url;
|
|
5
|
+
export const toolFunctionCall = async (tool_call_id, resultArgs, args, function_name) => {
|
|
6
|
+
const result = await axios.post(`${BASE_URL}/tool/toolFunctionCall`, {
|
|
7
|
+
tool_call_id,
|
|
8
|
+
resultArgs,
|
|
9
|
+
args,
|
|
10
|
+
function_name,
|
|
11
|
+
});
|
|
12
|
+
return result?.data;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,eAAe;AACf,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC;AAErC,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EACnC,YAAY,EACZ,UAAU,EACV,IAAI,EACJ,aAAa,EACb,EAAE;IACF,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,wBAAwB,EAAE;QACnE,YAAY;QACZ,UAAU;QACV,IAAI;QACJ,aAAa;KACd,CAAC,CAAC;IACH,OAAO,MAAM,EAAE,IAAI,CAAC;AACtB,CAAC,CAAC"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import * as os from "os";
|
|
5
|
+
import { render } from "ink";
|
|
6
|
+
import React from "react";
|
|
7
|
+
// The App component must be imported. We rely on index.tsx exporting it.
|
|
8
|
+
import { App } from "./index.js";
|
|
9
|
+
import * as dotenv from "dotenv";
|
|
10
|
+
import chalk from "chalk";
|
|
11
|
+
// --- Configuration Constants ---
|
|
12
|
+
const HOME_DIR = os.homedir();
|
|
13
|
+
const CLIPPY_DIR = path.join(HOME_DIR, ".clippy");
|
|
14
|
+
const CONFIG_PATH = path.join(CLIPPY_DIR, "config");
|
|
15
|
+
const CONFIG_CONTENT = `# Clippy Configuration File
|
|
16
|
+
#
|
|
17
|
+
# Place your Clippy API key here.
|
|
18
|
+
# You can get a key from Clippy Web Studio.
|
|
19
|
+
#
|
|
20
|
+
API_KEY=
|
|
21
|
+
`;
|
|
22
|
+
function handleInit() {
|
|
23
|
+
if (fs.existsSync(CONFIG_PATH)) {
|
|
24
|
+
console.warn(`
|
|
25
|
+
⚠️ Warning: Clippy configuration already exists.
|
|
26
|
+
Path: ${CONFIG_PATH}
|
|
27
|
+
If you need to re-initialize, please delete the file first.
|
|
28
|
+
`);
|
|
29
|
+
process.exit(0);
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
if (!fs.existsSync(CLIPPY_DIR)) {
|
|
33
|
+
fs.mkdirSync(CLIPPY_DIR, { recursive: true });
|
|
34
|
+
console.log(`✅ Created configuration directory: ${CLIPPY_DIR}`);
|
|
35
|
+
}
|
|
36
|
+
fs.writeFileSync(CONFIG_PATH, CONFIG_CONTENT);
|
|
37
|
+
console.log(`
|
|
38
|
+
🎉 Successfully initialized Clippy!
|
|
39
|
+
Configuration file created at: ${CONFIG_PATH}
|
|
40
|
+
|
|
41
|
+
Please edit this file and add your CLIPPY API KEY:
|
|
42
|
+
API_KEY=<YOUR_CLIPPY_API_KEY>
|
|
43
|
+
|
|
44
|
+
Then run: clippy <your command here>
|
|
45
|
+
(e.g., clippy npm run dev)
|
|
46
|
+
`);
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.error(`\n❌ Error initializing Clippy:`, error);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function runTuiApp() {
|
|
55
|
+
dotenv.config({ path: CONFIG_PATH, override: true });
|
|
56
|
+
// 2. Check for API key presence before rendering the app
|
|
57
|
+
if (!process.env.API_KEY || process.env.API_KEY.trim() === "") {
|
|
58
|
+
const pathDisplay = CONFIG_PATH;
|
|
59
|
+
console.error(chalk.redBright("\n❌ ERROR: API_KEY is missing or empty in your configuration file."));
|
|
60
|
+
console.error(chalk.yellow(`Please edit ${pathDisplay} and add your API key.\n`));
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
if (!fs.existsSync(CONFIG_PATH)) {
|
|
64
|
+
console.error(`
|
|
65
|
+
❌ Clippy is not configured.
|
|
66
|
+
Please run: clippy init
|
|
67
|
+
`);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
// add custom logic to verify API KEY authenticity
|
|
71
|
+
render(React.createElement(App, {}));
|
|
72
|
+
}
|
|
73
|
+
const args = process.argv.slice(2);
|
|
74
|
+
const command = args[0];
|
|
75
|
+
if (command === "init") {
|
|
76
|
+
handleInit();
|
|
77
|
+
}
|
|
78
|
+
else if (command) {
|
|
79
|
+
runTuiApp();
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
console.log(`
|
|
83
|
+
Clippy - Your AI-powered CLI Debugger.
|
|
84
|
+
|
|
85
|
+
Usage:
|
|
86
|
+
clippy init - Create the configuration file (~/.clippy/config)
|
|
87
|
+
clippy <command>... - Run a command and launch the interactive AI debugger
|
|
88
|
+
`);
|
|
89
|
+
process.exit(0);
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
import ignore from "ignore";
|
|
5
|
+
function findRoot(startDir) {
|
|
6
|
+
let current = startDir;
|
|
7
|
+
while (true) {
|
|
8
|
+
const gi = path.join(current, ".gitignore");
|
|
9
|
+
if (fs.existsSync(gi))
|
|
10
|
+
return current;
|
|
11
|
+
const parent = path.dirname(current);
|
|
12
|
+
if (parent === current)
|
|
13
|
+
return null;
|
|
14
|
+
current = parent;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function loadIgnoreMatcher(root) {
|
|
18
|
+
const ig = ignore();
|
|
19
|
+
const gitIgnorePath = path.join(root, ".gitignore");
|
|
20
|
+
if (fs.existsSync(gitIgnorePath)) {
|
|
21
|
+
const contents = fs.readFileSync(gitIgnorePath, "utf8");
|
|
22
|
+
ig.add(contents);
|
|
23
|
+
}
|
|
24
|
+
ig.add(".git/");
|
|
25
|
+
return ig;
|
|
26
|
+
}
|
|
27
|
+
function buildTree(root, dir, ig) {
|
|
28
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
29
|
+
const children = [];
|
|
30
|
+
for (const e of entries) {
|
|
31
|
+
const abs = path.join(dir, e.name);
|
|
32
|
+
const rel = path.relative(root, abs);
|
|
33
|
+
const relPosix = rel.replace(/\\/g, "/");
|
|
34
|
+
if (e.isDirectory()) {
|
|
35
|
+
const relDir = relPosix.endsWith("/") ? relPosix : relPosix + "/";
|
|
36
|
+
if (ig.ignores(relDir))
|
|
37
|
+
continue;
|
|
38
|
+
const child = buildTree(root, abs, ig);
|
|
39
|
+
children.push({ name: e.name, type: "dir", children: child.children });
|
|
40
|
+
}
|
|
41
|
+
else if (e.isFile()) {
|
|
42
|
+
if (ig.ignores(relPosix))
|
|
43
|
+
continue;
|
|
44
|
+
children.push({ name: e.name, type: "file" });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
children.sort((a, b) => {
|
|
48
|
+
if (a.type !== b.type)
|
|
49
|
+
return a.type === "dir" ? -1 : 1;
|
|
50
|
+
return a.name.localeCompare(b.name);
|
|
51
|
+
});
|
|
52
|
+
return { name: path.basename(dir), type: "dir", children };
|
|
53
|
+
}
|
|
54
|
+
function toYaml(node, indent = 0) {
|
|
55
|
+
const pad = " ".repeat(indent);
|
|
56
|
+
if (node.type === "file") {
|
|
57
|
+
return `${pad}- ${node.name}`;
|
|
58
|
+
}
|
|
59
|
+
const header = `${pad}- ${node.name}/`;
|
|
60
|
+
if (!node.children || node.children.length === 0) {
|
|
61
|
+
return header;
|
|
62
|
+
}
|
|
63
|
+
const body = node.children
|
|
64
|
+
.map((child) => toYaml(child, indent + 1))
|
|
65
|
+
.join("\n");
|
|
66
|
+
return `${header}\n${body}`;
|
|
67
|
+
}
|
|
68
|
+
export function generateYaml(startDir = process.cwd()) {
|
|
69
|
+
const repoRoot = findRoot(startDir) || startDir;
|
|
70
|
+
const ig = loadIgnoreMatcher(repoRoot);
|
|
71
|
+
const tree = buildTree(repoRoot, repoRoot, ig);
|
|
72
|
+
const yaml = `project:\n${toYaml(tree, 1)}`;
|
|
73
|
+
return { yaml, root: repoRoot };
|
|
74
|
+
}
|
|
75
|
+
const isDirectRun = (() => {
|
|
76
|
+
try {
|
|
77
|
+
const thisFile = path.resolve(fileURLToPath(import.meta.url));
|
|
78
|
+
const invoked = process.argv[1] ? path.resolve(process.argv[1]) : "";
|
|
79
|
+
return thisFile === invoked;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
})();
|
|
85
|
+
if (isDirectRun) {
|
|
86
|
+
const start = process.cwd();
|
|
87
|
+
const { yaml, root } = generateYaml(start);
|
|
88
|
+
const outPath = path.join(root, "hierarchy.yaml");
|
|
89
|
+
fs.writeFileSync(outPath, yaml + "\n", "utf8");
|
|
90
|
+
console.log(`Hierarchy written to ${outPath}`);
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=code_hierarchy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code_hierarchy.js","sourceRoot":"","sources":["../code_hierarchy.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
package/dist/config.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import dotenv from "dotenv";
|
|
2
|
+
dotenv.config();
|
|
3
|
+
export const config = {
|
|
4
|
+
redis_username: process.env.REDIS_USERNAME || "default",
|
|
5
|
+
redis_password: process.env.REDIS_PASSWORD || "",
|
|
6
|
+
redis_host: process.env.REDIS_HOST || "",
|
|
7
|
+
redis_port: process.env.REDIS_PORT || "25061",
|
|
8
|
+
websocket_url: process.env.WEB_SOCKET_URL || "",
|
|
9
|
+
auth_key: process.env.AUTH_KEY || "",
|
|
10
|
+
api_base_url: process.env.API_BASE_URL || "https://prod.revise.network/clippy/api",
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,SAAS;IACvD,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE;IAChD,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE;IACxC,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO;IAC7C,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE;IAC/C,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE;IACpC,YAAY,EACV,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,wCAAwC;CACvE,CAAC"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState, useMemo, useRef, useCallback, } from "react";
|
|
4
|
+
import { useInput, useApp, render, Box, Text, useStdout } from "ink";
|
|
5
|
+
import stringWidth from "string-width";
|
|
6
|
+
import sliceAnsi from "slice-ansi";
|
|
7
|
+
import { spawn as ptySpawn } from "node-pty";
|
|
8
|
+
import TextInput from "ink-text-input";
|
|
9
|
+
import * as dotenv from "dotenv";
|
|
10
|
+
import { marked } from "marked";
|
|
11
|
+
import { markedTerminal } from "marked-terminal";
|
|
12
|
+
import { useWebSocket } from "./useWebSocket.js";
|
|
13
|
+
import { config } from "./config.js";
|
|
14
|
+
import Spinner from "ink-spinner";
|
|
15
|
+
dotenv.config();
|
|
16
|
+
if (typeof process !== "undefined" && process.on) {
|
|
17
|
+
process.on("SIGINT", () => {
|
|
18
|
+
console.log("\nCtrl+C detected! Exiting...");
|
|
19
|
+
process.exit();
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
marked.use(markedTerminal({
|
|
23
|
+
reflowText: false,
|
|
24
|
+
showSectionPrefix: false,
|
|
25
|
+
unescape: false,
|
|
26
|
+
}));
|
|
27
|
+
// Override just the 'text' renderer to handle inline tokens:
|
|
28
|
+
marked.use({
|
|
29
|
+
renderer: {
|
|
30
|
+
text(tokenOrString) {
|
|
31
|
+
if (typeof tokenOrString === "object" && tokenOrString?.tokens) {
|
|
32
|
+
// @ts-ignore - 'this' is the renderer context with a parser
|
|
33
|
+
return this.parser.parseInline(tokenOrString.tokens);
|
|
34
|
+
}
|
|
35
|
+
return typeof tokenOrString === "string"
|
|
36
|
+
? tokenOrString
|
|
37
|
+
: tokenOrString?.text ?? "";
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
//get last 50 lines of logs
|
|
42
|
+
function getLast50Lines(str) {
|
|
43
|
+
const lines = str.split("\n");
|
|
44
|
+
return lines.slice(-50).join("\n");
|
|
45
|
+
}
|
|
46
|
+
// Helper function to wrap text to a specific width, accounting for ANSI codes
|
|
47
|
+
function wrapText(text, maxWidth) {
|
|
48
|
+
if (maxWidth <= 0)
|
|
49
|
+
return [text];
|
|
50
|
+
const words = text.split(" ");
|
|
51
|
+
const lines = [];
|
|
52
|
+
let currentLine = "";
|
|
53
|
+
for (const word of words) {
|
|
54
|
+
const testLine = currentLine ? `${currentLine} ${word}` : word;
|
|
55
|
+
const width = stringWidth(testLine);
|
|
56
|
+
if (width <= maxWidth) {
|
|
57
|
+
currentLine = testLine;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
if (currentLine) {
|
|
61
|
+
lines.push(currentLine);
|
|
62
|
+
}
|
|
63
|
+
currentLine = word;
|
|
64
|
+
// If a single word is too long, it will overflow - keep it as one line
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (currentLine) {
|
|
68
|
+
lines.push(currentLine);
|
|
69
|
+
}
|
|
70
|
+
return lines.length > 0 ? lines : [""];
|
|
71
|
+
}
|
|
72
|
+
//scrollable content component
|
|
73
|
+
const ScrollableContent = ({ lines, maxHeight, isFocused, onScrollChange, scrollOffset, }) => {
|
|
74
|
+
const totalLines = lines.length;
|
|
75
|
+
const visibleLines = Math.max(0, Math.min(maxHeight, totalLines));
|
|
76
|
+
const maxOffset = Math.max(0, totalLines - visibleLines);
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
if (maxOffset === 0) {
|
|
79
|
+
if (scrollOffset !== 0) {
|
|
80
|
+
onScrollChange(0);
|
|
81
|
+
}
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
// Auto-scroll to bottom when not focused
|
|
85
|
+
if (!isFocused) {
|
|
86
|
+
onScrollChange(maxOffset);
|
|
87
|
+
}
|
|
88
|
+
}, [totalLines, maxOffset, isFocused]);
|
|
89
|
+
const effectiveOffset = Math.min(maxOffset, Math.max(0, scrollOffset));
|
|
90
|
+
const displayedLines = lines.slice(effectiveOffset, effectiveOffset + visibleLines);
|
|
91
|
+
let scrollPosition = 0;
|
|
92
|
+
if (totalLines > visibleLines) {
|
|
93
|
+
scrollPosition = Math.floor((effectiveOffset / maxOffset) * 100);
|
|
94
|
+
}
|
|
95
|
+
const scrollBarIndicator = totalLines > visibleLines ? `[${scrollPosition}%]` : "";
|
|
96
|
+
return (_jsxs(Box, { flexDirection: "column", height: maxHeight, overflow: "hidden", children: [displayedLines.map((line) => {
|
|
97
|
+
const rendered = marked.parseInline(line.text);
|
|
98
|
+
return _jsx(Text, { children: rendered }, line.key);
|
|
99
|
+
}), _jsx(Box, { position: "absolute", children: _jsx(Text, { color: "yellowBright", bold: true, children: scrollBarIndicator }) })] }));
|
|
100
|
+
};
|
|
101
|
+
//AI chat
|
|
102
|
+
const ScrollableContentChat = ({ lines, maxHeight, isFocused, onScrollChange, scrollOffset, isLoading, }) => {
|
|
103
|
+
const totalLines = lines.length;
|
|
104
|
+
const visibleLines = Math.max(0, Math.min(maxHeight, totalLines));
|
|
105
|
+
const maxOffset = Math.max(0, totalLines - visibleLines);
|
|
106
|
+
const animationRef = useRef(null);
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
if (maxOffset === 0) {
|
|
109
|
+
if (scrollOffset !== 0) {
|
|
110
|
+
onScrollChange(0);
|
|
111
|
+
}
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
// Auto-scroll to bottom when not focused
|
|
115
|
+
if (!isFocused) {
|
|
116
|
+
// Cancel any ongoing animation
|
|
117
|
+
if (animationRef.current) {
|
|
118
|
+
clearInterval(animationRef.current);
|
|
119
|
+
}
|
|
120
|
+
// Smooth scroll animation
|
|
121
|
+
const start = scrollOffset;
|
|
122
|
+
const distance = maxOffset - start;
|
|
123
|
+
const duration = 500; // 500ms animation
|
|
124
|
+
const startTime = Date.now();
|
|
125
|
+
const animate = () => {
|
|
126
|
+
const elapsed = Date.now() - startTime;
|
|
127
|
+
const progress = Math.min(elapsed / duration, 1);
|
|
128
|
+
// Easing function (ease-out)
|
|
129
|
+
const easeOut = 1 - Math.pow(1 - progress, 3);
|
|
130
|
+
const newOffset = Math.round(start + distance * easeOut);
|
|
131
|
+
onScrollChange(newOffset);
|
|
132
|
+
if (progress < 1) {
|
|
133
|
+
animationRef.current = setTimeout(animate, 16); // ~60fps
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
animationRef.current = null;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
animate();
|
|
140
|
+
}
|
|
141
|
+
return () => {
|
|
142
|
+
if (animationRef.current) {
|
|
143
|
+
clearInterval(animationRef.current);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}, [totalLines, maxOffset, isFocused]);
|
|
147
|
+
const effectiveOffset = Math.min(maxOffset, Math.max(0, scrollOffset));
|
|
148
|
+
const displayedLines = lines.slice(effectiveOffset, effectiveOffset + visibleLines);
|
|
149
|
+
let scrollPosition = 0;
|
|
150
|
+
if (totalLines > visibleLines) {
|
|
151
|
+
scrollPosition = Math.floor((effectiveOffset / maxOffset) * 100);
|
|
152
|
+
}
|
|
153
|
+
const scrollBarIndicator = totalLines > visibleLines ? `[${scrollPosition}%]` : "";
|
|
154
|
+
return (_jsxs(Box, { flexDirection: "column", height: maxHeight, overflow: "hidden", children: [displayedLines.map((line) => {
|
|
155
|
+
if (line?.text === "" || line?.text === undefined)
|
|
156
|
+
return;
|
|
157
|
+
const rendered = marked.parseInline(line?.text);
|
|
158
|
+
return _jsx(Text, { children: rendered }, line.key);
|
|
159
|
+
}), isLoading && (_jsx(_Fragment, { children: _jsxs(Text, { color: "grey", children: [_jsx(Spinner, { type: "dots" }), "\u00A0 Analyzing..."] }) })), _jsx(Box, { position: "absolute", children: _jsx(Text, { color: "yellowBright", bold: true, children: scrollBarIndicator }) })] }));
|
|
160
|
+
};
|
|
161
|
+
//border for the content
|
|
162
|
+
const BorderBox = ({ title, children, isFocused, width, }) => (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: isFocused ? "greenBright" : "gray", paddingX: 1, paddingY: 0, marginRight: 1, width: width, overflow: "hidden", children: [_jsx(Box, { marginBottom: 1, borderBottom: isFocused ? true : undefined, borderBottomColor: isFocused ? "greenBright" : "gray", children: _jsxs(Text, { color: "cyan", bold: isFocused, children: [title, " ", isFocused ? " (FOCUSED)" : ""] }) }), children] }));
|
|
163
|
+
export const App = () => {
|
|
164
|
+
const { stdout } = useStdout();
|
|
165
|
+
const { exit } = useApp();
|
|
166
|
+
const [chatInput, setChatInput] = useState("");
|
|
167
|
+
const [rawLogData, setRawLogData] = useState([]);
|
|
168
|
+
const partialLine = useRef("");
|
|
169
|
+
const logKeyCounter = useRef(0);
|
|
170
|
+
const [activePane, setActivePane] = useState("input");
|
|
171
|
+
const [logScroll, setLogScroll] = useState(0);
|
|
172
|
+
const [chatScroll, setChatScroll] = useState(0);
|
|
173
|
+
const [terminalRows, setTerminalRows] = useState(stdout?.rows || 20);
|
|
174
|
+
const [terminalCols, setTerminalCols] = useState(stdout?.columns || 80);
|
|
175
|
+
//websocket hook
|
|
176
|
+
const { connectWebSocket, sendQuery, chatResponseMessages, setChatResponseMessages, isConnected,
|
|
177
|
+
// userReply,
|
|
178
|
+
isLoading, setTrimmedChats, API_KEY, } = useWebSocket(config.websocket_url);
|
|
179
|
+
const SCROLL_HEIGHT = terminalRows - 6;
|
|
180
|
+
const LOGS_HEIGHT = SCROLL_HEIGHT;
|
|
181
|
+
const INPUT_BOX_HEIGHT = 5; // Border (2) + marginTop (1) + content (1) + padding (~1)
|
|
182
|
+
const CHAT_HISTORY_HEIGHT = SCROLL_HEIGHT - INPUT_BOX_HEIGHT;
|
|
183
|
+
useEffect(() => {
|
|
184
|
+
const handleResize = () => {
|
|
185
|
+
if (stdout?.rows) {
|
|
186
|
+
setTerminalRows(stdout.rows);
|
|
187
|
+
}
|
|
188
|
+
if (stdout?.columns) {
|
|
189
|
+
setTerminalCols(stdout.columns);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
process.stdout.on("resize", handleResize);
|
|
193
|
+
return () => {
|
|
194
|
+
process.stdout.off("resize", handleResize);
|
|
195
|
+
};
|
|
196
|
+
}, [stdout]);
|
|
197
|
+
//web socket connection
|
|
198
|
+
useEffect(() => {
|
|
199
|
+
connectWebSocket();
|
|
200
|
+
}, []);
|
|
201
|
+
//get the AIMessage content inside the progress event
|
|
202
|
+
let lastAIMessage = "";
|
|
203
|
+
function extractAIMessages(obj) {
|
|
204
|
+
if (obj?.type !== "progress")
|
|
205
|
+
return "aaa";
|
|
206
|
+
const messages = (obj.data && obj.data?.messages) ?? [];
|
|
207
|
+
const latestAI = [...messages]
|
|
208
|
+
.reverse()
|
|
209
|
+
.find((m) => m.id?.includes("AIMessage"));
|
|
210
|
+
const content = latestAI?.kwargs?.content?.trim();
|
|
211
|
+
if (!content)
|
|
212
|
+
return undefined;
|
|
213
|
+
if (content === lastAIMessage) {
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
lastAIMessage = content;
|
|
217
|
+
if (content === undefined)
|
|
218
|
+
return;
|
|
219
|
+
return content;
|
|
220
|
+
}
|
|
221
|
+
// Auto-switch to chat pane when server finishes responding
|
|
222
|
+
useEffect(() => {
|
|
223
|
+
if (chatResponseMessages.length === 0)
|
|
224
|
+
return;
|
|
225
|
+
const lastMessage = chatResponseMessages[chatResponseMessages.length - 1];
|
|
226
|
+
// Switch focus when we get a final message type (response, ask_user, or error)
|
|
227
|
+
if (lastMessage?.type === "response" ||
|
|
228
|
+
lastMessage?.type === "progress" ||
|
|
229
|
+
lastMessage?.type === "ask_user" ||
|
|
230
|
+
lastMessage?.type === "error") {
|
|
231
|
+
// Delay to ensure auto-scroll animation completes first (500ms scroll + 100ms buffer)
|
|
232
|
+
setTimeout(() => setActivePane("chat"), 600);
|
|
233
|
+
}
|
|
234
|
+
}, [chatResponseMessages]);
|
|
235
|
+
const chatLinesChat = useMemo(() => {
|
|
236
|
+
// Calculate available width for chat (half terminal width minus borders and padding)
|
|
237
|
+
const availableWidth = Math.floor(terminalCols / 2) - 6; // Adjust as needed
|
|
238
|
+
return chatResponseMessages.flatMap((msg, index) => {
|
|
239
|
+
// Create a label depending on the message type
|
|
240
|
+
const prefix = `${msg.type === "user" ? "🧑" : "🤖"} `;
|
|
241
|
+
const prefixWidth = stringWidth(prefix);
|
|
242
|
+
//progress event chat responses
|
|
243
|
+
// Extract message content
|
|
244
|
+
const extracted = extractAIMessages(msg);
|
|
245
|
+
const content = msg.type === "progress"
|
|
246
|
+
? Array.isArray(extracted)
|
|
247
|
+
? extracted.join("\n") // nicely formatted output
|
|
248
|
+
: extracted || ""
|
|
249
|
+
: msg.message ||
|
|
250
|
+
msg?.data?.finalMessage ||
|
|
251
|
+
msg?.data?.message ||
|
|
252
|
+
JSON.stringify(msg, null, 2);
|
|
253
|
+
if (content === "")
|
|
254
|
+
return;
|
|
255
|
+
const contentLines = content?.split("\n");
|
|
256
|
+
const lines = contentLines.flatMap((line, lineIndex) => {
|
|
257
|
+
const fullLine = (lineIndex === 0 ? prefix : " ".repeat(prefixWidth)) + line;
|
|
258
|
+
const wrappedLines = wrapText(fullLine, availableWidth);
|
|
259
|
+
return wrappedLines.map((wrappedLine, wrapIndex) => ({
|
|
260
|
+
key: `chat-${index}-line-${lineIndex}-wrap-${wrapIndex}`,
|
|
261
|
+
text: wrappedLine,
|
|
262
|
+
}));
|
|
263
|
+
});
|
|
264
|
+
// Add spacing after user messages for readability
|
|
265
|
+
if (msg.type === "user") {
|
|
266
|
+
lines.push({
|
|
267
|
+
key: `chat-${index}-spacer`,
|
|
268
|
+
text: " ",
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
return lines;
|
|
272
|
+
});
|
|
273
|
+
}, [chatResponseMessages, terminalCols]);
|
|
274
|
+
const currentLogDataString = useMemo(() => rawLogData.map((l) => l.text).join("\n"), [rawLogData]);
|
|
275
|
+
const logLines = useMemo(() => {
|
|
276
|
+
const availableWidth = Math.floor(terminalCols / 2) - 6;
|
|
277
|
+
return rawLogData.map((line) => {
|
|
278
|
+
// Expand tabs to spaces (assuming 8-space tabs)
|
|
279
|
+
const expandedText = line.text.replace(/\t/g, " ".repeat(8));
|
|
280
|
+
// Truncate lines that are too wide, properly handling ANSI codes
|
|
281
|
+
const width = stringWidth(expandedText);
|
|
282
|
+
if (width > availableWidth) {
|
|
283
|
+
const truncated = sliceAnsi(expandedText, 0, availableWidth - 3);
|
|
284
|
+
return {
|
|
285
|
+
key: line.key,
|
|
286
|
+
text: truncated + "...",
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
return {
|
|
290
|
+
key: line.key,
|
|
291
|
+
text: expandedText,
|
|
292
|
+
};
|
|
293
|
+
});
|
|
294
|
+
}, [rawLogData, terminalCols]);
|
|
295
|
+
const runBashCommandWithPipe = useCallback((command) => {
|
|
296
|
+
const shell = process.env.SHELL || "bash";
|
|
297
|
+
const cols = Math.floor(terminalCols / 2) - 6; // Match the BorderBox width
|
|
298
|
+
const rows = LOGS_HEIGHT - 2;
|
|
299
|
+
const ptyProcess = ptySpawn(shell, ["-c", command], {
|
|
300
|
+
cwd: process.cwd(),
|
|
301
|
+
env: process.env,
|
|
302
|
+
cols: cols,
|
|
303
|
+
rows: rows,
|
|
304
|
+
});
|
|
305
|
+
ptyProcess.onData((chunk) => {
|
|
306
|
+
let data = partialLine.current + chunk;
|
|
307
|
+
const lines = data.split("\n");
|
|
308
|
+
partialLine.current = lines.pop() || "";
|
|
309
|
+
if (lines.length > 0) {
|
|
310
|
+
const newLines = lines.map((line) => ({
|
|
311
|
+
key: `log-${logKeyCounter.current++}`,
|
|
312
|
+
text: line,
|
|
313
|
+
}));
|
|
314
|
+
setRawLogData((prevLines) => [...prevLines, ...newLines]);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
ptyProcess.onExit(({ exitCode }) => {
|
|
318
|
+
if (partialLine.current.length > 0) {
|
|
319
|
+
const remainingLine = {
|
|
320
|
+
key: `log-${logKeyCounter.current++}`,
|
|
321
|
+
text: partialLine.current,
|
|
322
|
+
};
|
|
323
|
+
setRawLogData((prevLines) => [...prevLines, remainingLine]);
|
|
324
|
+
partialLine.current = "";
|
|
325
|
+
}
|
|
326
|
+
const exitLine = {
|
|
327
|
+
key: `log-${logKeyCounter.current++}`,
|
|
328
|
+
text: `\n[Process exited with code ${exitCode}]\n`,
|
|
329
|
+
};
|
|
330
|
+
setRawLogData((prevLines) => [...prevLines, exitLine]);
|
|
331
|
+
});
|
|
332
|
+
return () => ptyProcess.kill();
|
|
333
|
+
}, [terminalCols, LOGS_HEIGHT]);
|
|
334
|
+
useEffect(() => {
|
|
335
|
+
const cmd = process.argv.slice(2).join(" ") ||
|
|
336
|
+
'echo "Welcome to the Scrollable CLI Debugger." && echo "Run a command after the script: tsx cli-app.tsx ls -la" && sleep 0.5 && echo "Fetching logs..." && echo "---------------------------" && ls -la';
|
|
337
|
+
const unsubscribe = runBashCommandWithPipe(cmd);
|
|
338
|
+
return () => {
|
|
339
|
+
if (unsubscribe) {
|
|
340
|
+
unsubscribe();
|
|
341
|
+
if (partialLine.current.length > 0) {
|
|
342
|
+
const remainingLine = {
|
|
343
|
+
key: `log-${logKeyCounter.current++}`,
|
|
344
|
+
text: partialLine.current,
|
|
345
|
+
};
|
|
346
|
+
setRawLogData((prevLines) => [...prevLines, remainingLine]);
|
|
347
|
+
partialLine.current = "";
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
}, [runBashCommandWithPipe]);
|
|
352
|
+
async function userMessageSubmitted() {
|
|
353
|
+
if (!chatInput.trim())
|
|
354
|
+
return;
|
|
355
|
+
//send message to socket connection
|
|
356
|
+
const userMessage = {
|
|
357
|
+
type: "user",
|
|
358
|
+
message: chatInput,
|
|
359
|
+
};
|
|
360
|
+
setChatResponseMessages((prev) => [
|
|
361
|
+
...prev,
|
|
362
|
+
JSON.parse(JSON.stringify(userMessage)),
|
|
363
|
+
]);
|
|
364
|
+
setTrimmedChats((prev) => [
|
|
365
|
+
...prev,
|
|
366
|
+
JSON.parse(JSON.stringify(userMessage)),
|
|
367
|
+
]);
|
|
368
|
+
//last response message
|
|
369
|
+
const lastMessage = chatResponseMessages[chatResponseMessages.length - 1];
|
|
370
|
+
//logs
|
|
371
|
+
const logs = getLast50Lines(currentLogDataString);
|
|
372
|
+
// Decide whether to send state or not
|
|
373
|
+
if (lastMessage?.type === "response" && lastMessage?.data?.state) {
|
|
374
|
+
sendQuery(chatInput, logs, lastMessage.data.state);
|
|
375
|
+
}
|
|
376
|
+
else if (lastMessage?.type === "ask_user" && lastMessage?.data?.state) {
|
|
377
|
+
sendQuery(chatInput, logs, lastMessage?.data?.state);
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
sendQuery(chatInput, logs);
|
|
381
|
+
}
|
|
382
|
+
setChatInput("");
|
|
383
|
+
}
|
|
384
|
+
useInput((inputStr, key) => {
|
|
385
|
+
if (inputStr === "c" && key.ctrl) {
|
|
386
|
+
exit();
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
if (key.ctrl && inputStr === "l") {
|
|
390
|
+
setRawLogData([]);
|
|
391
|
+
logKeyCounter.current = 0;
|
|
392
|
+
partialLine.current = "";
|
|
393
|
+
setLogScroll(0);
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
if (key.ctrl && inputStr === "k") {
|
|
397
|
+
setChatResponseMessages([]);
|
|
398
|
+
setChatScroll(0);
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
if (key.tab) {
|
|
402
|
+
if (activePane === "input")
|
|
403
|
+
setActivePane("logs");
|
|
404
|
+
else if (activePane === "logs")
|
|
405
|
+
setActivePane("chat");
|
|
406
|
+
else
|
|
407
|
+
setActivePane("input");
|
|
408
|
+
return true;
|
|
409
|
+
}
|
|
410
|
+
const isScrollPane = activePane === "logs" || activePane === "chat";
|
|
411
|
+
const scrollDelta = 1;
|
|
412
|
+
if (isScrollPane && (key.upArrow || key.downArrow)) {
|
|
413
|
+
const currentScroll = activePane === "logs" ? logScroll : chatScroll;
|
|
414
|
+
const setScroll = activePane === "logs" ? setLogScroll : setChatScroll;
|
|
415
|
+
const lines = activePane === "logs" ? logLines : chatLinesChat;
|
|
416
|
+
const maxHeight = activePane === "logs" ? LOGS_HEIGHT - 2 : CHAT_HISTORY_HEIGHT - 1;
|
|
417
|
+
const totalLines = lines.length;
|
|
418
|
+
const visibleLines = Math.max(0, Math.min(maxHeight, totalLines));
|
|
419
|
+
const maxOffset = Math.max(0, totalLines - visibleLines);
|
|
420
|
+
let newScroll = currentScroll;
|
|
421
|
+
if (key.upArrow) {
|
|
422
|
+
newScroll = Math.max(0, currentScroll - scrollDelta);
|
|
423
|
+
}
|
|
424
|
+
else if (key.downArrow) {
|
|
425
|
+
newScroll = Math.min(maxOffset, currentScroll + scrollDelta);
|
|
426
|
+
}
|
|
427
|
+
if (newScroll !== currentScroll) {
|
|
428
|
+
setScroll(newScroll);
|
|
429
|
+
}
|
|
430
|
+
return true;
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
// const text = dedent`
|
|
434
|
+
// **Run your Ink application**:
|
|
435
|
+
// `;
|
|
436
|
+
return (_jsxs(Box, { flexDirection: "column", height: terminalRows, width: "100%", padding: 0, overflow: "hidden", children: [_jsxs(Box, { flexDirection: "row", width: "100%", height: LOGS_HEIGHT, padding: 0, overflow: "hidden", children: [_jsx(BorderBox, { title: "Command Logs", isFocused: activePane === "logs", width: "50%", children: _jsx(ScrollableContent, { lines: logLines, maxHeight: LOGS_HEIGHT - 2, isFocused: activePane === "logs", scrollOffset: logScroll, onScrollChange: setLogScroll }) }), _jsxs(BorderBox, { title: "AI Chat", isFocused: activePane === "chat", width: "50%", children: [!API_KEY ? (_jsxs(Text, { children: ["Auth key not found.", "\n", "Login using: ", _jsx(Text, { color: "blue", children: "clippy login <your-auth-key>" })] })) :
|
|
437
|
+
isConnected ? (_jsx(ScrollableContentChat, { lines: chatLinesChat, maxHeight: CHAT_HISTORY_HEIGHT - 1, isFocused: activePane === "chat", scrollOffset: chatScroll, onScrollChange: setChatScroll, isLoading: isLoading })) : (_jsx(Text, { children: "AI Chat not connected" })), isConnected && (_jsxs(Box, { borderStyle: "round", borderColor: activePane === "input" ? "greenBright" : "white", paddingX: 1, width: "100%", overflow: "hidden", children: [_jsx(Text, { color: "white", bold: activePane === "input", children: "Input:" }), _jsx(TextInput, { placeholder: "What's bugging you today?", value: chatInput, onChange: setChatInput, onSubmit: userMessageSubmitted, focus: activePane === "input" })] }))] })] }), _jsx(Box, { marginTop: 1, justifyContent: "center", children: _jsx(Text, { color: "#949494", children: "[Tab] Switch Focus [ \u2B06 / \u2B07 ] Scroll (Keyboard Only) [Enter] Send [Ctrl+C] Exit" }) })] }));
|
|
438
|
+
};
|
|
439
|
+
render(_jsx(App, {}));
|
|
440
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/ui-graph.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// import * as fs from 'fs';
|
|
2
|
+
// import {
|
|
3
|
+
// StateGraph,
|
|
4
|
+
// START,
|
|
5
|
+
// END,
|
|
6
|
+
// Annotation,
|
|
7
|
+
// messagesStateReducer,
|
|
8
|
+
// AnnotationRoot,
|
|
9
|
+
// Command,
|
|
10
|
+
// } from "@langchain/langgraph";
|
|
11
|
+
// import { createReactAgent } from "@langchain/langgraph/prebuilt";
|
|
12
|
+
// import { ChatOpenAI } from "@langchain/openai";
|
|
13
|
+
// import { TavilySearchResults } from "@langchain/community/tools/tavily_search";
|
|
14
|
+
// import { AIMessage, BaseMessage, HumanMessage, SystemMessage } from "@langchain/core/messages";
|
|
15
|
+
// import { tool } from "@langchain/core/tools";
|
|
16
|
+
// import { z } from "zod";
|
|
17
|
+
export {};
|
|
18
|
+
// import * as dotenv from "dotenv";
|
|
19
|
+
// dotenv.config();
|
|
20
|
+
// const llm = new ChatOpenAI({
|
|
21
|
+
// model: "gpt-4o",
|
|
22
|
+
// temperature: 0,
|
|
23
|
+
// openAIApiKey: process.env.OPENAI_API_KEY,
|
|
24
|
+
// });
|
|
25
|
+
// function getContextLines(
|
|
26
|
+
// fileName: string,
|
|
27
|
+
// lineNumber: number,
|
|
28
|
+
// before: number = 3,
|
|
29
|
+
// after: number = 3
|
|
30
|
+
// ): string {
|
|
31
|
+
// const lines = fs.readFileSync(fileName, 'utf-8').split('\n');
|
|
32
|
+
// const start = Math.max(0, lineNumber - before - 1);
|
|
33
|
+
// const end = Math.min(lines.length, lineNumber + after);
|
|
34
|
+
// return lines.slice(start, end).join('\n');
|
|
35
|
+
// }
|
|
36
|
+
// const getContextLinesTool = tool(
|
|
37
|
+
// async ({ fileName, lineNumber, before = 3, after = 3 }) => {
|
|
38
|
+
// console.log("Reading files:", fileName, lineNumber);
|
|
39
|
+
// return getContextLines(`${fileName}`, lineNumber, before, after);
|
|
40
|
+
// },
|
|
41
|
+
// {
|
|
42
|
+
// name: "get_context_lines",
|
|
43
|
+
// description: "Get a few lines before and after a line number in a file.",
|
|
44
|
+
// schema: z.object({
|
|
45
|
+
// fileName: z.string().describe("Path to the file"),
|
|
46
|
+
// lineNumber: z.number().describe("Line number (1-based)"),
|
|
47
|
+
// before: z.number().optional().describe("Lines before"),
|
|
48
|
+
// after: z.number().optional().describe("Lines after")
|
|
49
|
+
// })
|
|
50
|
+
// }
|
|
51
|
+
// );
|
|
52
|
+
// const agent = createReactAgent({
|
|
53
|
+
// llm: llm,
|
|
54
|
+
// tools: [getContextLinesTool]
|
|
55
|
+
// })
|
|
56
|
+
// const webSearchTool = new TavilySearchResults({
|
|
57
|
+
// maxResults: 4,
|
|
58
|
+
// apiKey: process.env.TAVILY_API_KEY,
|
|
59
|
+
// });
|
|
60
|
+
// const tools = [webSearchTool];
|
|
61
|
+
// const GraphState = Annotation.Root({
|
|
62
|
+
// messages: Annotation<BaseMessage[]>({
|
|
63
|
+
// reducer: messagesStateReducer,
|
|
64
|
+
// default: () => [],
|
|
65
|
+
// }),
|
|
66
|
+
// userInput: Annotation<string>,
|
|
67
|
+
// logs: Annotation<string>
|
|
68
|
+
// });
|
|
69
|
+
// type GS = {
|
|
70
|
+
// logs: string,
|
|
71
|
+
// messages: BaseMessage[],
|
|
72
|
+
// userInput: string
|
|
73
|
+
// }
|
|
74
|
+
// const primaryNode = async (state: GS) => {
|
|
75
|
+
// const systemMessage = new SystemMessage(`
|
|
76
|
+
// You are an AI debugging assistant.
|
|
77
|
+
// Your primary goal is to help developers **reproduce, diagnose, and resolve bugs** quickly and reliably.
|
|
78
|
+
// You are NOT a generic code generator — focus on debugging workflows.
|
|
79
|
+
// Core principles:
|
|
80
|
+
// 1. Always start from the **symptom** (error message, stack trace, log, failing test, unexpected behavior).
|
|
81
|
+
// 2. Perform **root cause analysis**:
|
|
82
|
+
// - Map error to relevant files, functions, commits, or configs.
|
|
83
|
+
// - Identify likely causes, and explain reasoning with evidence.
|
|
84
|
+
// 3. Suggest **fixes cautiously**:
|
|
85
|
+
// - Provide minimal, safe code or config changes.
|
|
86
|
+
// - Emphasize why the change addresses the root cause.
|
|
87
|
+
// - Flag possible side effects or regressions.
|
|
88
|
+
// 4. Always include **verification**:
|
|
89
|
+
// - Propose tests, logs, or commands to confirm the fix.
|
|
90
|
+
// - Where relevant, suggest monitoring/observability signals to watch.
|
|
91
|
+
// 5. Keep answers **precise, actionable, and trustworthy**.
|
|
92
|
+
// - Show citations from logs, traces, or code when possible.
|
|
93
|
+
// - Avoid speculative fixes without evidence.
|
|
94
|
+
// You have access to runtime context such as logs, stack traces, CI output, terminal commands, and database state.
|
|
95
|
+
// Use these as primary inputs before analyzing code.
|
|
96
|
+
// You are an expert software developer. You need to help my user with debugging. Attaching some of the logs below. study it and help the user.
|
|
97
|
+
// You have access to tool calls that can help you read lines from the files used in the project you are debugging. Feel free to use them.
|
|
98
|
+
// Make sure you do as much of the work as possible. Call the tools if you think it'll help reduce steps for the user.
|
|
99
|
+
// No need to ask permission before calling tools.
|
|
100
|
+
// Expected output is a specfic fix.
|
|
101
|
+
// Only output fix as the final answer. Unless the user explicitly asks for a root cause analysis.
|
|
102
|
+
// Logs:
|
|
103
|
+
// ${state.logs}
|
|
104
|
+
// `);
|
|
105
|
+
// const messages = [systemMessage].concat(state.messages);
|
|
106
|
+
// const res = await agent.invoke({messages});
|
|
107
|
+
// console.log(res.messages.map(x => x.content));
|
|
108
|
+
// const newMessages = res.messages.slice(state.messages.length + 1)
|
|
109
|
+
// return new Command({
|
|
110
|
+
// goto: END,
|
|
111
|
+
// update: {
|
|
112
|
+
// messages: newMessages
|
|
113
|
+
// }
|
|
114
|
+
// })
|
|
115
|
+
// }
|
|
116
|
+
// const actionsNode = () => {
|
|
117
|
+
// return {}
|
|
118
|
+
// }
|
|
119
|
+
// export const graph = new StateGraph(GraphState)
|
|
120
|
+
// .addNode("primaryNode", primaryNode, {ends: ["actionsNode"]})
|
|
121
|
+
// .addNode("actionsNode", actionsNode)
|
|
122
|
+
// .addEdge(START, "primaryNode")
|
|
123
|
+
// .addEdge("primaryNode", END)
|
|
124
|
+
// .compile()
|
|
125
|
+
//# sourceMappingURL=ui-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-graph.js","sourceRoot":"","sources":["../ui-graph.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,WAAW;AACX,gBAAgB;AAChB,WAAW;AACX,SAAS;AACT,gBAAgB;AAChB,yBAAyB;AACzB,mBAAmB;AACnB,YAAY;AACZ,iCAAiC;AACjC,oEAAoE;AACpE,kDAAkD;AAClD,kFAAkF;AAClF,kGAAkG;AAClG,gDAAgD;AAChD,2BAA2B;;AAE3B,oCAAoC;AACpC,mBAAmB;AAEnB,+BAA+B;AAC/B,oBAAoB;AACpB,mBAAmB;AACnB,6CAA6C;AAC7C,MAAM;AAEN,4BAA4B;AAC5B,sBAAsB;AACtB,wBAAwB;AACxB,wBAAwB;AACxB,sBAAsB;AACtB,cAAc;AACd,kEAAkE;AAClE,wDAAwD;AACxD,4DAA4D;AAC5D,+CAA+C;AAC/C,IAAI;AAEJ,oCAAoC;AACpC,iEAAiE;AACjE,2DAA2D;AAE3D,wEAAwE;AACxE,OAAO;AACP,MAAM;AACN,iCAAiC;AACjC,gFAAgF;AAChF,yBAAyB;AACzB,2DAA2D;AAC3D,kEAAkE;AAClE,gEAAgE;AAChE,6DAA6D;AAC7D,SAAS;AACT,MAAM;AACN,KAAK;AAEL,mCAAmC;AACnC,cAAc;AACd,iCAAiC;AACjC,KAAK;AAEL,kDAAkD;AAClD,kBAAkB;AAClB,uCAAuC;AACvC,MAAM;AAEN,iCAAiC;AAEjC,uCAAuC;AACvC,yCAAyC;AACzC,qCAAqC;AACrC,yBAAyB;AACzB,QAAQ;AACR,mCAAmC;AACnC,4BAA4B;AAC5B,MAAM;AAEN,cAAc;AACd,iBAAiB;AACjB,4BAA4B;AAC5B,sBAAsB;AACtB,IAAI;AAEJ,6CAA6C;AAC7C,6CAA6C;AAC7C,0CAA0C;AAC1C,2GAA2G;AAC3G,uEAAuE;AAEvE,mBAAmB;AACnB,6GAA6G;AAC7G,uCAAuC;AACvC,qEAAqE;AACrE,oEAAoE;AACpE,mCAAmC;AACnC,qDAAqD;AACrD,0DAA0D;AAC1D,kDAAkD;AAClD,sCAAsC;AACtC,4DAA4D;AAC5D,0EAA0E;AAC1E,6DAA6D;AAC7D,gEAAgE;AAChE,iDAAiD;AAEjD,oHAAoH;AACpH,qDAAqD;AAErD,iJAAiJ;AAGjJ,8IAA8I;AAG9I,wHAAwH;AACxH,oDAAoD;AAEpD,sCAAsC;AAEtC,sGAAsG;AAGtG,UAAU;AACV,kBAAkB;AAClB,OAAO;AAEP,6DAA6D;AAC7D,+CAA+C;AAC/C,mDAAmD;AAEnD,qEAAqE;AAErE,wBAAwB;AACxB,eAAe;AACf,cAAc;AACd,2BAA2B;AAC3B,MAAM;AACN,MAAM;AACN,IAAI;AACJ,8BAA8B;AAC9B,aAAa;AACb,IAAI;AAGJ,kDAAkD;AAClD,oEAAoE;AACpE,2CAA2C;AAC3C,qCAAqC;AACrC,mCAAmC;AACnC,iBAAiB"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function useWebSocket(url: string): {
|
|
2
|
+
connectWebSocket: () => void;
|
|
3
|
+
socketId: string;
|
|
4
|
+
sendQuery: (query: string, logs: any, state?: any) => void;
|
|
5
|
+
chatResponseMessages: any[];
|
|
6
|
+
setChatResponseMessages: import("react").Dispatch<import("react").SetStateAction<any[]>>;
|
|
7
|
+
setTrimmedChats: import("react").Dispatch<import("react").SetStateAction<any[]>>;
|
|
8
|
+
isConnected: boolean;
|
|
9
|
+
connectionError: string;
|
|
10
|
+
isLoading: boolean;
|
|
11
|
+
API_KEY: string;
|
|
12
|
+
};
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
+
import { getContextLines } from "./utils.js";
|
|
3
|
+
import { toolFunctionCall } from "./api.js";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import os from "os";
|
|
6
|
+
import path from "path";
|
|
7
|
+
// Load Clippy config from ~/.clippy/config
|
|
8
|
+
const HOME_DIR = os.homedir();
|
|
9
|
+
const CLIPPY_DIR = path.join(HOME_DIR, ".clippy");
|
|
10
|
+
const CONFIG_PATH = path.join(CLIPPY_DIR, "config");
|
|
11
|
+
let API_KEY = "";
|
|
12
|
+
try {
|
|
13
|
+
const configText = fs.readFileSync(CONFIG_PATH, "utf8");
|
|
14
|
+
const match = configText.match(/^API_KEY\s*=\s*(.*)$/m);
|
|
15
|
+
if (match && match[1]) {
|
|
16
|
+
API_KEY = match[1].trim();
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
console.log("No API_KEY found in ~/.clippy/config");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
console.log("Failed to read Clippy config:", err);
|
|
24
|
+
}
|
|
25
|
+
export function useWebSocket(url) {
|
|
26
|
+
//refs
|
|
27
|
+
const socketRef = useRef(null);
|
|
28
|
+
const [socketId, setSocketId] = useState(null);
|
|
29
|
+
const [chatResponseMessages, setChatResponseMessages] = useState([]);
|
|
30
|
+
const [trimmedChats, setTrimmedChats] = useState([]);
|
|
31
|
+
const [visibleChats, setVisibleChats] = useState([]);
|
|
32
|
+
const [isConnected, setIsConnected] = useState(false);
|
|
33
|
+
const [connectionError, setConnectionError] = useState(null);
|
|
34
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
35
|
+
const authKey = API_KEY;
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (API_KEY === "") {
|
|
38
|
+
setConnectionError("No API_KEY found in ~/.clippy/config");
|
|
39
|
+
console.log("No API_KEY found in ~/.clippy/config");
|
|
40
|
+
process.exit();
|
|
41
|
+
}
|
|
42
|
+
}, [API_KEY]);
|
|
43
|
+
//web socket connection
|
|
44
|
+
const connectWebSocket = useCallback(() => {
|
|
45
|
+
if (socketRef.current) {
|
|
46
|
+
socketRef.current.close();
|
|
47
|
+
}
|
|
48
|
+
const socket = new WebSocket(url);
|
|
49
|
+
socketRef.current = socket;
|
|
50
|
+
setConnectionError(null);
|
|
51
|
+
setIsConnected(false);
|
|
52
|
+
socket.onopen = () => {
|
|
53
|
+
socket.send(JSON.stringify({ type: "recurring_connection", authKey }));
|
|
54
|
+
};
|
|
55
|
+
socket.onmessage = async (event) => {
|
|
56
|
+
try {
|
|
57
|
+
const raw = event.data;
|
|
58
|
+
let text = "";
|
|
59
|
+
if (typeof raw === "string") {
|
|
60
|
+
text = raw;
|
|
61
|
+
}
|
|
62
|
+
else if (raw instanceof ArrayBuffer) {
|
|
63
|
+
text = Buffer.from(raw).toString("utf8");
|
|
64
|
+
}
|
|
65
|
+
else if (ArrayBuffer.isView(raw)) {
|
|
66
|
+
// @ts-ignore - handle typed arrays
|
|
67
|
+
text = Buffer.from(raw.buffer).toString("utf8");
|
|
68
|
+
}
|
|
69
|
+
else if (raw && typeof raw.toString === "function") {
|
|
70
|
+
text = String(raw);
|
|
71
|
+
}
|
|
72
|
+
text = text?.trim?.() ?? "";
|
|
73
|
+
if (!text)
|
|
74
|
+
return; // ignore empty frames
|
|
75
|
+
if (!(text.startsWith("{") || text.startsWith("["))) {
|
|
76
|
+
return; // ignore non-JSON frames
|
|
77
|
+
}
|
|
78
|
+
const data = JSON.parse(text);
|
|
79
|
+
if (data.type === "user_assigned" && data.socketId) {
|
|
80
|
+
setIsConnected(true);
|
|
81
|
+
setSocketId(data.socketId);
|
|
82
|
+
}
|
|
83
|
+
if (![
|
|
84
|
+
"ack",
|
|
85
|
+
"ask_user",
|
|
86
|
+
"response",
|
|
87
|
+
"error",
|
|
88
|
+
"tool_function_call",
|
|
89
|
+
"ask_user",
|
|
90
|
+
"progress",
|
|
91
|
+
].includes(data.type)) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (data.type === "tool_function_call") {
|
|
95
|
+
if (data.function_name === "get_context_lines") {
|
|
96
|
+
const argsData = {
|
|
97
|
+
fileName: data.args.fileName,
|
|
98
|
+
lineNumber: data.args.lineNumber,
|
|
99
|
+
before: data.args.before,
|
|
100
|
+
after: data.args.after,
|
|
101
|
+
};
|
|
102
|
+
const result = getContextLines(argsData.fileName, argsData.lineNumber, argsData.before, argsData.after);
|
|
103
|
+
try {
|
|
104
|
+
await toolFunctionCall(data?.tool_call_id, result, data?.args, "tool_function_call");
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
setChatResponseMessages((prev) => [
|
|
108
|
+
...prev,
|
|
109
|
+
error?.response?.message || "Error, please try again",
|
|
110
|
+
]);
|
|
111
|
+
}
|
|
112
|
+
// await redisClient.set(data.tool_call_id, result, { EX: 120 });
|
|
113
|
+
}
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
setChatResponseMessages((prev) => [...prev, data]);
|
|
117
|
+
setVisibleChats((prev) => [...prev, data]);
|
|
118
|
+
// add non-progress responses to trimmedChats
|
|
119
|
+
if (data.type !== "progress") {
|
|
120
|
+
setTrimmedChats((prevTrimmed) => {
|
|
121
|
+
const updated = [...prevTrimmed, data];
|
|
122
|
+
// update visible chats with all trimmed messages
|
|
123
|
+
setVisibleChats(updated);
|
|
124
|
+
return updated;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
if (data.type === "response" ||
|
|
128
|
+
data.type === "error" ||
|
|
129
|
+
data.type === "ask_user") {
|
|
130
|
+
setIsLoading(false);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
console.warn("WebSocket message handling warning:", error);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
socket.onerror = () => {
|
|
139
|
+
console.error(`Web Socket connection error, please retry`);
|
|
140
|
+
setConnectionError("WebSocket error, please retry");
|
|
141
|
+
setIsConnected(false);
|
|
142
|
+
setIsLoading(false);
|
|
143
|
+
process.exit();
|
|
144
|
+
};
|
|
145
|
+
socket.onclose = () => {
|
|
146
|
+
console.warn("Web Socket connection closed");
|
|
147
|
+
setIsConnected(false);
|
|
148
|
+
setIsLoading(false);
|
|
149
|
+
process.exit();
|
|
150
|
+
};
|
|
151
|
+
}, [url, authKey]);
|
|
152
|
+
const sendQuery = useCallback((query, logs, state) => {
|
|
153
|
+
const socket = socketRef.current;
|
|
154
|
+
if (socket && socket.readyState === WebSocket.OPEN) {
|
|
155
|
+
setIsLoading(true);
|
|
156
|
+
const payload = state
|
|
157
|
+
? { type: "query", socketId, logs, query, state }
|
|
158
|
+
: { type: "query", socketId, logs, query };
|
|
159
|
+
socket.send(JSON.stringify(payload));
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
setConnectionError("WebSocket not connected");
|
|
163
|
+
throw new Error("Cannot send the message: Web socket not connected");
|
|
164
|
+
}
|
|
165
|
+
}, [socketId]);
|
|
166
|
+
// const userReply = useCallback(
|
|
167
|
+
// (text: string, socketId?: string, state?: any) => {
|
|
168
|
+
// const socket = socketRef.current;
|
|
169
|
+
// if (socket && socket.readyState === WebSocket.OPEN) {
|
|
170
|
+
// setIsLoading(true);
|
|
171
|
+
// const payload = { type: "user_reply", socketId, text, state };
|
|
172
|
+
// socket.send(JSON.stringify(payload));
|
|
173
|
+
// } else {
|
|
174
|
+
// setConnectionError("WebSocket not connected");
|
|
175
|
+
// throw new Error("Cannot send the message: Web socket not connected");
|
|
176
|
+
// }
|
|
177
|
+
// },
|
|
178
|
+
// [socketId]
|
|
179
|
+
// );
|
|
180
|
+
// Clean up on unmount
|
|
181
|
+
useEffect(() => {
|
|
182
|
+
return () => {
|
|
183
|
+
if (socketRef.current) {
|
|
184
|
+
socketRef.current.close();
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
}, []);
|
|
188
|
+
return {
|
|
189
|
+
connectWebSocket,
|
|
190
|
+
socketId,
|
|
191
|
+
sendQuery,
|
|
192
|
+
chatResponseMessages: visibleChats,
|
|
193
|
+
setChatResponseMessages: setVisibleChats,
|
|
194
|
+
setTrimmedChats,
|
|
195
|
+
isConnected,
|
|
196
|
+
connectionError,
|
|
197
|
+
// userReply,
|
|
198
|
+
isLoading,
|
|
199
|
+
API_KEY
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=useWebSocket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWebSocket.js","sourceRoot":"","sources":["../useWebSocket.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,2CAA2C;AAC3C,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;AAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AAClD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;AACpD,IAAI,OAAO,GAAG,EAAE,CAAC;AACjB,IAAI,CAAC;IACH,MAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACxD,IAAI,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACtB,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5B,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAAC,OAAO,GAAG,EAAE,CAAC;IACb,OAAO,CAAC,GAAG,CAAC,+BAA+B,EAAE,GAAG,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM;IACN,MAAM,SAAS,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAC;IACjD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAC9D,MAAM,CAAC,oBAAoB,EAAE,uBAAuB,CAAC,GAAG,QAAQ,CAAQ,EAAE,CAAC,CAAC;IAC5E,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAQ,EAAE,CAAC,CAAC;IAC5D,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAQ,EAAE,CAAC,CAAC;IAC5D,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAC5E,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAElD,MAAM,OAAO,GAAG,OAAO,CAAC;IACxB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;YACnB,kBAAkB,CAAC,sCAAsC,CAAC,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;YACpD,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,uBAAuB;IACvB,MAAM,gBAAgB,GAAG,WAAW,CAAC,GAAG,EAAE;QACxC,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;YACtB,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC5B,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;QAClC,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC;QAC3B,kBAAkB,CAAC,IAAI,CAAC,CAAC;QACzB,cAAc,CAAC,KAAK,CAAC,CAAC;QACtB,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE;YACnB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;QACzE,CAAC,CAAC;QAEF,MAAM,CAAC,SAAS,GAAG,KAAK,EAAE,KAAK,EAAE,EAAE;YACjC,IAAI,CAAC;gBACH,MAAM,GAAG,GAAI,KAAa,CAAC,IAAI,CAAC;gBAChC,IAAI,IAAI,GAAG,EAAE,CAAC;gBACd,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;oBAC5B,IAAI,GAAG,GAAG,CAAC;gBACb,CAAC;qBAAM,IAAI,GAAG,YAAY,WAAW,EAAE,CAAC;oBACtC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAC3C,CAAC;qBAAM,IAAI,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;oBACnC,mCAAmC;oBACnC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAClD,CAAC;qBAAM,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACrD,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;gBACrB,CAAC;gBAED,IAAI,GAAG,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC;gBAC5B,IAAI,CAAC,IAAI;oBAAE,OAAO,CAAC,sBAAsB;gBAEzC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;oBACpD,OAAO,CAAC,yBAAyB;gBACnC,CAAC;gBAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAE9B,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACnD,cAAc,CAAC,IAAI,CAAC,CAAC;oBACrB,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC7B,CAAC;gBACD,IACE,CAAC;oBACC,KAAK;oBACL,UAAU;oBACV,UAAU;oBACV,OAAO;oBACP,oBAAoB;oBACpB,UAAU;oBACV,UAAU;iBACX,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EACrB,CAAC;oBACD,OAAO;gBACT,CAAC;gBAED,IAAI,IAAI,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;oBACvC,IAAI,IAAI,CAAC,aAAa,KAAK,mBAAmB,EAAE,CAAC;wBAC/C,MAAM,QAAQ,GAAG;4BACf,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ;4BAC5B,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU;4BAChC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;4BACxB,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK;yBACvB,CAAC;wBACF,MAAM,MAAM,GAAG,eAAe,CAC5B,QAAQ,CAAC,QAAQ,EACjB,QAAQ,CAAC,UAAU,EACnB,QAAQ,CAAC,MAAM,EACf,QAAQ,CAAC,KAAK,CACf,CAAC;wBACF,IAAI,CAAC;4BACH,MAAM,gBAAgB,CACpB,IAAI,EAAE,YAAY,EAClB,MAAM,EACN,IAAI,EAAE,IAAI,EACV,oBAAoB,CACrB,CAAC;wBACJ,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,uBAAuB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;gCAChC,GAAG,IAAI;gCACP,KAAK,EAAE,QAAQ,EAAE,OAAO,IAAI,yBAAyB;6BACtD,CAAC,CAAC;wBACL,CAAC;wBACD,iEAAiE;oBACnE,CAAC;oBACD,OAAO;gBACT,CAAC;gBACD,uBAAuB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;gBACnD,eAAe,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;gBAC3C,6CAA6C;gBAC7C,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;oBAC7B,eAAe,CAAC,CAAC,WAAW,EAAE,EAAE;wBAC9B,MAAM,OAAO,GAAG,CAAC,GAAG,WAAW,EAAE,IAAI,CAAC,CAAC;wBACvC,iDAAiD;wBACjD,eAAe,CAAC,OAAO,CAAC,CAAC;wBACzB,OAAO,OAAO,CAAC;oBACjB,CAAC,CAAC,CAAC;gBACL,CAAC;gBACD,IACE,IAAI,CAAC,IAAI,KAAK,UAAU;oBACxB,IAAI,CAAC,IAAI,KAAK,OAAO;oBACrB,IAAI,CAAC,IAAI,KAAK,UAAU,EACxB,CAAC;oBACD,YAAY,CAAC,KAAK,CAAC,CAAC;gBACtB,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC;gBAC3D,OAAO;YACT,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE;YACpB,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;YAC3D,kBAAkB,CAAC,+BAA+B,CAAC,CAAC;YACpD,cAAc,CAAC,KAAK,CAAC,CAAC;YACtB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,CAAC,CAAC;QAEF,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE;YACpB,OAAO,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;YAC7C,cAAc,CAAC,KAAK,CAAC,CAAC;YACtB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IAEnB,MAAM,SAAS,GAAG,WAAW,CAC3B,CAAC,KAAa,EAAE,IAAS,EAAE,KAAW,EAAE,EAAE;QACxC,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC;QACjC,IAAI,MAAM,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;YACnD,YAAY,CAAC,IAAI,CAAC,CAAC;YACnB,MAAM,OAAO,GAAG,KAAK;gBACnB,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE;gBACjD,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;YAC7C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,kBAAkB,CAAC,yBAAyB,CAAC,CAAC;YAC9C,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,CAAC;IACH,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAC;IAEF,iCAAiC;IACjC,wDAAwD;IACxD,wCAAwC;IACxC,4DAA4D;IAC5D,4BAA4B;IAC5B,uEAAuE;IACvE,8CAA8C;IAC9C,eAAe;IACf,uDAAuD;IACvD,8EAA8E;IAC9E,QAAQ;IACR,OAAO;IACP,eAAe;IACf,KAAK;IAEL,sBAAsB;IACtB,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,GAAG,EAAE;YACV,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;gBACtB,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAC5B,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO;QACL,gBAAgB;QAChB,QAAQ;QACR,SAAS;QACT,oBAAoB,EAAE,YAAY;QAClC,uBAAuB,EAAE,eAAe;QACxC,eAAe;QACf,WAAW;QACX,eAAe;QACf,aAAa;QACb,SAAS;QACT,OAAO;KACR,CAAC;AACJ,CAAC"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getContextLines(fileName: string, lineNumber: number, before?: number, after?: number): string;
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
//parameter to redis
|
|
3
|
+
export function getContextLines(fileName, lineNumber, before = 3, after = 3) {
|
|
4
|
+
const lines = fs.readFileSync(fileName, "utf-8").split("\n");
|
|
5
|
+
const start = Math.max(0, lineNumber - before - 1);
|
|
6
|
+
const end = Math.min(lines.length, lineNumber + after);
|
|
7
|
+
return lines.slice(start, end).join("\n");
|
|
8
|
+
}
|
|
9
|
+
//redis connection
|
|
10
|
+
// const redisClient = createClient({
|
|
11
|
+
// url: `rediss://${config.redis_username}:${config.redis_password}@${config.redis_host}:${config.redis_port}`,
|
|
12
|
+
// socket: { tls: true },
|
|
13
|
+
// });
|
|
14
|
+
// redisClient.on("error", (err) => {
|
|
15
|
+
// console.error("Redis Client Error", err);
|
|
16
|
+
// });
|
|
17
|
+
// redisClient.on("connect", () => {
|
|
18
|
+
// console.log("Redis Client Connected");
|
|
19
|
+
// });
|
|
20
|
+
// redisClient.connect();
|
|
21
|
+
// export default redisClient;
|
|
22
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAIzB,oBAAoB;AACpB,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,UAAkB,EAClB,SAAiB,CAAC,EAClB,QAAgB,CAAC;IAEjB,MAAM,KAAK,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;IACnD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,KAAK,CAAC,CAAC;IACvD,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED,kBAAkB;AAClB,qCAAqC;AACrC,iHAAiH;AACjH,2BAA2B;AAC3B,MAAM;AAEN,qCAAqC;AACrC,8CAA8C;AAC9C,MAAM;AAEN,oCAAoC;AACpC,2CAA2C;AAC3C,MAAM;AAEN,yBAAyB;AAEzB,8BAA8B"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "clippy-test",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"bin": {
|
|
6
|
+
"clippy": "bin/clippy.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin/",
|
|
10
|
+
"dist/",
|
|
11
|
+
"README.md",
|
|
12
|
+
"LICENSE"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"start": "tsx index.tsx",
|
|
16
|
+
"dev": "tsx index.tsx",
|
|
17
|
+
"code-hierarchy": "tsx code_hierarchy.ts",
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"prepublishOnly": "npm run build"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@langchain/anthropic": "^0.3.24",
|
|
23
|
+
"@langchain/community": "^0.3.43",
|
|
24
|
+
"@langchain/core": "^0.3.56",
|
|
25
|
+
"@langchain/google-genai": "^0.2.9",
|
|
26
|
+
"@langchain/langgraph": "^0.2.72",
|
|
27
|
+
"@langchain/langgraph-checkpoint": "^0.0.17",
|
|
28
|
+
"@langchain/openai": "^0.5.10",
|
|
29
|
+
"@langchain/tavily": "^0.1.1",
|
|
30
|
+
"@langchain/textsplitters": "^0.1.0",
|
|
31
|
+
"@xterm/xterm": "^5.5.0",
|
|
32
|
+
"axios": "^1.12.2",
|
|
33
|
+
"blessed": "^0.1.81",
|
|
34
|
+
"chalk": "^5.6.2",
|
|
35
|
+
"convo-sdk": "^1.0.46",
|
|
36
|
+
"dedent": "^1.7.0",
|
|
37
|
+
"ignore": "^5.3.2",
|
|
38
|
+
"ink": "^6.3.1",
|
|
39
|
+
"ink-spinner": "^5.0.0",
|
|
40
|
+
"ink-text-input": "^6.0.0",
|
|
41
|
+
"marked": "^15.0.0",
|
|
42
|
+
"marked-terminal": "^7.3.0",
|
|
43
|
+
"node-pty": "^1.0.0",
|
|
44
|
+
"react": "^19.2.0",
|
|
45
|
+
"redis": "^5.8.3",
|
|
46
|
+
"term.js": "^0.0.7",
|
|
47
|
+
"tslab": "^1.0.22",
|
|
48
|
+
"tsx": "^4.19.2",
|
|
49
|
+
"zod": "^3.25.13"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/node": "^24.9.1",
|
|
53
|
+
"@types/react": "^19.1.13",
|
|
54
|
+
"typescript": "^5.9.3"
|
|
55
|
+
}
|
|
56
|
+
}
|