@arnilo/prism-coding-agent 0.0.8 → 0.0.11
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 +37 -6
- package/README.md +22 -7
- package/dist/artifacts.d.ts +6 -0
- package/dist/artifacts.js +35 -0
- package/dist/ask-user-decision.d.ts +160 -0
- package/dist/ask-user-decision.js +471 -0
- package/dist/checks.d.ts +26 -0
- package/dist/checks.js +249 -0
- package/dist/coding-checkpoint.d.ts +159 -0
- package/dist/coding-checkpoint.js +576 -0
- package/dist/git-exec.d.ts +62 -0
- package/dist/git-exec.js +257 -0
- package/dist/git-status.d.ts +30 -0
- package/dist/git-status.js +146 -0
- package/dist/git-tools.d.ts +34 -0
- package/dist/git-tools.js +502 -0
- package/dist/git.d.ts +139 -0
- package/dist/git.js +495 -0
- package/dist/goal-verify.d.ts +66 -0
- package/dist/goal-verify.js +283 -0
- package/dist/index.d.ts +40 -4
- package/dist/index.js +43 -5
- package/dist/limits.d.ts +76 -0
- package/dist/limits.js +81 -0
- package/dist/list.d.ts +14 -0
- package/dist/list.js +144 -0
- package/dist/repository.d.ts +119 -0
- package/dist/repository.js +633 -0
- package/dist/search.d.ts +14 -0
- package/dist/search.js +166 -0
- package/package.json +8 -5
package/dist/search.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { enforceExecutionPolicy } from "./execution-policy.js";
|
|
2
|
+
import { HARD_MAX_SEARCH_CONTEXT_LINES, HARD_MAX_SEARCH_MATCHES, validateCodingLimit, validateCodingLimitAllowZero, } from "./limits.js";
|
|
3
|
+
import { createLocalRepositoryOperations, resolveRepositoryLimits, RepositoryError, } from "./repository.js";
|
|
4
|
+
import { truncateLine } from "./truncate.js";
|
|
5
|
+
function errorResult(toolCallId, message) {
|
|
6
|
+
return {
|
|
7
|
+
toolCallId,
|
|
8
|
+
name: "repo_search",
|
|
9
|
+
content: [{ type: "text", text: message }],
|
|
10
|
+
error: { message },
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function formatMatch(match) {
|
|
14
|
+
const lines = [];
|
|
15
|
+
for (const before of match.before) {
|
|
16
|
+
const { text } = truncateLine(before, 500);
|
|
17
|
+
lines.push(`${match.path}-${text}`);
|
|
18
|
+
}
|
|
19
|
+
const { text } = truncateLine(match.text, 500);
|
|
20
|
+
lines.push(`${match.path}:${match.line}:${match.column}:${text}`);
|
|
21
|
+
for (const after of match.after) {
|
|
22
|
+
const truncated = truncateLine(after, 500);
|
|
23
|
+
lines.push(`${match.path}+${truncated.text}`);
|
|
24
|
+
}
|
|
25
|
+
return lines.join("\n");
|
|
26
|
+
}
|
|
27
|
+
function formatSearchText(result) {
|
|
28
|
+
if (result.matches.length === 0) {
|
|
29
|
+
return result.truncated
|
|
30
|
+
? `[truncated by ${result.truncatedBy ?? "limit"} before any matches]`
|
|
31
|
+
: "(no matches)";
|
|
32
|
+
}
|
|
33
|
+
const body = result.matches.map(formatMatch).join("\n");
|
|
34
|
+
if (!result.truncated)
|
|
35
|
+
return body;
|
|
36
|
+
return `${body}\n[truncated by ${result.truncatedBy ?? "limit"}]`;
|
|
37
|
+
}
|
|
38
|
+
export function createRepoSearchTool(cwd, options) {
|
|
39
|
+
const limits = resolveRepositoryLimits({
|
|
40
|
+
...options?.repository,
|
|
41
|
+
maxMatches: options?.maxMatches ?? options?.repository?.maxMatches,
|
|
42
|
+
maxContextLines: options?.maxContextLines ?? options?.repository?.maxContextLines,
|
|
43
|
+
exclude: options?.exclude ?? options?.repository?.exclude,
|
|
44
|
+
});
|
|
45
|
+
const ops = options?.operations ?? createLocalRepositoryOperations(limits);
|
|
46
|
+
return {
|
|
47
|
+
name: "repo_search",
|
|
48
|
+
description: `Search text files under the workspace. Default mode is literal substring match; set mode=regex for bounded regular expressions. Skips binary files, excluded basenames (default: ${limits.exclude.join(", ")}), and hidden names unless includeHidden is true. Does not follow symlinks. Caps matches/scanned bytes/time.`,
|
|
49
|
+
parameters: {
|
|
50
|
+
type: "object",
|
|
51
|
+
properties: {
|
|
52
|
+
query: { type: "string", description: "Literal text or regular expression to search for (required)" },
|
|
53
|
+
path: {
|
|
54
|
+
type: "string",
|
|
55
|
+
description: "Workspace-relative directory or file to search (default: workspace root)",
|
|
56
|
+
},
|
|
57
|
+
mode: {
|
|
58
|
+
type: "string",
|
|
59
|
+
description: 'Search mode: "literal" (default) or "regex"',
|
|
60
|
+
enum: ["literal", "regex"],
|
|
61
|
+
},
|
|
62
|
+
caseSensitive: {
|
|
63
|
+
type: "boolean",
|
|
64
|
+
description: "Case-sensitive matching (default false)",
|
|
65
|
+
},
|
|
66
|
+
includeHidden: {
|
|
67
|
+
type: "boolean",
|
|
68
|
+
description: "Include dotfile/dotdir names (default false)",
|
|
69
|
+
},
|
|
70
|
+
context: {
|
|
71
|
+
type: "number",
|
|
72
|
+
description: `Context lines before/after each match (default ${limits.maxContextLines}, hard ${HARD_MAX_SEARCH_CONTEXT_LINES})`,
|
|
73
|
+
},
|
|
74
|
+
maxMatches: {
|
|
75
|
+
type: "number",
|
|
76
|
+
description: `Maximum matches to retain (default ${limits.maxMatches}, hard ${HARD_MAX_SEARCH_MATCHES})`,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
required: ["query"],
|
|
80
|
+
additionalProperties: false,
|
|
81
|
+
},
|
|
82
|
+
async execute(args, context) {
|
|
83
|
+
const toolCallId = context.toolCallId;
|
|
84
|
+
if (context.signal?.aborted)
|
|
85
|
+
return errorResult(toolCallId, "Operation aborted");
|
|
86
|
+
const query = typeof args.query === "string" ? args.query : "";
|
|
87
|
+
if (query.length === 0)
|
|
88
|
+
return errorResult(toolCallId, "query is required and must be a non-empty string.");
|
|
89
|
+
const path = typeof args.path === "string" ? args.path : undefined;
|
|
90
|
+
const mode = args.mode === "regex" ? "regex" : "literal";
|
|
91
|
+
const caseSensitive = args.caseSensitive === true;
|
|
92
|
+
const includeHidden = args.includeHidden === true;
|
|
93
|
+
let contextLines;
|
|
94
|
+
let maxMatches;
|
|
95
|
+
try {
|
|
96
|
+
if (args.context !== undefined) {
|
|
97
|
+
contextLines = validateCodingLimitAllowZero("context", args.context, HARD_MAX_SEARCH_CONTEXT_LINES);
|
|
98
|
+
}
|
|
99
|
+
if (args.maxMatches !== undefined) {
|
|
100
|
+
maxMatches = validateCodingLimit("maxMatches", args.maxMatches, HARD_MAX_SEARCH_MATCHES);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
return errorResult(toolCallId, error instanceof Error ? error.message : String(error));
|
|
105
|
+
}
|
|
106
|
+
const policyCheck = await enforceExecutionPolicy(options?.executionPolicy, {
|
|
107
|
+
kind: "repo_search",
|
|
108
|
+
operation: "search",
|
|
109
|
+
paths: [path ? path : cwd],
|
|
110
|
+
risk: "low",
|
|
111
|
+
metadata: {
|
|
112
|
+
mode,
|
|
113
|
+
caseSensitive,
|
|
114
|
+
includeHidden,
|
|
115
|
+
context: contextLines,
|
|
116
|
+
maxMatches,
|
|
117
|
+
sessionId: context.sessionId,
|
|
118
|
+
runId: context.runId,
|
|
119
|
+
signal: context.signal,
|
|
120
|
+
},
|
|
121
|
+
}, toolCallId, "repo_search");
|
|
122
|
+
if (!policyCheck.allowed)
|
|
123
|
+
return policyCheck.result;
|
|
124
|
+
try {
|
|
125
|
+
const result = await ops.search({
|
|
126
|
+
root: cwd,
|
|
127
|
+
query,
|
|
128
|
+
path,
|
|
129
|
+
mode,
|
|
130
|
+
caseSensitive,
|
|
131
|
+
includeHidden,
|
|
132
|
+
exclude: limits.exclude,
|
|
133
|
+
context: contextLines ?? limits.maxContextLines,
|
|
134
|
+
maxMatches: maxMatches ?? limits.maxMatches,
|
|
135
|
+
signal: context.signal,
|
|
136
|
+
deadlineMs: limits.maxTimeMs,
|
|
137
|
+
});
|
|
138
|
+
return {
|
|
139
|
+
toolCallId,
|
|
140
|
+
name: "repo_search",
|
|
141
|
+
content: [{ type: "text", text: formatSearchText(result) }],
|
|
142
|
+
metadata: {
|
|
143
|
+
truncated: result.truncated,
|
|
144
|
+
truncatedBy: result.truncatedBy,
|
|
145
|
+
matchCount: result.matches.length,
|
|
146
|
+
scannedBytes: result.scannedBytes,
|
|
147
|
+
scannedFiles: result.scannedFiles,
|
|
148
|
+
scannedEntries: result.scannedEntries,
|
|
149
|
+
filesSkippedBinary: result.filesSkippedBinary,
|
|
150
|
+
filesSkippedOversize: result.filesSkippedOversize,
|
|
151
|
+
matches: result.matches,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
const message = error instanceof RepositoryError
|
|
157
|
+
? error.message
|
|
158
|
+
: error instanceof Error
|
|
159
|
+
? error.message
|
|
160
|
+
: String(error);
|
|
161
|
+
return errorResult(toolCallId, message);
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=search.js.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arnilo/prism-coding-agent",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Optional coding-agent tools (shell, read, write, edit) package for Prism.",
|
|
3
|
+
"version": "0.0.11",
|
|
4
|
+
"description": "Optional coding-agent tools (shell, read, write, edit, repo_list, repo_search, opt-in Git/check/ask-user-decision, and durable plan/checkpoint helpers) package for Prism.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -25,13 +25,16 @@
|
|
|
25
25
|
"pack:dry-run": "npm pack --dry-run"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"diff": "^
|
|
28
|
+
"diff": "^9.0.0"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
|
-
"@arnilo/prism": "0.0.
|
|
31
|
+
"@arnilo/prism": "0.0.11",
|
|
32
|
+
"@arnilo/prism-workflows": "0.0.11"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|
|
34
|
-
"@arnilo/prism": "file:../.."
|
|
35
|
+
"@arnilo/prism": "file:../..",
|
|
36
|
+
"@arnilo/prism-evals": "file:../evals",
|
|
37
|
+
"@arnilo/prism-workflows": "file:../workflows"
|
|
35
38
|
},
|
|
36
39
|
"engines": {
|
|
37
40
|
"node": ">=20"
|