@smartledger.technology/openai-claw 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +134 -0
- package/dist/agent.js +262 -0
- package/dist/agent.js.map +1 -0
- package/dist/autopr/index.js +127 -0
- package/dist/autopr/index.js.map +1 -0
- package/dist/client.js +199 -0
- package/dist/client.js.map +1 -0
- package/dist/commands/index.js +624 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/config.js +71 -0
- package/dist/config.js.map +1 -0
- package/dist/cost.js +97 -0
- package/dist/cost.js.map +1 -0
- package/dist/eval/cli.js +32 -0
- package/dist/eval/cli.js.map +1 -0
- package/dist/eval/index.js +134 -0
- package/dist/eval/index.js.map +1 -0
- package/dist/hooks/index.js +69 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.js +246 -0
- package/dist/index.js.map +1 -0
- package/dist/input.js +96 -0
- package/dist/input.js.map +1 -0
- package/dist/mcp/index.js +135 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/memory/compaction.js +70 -0
- package/dist/memory/compaction.js.map +1 -0
- package/dist/memory/index.js +56 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/notifications/index.js +80 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/permissions/index.js +104 -0
- package/dist/permissions/index.js.map +1 -0
- package/dist/planmode.js +12 -0
- package/dist/planmode.js.map +1 -0
- package/dist/plugins/index.js +239 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/prompts/system.js +148 -0
- package/dist/prompts/system.js.map +1 -0
- package/dist/rag/index.js +158 -0
- package/dist/rag/index.js.map +1 -0
- package/dist/self-review/index.js +157 -0
- package/dist/self-review/index.js.map +1 -0
- package/dist/session.js +113 -0
- package/dist/session.js.map +1 -0
- package/dist/skills/index.js +39 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/subagent.js +128 -0
- package/dist/subagent.js.map +1 -0
- package/dist/subagents/index.js +61 -0
- package/dist/subagents/index.js.map +1 -0
- package/dist/tools/bash.js +94 -0
- package/dist/tools/bash.js.map +1 -0
- package/dist/tools/edit.js +64 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools/glob.js +34 -0
- package/dist/tools/glob.js.map +1 -0
- package/dist/tools/grep.js +87 -0
- package/dist/tools/grep.js.map +1 -0
- package/dist/tools/index.js +44 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/ls.js +39 -0
- package/dist/tools/ls.js.map +1 -0
- package/dist/tools/read.js +126 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/semantic.js +40 -0
- package/dist/tools/semantic.js.map +1 -0
- package/dist/tools/shell.js +131 -0
- package/dist/tools/shell.js.map +1 -0
- package/dist/tools/task.js +91 -0
- package/dist/tools/task.js.map +1 -0
- package/dist/tools/todo.js +64 -0
- package/dist/tools/todo.js.map +1 -0
- package/dist/tools/types.js +7 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/webfetch.js +62 -0
- package/dist/tools/webfetch.js.map +1 -0
- package/dist/tools/websearch.js +82 -0
- package/dist/tools/websearch.js.map +1 -0
- package/dist/tools/write.js +39 -0
- package/dist/tools/write.js.map +1 -0
- package/dist/ui/repl.js +203 -0
- package/dist/ui/repl.js.map +1 -0
- package/dist/ui/tui/App.js +234 -0
- package/dist/ui/tui/App.js.map +1 -0
- package/dist/ui/tui/Diff.js +38 -0
- package/dist/ui/tui/Diff.js.map +1 -0
- package/dist/ui/tui/MessageView.js +50 -0
- package/dist/ui/tui/MessageView.js.map +1 -0
- package/dist/ui/tui/PermissionPrompt.js +47 -0
- package/dist/ui/tui/PermissionPrompt.js.map +1 -0
- package/dist/ui/tui/SlashSuggest.js +36 -0
- package/dist/ui/tui/SlashSuggest.js.map +1 -0
- package/dist/ui/tui/StatusBar.js +31 -0
- package/dist/ui/tui/StatusBar.js.map +1 -0
- package/dist/ui/tui/highlight.js +66 -0
- package/dist/ui/tui/highlight.js.map +1 -0
- package/dist/ui/tui/index.js +12 -0
- package/dist/ui/tui/index.js.map +1 -0
- package/dist/ui/tui/markdown.js +46 -0
- package/dist/ui/tui/markdown.js.map +1 -0
- package/dist/ui/tui/types.js +2 -0
- package/dist/ui/tui/types.js.map +1 -0
- package/dist/web/index.js +195 -0
- package/dist/web/index.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import os from "node:os";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import { spawn } from "node:child_process";
|
|
5
|
+
function loadNotifyConfig(config) {
|
|
6
|
+
const user = readJson(path.join(config.homeDir, "settings.json"));
|
|
7
|
+
const proj = readJson(path.join(config.workdir, ".claw", "settings.json"));
|
|
8
|
+
const merged = { ...(user?.notifications ?? {}), ...(proj?.notifications ?? {}) };
|
|
9
|
+
if (!merged.desktop && !merged.slack && !merged.ntfy)
|
|
10
|
+
return null;
|
|
11
|
+
return merged;
|
|
12
|
+
}
|
|
13
|
+
export async function notify(config, evt) {
|
|
14
|
+
const cfg = loadNotifyConfig(config);
|
|
15
|
+
if (!cfg)
|
|
16
|
+
return;
|
|
17
|
+
const min = cfg.minDurationSec ?? 30;
|
|
18
|
+
if (evt.durationSec !== undefined && evt.durationSec < min)
|
|
19
|
+
return;
|
|
20
|
+
const calls = [];
|
|
21
|
+
if (cfg.desktop)
|
|
22
|
+
calls.push(sendDesktop(evt));
|
|
23
|
+
if (cfg.slack?.webhook)
|
|
24
|
+
calls.push(sendSlack(cfg.slack.webhook, evt));
|
|
25
|
+
if (cfg.ntfy?.url)
|
|
26
|
+
calls.push(sendNtfy(cfg.ntfy, evt));
|
|
27
|
+
await Promise.allSettled(calls);
|
|
28
|
+
}
|
|
29
|
+
async function sendDesktop(evt) {
|
|
30
|
+
const title = `claw: ${evt.title}`;
|
|
31
|
+
const body = evt.body.slice(0, 200);
|
|
32
|
+
return new Promise((resolve) => {
|
|
33
|
+
if (os.platform() === "darwin") {
|
|
34
|
+
const script = `display notification ${JSON.stringify(body)} with title ${JSON.stringify(title)}`;
|
|
35
|
+
const p = spawn("osascript", ["-e", script], { stdio: "ignore" });
|
|
36
|
+
p.on("close", () => resolve());
|
|
37
|
+
p.on("error", () => resolve());
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (os.platform() === "linux") {
|
|
41
|
+
const p = spawn("notify-send", [title, body], { stdio: "ignore" });
|
|
42
|
+
p.on("close", () => resolve());
|
|
43
|
+
p.on("error", () => resolve()); // missing binary is non-fatal
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
resolve();
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
async function sendSlack(webhook, evt) {
|
|
50
|
+
try {
|
|
51
|
+
await fetch(webhook, {
|
|
52
|
+
method: "POST",
|
|
53
|
+
headers: { "Content-Type": "application/json" },
|
|
54
|
+
body: JSON.stringify({ text: `*claw — ${evt.title}*\n${evt.body}` }),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// notifications never crash the agent
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async function sendNtfy(cfg, evt) {
|
|
62
|
+
try {
|
|
63
|
+
const headers = { Title: `claw — ${evt.title}` };
|
|
64
|
+
if (cfg.priority === "high")
|
|
65
|
+
headers.Priority = "high";
|
|
66
|
+
await fetch(cfg.url, { method: "POST", headers, body: evt.body });
|
|
67
|
+
}
|
|
68
|
+
catch { }
|
|
69
|
+
}
|
|
70
|
+
function readJson(p) {
|
|
71
|
+
try {
|
|
72
|
+
if (!fs.existsSync(p))
|
|
73
|
+
return {};
|
|
74
|
+
return JSON.parse(fs.readFileSync(p, "utf8"));
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return {};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/notifications/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import readline from "node:readline";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { saveUserSetting } from "../config.js";
|
|
4
|
+
export class PermissionManager {
|
|
5
|
+
config;
|
|
6
|
+
sessionAllows = [];
|
|
7
|
+
prompter;
|
|
8
|
+
constructor(config, prompter) {
|
|
9
|
+
this.config = config;
|
|
10
|
+
this.prompter = prompter ?? defaultReadlinePrompter();
|
|
11
|
+
}
|
|
12
|
+
setPrompter(p) {
|
|
13
|
+
this.prompter = p;
|
|
14
|
+
}
|
|
15
|
+
setMode(mode) {
|
|
16
|
+
this.config.permissionMode = mode;
|
|
17
|
+
}
|
|
18
|
+
get mode() {
|
|
19
|
+
return this.config.permissionMode;
|
|
20
|
+
}
|
|
21
|
+
async check(toolName, input) {
|
|
22
|
+
if (this.config.permissionMode === "bypassPermissions")
|
|
23
|
+
return { allow: true };
|
|
24
|
+
const key = describe(toolName, input);
|
|
25
|
+
if (matchesAny(key, this.config.deniedTools)) {
|
|
26
|
+
return { allow: false, reason: `denied by config (${key})` };
|
|
27
|
+
}
|
|
28
|
+
if (matchesAny(key, this.config.allowedTools))
|
|
29
|
+
return { allow: true };
|
|
30
|
+
if (matchesAny(key, this.sessionAllows.map((a) => a.pattern)))
|
|
31
|
+
return { allow: true };
|
|
32
|
+
if (this.config.permissionMode === "acceptEdits") {
|
|
33
|
+
if (toolName === "Write" || toolName === "Edit")
|
|
34
|
+
return { allow: true };
|
|
35
|
+
}
|
|
36
|
+
if (this.config.permissionMode === "plan") {
|
|
37
|
+
return { allow: false, reason: "plan mode — propose changes instead of executing them" };
|
|
38
|
+
}
|
|
39
|
+
const answer = await this.prompter({ tool: toolName, key, input });
|
|
40
|
+
if (answer === "yes")
|
|
41
|
+
return { allow: true };
|
|
42
|
+
if (answer === "always") {
|
|
43
|
+
this.sessionAllows.push({ pattern: toolName });
|
|
44
|
+
return { allow: true };
|
|
45
|
+
}
|
|
46
|
+
if (answer === "save") {
|
|
47
|
+
this.config.allowedTools.push(toolName);
|
|
48
|
+
saveUserSetting(this.config, "allowedTools", this.config.allowedTools);
|
|
49
|
+
return { allow: true };
|
|
50
|
+
}
|
|
51
|
+
return { allow: false, reason: "user denied" };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function describe(tool, input) {
|
|
55
|
+
if (tool === "Bash" && input && typeof input.command === "string") {
|
|
56
|
+
const cmd = input.command.split(/\s+/)[0];
|
|
57
|
+
return `Bash(${cmd}:*)`;
|
|
58
|
+
}
|
|
59
|
+
return tool;
|
|
60
|
+
}
|
|
61
|
+
// Permission rule syntax accepted by matchesAny:
|
|
62
|
+
// "Read" — exact tool name (matches the bare key "Read")
|
|
63
|
+
// "Bash" — any Bash invocation (matches "Bash(<anything>)")
|
|
64
|
+
// "Bash:*" — same as above (prefix wildcard)
|
|
65
|
+
// "Bash(npm:*)" — Bash where the first token starts with "npm"
|
|
66
|
+
// "Bash(npm test)" — exact described key
|
|
67
|
+
function matchesAny(key, patterns) {
|
|
68
|
+
for (const pat of patterns) {
|
|
69
|
+
if (pat === key)
|
|
70
|
+
return true;
|
|
71
|
+
if (pat.endsWith(":*")) {
|
|
72
|
+
const prefix = pat.slice(0, -2);
|
|
73
|
+
if (key.startsWith(prefix))
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
if (!pat.includes("(") && key.startsWith(pat + "("))
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
function defaultReadlinePrompter() {
|
|
82
|
+
let rl = null;
|
|
83
|
+
const get = () => {
|
|
84
|
+
if (!rl)
|
|
85
|
+
rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
86
|
+
return rl;
|
|
87
|
+
};
|
|
88
|
+
return ({ tool, key }) => new Promise((resolve) => {
|
|
89
|
+
const r = get();
|
|
90
|
+
process.stdout.write(chalk.yellow(`\n? Allow ${chalk.bold(tool)} (${key})? `) +
|
|
91
|
+
chalk.dim("[y]es / [n]o / [a]lways / [s]ave: "));
|
|
92
|
+
r.question("", (answer) => {
|
|
93
|
+
const a = answer.trim().toLowerCase();
|
|
94
|
+
if (a === "y" || a === "yes")
|
|
95
|
+
return resolve("yes");
|
|
96
|
+
if (a === "a" || a === "always")
|
|
97
|
+
return resolve("always");
|
|
98
|
+
if (a === "s" || a === "save")
|
|
99
|
+
return resolve("save");
|
|
100
|
+
resolve("no");
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/permissions/index.ts"],"names":[],"mappings":"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"}
|
package/dist/planmode.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function planModeExtra() {
|
|
2
|
+
return [
|
|
3
|
+
"You are in PLAN MODE.",
|
|
4
|
+
"Do not write, edit, delete, or run any mutating commands. Instead, propose a step-by-step plan and wait for the user to exit plan mode before executing.",
|
|
5
|
+
"Read-only tools (Read, Grep, Glob, LS, WebFetch, WebSearch) are allowed for investigation.",
|
|
6
|
+
"When the plan is ready, end your message with a single line: 'Ready for plan approval.'",
|
|
7
|
+
].join("\n");
|
|
8
|
+
}
|
|
9
|
+
export function setPlanMode(config, enabled) {
|
|
10
|
+
config.permissionMode = enabled ? "plan" : "ask";
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=planmode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planmode.js","sourceRoot":"","sources":["../src/planmode.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,aAAa;IAC3B,OAAO;QACL,uBAAuB;QACvB,0JAA0J;QAC1J,4FAA4F;QAC5F,yFAAyF;KAC1F,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAkB,EAAE,OAAgB;IAC9D,MAAM,CAAC,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { spawnSync } from "node:child_process";
|
|
4
|
+
// Small, hardcoded registry. Names map to git URLs. Extend or replace freely.
|
|
5
|
+
export const REGISTRY = {
|
|
6
|
+
"pdf-skill": {
|
|
7
|
+
url: "https://github.com/codenlighten/openai-claw-pdf-skill.git",
|
|
8
|
+
description: "PDF table-extraction skill (placeholder registry entry)",
|
|
9
|
+
},
|
|
10
|
+
"security-reviewer": {
|
|
11
|
+
url: "https://github.com/codenlighten/openai-claw-security-reviewer.git",
|
|
12
|
+
description: "Security-review subagent (placeholder registry entry)",
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
export function pluginsDir(config) {
|
|
16
|
+
const dir = path.join(config.homeDir, "plugins");
|
|
17
|
+
if (!fs.existsSync(dir))
|
|
18
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
19
|
+
return dir;
|
|
20
|
+
}
|
|
21
|
+
export function lockfilePath(config) {
|
|
22
|
+
const dir = path.join(config.workdir, ".claw");
|
|
23
|
+
if (!fs.existsSync(dir))
|
|
24
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
25
|
+
return path.join(dir, "plugins.lock");
|
|
26
|
+
}
|
|
27
|
+
export function readLockfile(config) {
|
|
28
|
+
const file = lockfilePath(config);
|
|
29
|
+
if (!fs.existsSync(file))
|
|
30
|
+
return { version: 1, plugins: [] };
|
|
31
|
+
try {
|
|
32
|
+
return JSON.parse(fs.readFileSync(file, "utf8"));
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return { version: 1, plugins: [] };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function writeLockfile(config, lock) {
|
|
39
|
+
fs.writeFileSync(lockfilePath(config), JSON.stringify(lock, null, 2));
|
|
40
|
+
}
|
|
41
|
+
function detectName(source) {
|
|
42
|
+
if (REGISTRY[source])
|
|
43
|
+
return source;
|
|
44
|
+
// git URL → last path segment, drop .git
|
|
45
|
+
const base = source.split("/").pop() ?? source;
|
|
46
|
+
return base.replace(/\.git$/, "");
|
|
47
|
+
}
|
|
48
|
+
function resolveUrl(source) {
|
|
49
|
+
return REGISTRY[source]?.url ?? source;
|
|
50
|
+
}
|
|
51
|
+
function detectProvides(pluginDir) {
|
|
52
|
+
const skills = [];
|
|
53
|
+
const agents = [];
|
|
54
|
+
const mcp = [];
|
|
55
|
+
const skillsDir = path.join(pluginDir, "skills");
|
|
56
|
+
if (fs.existsSync(skillsDir)) {
|
|
57
|
+
for (const e of fs.readdirSync(skillsDir)) {
|
|
58
|
+
if (fs.existsSync(path.join(skillsDir, e, "SKILL.md")))
|
|
59
|
+
skills.push(e);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const agentsDir = path.join(pluginDir, "agents");
|
|
63
|
+
if (fs.existsSync(agentsDir)) {
|
|
64
|
+
for (const e of fs.readdirSync(agentsDir)) {
|
|
65
|
+
if (e.endsWith(".md"))
|
|
66
|
+
agents.push(e);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const mcpFile = path.join(pluginDir, "mcp.json");
|
|
70
|
+
if (fs.existsSync(mcpFile)) {
|
|
71
|
+
try {
|
|
72
|
+
const data = JSON.parse(fs.readFileSync(mcpFile, "utf8"));
|
|
73
|
+
if (data?.mcpServers && typeof data.mcpServers === "object") {
|
|
74
|
+
mcp.push(...Object.keys(data.mcpServers));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch { }
|
|
78
|
+
}
|
|
79
|
+
return { skills, agents, mcp };
|
|
80
|
+
}
|
|
81
|
+
function gitClone(url, dest) {
|
|
82
|
+
const res = spawnSync("git", ["clone", "--depth", "1", url, dest], { encoding: "utf8" });
|
|
83
|
+
if (res.status !== 0)
|
|
84
|
+
return { ok: false, error: (res.stderr || res.stdout || "git clone failed").trim() };
|
|
85
|
+
const rev = spawnSync("git", ["rev-parse", "HEAD"], { cwd: dest, encoding: "utf8" });
|
|
86
|
+
return { ok: true, ref: (rev.stdout || "").trim() };
|
|
87
|
+
}
|
|
88
|
+
function linkIntoUserConfig(config, pluginDir, provides) {
|
|
89
|
+
// Skills: symlink each skill directory into ~/.openai-claw/skills/<name>.
|
|
90
|
+
if (provides.skills.length) {
|
|
91
|
+
const target = path.join(config.homeDir, "skills");
|
|
92
|
+
fs.mkdirSync(target, { recursive: true });
|
|
93
|
+
for (const s of provides.skills) {
|
|
94
|
+
const link = path.join(target, s);
|
|
95
|
+
const src = path.resolve(pluginDir, "skills", s);
|
|
96
|
+
try {
|
|
97
|
+
fs.unlinkSync(link);
|
|
98
|
+
}
|
|
99
|
+
catch { }
|
|
100
|
+
try {
|
|
101
|
+
fs.symlinkSync(src, link, "dir");
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// fallback: copy directory contents (symlinks may be disabled)
|
|
105
|
+
copyDir(src, link);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Agents: symlink each .md into ~/.openai-claw/agents/.
|
|
110
|
+
if (provides.agents.length) {
|
|
111
|
+
const target = path.join(config.homeDir, "agents");
|
|
112
|
+
fs.mkdirSync(target, { recursive: true });
|
|
113
|
+
for (const a of provides.agents) {
|
|
114
|
+
const link = path.join(target, a);
|
|
115
|
+
const src = path.resolve(pluginDir, "agents", a);
|
|
116
|
+
try {
|
|
117
|
+
fs.unlinkSync(link);
|
|
118
|
+
}
|
|
119
|
+
catch { }
|
|
120
|
+
try {
|
|
121
|
+
fs.symlinkSync(src, link, "file");
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
try {
|
|
125
|
+
fs.copyFileSync(src, link);
|
|
126
|
+
}
|
|
127
|
+
catch { }
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// MCP: merge into ~/.openai-claw/settings.json
|
|
132
|
+
if (provides.mcp.length) {
|
|
133
|
+
try {
|
|
134
|
+
const mcpData = JSON.parse(fs.readFileSync(path.join(pluginDir, "mcp.json"), "utf8"));
|
|
135
|
+
const settingsPath = path.join(config.homeDir, "settings.json");
|
|
136
|
+
const current = fs.existsSync(settingsPath) ? JSON.parse(fs.readFileSync(settingsPath, "utf8")) : {};
|
|
137
|
+
current.mcpServers = { ...(current.mcpServers ?? {}), ...mcpData.mcpServers };
|
|
138
|
+
fs.writeFileSync(settingsPath, JSON.stringify(current, null, 2));
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// non-fatal
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function unlinkFromUserConfig(config, entry) {
|
|
146
|
+
for (const s of entry.provides.skills) {
|
|
147
|
+
const link = path.join(config.homeDir, "skills", s);
|
|
148
|
+
try {
|
|
149
|
+
fs.rmSync(link, { recursive: true, force: true });
|
|
150
|
+
}
|
|
151
|
+
catch { }
|
|
152
|
+
}
|
|
153
|
+
for (const a of entry.provides.agents) {
|
|
154
|
+
const link = path.join(config.homeDir, "agents", a);
|
|
155
|
+
try {
|
|
156
|
+
fs.rmSync(link, { force: true });
|
|
157
|
+
}
|
|
158
|
+
catch { }
|
|
159
|
+
}
|
|
160
|
+
if (entry.provides.mcp.length) {
|
|
161
|
+
try {
|
|
162
|
+
const settingsPath = path.join(config.homeDir, "settings.json");
|
|
163
|
+
if (!fs.existsSync(settingsPath))
|
|
164
|
+
return;
|
|
165
|
+
const current = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
|
|
166
|
+
for (const m of entry.provides.mcp) {
|
|
167
|
+
if (current.mcpServers)
|
|
168
|
+
delete current.mcpServers[m];
|
|
169
|
+
}
|
|
170
|
+
fs.writeFileSync(settingsPath, JSON.stringify(current, null, 2));
|
|
171
|
+
}
|
|
172
|
+
catch { }
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function copyDir(src, dest) {
|
|
176
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
177
|
+
for (const e of fs.readdirSync(src, { withFileTypes: true })) {
|
|
178
|
+
const s = path.join(src, e.name);
|
|
179
|
+
const d = path.join(dest, e.name);
|
|
180
|
+
if (e.isDirectory())
|
|
181
|
+
copyDir(s, d);
|
|
182
|
+
else
|
|
183
|
+
fs.copyFileSync(s, d);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
export function installPlugin(config, source) {
|
|
187
|
+
const name = detectName(source);
|
|
188
|
+
const url = resolveUrl(source);
|
|
189
|
+
const dir = path.join(pluginsDir(config), name);
|
|
190
|
+
if (fs.existsSync(dir))
|
|
191
|
+
return { ok: false, error: `Plugin '${name}' already installed at ${dir}. Use /plugins remove ${name} first.` };
|
|
192
|
+
const cloned = gitClone(url, dir);
|
|
193
|
+
if (!cloned.ok) {
|
|
194
|
+
try {
|
|
195
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
196
|
+
}
|
|
197
|
+
catch { }
|
|
198
|
+
return { ok: false, error: cloned.error };
|
|
199
|
+
}
|
|
200
|
+
const provides = detectProvides(dir);
|
|
201
|
+
const entry = {
|
|
202
|
+
name,
|
|
203
|
+
source: url,
|
|
204
|
+
installedAt: new Date().toISOString(),
|
|
205
|
+
ref: cloned.ref,
|
|
206
|
+
provides,
|
|
207
|
+
};
|
|
208
|
+
linkIntoUserConfig(config, dir, provides);
|
|
209
|
+
const lock = readLockfile(config);
|
|
210
|
+
lock.plugins = lock.plugins.filter((p) => p.name !== name).concat(entry);
|
|
211
|
+
writeLockfile(config, lock);
|
|
212
|
+
return { ok: true, entry };
|
|
213
|
+
}
|
|
214
|
+
export function removePlugin(config, name) {
|
|
215
|
+
const lock = readLockfile(config);
|
|
216
|
+
const idx = lock.plugins.findIndex((p) => p.name === name);
|
|
217
|
+
if (idx < 0)
|
|
218
|
+
return { ok: false, error: `Plugin '${name}' is not installed.` };
|
|
219
|
+
const entry = lock.plugins[idx];
|
|
220
|
+
unlinkFromUserConfig(config, entry);
|
|
221
|
+
const dir = path.join(pluginsDir(config), name);
|
|
222
|
+
try {
|
|
223
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
224
|
+
}
|
|
225
|
+
catch { }
|
|
226
|
+
lock.plugins.splice(idx, 1);
|
|
227
|
+
writeLockfile(config, lock);
|
|
228
|
+
return { ok: true, entry };
|
|
229
|
+
}
|
|
230
|
+
export function listInstalled(config) {
|
|
231
|
+
return readLockfile(config).plugins;
|
|
232
|
+
}
|
|
233
|
+
export function searchRegistry(query) {
|
|
234
|
+
const q = query.toLowerCase();
|
|
235
|
+
return Object.entries(REGISTRY)
|
|
236
|
+
.filter(([name, info]) => name.toLowerCase().includes(q) || info.description.toLowerCase().includes(q))
|
|
237
|
+
.map(([name, info]) => ({ name, ...info }));
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import os from "node:os";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { listMemories } from "../memory/index.js";
|
|
5
|
+
export function buildSystemPrompt(opts) {
|
|
6
|
+
const { config, tools, extras = [], variant = "main" } = opts;
|
|
7
|
+
const toolList = formatToolList(tools);
|
|
8
|
+
// Cache-friendly layout: keep workdir + platform info (stable for the session)
|
|
9
|
+
// before any project / memory content, and push volatile bits (date, model id,
|
|
10
|
+
// memory, extras) to the very end so the cached prefix survives /remember and
|
|
11
|
+
// model switches.
|
|
12
|
+
const stableEnv = [
|
|
13
|
+
`Primary working directory: ${config.workdir}`,
|
|
14
|
+
`Platform: ${os.platform()}`,
|
|
15
|
+
`Shell: ${process.env.SHELL ?? "/bin/sh"}`,
|
|
16
|
+
`OS Version: ${os.release()}`,
|
|
17
|
+
].join("\n");
|
|
18
|
+
const date = new Date().toISOString().split("T")[0];
|
|
19
|
+
const volatileEnv = [
|
|
20
|
+
`Today's date: ${date}`,
|
|
21
|
+
`You are powered by OpenAI's '${config.model}' model.`,
|
|
22
|
+
].join("\n");
|
|
23
|
+
const memoryContext = loadMemoryContext(config);
|
|
24
|
+
const claudeMd = loadProjectInstructions(config.workdir);
|
|
25
|
+
const base = `You are openai-claw, a CLI assistant for software engineering tasks. You are modeled after Anthropic's Claude Code but powered by OpenAI's API.
|
|
26
|
+
|
|
27
|
+
# Identity
|
|
28
|
+
- All text you output outside of tool use is shown to the user. Use it to communicate; tool calls happen silently.
|
|
29
|
+
- You may call multiple tools in a single response when there are no dependencies between them — this is the efficient default.
|
|
30
|
+
- Tool execution requires the user's permission unless preconfigured. Denied tools should prompt a change of approach, not a retry.
|
|
31
|
+
|
|
32
|
+
# Tools available
|
|
33
|
+
${toolList}
|
|
34
|
+
|
|
35
|
+
# Doing tasks
|
|
36
|
+
- The user will primarily request software engineering tasks: bugs, features, refactors, explanations, etc. Treat ambiguous requests as software tasks in the context of the current working directory.
|
|
37
|
+
- Prefer editing existing files over creating new ones. Never create README/docs files unless asked.
|
|
38
|
+
- Don't add features, abstractions, or error handling beyond what the task requires. Trust framework guarantees; validate only at system boundaries.
|
|
39
|
+
- Don't write comments that restate what code does. Only write comments explaining a non-obvious WHY (a hidden constraint, a workaround, a surprising invariant).
|
|
40
|
+
- Investigate failures at the root cause. Never use destructive shortcuts (\`--no-verify\`, \`git reset --hard\`, \`rm -rf\` on unknown state) to make obstacles go away.
|
|
41
|
+
|
|
42
|
+
# Tool-call discipline
|
|
43
|
+
- Parallel tool calls are great when the calls are independent (e.g. reading 10 different files). Do this aggressively.
|
|
44
|
+
- Do NOT issue parallel Edit calls against the same file — the first edit mutates the file and the later ones will fail with 'old_string not found'. For a single file: issue Edit calls sequentially (one per assistant turn), or rewrite the whole file with Write if changes are extensive.
|
|
45
|
+
- After an Edit fails, re-Read the file before retrying — the content has likely shifted.
|
|
46
|
+
- Preserve the existing indentation style of a file you're editing (tabs vs. spaces). Look at neighboring lines.
|
|
47
|
+
|
|
48
|
+
# Executing actions with care
|
|
49
|
+
- Local, reversible actions (editing files, running tests, reading state) are fine.
|
|
50
|
+
- Risky actions (force pushes, deleting branches, dropping tables, removing packages, sending messages, posting to PRs/issues, modifying CI) require confirmation unless the user has explicitly authorized them for the current scope.
|
|
51
|
+
- A user approving once doesn't mean approval forever — match action scope to what was requested.
|
|
52
|
+
|
|
53
|
+
# Tone and style
|
|
54
|
+
- Be concise. A simple question gets a direct answer, not headers and sections.
|
|
55
|
+
- Don't narrate internal deliberation. State results and decisions directly.
|
|
56
|
+
- One-or-two-sentence end-of-turn summary: what changed and what's next.
|
|
57
|
+
- When referencing code locations, use \`file_path:line_number\` so the user can navigate.
|
|
58
|
+
|
|
59
|
+
# Output conventions
|
|
60
|
+
- No emojis unless the user explicitly asks.
|
|
61
|
+
- Markdown is rendered as monospace CommonMark.
|
|
62
|
+
|
|
63
|
+
# Multimodal input
|
|
64
|
+
- The user can attach images via @path.png or the /img command. When you receive image content, describe what you see, extract text via OCR if relevant, or take action based on the image as instructed. If the current model doesn't support vision, say so plainly rather than hallucinating image contents.
|
|
65
|
+
- When an image is already attached to the user's message, do NOT call the Read tool on the image file path — Read returns the raw binary bytes, which are useless to you. Use the attached image directly. Only call Read on the image's file path if the user explicitly asks you to inspect the file's bytes (e.g. checking a header or magic number).
|
|
66
|
+
|
|
67
|
+
# Environment
|
|
68
|
+
${stableEnv}
|
|
69
|
+
${claudeMd ? `\n# Project instructions (from CLAUDE.md)\n${claudeMd}` : ""}
|
|
70
|
+
|
|
71
|
+
# Session
|
|
72
|
+
${volatileEnv}
|
|
73
|
+
${memoryContext ? `\n# Persistent memory\n${memoryContext}` : ""}
|
|
74
|
+
${extras.length ? `\n${extras.join("\n")}` : ""}`;
|
|
75
|
+
if (variant === "subagent-general") {
|
|
76
|
+
return `${base}\n\n# Subagent context\nYou are a subagent. Return a concise final summary of your findings. You will be invoked once with a self-contained prompt — there is no follow-up turn.`;
|
|
77
|
+
}
|
|
78
|
+
if (variant === "subagent-explore") {
|
|
79
|
+
return `${base}\n\n# Subagent context\nYou are an Explore subagent — read-only. Locate code, files, and references. Do not attempt to write or modify anything. Return a short report of where things live and key snippets.`;
|
|
80
|
+
}
|
|
81
|
+
return base;
|
|
82
|
+
}
|
|
83
|
+
function formatToolList(tools) {
|
|
84
|
+
const builtin = tools.filter((t) => !t.name.startsWith("mcp__") && t.name !== "Task");
|
|
85
|
+
const mcp = tools.filter((t) => t.name.startsWith("mcp__"));
|
|
86
|
+
const subagent = tools.filter((t) => t.name === "Task");
|
|
87
|
+
const lines = [];
|
|
88
|
+
if (builtin.length) {
|
|
89
|
+
lines.push("## Built-in tools");
|
|
90
|
+
for (const t of builtin)
|
|
91
|
+
lines.push(`- ${t.name}: ${t.description}`);
|
|
92
|
+
}
|
|
93
|
+
if (subagent.length) {
|
|
94
|
+
lines.push("\n## Subagents");
|
|
95
|
+
for (const t of subagent)
|
|
96
|
+
lines.push(`- ${t.name}: ${t.description}`);
|
|
97
|
+
}
|
|
98
|
+
if (mcp.length) {
|
|
99
|
+
lines.push("\n## MCP tools");
|
|
100
|
+
for (const t of mcp) {
|
|
101
|
+
// First sentence only — MCP tools often ship verbose descriptions.
|
|
102
|
+
const summary = t.description.split(/(?<=[.!?])\s/)[0];
|
|
103
|
+
lines.push(`- ${t.name}: ${summary}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return lines.join("\n");
|
|
107
|
+
}
|
|
108
|
+
function loadProjectInstructions(workdir) {
|
|
109
|
+
const candidates = [path.join(workdir, "CLAUDE.md"), path.join(workdir, ".claw", "CLAW.md")];
|
|
110
|
+
for (const p of candidates) {
|
|
111
|
+
if (fs.existsSync(p)) {
|
|
112
|
+
try {
|
|
113
|
+
return fs.readFileSync(p, "utf8").slice(0, 20_000);
|
|
114
|
+
}
|
|
115
|
+
catch { }
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return "";
|
|
119
|
+
}
|
|
120
|
+
function loadMemoryContext(config) {
|
|
121
|
+
const entries = listMemories(config);
|
|
122
|
+
if (entries.length === 0)
|
|
123
|
+
return "";
|
|
124
|
+
const priority = { user: 0, feedback: 1, project: 2, reference: 3 };
|
|
125
|
+
const sorted = [...entries].sort((a, b) => (priority[a.type] ?? 4) - (priority[b.type] ?? 4));
|
|
126
|
+
const MAX_CHARS = 32_000; // ~8k tokens at 4 chars/token
|
|
127
|
+
const parts = [];
|
|
128
|
+
let used = 0;
|
|
129
|
+
for (const e of sorted) {
|
|
130
|
+
const block = `## ${e.name} (${e.type})\n${e.description ? e.description + "\n\n" : ""}${e.body}`;
|
|
131
|
+
if (used + block.length > MAX_CHARS) {
|
|
132
|
+
parts.push(`…${entries.length - parts.length} more memory entries truncated.`);
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
parts.push(block);
|
|
136
|
+
used += block.length;
|
|
137
|
+
}
|
|
138
|
+
const idx = path.join(config.memoryDir, "MEMORY.md");
|
|
139
|
+
let header = "";
|
|
140
|
+
if (fs.existsSync(idx)) {
|
|
141
|
+
try {
|
|
142
|
+
header = fs.readFileSync(idx, "utf8").trim() + "\n\n";
|
|
143
|
+
}
|
|
144
|
+
catch { }
|
|
145
|
+
}
|
|
146
|
+
return header + parts.join("\n\n---\n\n");
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=system.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system.js","sourceRoot":"","sources":["../../src/prompts/system.ts"],"names":[],"mappings":"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"}
|