@oratis/lisa 0.8.0 → 0.9.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/dist/mcp/config.d.ts +4 -0
- package/dist/mcp/config.d.ts.map +1 -1
- package/dist/mcp/config.js +34 -0
- package/dist/mcp/config.js.map +1 -1
- package/dist/tools/github.d.ts +34 -0
- package/dist/tools/github.d.ts.map +1 -0
- package/dist/tools/github.js +140 -0
- package/dist/tools/github.js.map +1 -0
- package/dist/tools/github_link.d.ts +36 -0
- package/dist/tools/github_link.d.ts.map +1 -0
- package/dist/tools/github_link.js +127 -0
- package/dist/tools/github_link.js.map +1 -0
- package/dist/tools/mcp.d.ts +28 -0
- package/dist/tools/mcp.d.ts.map +1 -0
- package/dist/tools/mcp.js +55 -0
- package/dist/tools/mcp.js.map +1 -0
- package/dist/tools/npm_info.d.ts +21 -0
- package/dist/tools/npm_info.d.ts.map +1 -0
- package/dist/tools/npm_info.js +102 -0
- package/dist/tools/npm_info.js.map +1 -0
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +8 -0
- package/dist/tools/registry.js.map +1 -1
- package/dist/voice/dictation.d.ts +51 -0
- package/dist/voice/dictation.d.ts.map +1 -0
- package/dist/voice/dictation.js +70 -0
- package/dist/voice/dictation.js.map +1 -0
- package/dist/web/island.d.ts +1 -1
- package/dist/web/island.d.ts.map +1 -1
- package/dist/web/island.js +17 -4
- package/dist/web/island.js.map +1 -1
- package/dist/web/lisa-html.d.ts +1 -1
- package/dist/web/lisa-html.d.ts.map +1 -1
- package/dist/web/lisa-html.js +57 -11
- package/dist/web/lisa-html.js.map +1 -1
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +20 -1
- package/dist/web/server.js.map +1 -1
- package/package.json +1 -1
package/dist/mcp/config.d.ts
CHANGED
|
@@ -11,4 +11,8 @@ export interface McpConfig {
|
|
|
11
11
|
}
|
|
12
12
|
export declare function loadMcpConfig(): Promise<McpServerSpec[]>;
|
|
13
13
|
export declare const MCP_CONFIG_PATH: string;
|
|
14
|
+
/** Add or replace a server in mcp.json (upsert by name). Returns the spec. */
|
|
15
|
+
export declare function saveMcpServer(name: string, spec: Omit<McpServerSpec, "name">): Promise<void>;
|
|
16
|
+
/** Remove a server from mcp.json. Returns false if it wasn't there. */
|
|
17
|
+
export declare function deleteMcpServer(name: string): Promise<boolean>;
|
|
14
18
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/mcp/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/mcp/config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;CACzD;AAID,wBAAsB,aAAa,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAkB9D;AAED,eAAO,MAAM,eAAe,QAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/mcp/config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;CACzD;AAID,wBAAsB,aAAa,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAkB9D;AAED,eAAO,MAAM,eAAe,QAAc,CAAC;AAE3C,8EAA8E;AAC9E,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,uEAAuE;AACvE,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAYpE"}
|
package/dist/mcp/config.js
CHANGED
|
@@ -25,4 +25,38 @@ export async function loadMcpConfig() {
|
|
|
25
25
|
}));
|
|
26
26
|
}
|
|
27
27
|
export const MCP_CONFIG_PATH = CONFIG_PATH;
|
|
28
|
+
/** Add or replace a server in mcp.json (upsert by name). Returns the spec. */
|
|
29
|
+
export async function saveMcpServer(name, spec) {
|
|
30
|
+
let config = { mcpServers: {} };
|
|
31
|
+
if (await pathExists(CONFIG_PATH)) {
|
|
32
|
+
try {
|
|
33
|
+
config = JSON.parse(await fs.readFile(CONFIG_PATH, "utf8"));
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// start fresh on a corrupt file rather than lose the add
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (!config.mcpServers)
|
|
40
|
+
config.mcpServers = {};
|
|
41
|
+
config.mcpServers[name] = spec;
|
|
42
|
+
await fs.mkdir(path.dirname(CONFIG_PATH), { recursive: true });
|
|
43
|
+
await fs.writeFile(CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
44
|
+
}
|
|
45
|
+
/** Remove a server from mcp.json. Returns false if it wasn't there. */
|
|
46
|
+
export async function deleteMcpServer(name) {
|
|
47
|
+
if (!(await pathExists(CONFIG_PATH)))
|
|
48
|
+
return false;
|
|
49
|
+
let config;
|
|
50
|
+
try {
|
|
51
|
+
config = JSON.parse(await fs.readFile(CONFIG_PATH, "utf8"));
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
if (!config.mcpServers || !(name in config.mcpServers))
|
|
57
|
+
return false;
|
|
58
|
+
delete config.mcpServers[name];
|
|
59
|
+
await fs.writeFile(CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
28
62
|
//# sourceMappingURL=config.js.map
|
package/dist/mcp/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/mcp/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAe5C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAChD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACnD,IAAI,MAAiB,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC;IACxC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,mBAAmB,WAAW,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;IACxC,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACpD,IAAI;QACJ,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;QACrB,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI;QAC7B,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,KAAK;KACrC,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/mcp/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* github (integration) — a gh-CLI-backed tool covering the GitHub operations a
|
|
3
|
+
* coding agent / orchestrator actually needs beyond pr_status (list+CI) and
|
|
4
|
+
* github_link (URLs): issues (list/view/create/comment), PRs (view/create/
|
|
5
|
+
* comment/merge), CI runs (list/view), releases. One tool, action-dispatched.
|
|
6
|
+
*
|
|
7
|
+
* Read actions are safe; create/comment/merge are write actions (gated by the
|
|
8
|
+
* host approval layer like any mutating tool). Needs `gh` authenticated.
|
|
9
|
+
*/
|
|
10
|
+
import type { ToolDefinition } from "../types.js";
|
|
11
|
+
type GithubAction = "issue_list" | "issue_view" | "issue_create" | "issue_comment" | "pr_view" | "pr_create" | "pr_comment" | "pr_merge" | "run_list" | "run_view" | "release_list";
|
|
12
|
+
interface GithubInput {
|
|
13
|
+
action: GithubAction;
|
|
14
|
+
cwd?: string;
|
|
15
|
+
/** Issue / PR / run number (issue_view, pr_view, *_comment, pr_merge, run_view). */
|
|
16
|
+
number?: number;
|
|
17
|
+
title?: string;
|
|
18
|
+
body?: string;
|
|
19
|
+
/** pr_create base branch. */
|
|
20
|
+
base?: string;
|
|
21
|
+
/** issue_list / pr filter state. */
|
|
22
|
+
state?: "open" | "closed" | "all";
|
|
23
|
+
/** pr_merge method. Default squash. */
|
|
24
|
+
merge_method?: "squash" | "merge" | "rebase";
|
|
25
|
+
}
|
|
26
|
+
/** Build the gh argv for an action (without the leading "gh"). Pure + tested. */
|
|
27
|
+
export declare function buildGhArgs(input: GithubInput): {
|
|
28
|
+
args: string[];
|
|
29
|
+
} | {
|
|
30
|
+
error: string;
|
|
31
|
+
};
|
|
32
|
+
export declare const githubTool: ToolDefinition<GithubInput, string>;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=github.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/tools/github.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,KAAK,YAAY,GACb,YAAY,GAAG,YAAY,GAAG,cAAc,GAAG,eAAe,GAC9D,SAAS,GAAG,WAAW,GAAG,YAAY,GAAG,UAAU,GACnD,UAAU,GAAG,UAAU,GAAG,cAAc,CAAC;AAE7C,UAAU,WAAW;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IAClC,uCAAuC;IACvC,YAAY,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;CAC9C;AAED,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CA8CtF;AAsBD,eAAO,MAAM,UAAU,EAAE,cAAc,CAAC,WAAW,EAAE,MAAM,CA8C1D,CAAC"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { runIn, isDir, gitRoot } from "./exec-util.js";
|
|
2
|
+
/** Build the gh argv for an action (without the leading "gh"). Pure + tested. */
|
|
3
|
+
export function buildGhArgs(input) {
|
|
4
|
+
const need = (v, name) => v == null || v === "" ? `${input.action} needs ${name}` : null;
|
|
5
|
+
switch (input.action) {
|
|
6
|
+
case "issue_list":
|
|
7
|
+
return { args: ["issue", "list", "--state", input.state ?? "open", "--limit", "30", "--json", "number,title,state,author,labels"] };
|
|
8
|
+
case "issue_view": {
|
|
9
|
+
const e = need(input.number, "a number");
|
|
10
|
+
if (e)
|
|
11
|
+
return { error: e };
|
|
12
|
+
return { args: ["issue", "view", String(input.number), "--comments"] };
|
|
13
|
+
}
|
|
14
|
+
case "issue_create": {
|
|
15
|
+
const e = need(input.title, "a title");
|
|
16
|
+
if (e)
|
|
17
|
+
return { error: e };
|
|
18
|
+
return { args: ["issue", "create", "--title", input.title, "--body", input.body ?? ""] };
|
|
19
|
+
}
|
|
20
|
+
case "issue_comment": {
|
|
21
|
+
const e = need(input.number, "a number") || need(input.body, "a body");
|
|
22
|
+
if (e)
|
|
23
|
+
return { error: e };
|
|
24
|
+
return { args: ["issue", "comment", String(input.number), "--body", input.body] };
|
|
25
|
+
}
|
|
26
|
+
case "pr_view": {
|
|
27
|
+
const e = need(input.number, "a number");
|
|
28
|
+
if (e)
|
|
29
|
+
return { error: e };
|
|
30
|
+
return { args: ["pr", "view", String(input.number), "--comments"] };
|
|
31
|
+
}
|
|
32
|
+
case "pr_create": {
|
|
33
|
+
const e = need(input.title, "a title");
|
|
34
|
+
if (e)
|
|
35
|
+
return { error: e };
|
|
36
|
+
const args = ["pr", "create", "--title", input.title, "--body", input.body ?? ""];
|
|
37
|
+
if (input.base)
|
|
38
|
+
args.push("--base", input.base);
|
|
39
|
+
return { args };
|
|
40
|
+
}
|
|
41
|
+
case "pr_comment": {
|
|
42
|
+
const e = need(input.number, "a number") || need(input.body, "a body");
|
|
43
|
+
if (e)
|
|
44
|
+
return { error: e };
|
|
45
|
+
return { args: ["pr", "comment", String(input.number), "--body", input.body] };
|
|
46
|
+
}
|
|
47
|
+
case "pr_merge": {
|
|
48
|
+
const e = need(input.number, "a number");
|
|
49
|
+
if (e)
|
|
50
|
+
return { error: e };
|
|
51
|
+
return { args: ["pr", "merge", String(input.number), `--${input.merge_method ?? "squash"}`, "--delete-branch"] };
|
|
52
|
+
}
|
|
53
|
+
case "run_list":
|
|
54
|
+
return { args: ["run", "list", "--limit", "15", "--json", "databaseId,name,status,conclusion,headBranch,event"] };
|
|
55
|
+
case "run_view": {
|
|
56
|
+
const e = need(input.number, "a run id (number)");
|
|
57
|
+
if (e)
|
|
58
|
+
return { error: e };
|
|
59
|
+
return { args: ["run", "view", String(input.number)] };
|
|
60
|
+
}
|
|
61
|
+
case "release_list":
|
|
62
|
+
return { args: ["release", "list", "--limit", "10"] };
|
|
63
|
+
default:
|
|
64
|
+
return { error: `unknown action: ${input.action}` };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** Compact a gh --json issue/PR/run array into readable lines. */
|
|
68
|
+
function formatJsonList(action, raw) {
|
|
69
|
+
let arr;
|
|
70
|
+
try {
|
|
71
|
+
arr = JSON.parse(raw);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return raw.trim();
|
|
75
|
+
}
|
|
76
|
+
if (!Array.isArray(arr) || arr.length === 0)
|
|
77
|
+
return "(none)";
|
|
78
|
+
if (action === "issue_list") {
|
|
79
|
+
return arr.map((i) => {
|
|
80
|
+
const labels = (i.labels ?? []).map((l) => l.name).join(", ");
|
|
81
|
+
return `#${i.number} [${i.state}] ${i.title}${labels ? ` (${labels})` : ""} — @${i.author?.login ?? "?"}`;
|
|
82
|
+
}).join("\n");
|
|
83
|
+
}
|
|
84
|
+
if (action === "run_list") {
|
|
85
|
+
return arr.map((r) => {
|
|
86
|
+
const s = r.conclusion || r.status || "?";
|
|
87
|
+
return `${r.databaseId} ${s} · ${r.name} · ${r.headBranch} (${r.event})`;
|
|
88
|
+
}).join("\n");
|
|
89
|
+
}
|
|
90
|
+
return raw.trim();
|
|
91
|
+
}
|
|
92
|
+
export const githubTool = {
|
|
93
|
+
name: "github",
|
|
94
|
+
description: "GitHub operations via gh: issues (issue_list / issue_view / issue_create / issue_comment), " +
|
|
95
|
+
"PRs (pr_view / pr_create / pr_comment / pr_merge), CI (run_list / run_view), releases " +
|
|
96
|
+
"(release_list). For listing open PRs with CI use pr_status; for URLs use github_link. " +
|
|
97
|
+
"create/comment/merge are write actions. Needs `gh` authenticated.",
|
|
98
|
+
inputSchema: {
|
|
99
|
+
type: "object",
|
|
100
|
+
properties: {
|
|
101
|
+
action: {
|
|
102
|
+
type: "string",
|
|
103
|
+
enum: ["issue_list", "issue_view", "issue_create", "issue_comment", "pr_view", "pr_create", "pr_comment", "pr_merge", "run_list", "run_view", "release_list"],
|
|
104
|
+
},
|
|
105
|
+
cwd: { type: "string", description: "Absolute path inside the repo. Defaults to the current directory." },
|
|
106
|
+
number: { type: "integer", description: "Issue / PR number, or run id (per action)." },
|
|
107
|
+
title: { type: "string", description: "For issue_create / pr_create." },
|
|
108
|
+
body: { type: "string", description: "Body for create/comment actions." },
|
|
109
|
+
base: { type: "string", description: "Base branch for pr_create." },
|
|
110
|
+
state: { type: "string", enum: ["open", "closed", "all"], description: "Filter for issue_list (default open)." },
|
|
111
|
+
merge_method: { type: "string", enum: ["squash", "merge", "rebase"], description: "For pr_merge (default squash)." },
|
|
112
|
+
},
|
|
113
|
+
required: ["action"],
|
|
114
|
+
additionalProperties: false,
|
|
115
|
+
},
|
|
116
|
+
async execute(input, ctx) {
|
|
117
|
+
const cwd = input.cwd && input.cwd.startsWith("/") ? input.cwd : ctx.cwd;
|
|
118
|
+
if (!(await isDir(cwd)))
|
|
119
|
+
return `(not a directory: ${cwd})`;
|
|
120
|
+
const root = (await gitRoot(cwd, ctx.signal)) ?? cwd;
|
|
121
|
+
const built = buildGhArgs(input);
|
|
122
|
+
if ("error" in built)
|
|
123
|
+
return `(${built.error})`;
|
|
124
|
+
const r = await runIn(root, "gh", built.args, { timeoutMs: 30000, signal: ctx.signal, maxBytes: 200_000 });
|
|
125
|
+
if (r.spawnError)
|
|
126
|
+
return "(the `gh` CLI isn't installed — needed for GitHub operations. https://cli.github.com)";
|
|
127
|
+
if (r.code !== 0) {
|
|
128
|
+
const e = r.stderr.trim();
|
|
129
|
+
if (/auth|login/i.test(e))
|
|
130
|
+
return "(`gh` isn't authenticated — run `gh auth login`)";
|
|
131
|
+
return `(gh ${input.action} failed: ${e.slice(0, 250) || "unknown error"})`;
|
|
132
|
+
}
|
|
133
|
+
const out = r.stdout.trim();
|
|
134
|
+
if (input.action === "issue_list" || input.action === "run_list") {
|
|
135
|
+
return formatJsonList(input.action, r.stdout) || "(none)";
|
|
136
|
+
}
|
|
137
|
+
return out || "(done)";
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/tools/github.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ToolDefinition } from "../types.js";
|
|
2
|
+
interface GithubLinkInput {
|
|
3
|
+
/** What to link: repo (default), branch, commit, file, pr, issue. */
|
|
4
|
+
target?: "repo" | "branch" | "commit" | "file" | "pr" | "issue";
|
|
5
|
+
cwd?: string;
|
|
6
|
+
/** Branch name or commit sha; defaults to the current branch/HEAD. */
|
|
7
|
+
ref?: string;
|
|
8
|
+
/** For target:file — path (absolute or repo-relative). */
|
|
9
|
+
path?: string;
|
|
10
|
+
start_line?: number;
|
|
11
|
+
end_line?: number;
|
|
12
|
+
/** For target:pr/issue — the number. */
|
|
13
|
+
number?: number;
|
|
14
|
+
/** Also open the URL in the default browser. */
|
|
15
|
+
open?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface Remote {
|
|
18
|
+
host: string;
|
|
19
|
+
owner: string;
|
|
20
|
+
repo: string;
|
|
21
|
+
}
|
|
22
|
+
/** Parse a git remote URL (scp or https/ssh) into host/owner/repo. Pure. */
|
|
23
|
+
export declare function parseRemote(url: string): Remote | null;
|
|
24
|
+
/** Build a GitHub URL for the given target. Pure + tested. */
|
|
25
|
+
export declare function buildUrl(r: Remote, target: NonNullable<GithubLinkInput["target"]>, opts?: {
|
|
26
|
+
ref?: string;
|
|
27
|
+
path?: string;
|
|
28
|
+
startLine?: number;
|
|
29
|
+
endLine?: number;
|
|
30
|
+
number?: number;
|
|
31
|
+
}): string | {
|
|
32
|
+
error: string;
|
|
33
|
+
};
|
|
34
|
+
export declare const githubLinkTool: ToolDefinition<GithubLinkInput, string>;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=github_link.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github_link.d.ts","sourceRoot":"","sources":["../../src/tools/github_link.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,UAAU,eAAe;IACvB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC;IAChE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAatD;AAED,8DAA8D;AAC9D,wBAAgB,QAAQ,CACtB,CAAC,EAAE,MAAM,EACT,MAAM,EAAE,WAAW,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,EAC9C,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAChG,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CA2B5B;AAED,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,eAAe,EAAE,MAAM,CAgElE,CAAC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* github_link (vibe-coding) — turn the local git context into a shareable
|
|
3
|
+
* GitHub URL: the repo, a branch, a commit, a file (optionally with a line
|
|
4
|
+
* range), or a PR / issue. So when LISA references "src/web/server.ts:120" or
|
|
5
|
+
* "PR #58" she can hand you a clickable link instead of a path.
|
|
6
|
+
*
|
|
7
|
+
* URL building is pure git (parses `origin`), so it needs no gh. `open:true`
|
|
8
|
+
* best-effort opens it in your browser.
|
|
9
|
+
*/
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import { runIn, isDir, gitRoot } from "./exec-util.js";
|
|
12
|
+
/** Parse a git remote URL (scp or https/ssh) into host/owner/repo. Pure. */
|
|
13
|
+
export function parseRemote(url) {
|
|
14
|
+
let s = url.trim().replace(/\.git$/i, "").replace(/\/$/, "");
|
|
15
|
+
// scp-like: git@github.com:owner/repo (also ssh://git@github.com/owner/repo)
|
|
16
|
+
let m = s.match(/^(?:ssh:\/\/)?[^@\s]*@([^:/]+)[:/](.+)$/i);
|
|
17
|
+
if (!m) {
|
|
18
|
+
// url: https://github.com/owner/repo
|
|
19
|
+
m = s.match(/^https?:\/\/(?:[^@/]+@)?([^/]+)\/(.+)$/i);
|
|
20
|
+
}
|
|
21
|
+
if (!m)
|
|
22
|
+
return null;
|
|
23
|
+
const host = m[1];
|
|
24
|
+
const parts = m[2].split("/").filter(Boolean);
|
|
25
|
+
if (parts.length < 2)
|
|
26
|
+
return null;
|
|
27
|
+
return { host, owner: parts[0], repo: parts[1] };
|
|
28
|
+
}
|
|
29
|
+
/** Build a GitHub URL for the given target. Pure + tested. */
|
|
30
|
+
export function buildUrl(r, target, opts = {}) {
|
|
31
|
+
const base = `https://${r.host}/${r.owner}/${r.repo}`;
|
|
32
|
+
switch (target) {
|
|
33
|
+
case "repo":
|
|
34
|
+
return base;
|
|
35
|
+
case "branch":
|
|
36
|
+
return opts.ref ? `${base}/tree/${encodeURIComponent(opts.ref)}` : base;
|
|
37
|
+
case "commit":
|
|
38
|
+
return opts.ref ? `${base}/commit/${opts.ref}` : { error: "commit needs a ref/sha" };
|
|
39
|
+
case "file": {
|
|
40
|
+
if (!opts.path)
|
|
41
|
+
return { error: "file needs a path" };
|
|
42
|
+
const ref = opts.ref || "HEAD";
|
|
43
|
+
const cleanPath = opts.path.split("/").map(encodeURIComponent).join("/").replace(/^\//, "");
|
|
44
|
+
let url = `${base}/blob/${encodeURIComponent(ref)}/${cleanPath}`;
|
|
45
|
+
if (opts.startLine) {
|
|
46
|
+
url += `#L${opts.startLine}`;
|
|
47
|
+
if (opts.endLine && opts.endLine !== opts.startLine)
|
|
48
|
+
url += `-L${opts.endLine}`;
|
|
49
|
+
}
|
|
50
|
+
return url;
|
|
51
|
+
}
|
|
52
|
+
case "pr":
|
|
53
|
+
return opts.number ? `${base}/pull/${opts.number}` : { error: "pr needs a number" };
|
|
54
|
+
case "issue":
|
|
55
|
+
return opts.number ? `${base}/issues/${opts.number}` : { error: "issue needs a number" };
|
|
56
|
+
default:
|
|
57
|
+
return { error: `unknown target: ${target}` };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export const githubLinkTool = {
|
|
61
|
+
name: "github_link",
|
|
62
|
+
description: "Build a shareable GitHub URL from the local git repo: target 'repo' (default), 'branch', " +
|
|
63
|
+
"'commit', 'file' (path + optional start_line/end_line), 'pr' or 'issue' (number). Defaults the " +
|
|
64
|
+
"ref to the current branch / HEAD. Use to give the user a clickable link to a file/line, commit, " +
|
|
65
|
+
"branch, or PR you're referencing. open:true also opens it in the browser. Needs a GitHub `origin` " +
|
|
66
|
+
"remote; no gh required.",
|
|
67
|
+
inputSchema: {
|
|
68
|
+
type: "object",
|
|
69
|
+
properties: {
|
|
70
|
+
target: { type: "string", enum: ["repo", "branch", "commit", "file", "pr", "issue"] },
|
|
71
|
+
cwd: { type: "string", description: "Absolute path inside the repo. Defaults to the current directory." },
|
|
72
|
+
ref: { type: "string", description: "Branch name or commit sha. Defaults to the current branch (for file/branch) or HEAD." },
|
|
73
|
+
path: { type: "string", description: "For target:file — absolute or repo-relative file path." },
|
|
74
|
+
start_line: { type: "integer", minimum: 1 },
|
|
75
|
+
end_line: { type: "integer", minimum: 1 },
|
|
76
|
+
number: { type: "integer", minimum: 1, description: "For target:pr or issue." },
|
|
77
|
+
open: { type: "boolean", description: "Also open the URL in the default browser." },
|
|
78
|
+
},
|
|
79
|
+
additionalProperties: false,
|
|
80
|
+
},
|
|
81
|
+
async execute(input, ctx) {
|
|
82
|
+
const cwd = input.cwd && input.cwd.startsWith("/") ? input.cwd : ctx.cwd;
|
|
83
|
+
if (!(await isDir(cwd)))
|
|
84
|
+
return `(not a directory: ${cwd})`;
|
|
85
|
+
const root = await gitRoot(cwd, ctx.signal);
|
|
86
|
+
if (!root)
|
|
87
|
+
return `(not a git repo: ${cwd})`;
|
|
88
|
+
const remoteR = await runIn(root, "git", ["-C", root, "remote", "get-url", "origin"], { timeoutMs: 5000, signal: ctx.signal });
|
|
89
|
+
if (remoteR.code !== 0)
|
|
90
|
+
return "(no `origin` remote on this repo)";
|
|
91
|
+
const remote = parseRemote(remoteR.stdout);
|
|
92
|
+
if (!remote)
|
|
93
|
+
return `(couldn't parse a GitHub URL from origin: ${remoteR.stdout.trim().slice(0, 120)})`;
|
|
94
|
+
const target = input.target ?? "repo";
|
|
95
|
+
// Resolve a default ref for branch/file when none given.
|
|
96
|
+
let ref = input.ref;
|
|
97
|
+
if (!ref && (target === "branch" || target === "file")) {
|
|
98
|
+
const b = await runIn(root, "git", ["-C", root, "rev-parse", "--abbrev-ref", "HEAD"], { timeoutMs: 5000, signal: ctx.signal });
|
|
99
|
+
if (b.code === 0)
|
|
100
|
+
ref = b.stdout.trim();
|
|
101
|
+
}
|
|
102
|
+
if (!ref && target === "commit") {
|
|
103
|
+
const h = await runIn(root, "git", ["-C", root, "rev-parse", "HEAD"], { timeoutMs: 5000, signal: ctx.signal });
|
|
104
|
+
if (h.code === 0)
|
|
105
|
+
ref = h.stdout.trim();
|
|
106
|
+
}
|
|
107
|
+
// For file: make the path repo-relative.
|
|
108
|
+
let filePath = input.path;
|
|
109
|
+
if (target === "file" && filePath) {
|
|
110
|
+
if (filePath.startsWith("/"))
|
|
111
|
+
filePath = path.relative(root, filePath);
|
|
112
|
+
if (filePath.startsWith(".."))
|
|
113
|
+
return `(file is outside the repo: ${input.path})`;
|
|
114
|
+
}
|
|
115
|
+
const built = buildUrl(remote, target, { ref, path: filePath, startLine: input.start_line, endLine: input.end_line, number: input.number });
|
|
116
|
+
if (typeof built !== "string")
|
|
117
|
+
return `(${built.error})`;
|
|
118
|
+
if (input.open) {
|
|
119
|
+
const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
|
|
120
|
+
const args = process.platform === "win32" ? ["/c", "start", built] : [built];
|
|
121
|
+
runIn(root, opener, args, { timeoutMs: 5000, signal: ctx.signal }).catch(() => { });
|
|
122
|
+
return `${built}\n(opened in browser)`;
|
|
123
|
+
}
|
|
124
|
+
return built;
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=github_link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github_link.js","sourceRoot":"","sources":["../../src/tools/github_link.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mcp (integration) — manage LISA's MCP server connections, so she can connect
|
|
3
|
+
* any integration that ships an MCP server (GitHub, Linear, Sentry, Postgres,
|
|
4
|
+
* filesystem, …) on request, rather than each needing a bespoke tool. MCP is
|
|
5
|
+
* the standard way to "add all the integrations an agent might use".
|
|
6
|
+
*
|
|
7
|
+
* list — configured MCP servers (from ~/.lisa/mcp.json)
|
|
8
|
+
* add — add a server (name + command [+ args/env]); connects on next start
|
|
9
|
+
* remove — remove a server
|
|
10
|
+
*
|
|
11
|
+
* Servers connect at startup, so add/remove take effect after a restart
|
|
12
|
+
* (`lisa serve --web`). Their tools then appear in LISA's toolset automatically.
|
|
13
|
+
*/
|
|
14
|
+
import type { ToolDefinition } from "../types.js";
|
|
15
|
+
interface McpInput {
|
|
16
|
+
action: "list" | "add" | "remove";
|
|
17
|
+
name?: string;
|
|
18
|
+
/** For add: the server command, e.g. "npx". */
|
|
19
|
+
command?: string;
|
|
20
|
+
/** For add: command args, e.g. ["-y","@modelcontextprotocol/server-filesystem","/path"]. */
|
|
21
|
+
args?: string[];
|
|
22
|
+
/** For add: env vars the server needs (e.g. API tokens). */
|
|
23
|
+
env?: Record<string, string>;
|
|
24
|
+
enabled?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare const mcpTool: ToolDefinition<McpInput, string>;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=mcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/tools/mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,UAAU,QAAQ;IAChB,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4FAA4F;IAC5F,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,4DAA4D;IAC5D,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,OAAO,EAAE,cAAc,CAAC,QAAQ,EAAE,MAAM,CA0DpD,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { loadMcpConfig, saveMcpServer, deleteMcpServer, MCP_CONFIG_PATH } from "../mcp/config.js";
|
|
2
|
+
export const mcpTool = {
|
|
3
|
+
name: "mcp",
|
|
4
|
+
description: "Manage MCP server connections — the standard way to add external integrations (GitHub, Linear, " +
|
|
5
|
+
"Sentry, Postgres, filesystem, …) whose tools then appear in LISA's toolset. action:'list' shows " +
|
|
6
|
+
"configured servers; 'add' (name + command [+ args/env]) adds one; 'remove' (name) deletes one. " +
|
|
7
|
+
"Servers connect at startup, so add/remove take effect after restarting `lisa serve --web`. Use " +
|
|
8
|
+
"when the user wants to connect a new integration via its MCP server.",
|
|
9
|
+
inputSchema: {
|
|
10
|
+
type: "object",
|
|
11
|
+
properties: {
|
|
12
|
+
action: { type: "string", enum: ["list", "add", "remove"] },
|
|
13
|
+
name: { type: "string", description: "Server name (for add/remove)." },
|
|
14
|
+
command: { type: "string", description: "Executable for add, e.g. 'npx'." },
|
|
15
|
+
args: { type: "array", items: { type: "string" }, description: "Args for add, e.g. ['-y','@scope/server-x']." },
|
|
16
|
+
env: { type: "object", additionalProperties: { type: "string" }, description: "Env vars the server needs (e.g. API tokens)." },
|
|
17
|
+
enabled: { type: "boolean", description: "Whether the server is enabled (default true)." },
|
|
18
|
+
},
|
|
19
|
+
required: ["action"],
|
|
20
|
+
additionalProperties: false,
|
|
21
|
+
},
|
|
22
|
+
async execute(input) {
|
|
23
|
+
if (input.action === "list") {
|
|
24
|
+
const servers = await loadMcpConfig();
|
|
25
|
+
if (servers.length === 0) {
|
|
26
|
+
return `(no MCP servers configured — add one with mcp action:'add', or edit ${MCP_CONFIG_PATH})`;
|
|
27
|
+
}
|
|
28
|
+
return (`${servers.length} MCP server(s) in ${MCP_CONFIG_PATH}:\n` +
|
|
29
|
+
servers
|
|
30
|
+
.map((s) => ` ${s.name}${s.enabled === false ? " (disabled)" : ""}: ${s.command} ${(s.args ?? []).join(" ")}`.trimEnd())
|
|
31
|
+
.join("\n"));
|
|
32
|
+
}
|
|
33
|
+
if (input.action === "remove") {
|
|
34
|
+
if (!input.name)
|
|
35
|
+
return "(remove needs a name — from mcp action:'list')";
|
|
36
|
+
const ok = await deleteMcpServer(input.name);
|
|
37
|
+
return ok
|
|
38
|
+
? `Removed MCP server "${input.name}". Restart \`lisa serve --web\` for it to disconnect.`
|
|
39
|
+
: `(no MCP server named "${input.name}")`;
|
|
40
|
+
}
|
|
41
|
+
// add
|
|
42
|
+
if (!input.name || !input.command) {
|
|
43
|
+
return "(add needs a name and a command, e.g. name:'filesystem' command:'npx' args:['-y','@modelcontextprotocol/server-filesystem','/path'])";
|
|
44
|
+
}
|
|
45
|
+
await saveMcpServer(input.name, {
|
|
46
|
+
command: input.command,
|
|
47
|
+
args: input.args ?? [],
|
|
48
|
+
env: input.env,
|
|
49
|
+
enabled: input.enabled ?? true,
|
|
50
|
+
});
|
|
51
|
+
return (`Added MCP server "${input.name}": ${input.command} ${(input.args ?? []).join(" ")}`.trimEnd() +
|
|
52
|
+
`\nRestart \`lisa serve --web\` to connect it — its tools then appear in my toolset automatically.`);
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/tools/mcp.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAclG,MAAM,CAAC,MAAM,OAAO,GAAqC;IACvD,IAAI,EAAE,KAAK;IACX,WAAW,EACT,iGAAiG;QACjG,kGAAkG;QAClG,iGAAiG;QACjG,iGAAiG;QACjG,sEAAsE;IACxE,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE;YAC3D,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+BAA+B,EAAE;YACtE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,iCAAiC,EAAE;YAC3E,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,8CAA8C,EAAE;YAC/G,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,8CAA8C,EAAE;YAC9H,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,+CAA+C,EAAE;SAC3F;QACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;QACpB,oBAAoB,EAAE,KAAK;KAC5B;IACD,KAAK,CAAC,OAAO,CAAC,KAAK;QACjB,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC5B,MAAM,OAAO,GAAG,MAAM,aAAa,EAAE,CAAC;YACtC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,uEAAuE,eAAe,GAAG,CAAC;YACnG,CAAC;YACD,OAAO,CACL,GAAG,OAAO,CAAC,MAAM,qBAAqB,eAAe,KAAK;gBAC1D,OAAO;qBACJ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC;qBACxH,IAAI,CAAC,IAAI,CAAC,CACd,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC9B,IAAI,CAAC,KAAK,CAAC,IAAI;gBAAE,OAAO,gDAAgD,CAAC;YACzE,MAAM,EAAE,GAAG,MAAM,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC7C,OAAO,EAAE;gBACP,CAAC,CAAC,uBAAuB,KAAK,CAAC,IAAI,uDAAuD;gBAC1F,CAAC,CAAC,yBAAyB,KAAK,CAAC,IAAI,IAAI,CAAC;QAC9C,CAAC;QAED,MAAM;QACN,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YAClC,OAAO,sIAAsI,CAAC;QAChJ,CAAC;QACD,MAAM,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE;YAC9B,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE;YACtB,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;SAC/B,CAAC,CAAC;QACH,OAAO,CACL,qBAAqB,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE;YAC9F,mGAAmG,CACpG,CAAC;IACJ,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* npm_info (integration) — the npm registry, the external service every JS
|
|
3
|
+
* agent touches. view a package's metadata, find outdated deps in a repo, or
|
|
4
|
+
* audit it for known vulnerabilities. No auth; uses the local npm CLI.
|
|
5
|
+
*/
|
|
6
|
+
import type { ToolDefinition } from "../types.js";
|
|
7
|
+
interface NpmInput {
|
|
8
|
+
action: "view" | "outdated" | "audit";
|
|
9
|
+
/** Package name for view (optionally name@range). */
|
|
10
|
+
package?: string;
|
|
11
|
+
cwd?: string;
|
|
12
|
+
}
|
|
13
|
+
/** Pure: format `npm view --json` metadata. Exported for tests. */
|
|
14
|
+
export declare function formatView(json: string): string;
|
|
15
|
+
/** Pure: format `npm outdated --json`. Exported for tests. */
|
|
16
|
+
export declare function formatOutdated(json: string): string;
|
|
17
|
+
/** Pure: summarise `npm audit --json` (npm v7+ shape). Exported for tests. */
|
|
18
|
+
export declare function formatAudit(json: string): string;
|
|
19
|
+
export declare const npmInfoTool: ToolDefinition<NpmInput, string>;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=npm_info.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npm_info.d.ts","sourceRoot":"","sources":["../../src/tools/npm_info.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,UAAU,QAAQ;IAChB,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC;IACtC,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAa/C;AAED,8DAA8D;AAC9D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMnD;AAED,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAShD;AAED,eAAO,MAAM,WAAW,EAAE,cAAc,CAAC,QAAQ,EAAE,MAAM,CA2CxD,CAAC"}
|