@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.
@@ -0,0 +1,283 @@
1
+ import { defineWorkflow, functionNode, resumeWorkflow, runWorkflow, suspend, } from "@arnilo/prism-workflows";
2
+ import { CODING_STATE_KEY, assertCodingResumeAllowed, buildCodingCheckpointMetadata, codingCheckpointStatePatch, codingPlanPathForTask, createCodingPlanMarkdown, fingerprintJson, parseCodingPlanTodos, readCodingCheckpointFromState, readCodingPlanFile, writeCodingPlanFile, } from "./coding-checkpoint.js";
3
+ import { DEFAULT_MAX_CHECK_SUMMARY_BYTES, DEFAULT_MAX_PR_HANDOFF_BYTES } from "./limits.js";
4
+ export const CODING_GOAL_VERIFY_WORKFLOW_ID = "coding-goal-verify";
5
+ export const CODING_GOAL_VERIFY_REVISION = "1";
6
+ export const CODING_GOAL_VERIFY_SUSPEND_REASON = "approve-coding-goal-verify";
7
+ export class CodingGoalVerifyError extends Error {
8
+ code = "ERR_PRISM_CODING_GOAL_VERIFY";
9
+ constructor(message) {
10
+ super(message);
11
+ this.name = "CodingGoalVerifyError";
12
+ }
13
+ }
14
+ function requireCoding(state) {
15
+ const coding = readCodingCheckpointFromState(state);
16
+ if (!coding)
17
+ throw new CodingGoalVerifyError("missing state.coding");
18
+ return coding;
19
+ }
20
+ function clipSummary(summary) {
21
+ const max = DEFAULT_MAX_CHECK_SUMMARY_BYTES;
22
+ const bytes = Buffer.from(summary, "utf8");
23
+ if (bytes.length <= max)
24
+ return summary;
25
+ return bytes.subarray(0, max).toString("utf8");
26
+ }
27
+ function normalizeChecks(checks) {
28
+ return checks.map((check) => ({
29
+ name: check.name,
30
+ exitCode: check.exitCode,
31
+ summary: clipSummary(check.summary),
32
+ }));
33
+ }
34
+ function assertHandoffBounded(handoff) {
35
+ const encoded = Buffer.byteLength(JSON.stringify(handoff), "utf8");
36
+ if (encoded > DEFAULT_MAX_PR_HANDOFF_BYTES) {
37
+ throw new CodingGoalVerifyError(`handoff exceeds ${DEFAULT_MAX_PR_HANDOFF_BYTES} byte limit (${encoded} bytes)`);
38
+ }
39
+ }
40
+ function fingerprintsFor(checks) {
41
+ return {
42
+ workflowRevision: CODING_GOAL_VERIFY_REVISION,
43
+ toolFingerprint: fingerprintJson({ tools: ["coding_check", "git_pr_handoff"], checks }),
44
+ policyFingerprint: fingerprintJson({ requireApproval: [CODING_GOAL_VERIFY_SUSPEND_REASON] }),
45
+ };
46
+ }
47
+ function defaultTodos(checkNames) {
48
+ return [
49
+ { id: "plan", text: "Write goal plan Markdown", done: false },
50
+ ...checkNames.map((name) => ({ id: `check-${name}`, text: `Run named check ${name}`, done: false })),
51
+ { id: "handoff", text: "Emit bounded PR handoff", done: false },
52
+ ];
53
+ }
54
+ function markTodos(todos, doneIds) {
55
+ return todos.map((todo) => (doneIds.has(todo.id) ? { ...todo, done: true } : todo));
56
+ }
57
+ /** Build the durable DAG used by `runCodingGoalVerify` (exported for hosts that want the definition alone). */
58
+ export function createCodingGoalVerifyWorkflow(options) {
59
+ const planPath = codingPlanPathForTask(options.taskId);
60
+ const fps = () => fingerprintsFor(options.checks);
61
+ const planNode = functionNode({
62
+ execute: async (ctx) => {
63
+ const todos = defaultTodos(options.checks);
64
+ const markdown = createCodingPlanMarkdown({
65
+ title: options.title,
66
+ taskId: options.taskId,
67
+ status: "planned",
68
+ todos,
69
+ notes: options.goal,
70
+ });
71
+ const plan = await writeCodingPlanFile({
72
+ workspaceRoot: options.cwd,
73
+ planPath,
74
+ markdown,
75
+ });
76
+ const metadata = buildCodingCheckpointMetadata({
77
+ taskId: options.taskId,
78
+ workspaceRoot: options.cwd,
79
+ baseBranch: options.baseBranch,
80
+ branch: options.branch,
81
+ planPath,
82
+ plan,
83
+ fingerprints: fps(),
84
+ todos: parseCodingPlanTodos(markdown),
85
+ status: "planned",
86
+ });
87
+ await ctx.updateState(codingCheckpointStatePatch(metadata), { mode: "merge" });
88
+ return { planPath, planSha256: plan.sha256 };
89
+ },
90
+ });
91
+ const verifyNode = functionNode({
92
+ execute: async (ctx) => {
93
+ const coding = requireCoding(ctx.state);
94
+ const checks = normalizeChecks(await Promise.all(options.checks.map((name) => options.runCheck(name))));
95
+ const failed = checks.some((check) => check.exitCode !== 0);
96
+ const done = new Set([
97
+ "plan",
98
+ ...options.checks.map((name) => `check-${name}`),
99
+ ]);
100
+ const todos = markTodos(coding.todos.length ? coding.todos : defaultTodos(options.checks), done);
101
+ const markdown = createCodingPlanMarkdown({
102
+ title: options.title,
103
+ taskId: options.taskId,
104
+ status: failed ? "awaiting_approval" : "ready_for_handoff",
105
+ todos,
106
+ notes: options.goal,
107
+ });
108
+ const plan = await writeCodingPlanFile({
109
+ workspaceRoot: options.cwd,
110
+ planPath,
111
+ markdown,
112
+ });
113
+ const next = buildCodingCheckpointMetadata({
114
+ ...coding,
115
+ plan,
116
+ checks,
117
+ todos: parseCodingPlanTodos(markdown),
118
+ status: failed ? "awaiting_approval" : "ready_for_handoff",
119
+ fingerprints: fps(),
120
+ updatedAt: new Date().toISOString(),
121
+ });
122
+ await ctx.updateState(codingCheckpointStatePatch(next), { mode: "merge" });
123
+ return { checks, failed };
124
+ },
125
+ });
126
+ const reviewNode = functionNode({
127
+ execute: async (ctx) => {
128
+ const coding = requireCoding(ctx.state);
129
+ const failed = coding.checks.some((check) => check.exitCode !== 0);
130
+ if (!failed)
131
+ return { approved: true, skipped: true };
132
+ if (!ctx.resume) {
133
+ return suspend({
134
+ reason: options.suspendReason,
135
+ data: {
136
+ taskId: coding.taskId,
137
+ branch: coding.branch,
138
+ planSha256: coding.plan.sha256,
139
+ checks: coding.checks,
140
+ },
141
+ resumeSchema: {
142
+ type: "object",
143
+ required: ["reviewer"],
144
+ properties: { reviewer: { type: "string" } },
145
+ },
146
+ });
147
+ }
148
+ const reviewer = ctx.resume.input?.reviewer ?? "unknown";
149
+ return { approved: true, reviewer, planSha256: coding.plan.sha256 };
150
+ },
151
+ });
152
+ const handoffNode = functionNode({
153
+ execute: async (ctx) => {
154
+ const coding = requireCoding(ctx.state);
155
+ const planFile = await readCodingPlanFile({
156
+ workspaceRoot: options.cwd,
157
+ planPath: coding.planPath,
158
+ expected: coding.plan,
159
+ });
160
+ assertCodingResumeAllowed({
161
+ metadata: coding,
162
+ expected: fps(),
163
+ expectedWorkspaceRoot: options.cwd,
164
+ expectedBaseBranch: options.baseBranch,
165
+ planBytes: Buffer.from(planFile.markdown, "utf8"),
166
+ });
167
+ const handoff = await options.buildHandoff({ coding, checks: coding.checks });
168
+ assertHandoffBounded(handoff);
169
+ const todos = markTodos(coding.todos.length ? coding.todos : defaultTodos(options.checks), new Set(["plan", "handoff", ...options.checks.map((name) => `check-${name}`)]));
170
+ const markdown = createCodingPlanMarkdown({
171
+ title: options.title,
172
+ taskId: options.taskId,
173
+ status: "completed",
174
+ todos,
175
+ notes: options.goal,
176
+ });
177
+ const plan = await writeCodingPlanFile({
178
+ workspaceRoot: options.cwd,
179
+ planPath,
180
+ markdown,
181
+ });
182
+ const next = buildCodingCheckpointMetadata({
183
+ ...coding,
184
+ plan,
185
+ handoff,
186
+ todos: parseCodingPlanTodos(markdown),
187
+ status: "completed",
188
+ fingerprints: fps(),
189
+ updatedAt: new Date().toISOString(),
190
+ });
191
+ await ctx.updateState(codingCheckpointStatePatch(next), { mode: "merge" });
192
+ return { handoff, codingStatus: next.status };
193
+ },
194
+ });
195
+ return defineWorkflow({
196
+ revision: CODING_GOAL_VERIFY_REVISION,
197
+ id: CODING_GOAL_VERIFY_WORKFLOW_ID,
198
+ nodes: {
199
+ plan: planNode,
200
+ verify: verifyNode,
201
+ review: reviewNode,
202
+ handoff: handoffNode,
203
+ },
204
+ edges: [
205
+ ["plan", "verify"],
206
+ ["verify", "review"],
207
+ ["review", "handoff"],
208
+ ],
209
+ limits: { maxConcurrency: 1, maxStateBytes: 64 * 1024 },
210
+ });
211
+ }
212
+ /**
213
+ * Run (or resume) a thin goal→verify coding composition.
214
+ * Fails closed when `approval` / `approval.validateResume` is missing.
215
+ */
216
+ export async function runCodingGoalVerify(options) {
217
+ if (!options.approval?.validateResume) {
218
+ throw new CodingGoalVerifyError("approval.validateResume is required");
219
+ }
220
+ if (!Array.isArray(options.checks) || options.checks.length < 1) {
221
+ throw new CodingGoalVerifyError("checks must declare at least one named check");
222
+ }
223
+ for (const name of options.checks) {
224
+ if (typeof name !== "string" || !/^[A-Za-z][A-Za-z0-9_-]{0,63}$/.test(name)) {
225
+ throw new CodingGoalVerifyError(`invalid check name: ${String(name)}`);
226
+ }
227
+ }
228
+ if (typeof options.runCheck !== "function") {
229
+ throw new CodingGoalVerifyError("runCheck is required");
230
+ }
231
+ if (typeof options.buildHandoff !== "function") {
232
+ throw new CodingGoalVerifyError("buildHandoff is required");
233
+ }
234
+ if (typeof options.goal !== "string" || options.goal.trim().length < 1) {
235
+ throw new CodingGoalVerifyError("goal is required");
236
+ }
237
+ if (typeof options.cwd !== "string" || options.cwd.length < 1) {
238
+ throw new CodingGoalVerifyError("cwd is required");
239
+ }
240
+ const taskId = options.taskId ?? "goal";
241
+ const title = options.title ?? options.goal.slice(0, 120);
242
+ const baseBranch = options.baseBranch ?? "main";
243
+ const branch = options.branch ?? `codex/${taskId}`;
244
+ const suspendReason = options.approval.reason ?? CODING_GOAL_VERIFY_SUSPEND_REASON;
245
+ const workflow = createCodingGoalVerifyWorkflow({
246
+ goal: options.goal,
247
+ cwd: options.cwd,
248
+ taskId,
249
+ title,
250
+ baseBranch,
251
+ branch,
252
+ checks: options.checks,
253
+ runCheck: options.runCheck,
254
+ buildHandoff: options.buildHandoff,
255
+ suspendReason,
256
+ });
257
+ const validateState = async (input) => {
258
+ if (CODING_STATE_KEY in input.value) {
259
+ readCodingCheckpointFromState(input.value);
260
+ }
261
+ };
262
+ const shared = {
263
+ checkpoints: options.checkpoints,
264
+ redactor: options.redactor,
265
+ ownership: options.ownership,
266
+ validateState,
267
+ validateResume: options.approval.validateResume,
268
+ signal: options.signal,
269
+ onEvent: options.onEvent,
270
+ };
271
+ if (options.resume) {
272
+ return resumeWorkflow(workflow, { runId: options.resume.runId, workflowId: workflow.id }, {
273
+ ...shared,
274
+ resume: {
275
+ decision: options.resume.decision,
276
+ expectedVersion: options.resume.expectedVersion,
277
+ input: options.resume.input,
278
+ },
279
+ });
280
+ }
281
+ return runWorkflow(workflow, { goal: options.goal, baseBranch }, shared);
282
+ }
283
+ //# sourceMappingURL=goal-verify.js.map
package/dist/index.d.ts CHANGED
@@ -6,14 +6,36 @@ export { createWriteTool } from "./write.js";
6
6
  export type { WriteToolOptions, WriteOperations } from "./write.js";
7
7
  export { createEditTool } from "./edit.js";
8
8
  export type { EditToolOptions, EditOperations, EditToolDetails, Edit } from "./edit.js";
9
+ export { createRepoListTool } from "./list.js";
10
+ export type { ListToolOptions } from "./list.js";
11
+ export { createRepoSearchTool } from "./search.js";
12
+ export type { SearchToolOptions } from "./search.js";
13
+ export { createLocalRepositoryOperations, resolveRepositoryLimits, compileSearchPattern, isBinaryBuffer, resolveRepoPath, toRepoRelative, RepositoryError, DEFAULT_REPO_EXCLUDE, } from "./repository.js";
14
+ export type { RepoEntryKind, RepoListEntry, RepositoryListRequest, RepositoryListResult, RepositorySearchMatch, RepositorySearchRequest, RepositorySearchResult, RepositoryOperations, RepositoryLimitOptions, ResolvedRepositoryLimits, } from "./repository.js";
15
+ export { createGitOperations, resolveGitLimits, parsePorcelainV2, GitError, SAFE_GIT_ENV, SAFE_GIT_CONFIG_ARGS, createBoundGitRunner, runGitCli, } from "./git.js";
16
+ export type { GitOperations, GitLimitOptions, ResolvedGitLimits, ArtifactReference, ArtifactWriter, PrHandoff, CreateGitOperationsOptions, GitStatusResult, GitStatusEntry, GitStatusBranch, GitStatusEntryKind, GitRunner, GitExecRequest, GitExecResult, BoundGitRunner, CreateGitRunnerOptions, } from "./git.js";
17
+ export { createGitTools, createGitStatusTool, createGitDiffTool, createGitBranchTool, createGitWorktreeTool, createGitApplyTool, createGitCommitTool, createGitPrHandoffTool, } from "./git-tools.js";
18
+ export type { GitToolsOptions } from "./git-tools.js";
19
+ export { createCodingCheckTool } from "./checks.js";
20
+ export type { CodingCheckToolOptions, NamedCheckDefinition } from "./checks.js";
21
+ export { ASK_USER_DECISION_RATIONALE_COUNT, ASK_USER_DECISION_SUSPEND_REASON, ASK_USER_DECISION_TOOL_NAME, DEFAULT_MAX_ASK_USER_DECISION_BULLET_BYTES, DEFAULT_MAX_ASK_USER_DECISION_CUSTOM_BYTES, DEFAULT_MAX_ASK_USER_DECISION_LABEL_BYTES, DEFAULT_MAX_ASK_USER_DECISION_OPTIONS, DEFAULT_MAX_ASK_USER_DECISION_QUESTION_BYTES, HARD_MAX_ASK_USER_DECISION_BULLET_BYTES, HARD_MAX_ASK_USER_DECISION_CUSTOM_BYTES, HARD_MAX_ASK_USER_DECISION_LABEL_BYTES, HARD_MAX_ASK_USER_DECISION_OPTIONS, HARD_MAX_ASK_USER_DECISION_QUESTION_BYTES, askUserDecisionResumeSchema, createAskUserDecisionResumeValidator, createAskUserDecisionTool, parseAskUserDecisionArgs, resolveAskUserDecisionAnswer, resolveAskUserDecisionLimits, suspendAskUserDecision, toAskUserDecisionSuspendData, validateAskUserDecisionAgentResume, validateAskUserDecisionResume, } from "./ask-user-decision.js";
22
+ export type { AskUserDecisionAnswer, AskUserDecisionHandler, AskUserDecisionOption, AskUserDecisionRequest, AskUserDecisionSelectionMode, AskUserDecisionSuspendData, AskUserDecisionToolOptions, ResolvedAskUserDecisionAnswer, ResolvedAskUserDecisionLimits, SuspendAskUserDecisionOptions, } from "./ask-user-decision.js";
23
+ export { createDirectoryArtifactWriter, createTempArtifactWriter, sha256Hex } from "./artifacts.js";
24
+ export { CODING_CHECKPOINT_SCHEMA_VERSION, CODING_STATE_KEY, CodingCheckpointError, assertCodingResumeAllowed, buildCodingCheckpointMetadata, codingCheckpointStatePatch, codingPlanPathForTask, createCodingArtifactRef, createCodingPlanMarkdown, fingerprintJson, parseCodingPlanTodos, readCodingCheckpointFromState, readCodingPlanFile, resolveCodingCheckpointLimits, validateCodingCheckpointMetadata, verifyCodingArtifactBytes, writeCodingPlanFile, } from "./coding-checkpoint.js";
25
+ export type { CodingArtifactKind, CodingArtifactRef, CodingCheckSummary, CodingCheckpointLimitOptions, CodingCheckpointMetadata, CodingFingerprints, CodingHandoffSummary, CodingTaskStatus, CodingTodoItem, ResolvedCodingCheckpointLimits, } from "./coding-checkpoint.js";
26
+ export { CODING_GOAL_VERIFY_REVISION, CODING_GOAL_VERIFY_SUSPEND_REASON, CODING_GOAL_VERIFY_WORKFLOW_ID, CodingGoalVerifyError, createCodingGoalVerifyWorkflow, runCodingGoalVerify, } from "./goal-verify.js";
27
+ export type { CodingGoalVerifyApproval, RunCodingGoalVerifyOptions, } from "./goal-verify.js";
9
28
  export { withFileMutationQueue } from "./file-mutation-queue.js";
10
29
  export { enforceExecutionPolicy } from "./execution-policy.js";
11
- export { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_MAX_TEXT_SCAN_BYTES, DEFAULT_MAX_WRITE_BYTES, DEFAULT_MAX_EDIT_FILE_BYTES, DEFAULT_MAX_EDIT_INPUT_BYTES, DEFAULT_MAX_EDITS, DEFAULT_SHELL_TIMEOUT_SECONDS, DEFAULT_MAX_TOTAL_OUTPUT_BYTES, HARD_MAX_BYTES, HARD_MAX_LINES, HARD_MAX_TEXT_SCAN_BYTES, HARD_MAX_IMAGE_BYTES, HARD_MAX_WRITE_BYTES, HARD_MAX_EDIT_FILE_BYTES, HARD_MAX_EDIT_INPUT_BYTES, HARD_MAX_EDITS, HARD_SHELL_TIMEOUT_SECONDS, HARD_MAX_TOTAL_OUTPUT_BYTES, } from "./limits.js";
30
+ export { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_MAX_TEXT_SCAN_BYTES, DEFAULT_MAX_WRITE_BYTES, DEFAULT_MAX_EDIT_FILE_BYTES, DEFAULT_MAX_EDIT_INPUT_BYTES, DEFAULT_MAX_EDITS, DEFAULT_SHELL_TIMEOUT_SECONDS, DEFAULT_MAX_TOTAL_OUTPUT_BYTES, DEFAULT_MAX_REPO_DEPTH, DEFAULT_MAX_REPO_ENTRIES, DEFAULT_MAX_REPO_FILES, DEFAULT_MAX_REPO_RESULTS, DEFAULT_MAX_REPO_CONCURRENCY, DEFAULT_MAX_SEARCH_SCAN_BYTES, DEFAULT_MAX_SEARCH_FILE_BYTES, DEFAULT_MAX_SEARCH_MATCHES, DEFAULT_MAX_SEARCH_PATTERN_BYTES, DEFAULT_MAX_SEARCH_LINE_BYTES, DEFAULT_MAX_SEARCH_CONTEXT_LINES, DEFAULT_MAX_SEARCH_TIME_MS, DEFAULT_MAX_GIT_PATHS, DEFAULT_MAX_GIT_REF_BYTES, DEFAULT_MAX_GIT_MESSAGE_BYTES, DEFAULT_MAX_GIT_OUTPUT_BYTES, DEFAULT_MAX_GIT_DIFF_LINES, DEFAULT_MAX_GIT_CHANGED_FILES, DEFAULT_MAX_GIT_PATCH_BYTES, DEFAULT_MAX_GIT_WORKTREES, DEFAULT_GIT_TIMEOUT_MS, DEFAULT_MAX_CHECK_NAMES, DEFAULT_MAX_CHECK_CONCURRENCY, DEFAULT_CHECK_TIMEOUT_MS, DEFAULT_MAX_CHECK_DIAGNOSTIC_LINES, DEFAULT_MAX_CHECK_OUTPUT_BYTES, DEFAULT_MAX_PR_HANDOFF_BYTES, DEFAULT_MAX_PR_COMMITS, DEFAULT_MAX_PLAN_BYTES, DEFAULT_MAX_TODOS, DEFAULT_MAX_TODO_TEXT_BYTES, DEFAULT_MAX_CODING_ARTIFACTS, DEFAULT_MAX_CODING_ARTIFACT_BYTES, DEFAULT_MAX_CHECK_SUMMARY_BYTES, DEFAULT_MAX_CODING_CHECKPOINT_BYTES, HARD_MAX_BYTES, HARD_MAX_LINES, HARD_MAX_TEXT_SCAN_BYTES, HARD_MAX_IMAGE_BYTES, HARD_MAX_WRITE_BYTES, HARD_MAX_EDIT_FILE_BYTES, HARD_MAX_EDIT_INPUT_BYTES, HARD_MAX_EDITS, HARD_SHELL_TIMEOUT_SECONDS, HARD_MAX_TOTAL_OUTPUT_BYTES, HARD_MAX_REPO_DEPTH, HARD_MAX_REPO_ENTRIES, HARD_MAX_REPO_FILES, HARD_MAX_REPO_RESULTS, HARD_MAX_REPO_CONCURRENCY, HARD_MAX_SEARCH_SCAN_BYTES, HARD_MAX_SEARCH_FILE_BYTES, HARD_MAX_SEARCH_MATCHES, HARD_MAX_SEARCH_PATTERN_BYTES, HARD_MAX_SEARCH_LINE_BYTES, HARD_MAX_SEARCH_CONTEXT_LINES, HARD_MAX_SEARCH_TIME_MS, HARD_MAX_GIT_PATHS, HARD_MAX_GIT_REF_BYTES, HARD_MAX_GIT_MESSAGE_BYTES, HARD_MAX_GIT_OUTPUT_BYTES, HARD_MAX_GIT_DIFF_LINES, HARD_MAX_GIT_CHANGED_FILES, HARD_MAX_GIT_PATCH_BYTES, HARD_MAX_GIT_WORKTREES, HARD_GIT_TIMEOUT_MS, HARD_MAX_CHECK_NAMES, HARD_MAX_CHECK_CONCURRENCY, HARD_CHECK_TIMEOUT_MS, HARD_MAX_CHECK_DIAGNOSTIC_LINES, HARD_MAX_CHECK_OUTPUT_BYTES, HARD_MAX_PR_HANDOFF_BYTES, HARD_MAX_PR_COMMITS, HARD_MAX_PLAN_BYTES, HARD_MAX_TODOS, HARD_MAX_TODO_TEXT_BYTES, HARD_MAX_CODING_ARTIFACTS, HARD_MAX_CODING_ARTIFACT_BYTES, HARD_MAX_CHECK_SUMMARY_BYTES, HARD_MAX_CODING_CHECKPOINT_BYTES, } from "./limits.js";
12
31
  import type { ExecutionPolicy, ToolDefinition } from "@arnilo/prism";
13
32
  import type { ShellToolOptions } from "./shell.js";
14
33
  import type { ReadToolOptions } from "./read.js";
15
34
  import type { WriteToolOptions } from "./write.js";
16
35
  import type { EditToolOptions } from "./edit.js";
36
+ import type { ListToolOptions } from "./list.js";
37
+ import type { SearchToolOptions } from "./search.js";
38
+ import type { RepositoryLimitOptions, RepositoryOperations } from "./repository.js";
17
39
  /** Per-tool options combined for the aggregator factories. */
18
40
  export interface ToolsOptions {
19
41
  /** Shared execution policy applied to every coding tool unless overridden per tool. */
@@ -22,12 +44,26 @@ export interface ToolsOptions {
22
44
  read?: ReadToolOptions;
23
45
  write?: WriteToolOptions;
24
46
  edit?: EditToolOptions;
47
+ list?: ListToolOptions;
48
+ search?: SearchToolOptions;
49
+ /**
50
+ * Shared repository limits/backends for `repo_list` / `repo_search`.
51
+ * Per-tool `list` / `search` options override these when both are set.
52
+ */
53
+ repository?: RepositoryLimitOptions & {
54
+ operations?: RepositoryOperations;
55
+ };
25
56
  }
26
57
  /**
27
- * The four coding tools: `shell`, `read`, `write`, `edit`. Register all of them for a coding agent.
58
+ * Full coding tool set: `shell`, `read`, `write`, `edit`, `repo_list`, `repo_search`.
59
+ * Opt-in tools (`createGitTools`, `createAskUserDecisionTool`, `createCodingCheckTool`)
60
+ * stay out — hosts register them explicitly.
28
61
  */
29
62
  export declare function createCodingTools(cwd: string, options?: ToolsOptions): readonly ToolDefinition[];
30
- /** Read-only subset: `read` only (this package ships no grep/find/ls). */
63
+ /**
64
+ * Read-only subset: `read`, `repo_list`, `repo_search`.
65
+ * Deliberate 0.0.9 expansion from the previous `read`-only set.
66
+ */
31
67
  export declare function createReadOnlyTools(cwd: string, options?: ToolsOptions): readonly ToolDefinition[];
32
- /** Every tool this package provides — identical to {@link createCodingTools} for now. */
68
+ /** Every tool this package provides — identical to {@link createCodingTools}. */
33
69
  export declare function createAllTools(cwd: string, options?: ToolsOptions): readonly ToolDefinition[];
package/dist/index.js CHANGED
@@ -8,36 +8,74 @@ export { createShellTool, createLocalBashOperations, getShellConfig, killProcess
8
8
  export { createReadTool, detectSupportedImageMimeType, detectSupportedImageMimeTypeFromFile, DEFAULT_MAX_IMAGE_BYTES, } from "./read.js";
9
9
  export { createWriteTool } from "./write.js";
10
10
  export { createEditTool } from "./edit.js";
11
+ export { createRepoListTool } from "./list.js";
12
+ export { createRepoSearchTool } from "./search.js";
13
+ export { createLocalRepositoryOperations, resolveRepositoryLimits, compileSearchPattern, isBinaryBuffer, resolveRepoPath, toRepoRelative, RepositoryError, DEFAULT_REPO_EXCLUDE, } from "./repository.js";
14
+ export { createGitOperations, resolveGitLimits, parsePorcelainV2, GitError, SAFE_GIT_ENV, SAFE_GIT_CONFIG_ARGS, createBoundGitRunner, runGitCli, } from "./git.js";
15
+ export { createGitTools, createGitStatusTool, createGitDiffTool, createGitBranchTool, createGitWorktreeTool, createGitApplyTool, createGitCommitTool, createGitPrHandoffTool, } from "./git-tools.js";
16
+ export { createCodingCheckTool } from "./checks.js";
17
+ export { ASK_USER_DECISION_RATIONALE_COUNT, ASK_USER_DECISION_SUSPEND_REASON, ASK_USER_DECISION_TOOL_NAME, DEFAULT_MAX_ASK_USER_DECISION_BULLET_BYTES, DEFAULT_MAX_ASK_USER_DECISION_CUSTOM_BYTES, DEFAULT_MAX_ASK_USER_DECISION_LABEL_BYTES, DEFAULT_MAX_ASK_USER_DECISION_OPTIONS, DEFAULT_MAX_ASK_USER_DECISION_QUESTION_BYTES, HARD_MAX_ASK_USER_DECISION_BULLET_BYTES, HARD_MAX_ASK_USER_DECISION_CUSTOM_BYTES, HARD_MAX_ASK_USER_DECISION_LABEL_BYTES, HARD_MAX_ASK_USER_DECISION_OPTIONS, HARD_MAX_ASK_USER_DECISION_QUESTION_BYTES, askUserDecisionResumeSchema, createAskUserDecisionResumeValidator, createAskUserDecisionTool, parseAskUserDecisionArgs, resolveAskUserDecisionAnswer, resolveAskUserDecisionLimits, suspendAskUserDecision, toAskUserDecisionSuspendData, validateAskUserDecisionAgentResume, validateAskUserDecisionResume, } from "./ask-user-decision.js";
18
+ export { createDirectoryArtifactWriter, createTempArtifactWriter, sha256Hex } from "./artifacts.js";
19
+ export { CODING_CHECKPOINT_SCHEMA_VERSION, CODING_STATE_KEY, CodingCheckpointError, assertCodingResumeAllowed, buildCodingCheckpointMetadata, codingCheckpointStatePatch, codingPlanPathForTask, createCodingArtifactRef, createCodingPlanMarkdown, fingerprintJson, parseCodingPlanTodos, readCodingCheckpointFromState, readCodingPlanFile, resolveCodingCheckpointLimits, validateCodingCheckpointMetadata, verifyCodingArtifactBytes, writeCodingPlanFile, } from "./coding-checkpoint.js";
20
+ export { CODING_GOAL_VERIFY_REVISION, CODING_GOAL_VERIFY_SUSPEND_REASON, CODING_GOAL_VERIFY_WORKFLOW_ID, CodingGoalVerifyError, createCodingGoalVerifyWorkflow, runCodingGoalVerify, } from "./goal-verify.js";
11
21
  // --- generic primitives (re-exported for hosts that want them) ---
12
22
  export { withFileMutationQueue } from "./file-mutation-queue.js";
13
23
  export { enforceExecutionPolicy } from "./execution-policy.js";
14
- export { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_MAX_TEXT_SCAN_BYTES, DEFAULT_MAX_WRITE_BYTES, DEFAULT_MAX_EDIT_FILE_BYTES, DEFAULT_MAX_EDIT_INPUT_BYTES, DEFAULT_MAX_EDITS, DEFAULT_SHELL_TIMEOUT_SECONDS, DEFAULT_MAX_TOTAL_OUTPUT_BYTES, HARD_MAX_BYTES, HARD_MAX_LINES, HARD_MAX_TEXT_SCAN_BYTES, HARD_MAX_IMAGE_BYTES, HARD_MAX_WRITE_BYTES, HARD_MAX_EDIT_FILE_BYTES, HARD_MAX_EDIT_INPUT_BYTES, HARD_MAX_EDITS, HARD_SHELL_TIMEOUT_SECONDS, HARD_MAX_TOTAL_OUTPUT_BYTES, } from "./limits.js";
24
+ export { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_MAX_TEXT_SCAN_BYTES, DEFAULT_MAX_WRITE_BYTES, DEFAULT_MAX_EDIT_FILE_BYTES, DEFAULT_MAX_EDIT_INPUT_BYTES, DEFAULT_MAX_EDITS, DEFAULT_SHELL_TIMEOUT_SECONDS, DEFAULT_MAX_TOTAL_OUTPUT_BYTES, DEFAULT_MAX_REPO_DEPTH, DEFAULT_MAX_REPO_ENTRIES, DEFAULT_MAX_REPO_FILES, DEFAULT_MAX_REPO_RESULTS, DEFAULT_MAX_REPO_CONCURRENCY, DEFAULT_MAX_SEARCH_SCAN_BYTES, DEFAULT_MAX_SEARCH_FILE_BYTES, DEFAULT_MAX_SEARCH_MATCHES, DEFAULT_MAX_SEARCH_PATTERN_BYTES, DEFAULT_MAX_SEARCH_LINE_BYTES, DEFAULT_MAX_SEARCH_CONTEXT_LINES, DEFAULT_MAX_SEARCH_TIME_MS, DEFAULT_MAX_GIT_PATHS, DEFAULT_MAX_GIT_REF_BYTES, DEFAULT_MAX_GIT_MESSAGE_BYTES, DEFAULT_MAX_GIT_OUTPUT_BYTES, DEFAULT_MAX_GIT_DIFF_LINES, DEFAULT_MAX_GIT_CHANGED_FILES, DEFAULT_MAX_GIT_PATCH_BYTES, DEFAULT_MAX_GIT_WORKTREES, DEFAULT_GIT_TIMEOUT_MS, DEFAULT_MAX_CHECK_NAMES, DEFAULT_MAX_CHECK_CONCURRENCY, DEFAULT_CHECK_TIMEOUT_MS, DEFAULT_MAX_CHECK_DIAGNOSTIC_LINES, DEFAULT_MAX_CHECK_OUTPUT_BYTES, DEFAULT_MAX_PR_HANDOFF_BYTES, DEFAULT_MAX_PR_COMMITS, DEFAULT_MAX_PLAN_BYTES, DEFAULT_MAX_TODOS, DEFAULT_MAX_TODO_TEXT_BYTES, DEFAULT_MAX_CODING_ARTIFACTS, DEFAULT_MAX_CODING_ARTIFACT_BYTES, DEFAULT_MAX_CHECK_SUMMARY_BYTES, DEFAULT_MAX_CODING_CHECKPOINT_BYTES, HARD_MAX_BYTES, HARD_MAX_LINES, HARD_MAX_TEXT_SCAN_BYTES, HARD_MAX_IMAGE_BYTES, HARD_MAX_WRITE_BYTES, HARD_MAX_EDIT_FILE_BYTES, HARD_MAX_EDIT_INPUT_BYTES, HARD_MAX_EDITS, HARD_SHELL_TIMEOUT_SECONDS, HARD_MAX_TOTAL_OUTPUT_BYTES, HARD_MAX_REPO_DEPTH, HARD_MAX_REPO_ENTRIES, HARD_MAX_REPO_FILES, HARD_MAX_REPO_RESULTS, HARD_MAX_REPO_CONCURRENCY, HARD_MAX_SEARCH_SCAN_BYTES, HARD_MAX_SEARCH_FILE_BYTES, HARD_MAX_SEARCH_MATCHES, HARD_MAX_SEARCH_PATTERN_BYTES, HARD_MAX_SEARCH_LINE_BYTES, HARD_MAX_SEARCH_CONTEXT_LINES, HARD_MAX_SEARCH_TIME_MS, HARD_MAX_GIT_PATHS, HARD_MAX_GIT_REF_BYTES, HARD_MAX_GIT_MESSAGE_BYTES, HARD_MAX_GIT_OUTPUT_BYTES, HARD_MAX_GIT_DIFF_LINES, HARD_MAX_GIT_CHANGED_FILES, HARD_MAX_GIT_PATCH_BYTES, HARD_MAX_GIT_WORKTREES, HARD_GIT_TIMEOUT_MS, HARD_MAX_CHECK_NAMES, HARD_MAX_CHECK_CONCURRENCY, HARD_CHECK_TIMEOUT_MS, HARD_MAX_CHECK_DIAGNOSTIC_LINES, HARD_MAX_CHECK_OUTPUT_BYTES, HARD_MAX_PR_HANDOFF_BYTES, HARD_MAX_PR_COMMITS, HARD_MAX_PLAN_BYTES, HARD_MAX_TODOS, HARD_MAX_TODO_TEXT_BYTES, HARD_MAX_CODING_ARTIFACTS, HARD_MAX_CODING_ARTIFACT_BYTES, HARD_MAX_CHECK_SUMMARY_BYTES, HARD_MAX_CODING_CHECKPOINT_BYTES, } from "./limits.js";
15
25
  import { createShellTool } from "./shell.js";
16
26
  import { createReadTool } from "./read.js";
17
27
  import { createWriteTool } from "./write.js";
18
28
  import { createEditTool } from "./edit.js";
29
+ import { createRepoListTool } from "./list.js";
30
+ import { createRepoSearchTool } from "./search.js";
19
31
  function withSharedExecutionPolicy(toolOptions, shared) {
20
32
  if (!shared)
21
33
  return (toolOptions ?? {});
22
34
  return { ...(toolOptions ?? {}), executionPolicy: toolOptions?.executionPolicy ?? shared };
23
35
  }
36
+ function withRepositoryDefaults(toolOptions, shared) {
37
+ if (!shared && !toolOptions)
38
+ return {};
39
+ return {
40
+ ...(toolOptions ?? {}),
41
+ repository: toolOptions?.repository ?? shared,
42
+ operations: toolOptions?.operations ?? shared?.operations,
43
+ exclude: toolOptions?.exclude ?? shared?.exclude,
44
+ };
45
+ }
24
46
  /**
25
- * The four coding tools: `shell`, `read`, `write`, `edit`. Register all of them for a coding agent.
47
+ * Full coding tool set: `shell`, `read`, `write`, `edit`, `repo_list`, `repo_search`.
48
+ * Opt-in tools (`createGitTools`, `createAskUserDecisionTool`, `createCodingCheckTool`)
49
+ * stay out — hosts register them explicitly.
26
50
  */
27
51
  export function createCodingTools(cwd, options) {
28
52
  const policy = options?.executionPolicy;
53
+ const listOpts = withRepositoryDefaults(options?.list, options?.repository);
54
+ const searchOpts = withRepositoryDefaults(options?.search, options?.repository);
29
55
  return [
30
56
  createShellTool(cwd, withSharedExecutionPolicy(options?.shell, policy)),
31
57
  createReadTool(cwd, withSharedExecutionPolicy(options?.read, policy)),
32
58
  createWriteTool(cwd, withSharedExecutionPolicy(options?.write, policy)),
33
59
  createEditTool(cwd, withSharedExecutionPolicy(options?.edit, policy)),
60
+ createRepoListTool(cwd, withSharedExecutionPolicy(listOpts, policy)),
61
+ createRepoSearchTool(cwd, withSharedExecutionPolicy(searchOpts, policy)),
34
62
  ];
35
63
  }
36
- /** Read-only subset: `read` only (this package ships no grep/find/ls). */
64
+ /**
65
+ * Read-only subset: `read`, `repo_list`, `repo_search`.
66
+ * Deliberate 0.0.9 expansion from the previous `read`-only set.
67
+ */
37
68
  export function createReadOnlyTools(cwd, options) {
38
- return [createReadTool(cwd, withSharedExecutionPolicy(options?.read, options?.executionPolicy))];
69
+ const policy = options?.executionPolicy;
70
+ const listOpts = withRepositoryDefaults(options?.list, options?.repository);
71
+ const searchOpts = withRepositoryDefaults(options?.search, options?.repository);
72
+ return [
73
+ createReadTool(cwd, withSharedExecutionPolicy(options?.read, policy)),
74
+ createRepoListTool(cwd, withSharedExecutionPolicy(listOpts, policy)),
75
+ createRepoSearchTool(cwd, withSharedExecutionPolicy(searchOpts, policy)),
76
+ ];
39
77
  }
40
- /** Every tool this package provides — identical to {@link createCodingTools} for now. */
78
+ /** Every tool this package provides — identical to {@link createCodingTools}. */
41
79
  export function createAllTools(cwd, options) {
42
80
  return createCodingTools(cwd, options);
43
81
  }
package/dist/limits.d.ts CHANGED
@@ -18,5 +18,81 @@ export declare const DEFAULT_SHELL_TIMEOUT_SECONDS = 600;
18
18
  export declare const HARD_SHELL_TIMEOUT_SECONDS = 3600;
19
19
  export declare const DEFAULT_MAX_TOTAL_OUTPUT_BYTES: number;
20
20
  export declare const HARD_MAX_TOTAL_OUTPUT_BYTES: number;
21
+ /** Repository list/search defaults and hard caps (Phase 4 / review-coverage). */
22
+ export declare const DEFAULT_MAX_REPO_DEPTH = 32;
23
+ export declare const HARD_MAX_REPO_DEPTH = 128;
24
+ export declare const DEFAULT_MAX_REPO_ENTRIES = 10000;
25
+ export declare const HARD_MAX_REPO_ENTRIES = 100000;
26
+ export declare const DEFAULT_MAX_REPO_FILES = 10000;
27
+ export declare const HARD_MAX_REPO_FILES = 100000;
28
+ export declare const DEFAULT_MAX_REPO_RESULTS = 1000;
29
+ export declare const HARD_MAX_REPO_RESULTS = 10000;
30
+ export declare const DEFAULT_MAX_REPO_CONCURRENCY = 8;
31
+ export declare const HARD_MAX_REPO_CONCURRENCY = 32;
32
+ export declare const DEFAULT_MAX_SEARCH_SCAN_BYTES: number;
33
+ export declare const HARD_MAX_SEARCH_SCAN_BYTES: number;
34
+ export declare const DEFAULT_MAX_SEARCH_FILE_BYTES: number;
35
+ export declare const HARD_MAX_SEARCH_FILE_BYTES: number;
36
+ export declare const DEFAULT_MAX_SEARCH_MATCHES = 1000;
37
+ export declare const HARD_MAX_SEARCH_MATCHES = 10000;
38
+ export declare const DEFAULT_MAX_SEARCH_PATTERN_BYTES = 512;
39
+ export declare const HARD_MAX_SEARCH_PATTERN_BYTES = 4096;
40
+ export declare const DEFAULT_MAX_SEARCH_LINE_BYTES: number;
41
+ export declare const HARD_MAX_SEARCH_LINE_BYTES: number;
42
+ export declare const DEFAULT_MAX_SEARCH_CONTEXT_LINES = 5;
43
+ export declare const HARD_MAX_SEARCH_CONTEXT_LINES = 20;
44
+ export declare const DEFAULT_MAX_SEARCH_TIME_MS = 30000;
45
+ export declare const HARD_MAX_SEARCH_TIME_MS = 300000;
46
+ export declare const DEFAULT_BINARY_SNIFF_BYTES = 8192;
47
+ /** Structured Git / named-check / PR-handoff defaults and hard caps (Phase 4). */
48
+ export declare const DEFAULT_MAX_GIT_PATHS = 1000;
49
+ export declare const HARD_MAX_GIT_PATHS = 10000;
50
+ export declare const DEFAULT_MAX_GIT_REF_BYTES = 1024;
51
+ export declare const HARD_MAX_GIT_REF_BYTES = 4096;
52
+ export declare const DEFAULT_MAX_GIT_MESSAGE_BYTES: number;
53
+ export declare const HARD_MAX_GIT_MESSAGE_BYTES: number;
54
+ export declare const DEFAULT_MAX_GIT_OUTPUT_BYTES: number;
55
+ export declare const HARD_MAX_GIT_OUTPUT_BYTES: number;
56
+ export declare const DEFAULT_MAX_GIT_DIFF_LINES = 10000;
57
+ export declare const HARD_MAX_GIT_DIFF_LINES = 100000;
58
+ export declare const DEFAULT_MAX_GIT_CHANGED_FILES = 1000;
59
+ export declare const HARD_MAX_GIT_CHANGED_FILES = 10000;
60
+ export declare const DEFAULT_MAX_GIT_PATCH_BYTES: number;
61
+ export declare const HARD_MAX_GIT_PATCH_BYTES: number;
62
+ export declare const DEFAULT_MAX_GIT_WORKTREES = 4;
63
+ export declare const HARD_MAX_GIT_WORKTREES = 16;
64
+ export declare const DEFAULT_GIT_TIMEOUT_MS = 120000;
65
+ export declare const HARD_GIT_TIMEOUT_MS = 600000;
66
+ export declare const DEFAULT_MAX_CHECK_NAMES = 8;
67
+ export declare const HARD_MAX_CHECK_NAMES = 32;
68
+ export declare const DEFAULT_MAX_CHECK_CONCURRENCY = 1;
69
+ export declare const HARD_MAX_CHECK_CONCURRENCY = 4;
70
+ export declare const DEFAULT_CHECK_TIMEOUT_MS: number;
71
+ export declare const HARD_CHECK_TIMEOUT_MS: number;
72
+ export declare const DEFAULT_MAX_CHECK_DIAGNOSTIC_LINES = 2000;
73
+ export declare const HARD_MAX_CHECK_DIAGNOSTIC_LINES = 100000;
74
+ export declare const DEFAULT_MAX_CHECK_OUTPUT_BYTES: number;
75
+ export declare const HARD_MAX_CHECK_OUTPUT_BYTES: number;
76
+ export declare const DEFAULT_MAX_PR_HANDOFF_BYTES: number;
77
+ export declare const HARD_MAX_PR_HANDOFF_BYTES: number;
78
+ export declare const DEFAULT_MAX_PR_COMMITS = 100;
79
+ export declare const HARD_MAX_PR_COMMITS = 1000;
80
+ /** Durable coding plan / checkpoint metadata defaults and hard caps (Phase 4 Task 4). */
81
+ export declare const DEFAULT_MAX_PLAN_BYTES: number;
82
+ export declare const HARD_MAX_PLAN_BYTES: number;
83
+ export declare const DEFAULT_MAX_TODOS = 1000;
84
+ export declare const HARD_MAX_TODOS = 10000;
85
+ export declare const DEFAULT_MAX_TODO_TEXT_BYTES = 512;
86
+ export declare const HARD_MAX_TODO_TEXT_BYTES = 4096;
87
+ export declare const DEFAULT_MAX_CODING_ARTIFACTS = 16;
88
+ export declare const HARD_MAX_CODING_ARTIFACTS = 64;
89
+ export declare const DEFAULT_MAX_CODING_ARTIFACT_BYTES: number;
90
+ export declare const HARD_MAX_CODING_ARTIFACT_BYTES: number;
91
+ export declare const DEFAULT_MAX_CHECK_SUMMARY_BYTES = 1024;
92
+ export declare const HARD_MAX_CHECK_SUMMARY_BYTES = 8192;
93
+ export declare const DEFAULT_MAX_CODING_CHECKPOINT_BYTES: number;
94
+ export declare const HARD_MAX_CODING_CHECKPOINT_BYTES: number;
21
95
  /** Validate one configurable coding resource limit. Invalid values fail instead of clamping. */
22
96
  export declare function validateCodingLimit(name: string, value: number, hardCap: number): number;
97
+ /** Validate a non-negative integer limit (0 allowed), still capped. */
98
+ export declare function validateCodingLimitAllowZero(name: string, value: number, hardCap: number): number;
package/dist/limits.js CHANGED
@@ -18,6 +18,80 @@ export const DEFAULT_SHELL_TIMEOUT_SECONDS = 600;
18
18
  export const HARD_SHELL_TIMEOUT_SECONDS = 3_600;
19
19
  export const DEFAULT_MAX_TOTAL_OUTPUT_BYTES = 64 * 1024 * 1024;
20
20
  export const HARD_MAX_TOTAL_OUTPUT_BYTES = 1024 * 1024 * 1024;
21
+ /** Repository list/search defaults and hard caps (Phase 4 / review-coverage). */
22
+ export const DEFAULT_MAX_REPO_DEPTH = 32;
23
+ export const HARD_MAX_REPO_DEPTH = 128;
24
+ export const DEFAULT_MAX_REPO_ENTRIES = 10_000;
25
+ export const HARD_MAX_REPO_ENTRIES = 100_000;
26
+ export const DEFAULT_MAX_REPO_FILES = 10_000;
27
+ export const HARD_MAX_REPO_FILES = 100_000;
28
+ export const DEFAULT_MAX_REPO_RESULTS = 1_000;
29
+ export const HARD_MAX_REPO_RESULTS = 10_000;
30
+ export const DEFAULT_MAX_REPO_CONCURRENCY = 8;
31
+ export const HARD_MAX_REPO_CONCURRENCY = 32;
32
+ export const DEFAULT_MAX_SEARCH_SCAN_BYTES = 64 * 1024 * 1024;
33
+ export const HARD_MAX_SEARCH_SCAN_BYTES = 1024 * 1024 * 1024;
34
+ export const DEFAULT_MAX_SEARCH_FILE_BYTES = 8 * 1024 * 1024;
35
+ export const HARD_MAX_SEARCH_FILE_BYTES = 64 * 1024 * 1024;
36
+ export const DEFAULT_MAX_SEARCH_MATCHES = 1_000;
37
+ export const HARD_MAX_SEARCH_MATCHES = 10_000;
38
+ export const DEFAULT_MAX_SEARCH_PATTERN_BYTES = 512;
39
+ export const HARD_MAX_SEARCH_PATTERN_BYTES = 4_096;
40
+ export const DEFAULT_MAX_SEARCH_LINE_BYTES = 50 * 1024;
41
+ export const HARD_MAX_SEARCH_LINE_BYTES = 1024 * 1024;
42
+ export const DEFAULT_MAX_SEARCH_CONTEXT_LINES = 5;
43
+ export const HARD_MAX_SEARCH_CONTEXT_LINES = 20;
44
+ export const DEFAULT_MAX_SEARCH_TIME_MS = 30_000;
45
+ export const HARD_MAX_SEARCH_TIME_MS = 300_000;
46
+ export const DEFAULT_BINARY_SNIFF_BYTES = 8_192;
47
+ /** Structured Git / named-check / PR-handoff defaults and hard caps (Phase 4). */
48
+ export const DEFAULT_MAX_GIT_PATHS = 1_000;
49
+ export const HARD_MAX_GIT_PATHS = 10_000;
50
+ export const DEFAULT_MAX_GIT_REF_BYTES = 1_024;
51
+ export const HARD_MAX_GIT_REF_BYTES = 4_096;
52
+ export const DEFAULT_MAX_GIT_MESSAGE_BYTES = 64 * 1024;
53
+ export const HARD_MAX_GIT_MESSAGE_BYTES = 256 * 1024;
54
+ export const DEFAULT_MAX_GIT_OUTPUT_BYTES = 4 * 1024 * 1024;
55
+ export const HARD_MAX_GIT_OUTPUT_BYTES = 64 * 1024 * 1024;
56
+ export const DEFAULT_MAX_GIT_DIFF_LINES = 10_000;
57
+ export const HARD_MAX_GIT_DIFF_LINES = 100_000;
58
+ export const DEFAULT_MAX_GIT_CHANGED_FILES = 1_000;
59
+ export const HARD_MAX_GIT_CHANGED_FILES = 10_000;
60
+ export const DEFAULT_MAX_GIT_PATCH_BYTES = 16 * 1024 * 1024;
61
+ export const HARD_MAX_GIT_PATCH_BYTES = 64 * 1024 * 1024;
62
+ export const DEFAULT_MAX_GIT_WORKTREES = 4;
63
+ export const HARD_MAX_GIT_WORKTREES = 16;
64
+ export const DEFAULT_GIT_TIMEOUT_MS = 120_000;
65
+ export const HARD_GIT_TIMEOUT_MS = 600_000;
66
+ export const DEFAULT_MAX_CHECK_NAMES = 8;
67
+ export const HARD_MAX_CHECK_NAMES = 32;
68
+ export const DEFAULT_MAX_CHECK_CONCURRENCY = 1;
69
+ export const HARD_MAX_CHECK_CONCURRENCY = 4;
70
+ export const DEFAULT_CHECK_TIMEOUT_MS = 10 * 60_000;
71
+ export const HARD_CHECK_TIMEOUT_MS = 60 * 60_000;
72
+ export const DEFAULT_MAX_CHECK_DIAGNOSTIC_LINES = 2_000;
73
+ export const HARD_MAX_CHECK_DIAGNOSTIC_LINES = 100_000;
74
+ export const DEFAULT_MAX_CHECK_OUTPUT_BYTES = 4 * 1024 * 1024;
75
+ export const HARD_MAX_CHECK_OUTPUT_BYTES = 64 * 1024 * 1024;
76
+ export const DEFAULT_MAX_PR_HANDOFF_BYTES = 256 * 1024;
77
+ export const HARD_MAX_PR_HANDOFF_BYTES = 1024 * 1024;
78
+ export const DEFAULT_MAX_PR_COMMITS = 100;
79
+ export const HARD_MAX_PR_COMMITS = 1_000;
80
+ /** Durable coding plan / checkpoint metadata defaults and hard caps (Phase 4 Task 4). */
81
+ export const DEFAULT_MAX_PLAN_BYTES = 256 * 1024;
82
+ export const HARD_MAX_PLAN_BYTES = 1024 * 1024;
83
+ export const DEFAULT_MAX_TODOS = 1_000;
84
+ export const HARD_MAX_TODOS = 10_000;
85
+ export const DEFAULT_MAX_TODO_TEXT_BYTES = 512;
86
+ export const HARD_MAX_TODO_TEXT_BYTES = 4_096;
87
+ export const DEFAULT_MAX_CODING_ARTIFACTS = 16;
88
+ export const HARD_MAX_CODING_ARTIFACTS = 64;
89
+ export const DEFAULT_MAX_CODING_ARTIFACT_BYTES = 256 * 1024 * 1024;
90
+ export const HARD_MAX_CODING_ARTIFACT_BYTES = 2 * 1024 * 1024 * 1024;
91
+ export const DEFAULT_MAX_CHECK_SUMMARY_BYTES = 1_024;
92
+ export const HARD_MAX_CHECK_SUMMARY_BYTES = 8_192;
93
+ export const DEFAULT_MAX_CODING_CHECKPOINT_BYTES = 64 * 1024;
94
+ export const HARD_MAX_CODING_CHECKPOINT_BYTES = 512 * 1024;
21
95
  /** Validate one configurable coding resource limit. Invalid values fail instead of clamping. */
22
96
  export function validateCodingLimit(name, value, hardCap) {
23
97
  if (!Number.isSafeInteger(value) || value < 1 || value > hardCap) {
@@ -25,4 +99,11 @@ export function validateCodingLimit(name, value, hardCap) {
25
99
  }
26
100
  return value;
27
101
  }
102
+ /** Validate a non-negative integer limit (0 allowed), still capped. */
103
+ export function validateCodingLimitAllowZero(name, value, hardCap) {
104
+ if (!Number.isSafeInteger(value) || value < 0 || value > hardCap) {
105
+ throw new Error(`${name} must be a non-negative safe integer at most ${hardCap}`);
106
+ }
107
+ return value;
108
+ }
28
109
  //# sourceMappingURL=limits.js.map
package/dist/list.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `repo_list` tool: bounded native repository listing.
3
+ */
4
+ import type { ExecutionPolicy, ToolDefinition } from "@arnilo/prism";
5
+ import { type RepositoryLimitOptions, type RepositoryOperations } from "./repository.js";
6
+ export interface ListToolOptions {
7
+ executionPolicy?: ExecutionPolicy;
8
+ operations?: RepositoryOperations;
9
+ repository?: RepositoryLimitOptions;
10
+ maxDepth?: number;
11
+ maxResults?: number;
12
+ exclude?: readonly string[];
13
+ }
14
+ export declare function createRepoListTool(cwd: string, options?: ListToolOptions): ToolDefinition;