@arnilo/prism-coding-agent 0.0.22 → 0.0.24
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 +15 -3
- package/dist/ask-user-decision.js +2 -0
- package/dist/checks.js +2 -0
- package/dist/delete.js +2 -0
- package/dist/edit.js +2 -0
- package/dist/effects.d.ts +33 -0
- package/dist/effects.js +89 -0
- package/dist/git-tools.js +8 -0
- package/dist/glob.js +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/list.js +2 -0
- package/dist/move.js +2 -0
- package/dist/read.js +2 -0
- package/dist/search.js +2 -0
- package/dist/shell.js +2 -0
- package/dist/write.js +2 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.24] - 2026-08-04
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- Durable `AgentEventSource` (memory + PostgreSQL LISTEN/NOTIFY), recoverable `ToolEffectStore`, and AG-UI MCP/MCP Apps/A2A fronting for Phase 7.
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
- Publishable graph remains **47** manifests at **0.0.24**; peers and lockfile move together.
|
|
10
|
+
|
|
11
|
+
See [migration guide](../../docs/migration.md) for the 0.0.23 → 0.0.24 notes.
|
|
12
|
+
|
|
13
|
+
## [0.0.23] - 2026-08-03
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- Released with exact 0.0.23 graph.
|
|
17
|
+
|
|
3
18
|
## [0.0.22] - 2026-07-31
|
|
4
19
|
|
|
5
20
|
### Changed
|
|
@@ -16,14 +31,11 @@
|
|
|
16
31
|
### Changed
|
|
17
32
|
- `createCodingTools` returns 9 tools; `createReadOnlyTools` returns 4 (includes `glob`).
|
|
18
33
|
|
|
19
|
-
|
|
20
|
-
|
|
21
34
|
## [0.0.20] - 2026-07-31
|
|
22
35
|
|
|
23
36
|
### Changed
|
|
24
37
|
- Released with exact 0.0.20 graph.
|
|
25
38
|
|
|
26
|
-
|
|
27
39
|
## [0.0.19] - 2026-07-30
|
|
28
40
|
|
|
29
41
|
### Changed
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { suspend, } from "@arnilo/prism-workflows";
|
|
2
|
+
import { CODING_OBSERVATION_EFFECT } from "./effects.js";
|
|
2
3
|
import { enforceExecutionPolicy } from "./execution-policy.js";
|
|
3
4
|
import { validateCodingLimit } from "./limits.js";
|
|
4
5
|
export const ASK_USER_DECISION_TOOL_NAME = "ask_user_decision";
|
|
@@ -193,6 +194,7 @@ export function createAskUserDecisionTool(options) {
|
|
|
193
194
|
const ask = options.ask;
|
|
194
195
|
return {
|
|
195
196
|
name: ASK_USER_DECISION_TOOL_NAME,
|
|
197
|
+
effect: CODING_OBSERVATION_EFFECT,
|
|
196
198
|
description: "Ask the user to choose a direction when instructions are ambiguous and the choice matters. " +
|
|
197
199
|
"Provide 2+ options; each option MUST include exactly 3 pros and 3 cons. " +
|
|
198
200
|
'Use selectionMode "multiple" when several options may apply together; default is single choice. ' +
|
package/dist/checks.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
5
5
|
import { rm } from "node:fs/promises";
|
|
6
6
|
import { isAbsolute } from "node:path";
|
|
7
|
+
import { CODING_UNSUPPORTED_EFFECT } from "./effects.js";
|
|
7
8
|
import { enforceExecutionPolicy } from "./execution-policy.js";
|
|
8
9
|
import { DEFAULT_CHECK_TIMEOUT_MS, DEFAULT_MAX_CHECK_CONCURRENCY, DEFAULT_MAX_CHECK_DIAGNOSTIC_LINES, DEFAULT_MAX_CHECK_NAMES, DEFAULT_MAX_CHECK_OUTPUT_BYTES, HARD_CHECK_TIMEOUT_MS, HARD_MAX_BYTES, HARD_MAX_CHECK_CONCURRENCY, HARD_MAX_CHECK_DIAGNOSTIC_LINES, HARD_MAX_CHECK_NAMES, HARD_MAX_CHECK_OUTPUT_BYTES, validateCodingLimit, } from "./limits.js";
|
|
9
10
|
import { OutputAccumulator } from "./output-accumulator.js";
|
|
@@ -161,6 +162,7 @@ export function createCodingCheckTool(cwd, options) {
|
|
|
161
162
|
const names = [...checks.keys()].sort();
|
|
162
163
|
return {
|
|
163
164
|
name: "coding_check",
|
|
165
|
+
effect: CODING_UNSUPPORTED_EFFECT,
|
|
164
166
|
description: `Run a host-declared named check. Allowed names: ${names.join(", ")}. The model cannot choose executables or arguments.`,
|
|
165
167
|
exclusive: true,
|
|
166
168
|
parameters: {
|
package/dist/delete.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { lstat, readdir, rmdir, unlink } from "node:fs/promises";
|
|
2
|
+
import { CODING_LOCAL_EFFECT } from "./effects.js";
|
|
2
3
|
import { enforceExecutionPolicy } from "./execution-policy.js";
|
|
3
4
|
import { withFileMutationQueue } from "./file-mutation-queue.js";
|
|
4
5
|
import { resolveContainedMutationPath } from "./mutation-path.js";
|
|
@@ -28,6 +29,7 @@ export function createDeleteTool(cwd, options) {
|
|
|
28
29
|
const ops = options?.operations ?? defaultDeleteOperations;
|
|
29
30
|
return {
|
|
30
31
|
name: "delete",
|
|
32
|
+
effect: CODING_LOCAL_EFFECT,
|
|
31
33
|
description: "High-risk: permanently delete a single file or empty directory in the workspace. Non-empty directories are rejected (no recursive delete). No trash/recycle — host undo is not automatic. Prefer edit/write when content can be fixed in place.",
|
|
32
34
|
parameters: {
|
|
33
35
|
type: "object",
|
package/dist/edit.js
CHANGED
|
@@ -23,6 +23,7 @@ import { Buffer } from "node:buffer";
|
|
|
23
23
|
import { constants } from "node:fs";
|
|
24
24
|
import { access as fsAccess, stat as fsStat } from "node:fs/promises";
|
|
25
25
|
import { atomicWriteUtf8File } from "./atomic-write.js";
|
|
26
|
+
import { CODING_LOCAL_EFFECT } from "./effects.js";
|
|
26
27
|
import { readFileBounded } from "./bounded-file.js";
|
|
27
28
|
import { applyEditsToNormalizedContent, detectLineEnding, generateDiffString, generateUnifiedPatch, normalizeToLF, restoreLineEndings, stripBom, } from "./edit-diff.js";
|
|
28
29
|
import { enforceExecutionPolicy } from "./execution-policy.js";
|
|
@@ -95,6 +96,7 @@ export function createEditTool(cwd, options) {
|
|
|
95
96
|
const maxEdits = validateCodingLimit("maxEdits", options?.maxEdits ?? DEFAULT_MAX_EDITS, HARD_MAX_EDITS);
|
|
96
97
|
return {
|
|
97
98
|
name: "edit",
|
|
99
|
+
effect: CODING_LOCAL_EFFECT,
|
|
98
100
|
description: "Edit a single file using exact-then-fuzzy text replacement. Every edits[].oldText must match a unique, non-overlapping region of the original file. Exact match is tried first; if it fails, fuzzy match (unicode normalize + whitespace collapse) may still succeed silently — prefer exact oldText to avoid wrong-region edits. Duplicate/ambiguous matches fail closed and leave the file unchanged. If two changes affect the same block or nearby lines, merge them into one edit. Do not include large unchanged regions just to connect distant changes. When the host enabled requireReadBeforeWrite, read the path first or pass force=true.",
|
|
99
101
|
parameters: {
|
|
100
102
|
type: "object",
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { JsonObject, ToolEffectDeclaration, ToolEffectRecord, ToolResult } from "@arnilo/prism";
|
|
2
|
+
export declare const CODING_OBSERVATION_EFFECT: {
|
|
3
|
+
readonly kind: "none";
|
|
4
|
+
readonly idempotency: "none";
|
|
5
|
+
};
|
|
6
|
+
export declare const CODING_LOCAL_EFFECT: {
|
|
7
|
+
readonly kind: "local_mutation";
|
|
8
|
+
readonly idempotency: "optional";
|
|
9
|
+
};
|
|
10
|
+
export declare const CODING_UNSUPPORTED_EFFECT: {
|
|
11
|
+
readonly kind: "external_mutation";
|
|
12
|
+
readonly idempotency: "unsupported";
|
|
13
|
+
};
|
|
14
|
+
export declare function classifyGitBranchEffect(args: JsonObject): ToolEffectDeclaration;
|
|
15
|
+
export declare function classifyGitWorktreeEffect(args: JsonObject): ToolEffectDeclaration;
|
|
16
|
+
export declare function classifyGitApplyEffect(args: JsonObject): ToolEffectDeclaration;
|
|
17
|
+
export interface CodingEffectReconciliationInput {
|
|
18
|
+
readonly cwd: string;
|
|
19
|
+
readonly record: Pick<ToolEffectRecord, "toolCallId" | "toolName">;
|
|
20
|
+
readonly args: JsonObject;
|
|
21
|
+
readonly signal?: AbortSignal;
|
|
22
|
+
}
|
|
23
|
+
export type CodingEffectReconciliation = {
|
|
24
|
+
readonly status: "completed";
|
|
25
|
+
readonly result: ToolResult;
|
|
26
|
+
} | {
|
|
27
|
+
readonly status: "unknown";
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Checks only exact local postconditions. Callers retain the pending call arguments,
|
|
31
|
+
* then pass a completed result to ToolEffectStore.resolveUnknown() when this returns one.
|
|
32
|
+
*/
|
|
33
|
+
export declare function reconcileCodingToolEffect(input: CodingEffectReconciliationInput): Promise<CodingEffectReconciliation>;
|
package/dist/effects.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { readFile, stat } from "node:fs/promises";
|
|
2
|
+
import { Buffer } from "node:buffer";
|
|
3
|
+
import { HARD_MAX_WRITE_BYTES } from "./limits.js";
|
|
4
|
+
import { resolveContainedMutationPath } from "./mutation-path.js";
|
|
5
|
+
export const CODING_OBSERVATION_EFFECT = { kind: "none", idempotency: "none" };
|
|
6
|
+
export const CODING_LOCAL_EFFECT = { kind: "local_mutation", idempotency: "optional" };
|
|
7
|
+
export const CODING_UNSUPPORTED_EFFECT = { kind: "external_mutation", idempotency: "unsupported" };
|
|
8
|
+
export function classifyGitBranchEffect(args) {
|
|
9
|
+
return args.action === "list" || args.action === "validate" ? CODING_OBSERVATION_EFFECT : CODING_LOCAL_EFFECT;
|
|
10
|
+
}
|
|
11
|
+
export function classifyGitWorktreeEffect(args) {
|
|
12
|
+
return args.action === "list" ? CODING_OBSERVATION_EFFECT : CODING_LOCAL_EFFECT;
|
|
13
|
+
}
|
|
14
|
+
export function classifyGitApplyEffect(args) {
|
|
15
|
+
return args.action === "check" ? CODING_OBSERVATION_EFFECT : CODING_LOCAL_EFFECT;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Checks only exact local postconditions. Callers retain the pending call arguments,
|
|
19
|
+
* then pass a completed result to ToolEffectStore.resolveUnknown() when this returns one.
|
|
20
|
+
*/
|
|
21
|
+
export async function reconcileCodingToolEffect(input) {
|
|
22
|
+
input.signal?.throwIfAborted();
|
|
23
|
+
const completed = () => ({
|
|
24
|
+
status: "completed",
|
|
25
|
+
result: {
|
|
26
|
+
toolCallId: input.record.toolCallId,
|
|
27
|
+
name: input.record.toolName,
|
|
28
|
+
content: [{ type: "text", text: "Local tool postcondition verified." }],
|
|
29
|
+
value: { reconciled: true },
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
try {
|
|
33
|
+
if (input.record.toolName === "write") {
|
|
34
|
+
const path = stringArg(input.args, "path");
|
|
35
|
+
const content = stringArg(input.args, "content");
|
|
36
|
+
if (path === undefined || content === undefined || Buffer.byteLength(content, "utf8") > HARD_MAX_WRITE_BYTES)
|
|
37
|
+
return { status: "unknown" };
|
|
38
|
+
const target = await resolveContainedMutationPath(input.cwd, path);
|
|
39
|
+
const expected = Buffer.from(content, "utf8");
|
|
40
|
+
if ((await stat(target)).size !== expected.length)
|
|
41
|
+
return { status: "unknown" };
|
|
42
|
+
return (await readFile(target)).equals(expected) ? completed() : { status: "unknown" };
|
|
43
|
+
}
|
|
44
|
+
if (input.record.toolName === "delete") {
|
|
45
|
+
const path = stringArg(input.args, "path");
|
|
46
|
+
if (path === undefined)
|
|
47
|
+
return { status: "unknown" };
|
|
48
|
+
await resolveContainedMutationPath(input.cwd, path, { allowMissing: true });
|
|
49
|
+
return (await missing(input.cwd, path)) ? completed() : { status: "unknown" };
|
|
50
|
+
}
|
|
51
|
+
if (input.record.toolName === "move") {
|
|
52
|
+
const from = stringArg(input.args, "from");
|
|
53
|
+
const to = stringArg(input.args, "to");
|
|
54
|
+
if (from === undefined || to === undefined)
|
|
55
|
+
return { status: "unknown" };
|
|
56
|
+
await Promise.all([
|
|
57
|
+
resolveContainedMutationPath(input.cwd, from, { allowMissing: true }),
|
|
58
|
+
resolveContainedMutationPath(input.cwd, to, { allowMissing: true }),
|
|
59
|
+
]);
|
|
60
|
+
if (await missing(input.cwd, from)) {
|
|
61
|
+
try {
|
|
62
|
+
await resolveContainedMutationPath(input.cwd, to);
|
|
63
|
+
return completed();
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return { status: "unknown" };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// Containment/read failure is not proof that an effect did not happen.
|
|
73
|
+
}
|
|
74
|
+
return { status: "unknown" };
|
|
75
|
+
}
|
|
76
|
+
function stringArg(args, name) {
|
|
77
|
+
const value = args[name];
|
|
78
|
+
return typeof value === "string" ? value : undefined;
|
|
79
|
+
}
|
|
80
|
+
async function missing(cwd, path) {
|
|
81
|
+
try {
|
|
82
|
+
await resolveContainedMutationPath(cwd, path);
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
return error.code === "ENOENT" || error.code === "ENOTDIR";
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=effects.js.map
|
package/dist/git-tools.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createCodingCheckTool } from "./checks.js";
|
|
2
|
+
import { classifyGitApplyEffect, classifyGitBranchEffect, classifyGitWorktreeEffect, CODING_LOCAL_EFFECT, CODING_OBSERVATION_EFFECT, CODING_UNSUPPORTED_EFFECT, } from "./effects.js";
|
|
2
3
|
import { enforceExecutionPolicy } from "./execution-policy.js";
|
|
3
4
|
import { createGitOperations, GitError, } from "./git.js";
|
|
4
5
|
function errorResult(toolName, toolCallId, message) {
|
|
@@ -39,6 +40,7 @@ export function createGitStatusTool(cwd, options) {
|
|
|
39
40
|
const getOps = opsFactory(cwd, options);
|
|
40
41
|
return {
|
|
41
42
|
name: "git_status",
|
|
43
|
+
effect: CODING_OBSERVATION_EFFECT,
|
|
42
44
|
description: "Return structured Git status (porcelain v2) including branch metadata and dirty-state. Does not follow shell; paths are repository-relative.",
|
|
43
45
|
parameters: {
|
|
44
46
|
type: "object",
|
|
@@ -84,6 +86,7 @@ export function createGitDiffTool(cwd, options) {
|
|
|
84
86
|
const getOps = opsFactory(cwd, options);
|
|
85
87
|
return {
|
|
86
88
|
name: "git_diff",
|
|
89
|
+
effect: CODING_OBSERVATION_EFFECT,
|
|
87
90
|
description: "Return a bounded unified diff (--no-ext-diff --no-textconv). Large diffs truncate inline and may spill through the host artifact writer.",
|
|
88
91
|
parameters: {
|
|
89
92
|
type: "object",
|
|
@@ -138,6 +141,7 @@ export function createGitBranchTool(cwd, options) {
|
|
|
138
141
|
const getOps = opsFactory(cwd, options);
|
|
139
142
|
return {
|
|
140
143
|
name: "git_branch",
|
|
144
|
+
effect: classifyGitBranchEffect,
|
|
141
145
|
description: "Validate, list, create, or switch branches. Switch refuses a dirty worktree unless createCheckpoint=true.",
|
|
142
146
|
exclusive: true,
|
|
143
147
|
parameters: {
|
|
@@ -208,6 +212,7 @@ export function createGitWorktreeTool(cwd, options) {
|
|
|
208
212
|
const getOps = opsFactory(cwd, options);
|
|
209
213
|
return {
|
|
210
214
|
name: "git_worktree",
|
|
215
|
+
effect: classifyGitWorktreeEffect,
|
|
211
216
|
description: "List, add, or remove Git worktrees within finite caps. Prefer disposable worktrees for mutating transactions.",
|
|
212
217
|
exclusive: true,
|
|
213
218
|
parameters: {
|
|
@@ -269,6 +274,7 @@ export function createGitApplyTool(cwd, options) {
|
|
|
269
274
|
const getOps = opsFactory(cwd, options);
|
|
270
275
|
return {
|
|
271
276
|
name: "git_apply",
|
|
277
|
+
effect: classifyGitApplyEffect,
|
|
272
278
|
description: "Check, apply, or reverse a unified patch. Always runs apply --check first for apply/reverse. Dirty trees require createCheckpoint=true; failures restore the checkpoint or clean tree.",
|
|
273
279
|
exclusive: true,
|
|
274
280
|
parameters: {
|
|
@@ -336,6 +342,7 @@ export function createGitCommitTool(cwd, options) {
|
|
|
336
342
|
const getOps = opsFactory(cwd, options);
|
|
337
343
|
return {
|
|
338
344
|
name: "git_commit",
|
|
345
|
+
effect: CODING_LOCAL_EFFECT,
|
|
339
346
|
description: "Stage and commit explicit paths only (never `git add -A`). Refuses dirty unrelated worktrees unless createCheckpoint=true. Uses --no-verify and a temp message file; never pushes.",
|
|
340
347
|
exclusive: true,
|
|
341
348
|
parameters: {
|
|
@@ -395,6 +402,7 @@ export function createGitPrHandoffTool(cwd, options) {
|
|
|
395
402
|
const getOps = opsFactory(cwd, options);
|
|
396
403
|
return {
|
|
397
404
|
name: "git_pr_handoff",
|
|
405
|
+
effect: CODING_UNSUPPORTED_EFFECT,
|
|
398
406
|
description: "Build a bounded host-owned PR handoff payload (base/head/commits/paths/diffstat/checks/artifact). Never pushes, authenticates, or opens a PR.",
|
|
399
407
|
exclusive: true,
|
|
400
408
|
parameters: {
|
package/dist/glob.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CODING_OBSERVATION_EFFECT } from "./effects.js";
|
|
1
2
|
import { enforceExecutionPolicy } from "./execution-policy.js";
|
|
2
3
|
import { HARD_MAX_REPO_DEPTH, HARD_MAX_REPO_RESULTS, validateCodingLimit, validateCodingLimitAllowZero } from "./limits.js";
|
|
3
4
|
import { createLocalRepositoryOperations, RepositoryError, resolveRepositoryLimits, } from "./repository.js";
|
|
@@ -30,6 +31,7 @@ export function createGlobTool(cwd, options) {
|
|
|
30
31
|
const ops = options?.operations ?? createLocalRepositoryOperations(limits);
|
|
31
32
|
return {
|
|
32
33
|
name: "glob",
|
|
34
|
+
effect: CODING_OBSERVATION_EFFECT,
|
|
33
35
|
description: `Find workspace files by glob pattern without shell find. Supports * (segment), ? (one char), and ** (directories). Brace expansion is rejected. Skips hidden names and excluded basenames (default: ${limits.exclude.join(", ")}) unless overridden. Does not follow symlinks. Results paginate with offset/maxResults (default ${limits.maxResults}). Depth default ${limits.maxDepth}. Prefer repo_list to enumerate directories and repo_search to find text inside files.`,
|
|
34
36
|
parameters: {
|
|
35
37
|
type: "object",
|
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export type { CodingArtifactKind, CodingArtifactRef, CodingCheckpointLimitOption
|
|
|
9
9
|
export { assertCodingResumeAllowed, buildCodingCheckpointMetadata, CODING_CHECKPOINT_SCHEMA_VERSION, CODING_STATE_KEY, CodingCheckpointError, codingCheckpointStatePatch, codingPlanPathForTask, createCodingArtifactRef, createCodingPlanMarkdown, fingerprintJson, parseCodingPlanTodos, readCodingCheckpointFromState, readCodingPlanFile, resolveCodingCheckpointLimits, validateCodingCheckpointMetadata, verifyCodingArtifactBytes, writeCodingPlanFile, } from "./coding-checkpoint.js";
|
|
10
10
|
export type { Edit, EditOperations, EditToolDetails, EditToolOptions } from "./edit.js";
|
|
11
11
|
export { createEditTool } from "./edit.js";
|
|
12
|
+
export type { CodingEffectReconciliation, CodingEffectReconciliationInput } from "./effects.js";
|
|
13
|
+
export { classifyGitApplyEffect, classifyGitBranchEffect, classifyGitWorktreeEffect, CODING_LOCAL_EFFECT, CODING_OBSERVATION_EFFECT, CODING_UNSUPPORTED_EFFECT, reconcileCodingToolEffect, } from "./effects.js";
|
|
12
14
|
export type { ArtifactReference, ArtifactWriter, BoundGitRunner, CreateGitOperationsOptions, CreateGitRunnerOptions, GitExecRequest, GitExecResult, GitLimitOptions, GitOperations, GitRunner, GitStatusBranch, GitStatusEntry, GitStatusEntryKind, GitStatusResult, PrHandoff, ResolvedGitLimits, } from "./git.js";
|
|
13
15
|
export { createBoundGitRunner, createGitOperations, GitError, parsePorcelainV2, resolveGitLimits, runGitCli, SAFE_GIT_CONFIG_ARGS, SAFE_GIT_ENV, } from "./git.js";
|
|
14
16
|
export type { GitToolsOptions } from "./git-tools.js";
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ export { createCodingCheckTool } from "./checks.js";
|
|
|
10
10
|
export { createDeleteTool } from "./delete.js";
|
|
11
11
|
export { assertCodingResumeAllowed, buildCodingCheckpointMetadata, CODING_CHECKPOINT_SCHEMA_VERSION, CODING_STATE_KEY, CodingCheckpointError, codingCheckpointStatePatch, codingPlanPathForTask, createCodingArtifactRef, createCodingPlanMarkdown, fingerprintJson, parseCodingPlanTodos, readCodingCheckpointFromState, readCodingPlanFile, resolveCodingCheckpointLimits, validateCodingCheckpointMetadata, verifyCodingArtifactBytes, writeCodingPlanFile, } from "./coding-checkpoint.js";
|
|
12
12
|
export { createEditTool } from "./edit.js";
|
|
13
|
+
export { classifyGitApplyEffect, classifyGitBranchEffect, classifyGitWorktreeEffect, CODING_LOCAL_EFFECT, CODING_OBSERVATION_EFFECT, CODING_UNSUPPORTED_EFFECT, reconcileCodingToolEffect, } from "./effects.js";
|
|
13
14
|
export { createBoundGitRunner, createGitOperations, GitError, parsePorcelainV2, resolveGitLimits, runGitCli, SAFE_GIT_CONFIG_ARGS, SAFE_GIT_ENV, } from "./git.js";
|
|
14
15
|
export { createGitApplyTool, createGitBranchTool, createGitCommitTool, createGitDiffTool, createGitPrHandoffTool, createGitStatusTool, createGitTools, createGitWorktreeTool, } from "./git-tools.js";
|
|
15
16
|
export { CODING_GOAL_VERIFY_REVISION, CODING_GOAL_VERIFY_SUSPEND_REASON, CODING_GOAL_VERIFY_WORKFLOW_ID, CodingGoalVerifyError, createCodingGoalVerifyWorkflow, runCodingGoalVerify, } from "./goal-verify.js";
|
package/dist/list.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CODING_OBSERVATION_EFFECT } from "./effects.js";
|
|
1
2
|
import { enforceExecutionPolicy } from "./execution-policy.js";
|
|
2
3
|
import { HARD_MAX_REPO_DEPTH, HARD_MAX_REPO_RESULTS, validateCodingLimit, validateCodingLimitAllowZero } from "./limits.js";
|
|
3
4
|
import { createLocalRepositoryOperations, RepositoryError, resolveRepositoryLimits, } from "./repository.js";
|
|
@@ -33,6 +34,7 @@ export function createRepoListTool(cwd, options) {
|
|
|
33
34
|
const ops = options?.operations ?? createLocalRepositoryOperations(limits);
|
|
34
35
|
return {
|
|
35
36
|
name: "repo_list",
|
|
37
|
+
effect: CODING_OBSERVATION_EFFECT,
|
|
36
38
|
description: `List repository entries under the workspace with deterministic relative paths. Prefer glob when you already know a filename pattern (*.ts, **/src/**). Prefer repo_search to find text inside files. Skips hidden names and excluded basenames (default: ${limits.exclude.join(", ")}) unless overridden. Does not follow symlinks. Results paginate with offset/maxResults (default ${limits.maxResults}). Depth default ${limits.maxDepth}.`,
|
|
37
39
|
parameters: {
|
|
38
40
|
type: "object",
|
package/dist/move.js
CHANGED
|
@@ -2,6 +2,7 @@ import { access, constants } from "node:fs";
|
|
|
2
2
|
import { dirname } from "node:path";
|
|
3
3
|
import { lstat, rename, unlink } from "node:fs/promises";
|
|
4
4
|
import { promisify } from "node:util";
|
|
5
|
+
import { CODING_LOCAL_EFFECT } from "./effects.js";
|
|
5
6
|
import { enforceExecutionPolicy } from "./execution-policy.js";
|
|
6
7
|
import { withFileMutationQueue } from "./file-mutation-queue.js";
|
|
7
8
|
import { resolveContainedMutationPath } from "./mutation-path.js";
|
|
@@ -36,6 +37,7 @@ export function createMoveTool(cwd, options) {
|
|
|
36
37
|
const ops = options?.operations ?? defaultMoveOperations;
|
|
37
38
|
return {
|
|
38
39
|
name: "move",
|
|
40
|
+
effect: CODING_LOCAL_EFFECT,
|
|
39
41
|
description: "High-risk: move or rename a file within the workspace. Set overwrite=true to replace an existing destination file only (directories/non-empty dest rejected). Does not create parent directories. No trash — host undo is not automatic.",
|
|
40
42
|
parameters: {
|
|
41
43
|
type: "object",
|
package/dist/read.js
CHANGED
|
@@ -23,6 +23,7 @@ import { Buffer } from "node:buffer";
|
|
|
23
23
|
import { constants } from "node:fs";
|
|
24
24
|
import { access as fsAccess, stat as fsStat, open } from "node:fs/promises";
|
|
25
25
|
import { readFileBounded } from "./bounded-file.js";
|
|
26
|
+
import { CODING_OBSERVATION_EFFECT } from "./effects.js";
|
|
26
27
|
import { enforceExecutionPolicy } from "./execution-policy.js";
|
|
27
28
|
import { DEFAULT_MAX_BYTES, DEFAULT_MAX_IMAGE_BYTES, DEFAULT_MAX_LINES, DEFAULT_MAX_TEXT_SCAN_BYTES, HARD_MAX_BYTES, HARD_MAX_IMAGE_BYTES, HARD_MAX_LINES, HARD_MAX_TEXT_SCAN_BYTES, validateCodingLimit, } from "./limits.js";
|
|
28
29
|
import { resolveReadPathAsync } from "./path-utils.js";
|
|
@@ -307,6 +308,7 @@ export function createReadTool(cwd, options) {
|
|
|
307
308
|
const maxScanBytes = validateCodingLimit("maxScanBytes", options?.maxScanBytes ?? DEFAULT_MAX_TEXT_SCAN_BYTES, HARD_MAX_TEXT_SCAN_BYTES);
|
|
308
309
|
return {
|
|
309
310
|
name: "read",
|
|
311
|
+
effect: CODING_OBSERVATION_EFFECT,
|
|
310
312
|
description: `Read the contents of a file. Supports text files and images (jpg, png, gif, webp, bmp); images are returned as image content. For text files, output is truncated to ${maxLines} lines or ${maxBytes / 1024}KB (whichever is hit first). When truncated, continue with the suggested offset until complete. Prefer repo_search to find text across many files.`,
|
|
311
313
|
parameters: {
|
|
312
314
|
type: "object",
|
package/dist/search.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CODING_OBSERVATION_EFFECT } from "./effects.js";
|
|
1
2
|
import { enforceExecutionPolicy } from "./execution-policy.js";
|
|
2
3
|
import { HARD_MAX_SEARCH_CONTEXT_LINES, HARD_MAX_SEARCH_MATCHES, validateCodingLimit, validateCodingLimitAllowZero } from "./limits.js";
|
|
3
4
|
import { createLocalRepositoryOperations, RepositoryError, resolveRepositoryLimits, } from "./repository.js";
|
|
@@ -101,6 +102,7 @@ export function createRepoSearchTool(cwd, options) {
|
|
|
101
102
|
const ops = options?.operations ?? createLocalRepositoryOperations(limits);
|
|
102
103
|
return {
|
|
103
104
|
name: "repo_search",
|
|
105
|
+
effect: CODING_OBSERVATION_EFFECT,
|
|
104
106
|
description: `Search text files under the workspace using literal substring match. Use outputMode "files_with_matches" for paths only or "count" for totals without line bodies. 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.`,
|
|
105
107
|
parameters: {
|
|
106
108
|
type: "object",
|
package/dist/shell.js
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
import { spawn } from "node:child_process";
|
|
24
24
|
import { constants, existsSync } from "node:fs";
|
|
25
25
|
import { access as fsAccess } from "node:fs/promises";
|
|
26
|
+
import { CODING_UNSUPPORTED_EFFECT } from "./effects.js";
|
|
26
27
|
import { enforceExecutionPolicy } from "./execution-policy.js";
|
|
27
28
|
import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_MAX_TOTAL_OUTPUT_BYTES, DEFAULT_SHELL_TIMEOUT_SECONDS, HARD_MAX_BYTES, HARD_MAX_LINES, HARD_MAX_TOTAL_OUTPUT_BYTES, HARD_SHELL_TIMEOUT_SECONDS, validateCodingLimit, } from "./limits.js";
|
|
28
29
|
import { OutputAccumulator } from "./output-accumulator.js";
|
|
@@ -264,6 +265,7 @@ export function createShellTool(cwd, options) {
|
|
|
264
265
|
const tempFilePrefix = options?.tempFilePrefix ?? "prism-shell";
|
|
265
266
|
return {
|
|
266
267
|
name: "shell",
|
|
268
|
+
effect: CODING_UNSUPPORTED_EFFECT,
|
|
267
269
|
exclusive: true,
|
|
268
270
|
description: `Execute a shell command in the current working directory. Returns combined stdout and stderr. Prefer repo_list, repo_search, glob, read, write, edit, delete, or move for those jobs — use shell only when no dedicated tool fits. Output is truncated to the last ${maxLines} lines or ${maxBytes / 1024}KB and capped at ${formatSize(maxTotalOutputBytes)} total. Truncated successful output is saved to a temp file. Timeout defaults to ${defaultTimeout} seconds.`,
|
|
269
271
|
parameters: {
|
package/dist/write.js
CHANGED
|
@@ -18,6 +18,7 @@ import { Buffer } from "node:buffer";
|
|
|
18
18
|
import { mkdir as fsMkdir } from "node:fs/promises";
|
|
19
19
|
import { dirname } from "node:path";
|
|
20
20
|
import { atomicWriteUtf8File } from "./atomic-write.js";
|
|
21
|
+
import { CODING_LOCAL_EFFECT } from "./effects.js";
|
|
21
22
|
import { enforceExecutionPolicy } from "./execution-policy.js";
|
|
22
23
|
import { withFileMutationQueue } from "./file-mutation-queue.js";
|
|
23
24
|
import { DEFAULT_MAX_WRITE_BYTES, HARD_MAX_WRITE_BYTES, validateCodingLimit } from "./limits.js";
|
|
@@ -45,6 +46,7 @@ export function createWriteTool(cwd, options) {
|
|
|
45
46
|
const maxInputBytes = validateCodingLimit("maxInputBytes", options?.maxInputBytes ?? DEFAULT_MAX_WRITE_BYTES, HARD_MAX_WRITE_BYTES);
|
|
46
47
|
return {
|
|
47
48
|
name: "write",
|
|
49
|
+
effect: CODING_LOCAL_EFFECT,
|
|
48
50
|
description: "Create or overwrite a file (full replace). Creates parent directories. Prefer edit for targeted changes. When the host enabled requireReadBeforeWrite, read the path first or pass force=true to override.",
|
|
49
51
|
parameters: {
|
|
50
52
|
type: "object",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arnilo/prism-coding-agent",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.24",
|
|
4
4
|
"description": "Optional coding-agent tools (shell, read, write, edit, repo_list, repo_search, glob, delete, move, 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",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"diff": "^9.0.0"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
|
-
"@arnilo/prism": "0.0.
|
|
32
|
-
"@arnilo/prism-workflows": "0.0.
|
|
31
|
+
"@arnilo/prism": "0.0.24",
|
|
32
|
+
"@arnilo/prism-workflows": "0.0.24"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@arnilo/prism": "file:../..",
|