claude-opencode-mcp 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/CHANGELOG.md +56 -0
- package/LICENSE +21 -0
- package/README.md +514 -0
- package/SECURITY.md +80 -0
- package/agents/deepseek-coder.md +32 -0
- package/agents/deepseek-researcher.md +36 -0
- package/agents/deepseek-reviewer.md +31 -0
- package/agents/deepseek-tester.md +31 -0
- package/dist/cli/init.d.ts +6 -0
- package/dist/cli/init.js +208 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/config/config.d.ts +109 -0
- package/dist/config/config.js +163 -0
- package/dist/config/config.js.map +1 -0
- package/dist/errors.d.ts +29 -0
- package/dist/errors.js +68 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +116 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/execute.d.ts +30 -0
- package/dist/mcp/execute.js +128 -0
- package/dist/mcp/execute.js.map +1 -0
- package/dist/mcp/server.d.ts +19 -0
- package/dist/mcp/server.js +38 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/session-utils.d.ts +5 -0
- package/dist/mcp/session-utils.js +55 -0
- package/dist/mcp/session-utils.js.map +1 -0
- package/dist/mcp/tool-utils.d.ts +11 -0
- package/dist/mcp/tool-utils.js +44 -0
- package/dist/mcp/tool-utils.js.map +1 -0
- package/dist/mcp/tools/abort-session.d.ts +3 -0
- package/dist/mcp/tools/abort-session.js +48 -0
- package/dist/mcp/tools/abort-session.js.map +1 -0
- package/dist/mcp/tools/create-session.d.ts +3 -0
- package/dist/mcp/tools/create-session.js +53 -0
- package/dist/mcp/tools/create-session.js.map +1 -0
- package/dist/mcp/tools/delegate-task.d.ts +4 -0
- package/dist/mcp/tools/delegate-task.js +98 -0
- package/dist/mcp/tools/delegate-task.js.map +1 -0
- package/dist/mcp/tools/get-diff.d.ts +3 -0
- package/dist/mcp/tools/get-diff.js +97 -0
- package/dist/mcp/tools/get-diff.js.map +1 -0
- package/dist/mcp/tools/get-session.d.ts +3 -0
- package/dist/mcp/tools/get-session.js +79 -0
- package/dist/mcp/tools/get-session.js.map +1 -0
- package/dist/mcp/tools/list-agents.d.ts +3 -0
- package/dist/mcp/tools/list-agents.js +72 -0
- package/dist/mcp/tools/list-agents.js.map +1 -0
- package/dist/mcp/tools/send-message.d.ts +3 -0
- package/dist/mcp/tools/send-message.js +59 -0
- package/dist/mcp/tools/send-message.js.map +1 -0
- package/dist/opencode/agents.d.ts +46 -0
- package/dist/opencode/agents.js +239 -0
- package/dist/opencode/agents.js.map +1 -0
- package/dist/opencode/binary.d.ts +19 -0
- package/dist/opencode/binary.js +129 -0
- package/dist/opencode/binary.js.map +1 -0
- package/dist/opencode/client.d.ts +32 -0
- package/dist/opencode/client.js +55 -0
- package/dist/opencode/client.js.map +1 -0
- package/dist/opencode/manager.d.ts +66 -0
- package/dist/opencode/manager.js +492 -0
- package/dist/opencode/manager.js.map +1 -0
- package/dist/opencode/permission-watcher.d.ts +26 -0
- package/dist/opencode/permission-watcher.js +144 -0
- package/dist/opencode/permission-watcher.js.map +1 -0
- package/dist/opencode/run.d.ts +39 -0
- package/dist/opencode/run.js +318 -0
- package/dist/opencode/run.js.map +1 -0
- package/dist/opencode/sessions.d.ts +26 -0
- package/dist/opencode/sessions.js +105 -0
- package/dist/opencode/sessions.js.map +1 -0
- package/dist/opencode/setup.d.ts +38 -0
- package/dist/opencode/setup.js +109 -0
- package/dist/opencode/setup.js.map +1 -0
- package/dist/security/paths.d.ts +20 -0
- package/dist/security/paths.js +93 -0
- package/dist/security/paths.js.map +1 -0
- package/dist/security/policy.d.ts +17 -0
- package/dist/security/policy.js +86 -0
- package/dist/security/policy.js.map +1 -0
- package/dist/types/index.d.ts +131 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/util/fs.d.ts +12 -0
- package/dist/util/fs.js +73 -0
- package/dist/util/fs.js.map +1 -0
- package/dist/util/git.d.ts +54 -0
- package/dist/util/git.js +202 -0
- package/dist/util/git.js.map +1 -0
- package/dist/util/logger.d.ts +21 -0
- package/dist/util/logger.js +129 -0
- package/dist/util/logger.js.map +1 -0
- package/dist/util/text.d.ts +11 -0
- package/dist/util/text.js +126 -0
- package/dist/util/text.js.map +1 -0
- package/dist/workspace/context.d.ts +12 -0
- package/dist/workspace/context.js +67 -0
- package/dist/workspace/context.js.map +1 -0
- package/dist/workspace/resolver.d.ts +35 -0
- package/dist/workspace/resolver.js +112 -0
- package/dist/workspace/resolver.js.map +1 -0
- package/dist/workspace/validator.d.ts +13 -0
- package/dist/workspace/validator.js +102 -0
- package/dist/workspace/validator.js.map +1 -0
- package/docs/agent-configuration.md +100 -0
- package/docs/architecture.md +115 -0
- package/docs/claude-code-setup.md +116 -0
- package/docs/configuration.md +184 -0
- package/docs/contributing.md +71 -0
- package/docs/deepseek-setup.md +84 -0
- package/docs/development.md +146 -0
- package/docs/installation.md +88 -0
- package/docs/opencode-setup.md +97 -0
- package/docs/security-audit.md +80 -0
- package/docs/security.md +128 -0
- package/docs/troubleshooting.md +126 -0
- package/docs/workspace-model.md +126 -0
- package/package.json +79 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export interface GitRunResult {
|
|
2
|
+
code: number;
|
|
3
|
+
stdout: string;
|
|
4
|
+
stderr: string;
|
|
5
|
+
failed: boolean;
|
|
6
|
+
missing: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function runGit(cwd: string, args: string[], options?: {
|
|
9
|
+
timeoutMs?: number;
|
|
10
|
+
maxBuffer?: number;
|
|
11
|
+
}): Promise<GitRunResult>;
|
|
12
|
+
export declare function isGitAvailable(): Promise<boolean>;
|
|
13
|
+
export declare function isGitRepository(cwd: string): Promise<boolean>;
|
|
14
|
+
export declare function findGitRoot(cwd: string): Promise<string | null>;
|
|
15
|
+
export interface GitBaseline {
|
|
16
|
+
/** Commit the workspace was at when the session started (may be null for unborn HEAD). */
|
|
17
|
+
head: string | null;
|
|
18
|
+
/** Commit created by `git stash create` capturing dirty state (null when clean). */
|
|
19
|
+
stashRef: string | null;
|
|
20
|
+
/** Untracked files present at baseline time. */
|
|
21
|
+
untracked: string[];
|
|
22
|
+
/** Whether HEAD exists. */
|
|
23
|
+
unborn: boolean;
|
|
24
|
+
/** Whether the working tree had tracked changes at baseline time. */
|
|
25
|
+
dirty: boolean;
|
|
26
|
+
}
|
|
27
|
+
/** Capture a non-invasive baseline of the git working tree. */
|
|
28
|
+
export declare function captureGitBaseline(cwd: string): Promise<GitBaseline | null>;
|
|
29
|
+
export interface GitDiffResult {
|
|
30
|
+
patch: string;
|
|
31
|
+
files: Array<{
|
|
32
|
+
file: string;
|
|
33
|
+
additions: number;
|
|
34
|
+
deletions: number;
|
|
35
|
+
status: "modified" | "added" | "deleted" | "renamed" | "unknown";
|
|
36
|
+
}>;
|
|
37
|
+
truncated: boolean;
|
|
38
|
+
note?: string;
|
|
39
|
+
}
|
|
40
|
+
interface ParsedFile {
|
|
41
|
+
file: string;
|
|
42
|
+
additions: number;
|
|
43
|
+
deletions: number;
|
|
44
|
+
status: "modified" | "added" | "deleted" | "renamed" | "unknown";
|
|
45
|
+
}
|
|
46
|
+
export declare function parseUnifiedDiff(patch: string): ParsedFile[];
|
|
47
|
+
export interface DiffOptions {
|
|
48
|
+
maxPatchChars?: number;
|
|
49
|
+
maxNewFiles?: number;
|
|
50
|
+
}
|
|
51
|
+
/** Compute the workspace diff between the recorded baseline and the current state. */
|
|
52
|
+
export declare function diffSinceBaseline(cwd: string, baseline: GitBaseline, options?: DiffOptions): Promise<GitDiffResult>;
|
|
53
|
+
export declare function currentHead(cwd: string): Promise<string | null>;
|
|
54
|
+
export {};
|
package/dist/util/git.js
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { BridgeError } from "../errors.js";
|
|
4
|
+
const DEFAULT_TIMEOUT_MS = 20_000;
|
|
5
|
+
const DEFAULT_MAX_BUFFER = 16 * 1024 * 1024;
|
|
6
|
+
export async function runGit(cwd, args, options = {}) {
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
execFile("git", args, {
|
|
9
|
+
cwd,
|
|
10
|
+
timeout: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
11
|
+
maxBuffer: options.maxBuffer ?? DEFAULT_MAX_BUFFER,
|
|
12
|
+
windowsHide: true,
|
|
13
|
+
env: { ...process.env, GIT_OPTIONAL_LOCKS: "0", GIT_PAGER: "cat" },
|
|
14
|
+
}, (error, stdout, stderr) => {
|
|
15
|
+
const stdoutText = typeof stdout === "string" ? stdout : String(stdout ?? "");
|
|
16
|
+
const stderrText = typeof stderr === "string" ? stderr : String(stderr ?? "");
|
|
17
|
+
if (error) {
|
|
18
|
+
const errno = error.code;
|
|
19
|
+
const missing = errno === "ENOENT";
|
|
20
|
+
const code = typeof error.code === "number"
|
|
21
|
+
? (error.code ?? 1)
|
|
22
|
+
: 1;
|
|
23
|
+
resolve({ code, stdout: stdoutText, stderr: stderrText, failed: true, missing });
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
resolve({ code: 0, stdout: stdoutText, stderr: stderrText, failed: false, missing: false });
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
export async function isGitAvailable() {
|
|
31
|
+
const result = await runGit(process.cwd(), ["--version"], { timeoutMs: 5_000 });
|
|
32
|
+
return !result.missing && !result.failed;
|
|
33
|
+
}
|
|
34
|
+
export async function isGitRepository(cwd) {
|
|
35
|
+
const result = await runGit(cwd, ["rev-parse", "--is-inside-work-tree"], { timeoutMs: 5_000 });
|
|
36
|
+
return !result.failed && result.stdout.trim() === "true";
|
|
37
|
+
}
|
|
38
|
+
export async function findGitRoot(cwd) {
|
|
39
|
+
const result = await runGit(cwd, ["rev-parse", "--show-toplevel"], { timeoutMs: 5_000 });
|
|
40
|
+
if (result.failed)
|
|
41
|
+
return null;
|
|
42
|
+
const root = result.stdout.trim();
|
|
43
|
+
if (!root)
|
|
44
|
+
return null;
|
|
45
|
+
return path.resolve(root);
|
|
46
|
+
}
|
|
47
|
+
/** Capture a non-invasive baseline of the git working tree. */
|
|
48
|
+
export async function captureGitBaseline(cwd) {
|
|
49
|
+
const inside = await isGitRepository(cwd);
|
|
50
|
+
if (!inside)
|
|
51
|
+
return null;
|
|
52
|
+
const headResult = await runGit(cwd, ["rev-parse", "HEAD"], { timeoutMs: 5_000 });
|
|
53
|
+
const head = headResult.failed ? null : headResult.stdout.trim() || null;
|
|
54
|
+
let stashRef = null;
|
|
55
|
+
const stashResult = await runGit(cwd, ["stash", "create"], { timeoutMs: 10_000 });
|
|
56
|
+
if (!stashResult.failed && stashResult.stdout.trim()) {
|
|
57
|
+
stashRef = stashResult.stdout.trim();
|
|
58
|
+
}
|
|
59
|
+
const untrackedResult = await runGit(cwd, ["ls-files", "--others", "--exclude-standard"], {
|
|
60
|
+
timeoutMs: 10_000,
|
|
61
|
+
});
|
|
62
|
+
const untracked = untrackedResult.failed
|
|
63
|
+
? []
|
|
64
|
+
: untrackedResult.stdout
|
|
65
|
+
.split("\n")
|
|
66
|
+
.map((line) => line.trim())
|
|
67
|
+
.filter(Boolean);
|
|
68
|
+
return {
|
|
69
|
+
head,
|
|
70
|
+
stashRef,
|
|
71
|
+
untracked,
|
|
72
|
+
unborn: head === null,
|
|
73
|
+
dirty: stashRef !== null,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
export function parseUnifiedDiff(patch) {
|
|
77
|
+
const files = [];
|
|
78
|
+
let current = null;
|
|
79
|
+
for (const line of patch.split("\n")) {
|
|
80
|
+
if (line.startsWith("diff --git ")) {
|
|
81
|
+
if (current)
|
|
82
|
+
files.push(current);
|
|
83
|
+
const parts = line.slice("diff --git ".length).trim().split(" ");
|
|
84
|
+
const bPath = parts.length >= 2 ? parts[parts.length - 1] : undefined;
|
|
85
|
+
const cleaned = bPath?.replace(/^b\//, "") ?? "unknown";
|
|
86
|
+
current = { file: cleaned, additions: 0, deletions: 0, status: "modified" };
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (!current)
|
|
90
|
+
continue;
|
|
91
|
+
if (line.startsWith("new file mode")) {
|
|
92
|
+
current.status = "added";
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (line.startsWith("deleted file mode")) {
|
|
96
|
+
current.status = "deleted";
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (line.startsWith("rename from ")) {
|
|
100
|
+
current.status = "renamed";
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (line.startsWith("rename to ")) {
|
|
104
|
+
current.file = line.slice("rename to ".length).trim();
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (line.startsWith("+++") || line.startsWith("---") || line.startsWith("@@"))
|
|
108
|
+
continue;
|
|
109
|
+
if (line.startsWith("+")) {
|
|
110
|
+
current.additions += 1;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (line.startsWith("-")) {
|
|
114
|
+
current.deletions += 1;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (current)
|
|
118
|
+
files.push(current);
|
|
119
|
+
return files;
|
|
120
|
+
}
|
|
121
|
+
async function newFilePatch(cwd, file) {
|
|
122
|
+
const result = await runGit(cwd, ["diff", "--no-color", "--no-ext-diff", "--no-index", "--", "/dev/null", file], {
|
|
123
|
+
timeoutMs: 15_000,
|
|
124
|
+
});
|
|
125
|
+
// `git diff --no-index` exits with code 1 when differences are found.
|
|
126
|
+
if (result.missing)
|
|
127
|
+
return "";
|
|
128
|
+
return result.stdout;
|
|
129
|
+
}
|
|
130
|
+
/** Compute the workspace diff between the recorded baseline and the current state. */
|
|
131
|
+
export async function diffSinceBaseline(cwd, baseline, options = {}) {
|
|
132
|
+
const maxPatchChars = options.maxPatchChars ?? 60_000;
|
|
133
|
+
const maxNewFiles = options.maxNewFiles ?? 40;
|
|
134
|
+
const notes = [];
|
|
135
|
+
const chunks = [];
|
|
136
|
+
const ref = baseline.stashRef ?? baseline.head;
|
|
137
|
+
if (ref) {
|
|
138
|
+
const result = await runGit(cwd, ["diff", "--no-color", "--no-ext-diff", ref, "--"], {
|
|
139
|
+
timeoutMs: 20_000,
|
|
140
|
+
});
|
|
141
|
+
if (result.failed) {
|
|
142
|
+
throw new BridgeError("OPENCODE_ERROR", `git diff failed: ${result.stderr.trim() || "unknown error"}`);
|
|
143
|
+
}
|
|
144
|
+
if (result.stdout.trim())
|
|
145
|
+
chunks.push(result.stdout);
|
|
146
|
+
}
|
|
147
|
+
else if (baseline.unborn) {
|
|
148
|
+
const tracked = await runGit(cwd, ["ls-files", "--cached", "--others", "--exclude-standard"], {
|
|
149
|
+
timeoutMs: 15_000,
|
|
150
|
+
});
|
|
151
|
+
if (!tracked.failed) {
|
|
152
|
+
const files = tracked.stdout
|
|
153
|
+
.split("\n")
|
|
154
|
+
.map((line) => line.trim())
|
|
155
|
+
.filter(Boolean)
|
|
156
|
+
.slice(0, maxNewFiles);
|
|
157
|
+
for (const file of files) {
|
|
158
|
+
const patch = await newFilePatch(cwd, file);
|
|
159
|
+
if (patch.trim())
|
|
160
|
+
chunks.push(patch);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
notes.push("Repository has no commits yet; every tracked file is reported as added.");
|
|
164
|
+
}
|
|
165
|
+
const untrackedNow = await runGit(cwd, ["ls-files", "--others", "--exclude-standard"], {
|
|
166
|
+
timeoutMs: 10_000,
|
|
167
|
+
});
|
|
168
|
+
if (!untrackedNow.failed) {
|
|
169
|
+
const baselineSet = new Set(baseline.untracked);
|
|
170
|
+
const newFiles = untrackedNow.stdout
|
|
171
|
+
.split("\n")
|
|
172
|
+
.map((line) => line.trim())
|
|
173
|
+
.filter((line) => line && !baselineSet.has(line));
|
|
174
|
+
if (newFiles.length > maxNewFiles) {
|
|
175
|
+
notes.push(`Only the first ${maxNewFiles} new untracked files are shown.`);
|
|
176
|
+
}
|
|
177
|
+
for (const file of newFiles.slice(0, maxNewFiles)) {
|
|
178
|
+
const patch = await newFilePatch(cwd, file);
|
|
179
|
+
if (patch.trim())
|
|
180
|
+
chunks.push(patch);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
let patch = chunks.join("\n");
|
|
184
|
+
let truncated = false;
|
|
185
|
+
if (patch.length > maxPatchChars) {
|
|
186
|
+
patch = `${patch.slice(0, maxPatchChars)}\n… [diff truncated at ${maxPatchChars} characters] …\n`;
|
|
187
|
+
truncated = true;
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
patch,
|
|
191
|
+
files: parseUnifiedDiff(patch),
|
|
192
|
+
truncated,
|
|
193
|
+
...(notes.length > 0 ? { note: notes.join(" ") } : {}),
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
export async function currentHead(cwd) {
|
|
197
|
+
const result = await runGit(cwd, ["rev-parse", "HEAD"], { timeoutMs: 5_000 });
|
|
198
|
+
if (result.failed)
|
|
199
|
+
return null;
|
|
200
|
+
return result.stdout.trim() || null;
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/util/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type LogLevel = "debug" | "info" | "warn" | "error" | "silent";
|
|
2
|
+
export interface LogFields {
|
|
3
|
+
[key: string]: unknown;
|
|
4
|
+
}
|
|
5
|
+
export interface Logger {
|
|
6
|
+
readonly level: LogLevel;
|
|
7
|
+
debug(message: string, fields?: LogFields): void;
|
|
8
|
+
info(message: string, fields?: LogFields): void;
|
|
9
|
+
warn(message: string, fields?: LogFields): void;
|
|
10
|
+
error(message: string, fields?: LogFields): void;
|
|
11
|
+
child(bindings: LogFields): Logger;
|
|
12
|
+
}
|
|
13
|
+
export declare function parseLogLevel(value: string | undefined, fallback?: LogLevel): LogLevel;
|
|
14
|
+
export interface CreateLoggerOptions {
|
|
15
|
+
level?: LogLevel;
|
|
16
|
+
file?: string | null;
|
|
17
|
+
bindings?: LogFields;
|
|
18
|
+
}
|
|
19
|
+
export declare function createLogger(options?: CreateLoggerOptions): Logger;
|
|
20
|
+
export declare function defaultLogFile(): string;
|
|
21
|
+
export declare function stateDirectory(): string;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
const LEVELS = {
|
|
5
|
+
debug: 10,
|
|
6
|
+
info: 20,
|
|
7
|
+
warn: 30,
|
|
8
|
+
error: 40,
|
|
9
|
+
silent: 100,
|
|
10
|
+
};
|
|
11
|
+
const MAX_LOG_BYTES = 5 * 1024 * 1024;
|
|
12
|
+
export function parseLogLevel(value, fallback = "info") {
|
|
13
|
+
if (!value)
|
|
14
|
+
return fallback;
|
|
15
|
+
const normalized = value.trim().toLowerCase();
|
|
16
|
+
if (normalized in LEVELS)
|
|
17
|
+
return normalized;
|
|
18
|
+
return fallback;
|
|
19
|
+
}
|
|
20
|
+
const SENSITIVE_KEY_PATTERN = /(pass(word|phrase)?|secret|token|authorization|api[-_]?key|credential|private[-_]?key)/i;
|
|
21
|
+
/** Never let credentials reach stderr or the log file, even by accident. */
|
|
22
|
+
function redactValue(key, value) {
|
|
23
|
+
if (SENSITIVE_KEY_PATTERN.test(key))
|
|
24
|
+
return "[redacted]";
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
function formatFields(fields) {
|
|
28
|
+
if (!fields || Object.keys(fields).length === 0)
|
|
29
|
+
return "";
|
|
30
|
+
const parts = [];
|
|
31
|
+
for (const [key, rawValue] of Object.entries(fields)) {
|
|
32
|
+
if (rawValue === undefined)
|
|
33
|
+
continue;
|
|
34
|
+
const value = redactValue(key, rawValue);
|
|
35
|
+
let rendered;
|
|
36
|
+
if (typeof value === "string")
|
|
37
|
+
rendered = value;
|
|
38
|
+
else {
|
|
39
|
+
try {
|
|
40
|
+
rendered = JSON.stringify(value);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
rendered = String(value);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (rendered.length > 2000)
|
|
47
|
+
rendered = `${rendered.slice(0, 2000)}…`;
|
|
48
|
+
parts.push(`${key}=${rendered}`);
|
|
49
|
+
}
|
|
50
|
+
return parts.length > 0 ? ` ${parts.join(" ")}` : "";
|
|
51
|
+
}
|
|
52
|
+
class StderrLogger {
|
|
53
|
+
level;
|
|
54
|
+
bindings;
|
|
55
|
+
file;
|
|
56
|
+
constructor(level, bindings = {}, file = null) {
|
|
57
|
+
this.level = level;
|
|
58
|
+
this.bindings = bindings;
|
|
59
|
+
this.file = file;
|
|
60
|
+
}
|
|
61
|
+
child(bindings) {
|
|
62
|
+
return new StderrLogger(this.level, { ...this.bindings, ...bindings }, this.file);
|
|
63
|
+
}
|
|
64
|
+
write(level, message, fields) {
|
|
65
|
+
if (LEVELS[level] < LEVELS[this.level])
|
|
66
|
+
return;
|
|
67
|
+
const timestamp = new Date().toISOString();
|
|
68
|
+
const line = `[${timestamp}] [${level.toUpperCase()}] ${message}${formatFields({
|
|
69
|
+
...this.bindings,
|
|
70
|
+
...fields,
|
|
71
|
+
})}\n`;
|
|
72
|
+
try {
|
|
73
|
+
process.stderr.write(line);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// stderr can be closed during shutdown; ignore.
|
|
77
|
+
}
|
|
78
|
+
if (this.file)
|
|
79
|
+
this.writeFile(line);
|
|
80
|
+
}
|
|
81
|
+
writeFile(line) {
|
|
82
|
+
const file = this.file;
|
|
83
|
+
if (!file)
|
|
84
|
+
return;
|
|
85
|
+
try {
|
|
86
|
+
fs.mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 });
|
|
87
|
+
try {
|
|
88
|
+
const stat = fs.statSync(file);
|
|
89
|
+
if (stat.size > MAX_LOG_BYTES) {
|
|
90
|
+
fs.renameSync(file, `${file}.1`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// file does not exist yet
|
|
95
|
+
}
|
|
96
|
+
// 0o600 on creation: logs contain workspace paths and agent output.
|
|
97
|
+
fs.appendFileSync(file, line, { mode: 0o600 });
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// logging must never break the bridge
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
debug(message, fields) {
|
|
104
|
+
this.write("debug", message, fields);
|
|
105
|
+
}
|
|
106
|
+
info(message, fields) {
|
|
107
|
+
this.write("info", message, fields);
|
|
108
|
+
}
|
|
109
|
+
warn(message, fields) {
|
|
110
|
+
this.write("warn", message, fields);
|
|
111
|
+
}
|
|
112
|
+
error(message, fields) {
|
|
113
|
+
this.write("error", message, fields);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
export function createLogger(options = {}) {
|
|
117
|
+
const level = options.level ?? parseLogLevel(process.env.CLAUDE_OPENCODE_LOG, "info");
|
|
118
|
+
return new StderrLogger(level, options.bindings ?? {}, options.file ?? null);
|
|
119
|
+
}
|
|
120
|
+
export function defaultLogFile() {
|
|
121
|
+
return path.join(stateDirectory(), "bridge.log");
|
|
122
|
+
}
|
|
123
|
+
export function stateDirectory() {
|
|
124
|
+
const override = process.env.CLAUDE_OPENCODE_STATE_DIR;
|
|
125
|
+
if (override?.trim())
|
|
126
|
+
return path.resolve(override);
|
|
127
|
+
return path.join(os.homedir(), ".local", "state", "claude-opencode-mcp");
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/util/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,MAAM,MAAM,GAA6B;IACvC,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,EAAE;IACR,KAAK,EAAE,EAAE;IACT,MAAM,EAAE,GAAG;CACZ,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAetC,MAAM,UAAU,aAAa,CAAC,KAAyB,EAAE,WAAqB,MAAM;IAClF,IAAI,CAAC,KAAK;QAAE,OAAO,QAAQ,CAAC;IAC5B,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9C,IAAI,UAAU,IAAI,MAAM;QAAE,OAAO,UAAsB,CAAC;IACxD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,qBAAqB,GACzB,yFAAyF,CAAC;AAE5F,4EAA4E;AAC5E,SAAS,WAAW,CAAC,GAAW,EAAE,KAAc;IAC9C,IAAI,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,YAAY,CAAC;IACzD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,YAAY,CAAC,MAA6B;IACjD,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC3D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACrD,IAAI,QAAQ,KAAK,SAAS;YAAE,SAAS;QACrC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACzC,IAAI,QAAgB,CAAC;QACrB,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,QAAQ,GAAG,KAAK,CAAC;aAC3C,CAAC;YACJ,IAAI,CAAC;gBACH,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACnC,CAAC;YAAC,MAAM,CAAC;gBACP,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,GAAG,IAAI;YAAE,QAAQ,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC;QACrE,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,QAAQ,EAAE,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACvD,CAAC;AAED,MAAM,YAAY;IACP,KAAK,CAAW;IACR,QAAQ,CAAY;IACpB,IAAI,CAAgB;IAErC,YAAY,KAAe,EAAE,WAAsB,EAAE,EAAE,OAAsB,IAAI;QAC/E,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,QAAmB;QACvB,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,QAAQ,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACpF,CAAC;IAEO,KAAK,CAAC,KAAkC,EAAE,OAAe,EAAE,MAAkB;QACnF,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO;QAC/C,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,IAAI,SAAS,MAAM,KAAK,CAAC,WAAW,EAAE,KAAK,OAAO,GAAG,YAAY,CAAC;YAC7E,GAAG,IAAI,CAAC,QAAQ;YAChB,GAAG,MAAM;SACV,CAAC,IAAI,CAAC;QACP,IAAI,CAAC;YACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,gDAAgD;QAClD,CAAC;QACD,IAAI,IAAI,CAAC,IAAI;YAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAEO,SAAS,CAAC,IAAY;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,CAAC;YACH,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACnE,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC/B,IAAI,IAAI,CAAC,IAAI,GAAG,aAAa,EAAE,CAAC;oBAC9B,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC;gBACnC,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,0BAA0B;YAC5B,CAAC;YACD,oEAAoE;YACpE,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC;YACP,sCAAsC;QACxC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,MAAkB;QACvC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,MAAkB;QACtC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,MAAkB;QACtC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,MAAkB;QACvC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;CACF;AAQD,MAAM,UAAU,YAAY,CAAC,UAA+B,EAAE;IAC5D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;IACtF,OAAO,IAAI,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,YAAY,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC;IACvD,IAAI,QAAQ,EAAE,IAAI,EAAE;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpD,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,qBAAqB,CAAC,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Finding } from "../types/index.js";
|
|
2
|
+
export declare function stripAnsi(text: string): string;
|
|
3
|
+
export interface TruncateResult {
|
|
4
|
+
text: string;
|
|
5
|
+
truncated: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function truncate(text: string, maxChars: number): TruncateResult;
|
|
8
|
+
export declare function oneLine(text: string, maxChars?: number): string;
|
|
9
|
+
export declare function extractFindings(text: string, maxFindings?: number): Finding[];
|
|
10
|
+
export declare function summarizeText(text: string, maxChars: number): string;
|
|
11
|
+
export declare function requestId(): string;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
const ESCAPE = String.fromCharCode(27);
|
|
2
|
+
const ANSI_PATTERN = new RegExp(`${ESCAPE}\\[[0-9;]*[A-Za-z]`, "g");
|
|
3
|
+
export function stripAnsi(text) {
|
|
4
|
+
return text.replace(ANSI_PATTERN, "");
|
|
5
|
+
}
|
|
6
|
+
export function truncate(text, maxChars) {
|
|
7
|
+
if (maxChars <= 0 || text.length <= maxChars) {
|
|
8
|
+
return { text, truncated: false };
|
|
9
|
+
}
|
|
10
|
+
const head = Math.max(0, maxChars - 200);
|
|
11
|
+
const tail = Math.max(0, Math.min(120, Math.floor(maxChars / 20)));
|
|
12
|
+
const omitted = text.length - head - tail;
|
|
13
|
+
const marker = `\n\n… [truncated ${omitted} characters] …\n\n`;
|
|
14
|
+
return {
|
|
15
|
+
text: `${text.slice(0, head)}${marker}${tail > 0 ? text.slice(-tail) : ""}`,
|
|
16
|
+
truncated: true,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function oneLine(text, maxChars = 300) {
|
|
20
|
+
const collapsed = text.replace(/\s+/g, " ").trim();
|
|
21
|
+
return collapsed.length > maxChars ? `${collapsed.slice(0, maxChars)}…` : collapsed;
|
|
22
|
+
}
|
|
23
|
+
const FINDINGS_HEADING = /^#{1,6}\s*(findings?|issues?|bugs?|risks?|problems?)\b.*$/im;
|
|
24
|
+
const ANY_HEADING = /^#{1,6}\s+(.+?)\s*$/gm;
|
|
25
|
+
function sectionsFromMarkdown(text) {
|
|
26
|
+
const sections = [];
|
|
27
|
+
const matches = [...text.matchAll(ANY_HEADING)];
|
|
28
|
+
for (let index = 0; index < matches.length; index += 1) {
|
|
29
|
+
const match = matches[index];
|
|
30
|
+
if (!match)
|
|
31
|
+
continue;
|
|
32
|
+
const title = (match[1] ?? "").trim();
|
|
33
|
+
const start = (match.index ?? 0) + match[0].length;
|
|
34
|
+
const next = matches[index + 1];
|
|
35
|
+
const end = next && next.index !== undefined ? next.index : text.length;
|
|
36
|
+
sections.push({ title, body: text.slice(start, end).trim() });
|
|
37
|
+
}
|
|
38
|
+
return sections;
|
|
39
|
+
}
|
|
40
|
+
export function extractFindings(text, maxFindings = 50) {
|
|
41
|
+
if (!text)
|
|
42
|
+
return [];
|
|
43
|
+
const sections = sectionsFromMarkdown(text);
|
|
44
|
+
const target = sections.find((section) => /^(findings?|issues?|bugs?|risks?|problems?)\b/i.test(section.title));
|
|
45
|
+
if (!target && !FINDINGS_HEADING.test(text))
|
|
46
|
+
return [];
|
|
47
|
+
const body = target ? target.body : "";
|
|
48
|
+
const findings = [];
|
|
49
|
+
for (const rawLine of body.split("\n")) {
|
|
50
|
+
const line = rawLine.trim();
|
|
51
|
+
if (!line)
|
|
52
|
+
continue;
|
|
53
|
+
const bullet = line.match(/^[-*+]\s+(.*)$/) ?? line.match(/^\d+[.)]\s+(.*)$/);
|
|
54
|
+
if (!bullet)
|
|
55
|
+
continue;
|
|
56
|
+
const item = (bullet[1] ?? "").trim();
|
|
57
|
+
if (!item)
|
|
58
|
+
continue;
|
|
59
|
+
let severity;
|
|
60
|
+
let rest = item;
|
|
61
|
+
const explicitSeverity = rest.match(/^\[(severity:\s*)?([a-z]+)\]\s*/i);
|
|
62
|
+
if (explicitSeverity) {
|
|
63
|
+
severity = explicitSeverity[2]?.toLowerCase();
|
|
64
|
+
rest = rest.slice(explicitSeverity[0].length);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
const prefix = rest.match(/^(critical|high|medium|low|info|warning|error)\s*[:—-]\s*/i);
|
|
68
|
+
if (prefix) {
|
|
69
|
+
severity = prefix[1]?.toLowerCase();
|
|
70
|
+
rest = rest.slice(prefix[0].length);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
let file;
|
|
74
|
+
let lineNumber;
|
|
75
|
+
const locationMatches = [...rest.matchAll(/\(([^()]+)\)/g)];
|
|
76
|
+
const locationMatch = locationMatches[locationMatches.length - 1];
|
|
77
|
+
if (locationMatch && locationMatch.index !== undefined) {
|
|
78
|
+
const inner = locationMatch[1] ?? "";
|
|
79
|
+
const withLine = inner.match(/^([\w@./\\-]+?):(\d+)(?::\d+)?$/);
|
|
80
|
+
if (withLine) {
|
|
81
|
+
file = withLine[1]?.trim();
|
|
82
|
+
lineNumber = Number.parseInt(withLine[2] ?? "", 10);
|
|
83
|
+
}
|
|
84
|
+
else if (/^[\w@./\\-]+\.[A-Za-z0-9]+(?::\d+)?$/.test(inner.trim())) {
|
|
85
|
+
const bare = inner.trim().match(/^([\w@./\\-]+?)(?::(\d+))?$/);
|
|
86
|
+
file = bare?.[1]?.trim();
|
|
87
|
+
lineNumber = bare?.[2] ? Number.parseInt(bare[2], 10) : undefined;
|
|
88
|
+
}
|
|
89
|
+
if (file) {
|
|
90
|
+
rest =
|
|
91
|
+
`${rest.slice(0, locationMatch.index)}${rest.slice(locationMatch.index + locationMatch[0].length)}`.trim();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const separator = rest.match(/^(.+?)\s+[—–-]\s+(.+)$/);
|
|
95
|
+
let title = rest;
|
|
96
|
+
let detail;
|
|
97
|
+
if (separator) {
|
|
98
|
+
title = separator[1]?.trim() ?? rest;
|
|
99
|
+
detail = separator[2]?.trim();
|
|
100
|
+
}
|
|
101
|
+
// Only bullets that carry a severity or a location are real findings;
|
|
102
|
+
// prose bullets such as "All good elsewhere" are left to the summary.
|
|
103
|
+
if (!severity && !file)
|
|
104
|
+
continue;
|
|
105
|
+
if (!title)
|
|
106
|
+
continue;
|
|
107
|
+
findings.push({
|
|
108
|
+
...(severity ? { severity } : {}),
|
|
109
|
+
title: title.slice(0, 500),
|
|
110
|
+
...(detail ? { detail: detail.slice(0, 2000) } : {}),
|
|
111
|
+
...(file ? { file } : {}),
|
|
112
|
+
...(lineNumber !== undefined && !Number.isNaN(lineNumber) ? { line: lineNumber } : {}),
|
|
113
|
+
});
|
|
114
|
+
if (findings.length >= maxFindings)
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
return findings;
|
|
118
|
+
}
|
|
119
|
+
export function summarizeText(text, maxChars) {
|
|
120
|
+
const cleaned = stripAnsi(text).trim();
|
|
121
|
+
return truncate(cleaned, maxChars).text;
|
|
122
|
+
}
|
|
123
|
+
export function requestId() {
|
|
124
|
+
return `req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/util/text.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ProfileCapabilities } from "../security/policy.js";
|
|
2
|
+
import type { AgentWorkspace } from "../types/index.js";
|
|
3
|
+
export interface TaskContextInput {
|
|
4
|
+
workspace: AgentWorkspace;
|
|
5
|
+
task: string;
|
|
6
|
+
hints: string[];
|
|
7
|
+
capabilities: ProfileCapabilities;
|
|
8
|
+
agentName: string;
|
|
9
|
+
/** Compact context is used for follow-up messages inside an existing session. */
|
|
10
|
+
compact?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare function buildTaskPrompt(input: TaskContextInput): string;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
function permissionLines(capabilities) {
|
|
2
|
+
return [
|
|
3
|
+
`- file edits: ${capabilities.canEdit ? "allowed" : "denied"}`,
|
|
4
|
+
`- shell commands: ${capabilities.canRunBash ? "allowed" : "denied"}`,
|
|
5
|
+
`- read-only agent: ${capabilities.readOnly ? "yes" : "no"}`,
|
|
6
|
+
].join("\n");
|
|
7
|
+
}
|
|
8
|
+
function instructionLines(capabilities) {
|
|
9
|
+
const lines = [
|
|
10
|
+
"- Work inside the specified workspace; do not read or write outside it.",
|
|
11
|
+
"- Inspect additional files and directories whenever that helps the task.",
|
|
12
|
+
"- Do not assume relevant code exists only under the supplied path hints.",
|
|
13
|
+
"- Your final message is consumed by an orchestrating agent: be concise, factual and specific.",
|
|
14
|
+
];
|
|
15
|
+
if (!capabilities.canEdit) {
|
|
16
|
+
lines.push("- You are read-only: do not modify any file, even through shell commands.");
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
lines.push("- Keep changes minimal and focused; run the relevant tests or checks when possible.");
|
|
20
|
+
lines.push("- Never run `git commit`, `git push`, or any other git command that rewrites history.");
|
|
21
|
+
}
|
|
22
|
+
if (capabilities.canRunBash && !capabilities.canEdit) {
|
|
23
|
+
lines.push("- Only run commands needed for inspection, building or testing; never write files.");
|
|
24
|
+
}
|
|
25
|
+
return lines.join("\n");
|
|
26
|
+
}
|
|
27
|
+
export function buildTaskPrompt(input) {
|
|
28
|
+
const { workspace, task, hints, capabilities, agentName } = input;
|
|
29
|
+
const hintLines = hints.length > 0
|
|
30
|
+
? hints.map((hint) => `- ${hint}`).join("\n")
|
|
31
|
+
: "- none supplied; discover the relevant files yourself";
|
|
32
|
+
if (input.compact) {
|
|
33
|
+
return [
|
|
34
|
+
`Workspace: ${workspace.cwd}`,
|
|
35
|
+
workspace.gitRoot ? `Git root: ${workspace.gitRoot}` : null,
|
|
36
|
+
`Agent: ${agentName}`,
|
|
37
|
+
"",
|
|
38
|
+
"Task:",
|
|
39
|
+
task,
|
|
40
|
+
"",
|
|
41
|
+
"Constraints:",
|
|
42
|
+
permissionLines(capabilities),
|
|
43
|
+
]
|
|
44
|
+
.filter((line) => line !== null)
|
|
45
|
+
.join("\n");
|
|
46
|
+
}
|
|
47
|
+
return [
|
|
48
|
+
"Workspace:",
|
|
49
|
+
workspace.cwd,
|
|
50
|
+
workspace.gitRoot ? `Git root: ${workspace.gitRoot}` : "Git root: (not a git repository)",
|
|
51
|
+
"",
|
|
52
|
+
`Agent: ${agentName}`,
|
|
53
|
+
"",
|
|
54
|
+
"Task:",
|
|
55
|
+
task,
|
|
56
|
+
"",
|
|
57
|
+
"Relevant paths (starting points only, not a boundary):",
|
|
58
|
+
hintLines,
|
|
59
|
+
"",
|
|
60
|
+
"Permissions:",
|
|
61
|
+
permissionLines(capabilities),
|
|
62
|
+
"",
|
|
63
|
+
"Instructions:",
|
|
64
|
+
instructionLines(capabilities),
|
|
65
|
+
].join("\n");
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=context.js.map
|