@arnilo/prism-coding-agent 0.0.25 → 0.0.27

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.
Files changed (49) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +2 -2
  3. package/dist/delete.d.ts +3 -0
  4. package/dist/delete.js +3 -1
  5. package/dist/edit.d.ts +3 -0
  6. package/dist/edit.js +2 -1
  7. package/dist/execution-policy.d.ts +7 -1
  8. package/dist/execution-policy.js +4 -1
  9. package/dist/forge/github.d.ts +2 -0
  10. package/dist/forge/github.js +554 -0
  11. package/dist/forge/index.d.ts +3 -0
  12. package/dist/forge/index.js +3 -0
  13. package/dist/forge/types.d.ts +150 -0
  14. package/dist/forge/types.js +19 -0
  15. package/dist/git-aware-repository.d.ts +25 -0
  16. package/dist/git-aware-repository.js +268 -0
  17. package/dist/git-tools.d.ts +3 -0
  18. package/dist/git-tools.js +4 -1
  19. package/dist/index.d.ts +12 -2
  20. package/dist/index.js +6 -1
  21. package/dist/language/client.d.ts +44 -0
  22. package/dist/language/client.js +290 -0
  23. package/dist/language/framing.d.ts +23 -0
  24. package/dist/language/framing.js +112 -0
  25. package/dist/language/index.d.ts +4 -0
  26. package/dist/language/index.js +4 -0
  27. package/dist/language/intelligence.d.ts +10 -0
  28. package/dist/language/intelligence.js +526 -0
  29. package/dist/language/types.d.ts +106 -0
  30. package/dist/language/types.js +21 -0
  31. package/dist/lifecycle.d.ts +75 -0
  32. package/dist/lifecycle.js +102 -0
  33. package/dist/limits.d.ts +41 -0
  34. package/dist/limits.js +41 -0
  35. package/dist/move.d.ts +3 -0
  36. package/dist/move.js +2 -1
  37. package/dist/output-accumulator.d.ts +8 -0
  38. package/dist/output-accumulator.js +45 -1
  39. package/dist/process/index.d.ts +3 -0
  40. package/dist/process/index.js +3 -0
  41. package/dist/process/sessions.d.ts +2 -0
  42. package/dist/process/sessions.js +592 -0
  43. package/dist/process/types.d.ts +146 -0
  44. package/dist/process/types.js +19 -0
  45. package/dist/repository.d.ts +21 -1
  46. package/dist/repository.js +10 -10
  47. package/dist/write.d.ts +3 -0
  48. package/dist/write.js +2 -1
  49. package/package.json +3 -3
@@ -0,0 +1,75 @@
1
+ import type { CodingProcessEvent } from "./process/types.js";
2
+ export type FileChangeOp = "write" | "edit" | "delete" | "move";
3
+ export interface FileChangedEvent {
4
+ readonly type: "file_changed";
5
+ /** Workspace-relative or policy-checked absolute path. Never a raw file body. */
6
+ readonly path: string;
7
+ readonly op: FileChangeOp;
8
+ readonly toolCallId?: string;
9
+ }
10
+ export interface WorktreeChangedEvent {
11
+ readonly type: "worktree_changed";
12
+ readonly action: "add" | "remove";
13
+ readonly path: string;
14
+ readonly toolCallId?: string;
15
+ }
16
+ export interface PermissionDeniedEvent {
17
+ readonly type: "permission_denied";
18
+ /** Policy decision reason. Never includes raw tool arguments. */
19
+ readonly reason: string;
20
+ readonly toolName: string;
21
+ readonly toolCallId?: string;
22
+ readonly approvalId?: string;
23
+ }
24
+ export interface ConfigurationChangedEvent {
25
+ readonly type: "configuration_changed";
26
+ /** Changed config keys only; values never travel in the event. */
27
+ readonly keys: readonly string[];
28
+ }
29
+ export type CodingLifecycleEvent = CodingProcessEvent | FileChangedEvent | WorktreeChangedEvent | PermissionDeniedEvent | ConfigurationChangedEvent;
30
+ export declare const DEFAULT_LIFECYCLE_MAX_EVENT_BYTES = 16384;
31
+ export declare const HARD_LIFECYCLE_MAX_EVENT_BYTES = 65536;
32
+ export declare const DEFAULT_LIFECYCLE_MAX_PATH_BYTES = 4096;
33
+ export declare const HARD_LIFECYCLE_MAX_PATH_BYTES = 16384;
34
+ export declare const DEFAULT_LIFECYCLE_MAX_REASON_BYTES = 1024;
35
+ export declare const HARD_LIFECYCLE_MAX_REASON_BYTES = 16384;
36
+ export declare const DEFAULT_LIFECYCLE_MAX_TOOL_NAME_BYTES = 256;
37
+ export declare const HARD_LIFECYCLE_MAX_TOOL_NAME_BYTES = 4096;
38
+ export declare const DEFAULT_LIFECYCLE_MAX_CONFIG_KEYS = 64;
39
+ export declare const HARD_LIFECYCLE_MAX_CONFIG_KEYS = 256;
40
+ export interface CodingLifecycleLimits {
41
+ readonly maxEventBytes?: number;
42
+ readonly maxPathBytes?: number;
43
+ readonly maxReasonBytes?: number;
44
+ readonly maxToolNameBytes?: number;
45
+ readonly maxConfigKeys?: number;
46
+ }
47
+ export interface ResolvedCodingLifecycleLimits {
48
+ readonly maxEventBytes: number;
49
+ readonly maxPathBytes: number;
50
+ readonly maxReasonBytes: number;
51
+ readonly maxToolNameBytes: number;
52
+ readonly maxConfigKeys: number;
53
+ }
54
+ export declare class CodingLifecycleError extends Error {
55
+ readonly code = "ERR_PRISM_LIFECYCLE_LIMIT";
56
+ constructor(message: string);
57
+ }
58
+ export declare function resolveCodingLifecycleLimits(limits?: CodingLifecycleLimits): ResolvedCodingLifecycleLimits;
59
+ export interface CodingLifecycleEmitter {
60
+ /**
61
+ * Delivers the event to every registered listener. Returns true when at least one
62
+ * listener received it. Drops (returns false) without throwing for unknown kinds,
63
+ * oversized events, or when no listener is registered, so producer success paths
64
+ * never break on telemetry.
65
+ */
66
+ emit(event: CodingLifecycleEvent): boolean;
67
+ /** Registers a listener; the returned function unregisters it. */
68
+ on(listener: (event: CodingLifecycleEvent) => void): () => void;
69
+ }
70
+ export interface CreateCodingLifecycleEmitterOptions {
71
+ readonly limits?: CodingLifecycleLimits;
72
+ /** Convenience initial listener, equivalent to `on`. */
73
+ readonly onEvent?: (event: CodingLifecycleEvent) => void;
74
+ }
75
+ export declare function createCodingLifecycleEmitter(options?: CreateCodingLifecycleEmitterOptions): CodingLifecycleEmitter;
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Consumer-gated coding lifecycle events (Phase 10 Task 1 freeze).
3
+ *
4
+ * Ships only event kinds with a consumer in 0.0.27 (ACP mapper and/or host
5
+ * `CodingLifecycleEmitter` callback). Deferred kinds — check_started/finished,
6
+ * task_created/completed, compaction_started/finished, subagent_started/stopped —
7
+ * MUST NOT be added here until a consumer exists
8
+ * (scripts/phase10-freeze-manifest.json lifecycle.deferredEvents).
9
+ */
10
+ import { validateCodingLimit } from "./limits.js";
11
+ export const DEFAULT_LIFECYCLE_MAX_EVENT_BYTES = 16_384;
12
+ export const HARD_LIFECYCLE_MAX_EVENT_BYTES = 65_536;
13
+ export const DEFAULT_LIFECYCLE_MAX_PATH_BYTES = 4_096;
14
+ export const HARD_LIFECYCLE_MAX_PATH_BYTES = 16_384;
15
+ export const DEFAULT_LIFECYCLE_MAX_REASON_BYTES = 1_024;
16
+ export const HARD_LIFECYCLE_MAX_REASON_BYTES = 16_384;
17
+ export const DEFAULT_LIFECYCLE_MAX_TOOL_NAME_BYTES = 256;
18
+ export const HARD_LIFECYCLE_MAX_TOOL_NAME_BYTES = 4_096;
19
+ export const DEFAULT_LIFECYCLE_MAX_CONFIG_KEYS = 64;
20
+ export const HARD_LIFECYCLE_MAX_CONFIG_KEYS = 256;
21
+ export class CodingLifecycleError extends Error {
22
+ code = "ERR_PRISM_LIFECYCLE_LIMIT";
23
+ constructor(message) {
24
+ super(message);
25
+ this.name = "CodingLifecycleError";
26
+ }
27
+ }
28
+ function validate(name, value, hard) {
29
+ try {
30
+ return validateCodingLimit(name, value, hard);
31
+ }
32
+ catch (error) {
33
+ throw new CodingLifecycleError(error instanceof Error ? error.message : String(error));
34
+ }
35
+ }
36
+ export function resolveCodingLifecycleLimits(limits) {
37
+ return {
38
+ maxEventBytes: validate("maxEventBytes", limits?.maxEventBytes ?? DEFAULT_LIFECYCLE_MAX_EVENT_BYTES, HARD_LIFECYCLE_MAX_EVENT_BYTES),
39
+ maxPathBytes: validate("maxPathBytes", limits?.maxPathBytes ?? DEFAULT_LIFECYCLE_MAX_PATH_BYTES, HARD_LIFECYCLE_MAX_PATH_BYTES),
40
+ maxReasonBytes: validate("maxReasonBytes", limits?.maxReasonBytes ?? DEFAULT_LIFECYCLE_MAX_REASON_BYTES, HARD_LIFECYCLE_MAX_REASON_BYTES),
41
+ maxToolNameBytes: validate("maxToolNameBytes", limits?.maxToolNameBytes ?? DEFAULT_LIFECYCLE_MAX_TOOL_NAME_BYTES, HARD_LIFECYCLE_MAX_TOOL_NAME_BYTES),
42
+ maxConfigKeys: validate("maxConfigKeys", limits?.maxConfigKeys ?? DEFAULT_LIFECYCLE_MAX_CONFIG_KEYS, HARD_LIFECYCLE_MAX_CONFIG_KEYS),
43
+ };
44
+ }
45
+ /** Frozen shipped kinds: the six CodingProcessEvent kinds plus the four new kinds. */
46
+ const FROZEN_EVENT_TYPES = new Set([
47
+ "process_started",
48
+ "process_exited",
49
+ "process_killed",
50
+ "process_released",
51
+ "process_expired",
52
+ "process_unknown",
53
+ "file_changed",
54
+ "worktree_changed",
55
+ "permission_denied",
56
+ "configuration_changed",
57
+ ]);
58
+ export function createCodingLifecycleEmitter(options = {}) {
59
+ const limits = resolveCodingLifecycleLimits(options.limits);
60
+ const listeners = new Set();
61
+ if (options.onEvent)
62
+ listeners.add(options.onEvent);
63
+ return {
64
+ emit(event) {
65
+ if (!event || typeof event !== "object" || !FROZEN_EVENT_TYPES.has(event.type))
66
+ return false;
67
+ if (Buffer.byteLength(JSON.stringify(event), "utf8") > limits.maxEventBytes)
68
+ return false;
69
+ switch (event.type) {
70
+ case "file_changed":
71
+ case "worktree_changed":
72
+ if (Buffer.byteLength(event.path, "utf8") > limits.maxPathBytes)
73
+ return false;
74
+ break;
75
+ case "permission_denied":
76
+ if (Buffer.byteLength(event.reason, "utf8") > limits.maxReasonBytes)
77
+ return false;
78
+ if (Buffer.byteLength(event.toolName, "utf8") > limits.maxToolNameBytes)
79
+ return false;
80
+ break;
81
+ case "configuration_changed":
82
+ if (event.keys.length > limits.maxConfigKeys)
83
+ return false;
84
+ break;
85
+ default:
86
+ break;
87
+ }
88
+ if (listeners.size === 0)
89
+ return false;
90
+ for (const listener of [...listeners])
91
+ listener(event);
92
+ return true;
93
+ },
94
+ on(listener) {
95
+ listeners.add(listener);
96
+ return () => {
97
+ listeners.delete(listener);
98
+ };
99
+ },
100
+ };
101
+ }
102
+ //# sourceMappingURL=lifecycle.js.map
package/dist/limits.d.ts CHANGED
@@ -53,6 +53,9 @@ export declare const DEFAULT_MAX_GIT_MESSAGE_BYTES: number;
53
53
  export declare const HARD_MAX_GIT_MESSAGE_BYTES: number;
54
54
  export declare const DEFAULT_MAX_GIT_OUTPUT_BYTES: number;
55
55
  export declare const HARD_MAX_GIT_OUTPUT_BYTES: number;
56
+ /** Phase 9 freeze: `git ls-files` stdout cap for ignore-aware enumeration. */
57
+ export declare const DEFAULT_MAX_LS_FILES_OUTPUT_BYTES: number;
58
+ export declare const HARD_MAX_LS_FILES_OUTPUT_BYTES: number;
56
59
  export declare const DEFAULT_MAX_GIT_DIFF_LINES = 10000;
57
60
  export declare const HARD_MAX_GIT_DIFF_LINES = 100000;
58
61
  export declare const DEFAULT_MAX_GIT_CHANGED_FILES = 1000;
@@ -92,6 +95,44 @@ export declare const DEFAULT_MAX_CHECK_SUMMARY_BYTES = 1024;
92
95
  export declare const HARD_MAX_CHECK_SUMMARY_BYTES = 8192;
93
96
  export declare const DEFAULT_MAX_CODING_CHECKPOINT_BYTES: number;
94
97
  export declare const HARD_MAX_CODING_CHECKPOINT_BYTES: number;
98
+ /** Phase 9 freeze: language-intelligence / LSP client caps. */
99
+ export declare const DEFAULT_MAX_LSP_MESSAGE_BYTES: number;
100
+ export declare const HARD_MAX_LSP_MESSAGE_BYTES: number;
101
+ export declare const DEFAULT_MAX_LSP_DIAGNOSTICS_PER_FILE = 200;
102
+ export declare const HARD_MAX_LSP_DIAGNOSTICS_PER_FILE = 1000;
103
+ export declare const DEFAULT_MAX_LSP_PENDING_REQUESTS = 32;
104
+ export declare const HARD_MAX_LSP_PENDING_REQUESTS = 128;
105
+ export declare const DEFAULT_MAX_LSP_RESULTS_PER_QUERY = 500;
106
+ export declare const HARD_MAX_LSP_RESULTS_PER_QUERY = 5000;
107
+ export declare const DEFAULT_MAX_LSP_TIMEOUT_MS = 30000;
108
+ export declare const HARD_MAX_LSP_TIMEOUT_MS = 120000;
109
+ export declare const DEFAULT_MAX_LSP_SERVERS = 4;
110
+ export declare const HARD_MAX_LSP_SERVERS = 8;
111
+ /** Freeze: restart budget is fixed at 3 (not host-configurable above). */
112
+ export declare const LSP_RESTARTS_PER_SERVER = 3;
113
+ /** Phase 9 freeze: managed process-session caps. */
114
+ export declare const DEFAULT_MAX_PROCESS_SESSIONS = 8;
115
+ export declare const HARD_MAX_PROCESS_SESSIONS = 32;
116
+ export declare const DEFAULT_MAX_PROCESS_INPUT_BYTES: number;
117
+ export declare const HARD_MAX_PROCESS_INPUT_BYTES: number;
118
+ export declare const DEFAULT_MAX_PROCESS_LIFETIME_MS: number;
119
+ export declare const HARD_MAX_PROCESS_LIFETIME_MS: number;
120
+ export declare const DEFAULT_MAX_PROCESS_OUTPUT_CHUNK_BYTES: number;
121
+ export declare const HARD_MAX_PROCESS_OUTPUT_CHUNK_BYTES: number;
122
+ /** Total output reuses existing accumulator ceilings (64 MiB / 1 GiB). */
123
+ export declare const DEFAULT_MAX_PROCESS_TOTAL_OUTPUT_BYTES: number;
124
+ export declare const HARD_MAX_PROCESS_TOTAL_OUTPUT_BYTES: number;
125
+ /** Forge (GitHub adapter) defaults and hard caps (Phase 9 Task 5). */
126
+ export declare const DEFAULT_MAX_FORGE_PAGES_PER_OPERATION = 10;
127
+ export declare const HARD_MAX_FORGE_PAGES_PER_OPERATION = 100;
128
+ export declare const DEFAULT_MAX_FORGE_PAYLOAD_BYTES: number;
129
+ export declare const HARD_MAX_FORGE_PAYLOAD_BYTES: number;
130
+ export declare const DEFAULT_MAX_FORGE_COMMENTS_PER_REVIEW = 100;
131
+ export declare const HARD_MAX_FORGE_COMMENTS_PER_REVIEW = 1000;
132
+ export declare const DEFAULT_MAX_FORGE_REQUEST_CONCURRENCY = 4;
133
+ export declare const HARD_MAX_FORGE_REQUEST_CONCURRENCY = 8;
134
+ export declare const DEFAULT_MAX_FORGE_REQUEST_TIMEOUT_MS = 30000;
135
+ export declare const HARD_MAX_FORGE_REQUEST_TIMEOUT_MS = 120000;
95
136
  /** Validate one configurable coding resource limit. Invalid values fail instead of clamping. */
96
137
  export declare function validateCodingLimit(name: string, value: number, hardCap: number): number;
97
138
  /** Validate a non-negative integer limit (0 allowed), still capped. */
package/dist/limits.js CHANGED
@@ -53,6 +53,9 @@ export const DEFAULT_MAX_GIT_MESSAGE_BYTES = 64 * 1024;
53
53
  export const HARD_MAX_GIT_MESSAGE_BYTES = 256 * 1024;
54
54
  export const DEFAULT_MAX_GIT_OUTPUT_BYTES = 4 * 1024 * 1024;
55
55
  export const HARD_MAX_GIT_OUTPUT_BYTES = 64 * 1024 * 1024;
56
+ /** Phase 9 freeze: `git ls-files` stdout cap for ignore-aware enumeration. */
57
+ export const DEFAULT_MAX_LS_FILES_OUTPUT_BYTES = 8 * 1024 * 1024;
58
+ export const HARD_MAX_LS_FILES_OUTPUT_BYTES = 64 * 1024 * 1024;
56
59
  export const DEFAULT_MAX_GIT_DIFF_LINES = 10_000;
57
60
  export const HARD_MAX_GIT_DIFF_LINES = 100_000;
58
61
  export const DEFAULT_MAX_GIT_CHANGED_FILES = 1_000;
@@ -92,6 +95,44 @@ export const DEFAULT_MAX_CHECK_SUMMARY_BYTES = 1_024;
92
95
  export const HARD_MAX_CHECK_SUMMARY_BYTES = 8_192;
93
96
  export const DEFAULT_MAX_CODING_CHECKPOINT_BYTES = 64 * 1024;
94
97
  export const HARD_MAX_CODING_CHECKPOINT_BYTES = 512 * 1024;
98
+ /** Phase 9 freeze: language-intelligence / LSP client caps. */
99
+ export const DEFAULT_MAX_LSP_MESSAGE_BYTES = 4 * 1024 * 1024;
100
+ export const HARD_MAX_LSP_MESSAGE_BYTES = 32 * 1024 * 1024;
101
+ export const DEFAULT_MAX_LSP_DIAGNOSTICS_PER_FILE = 200;
102
+ export const HARD_MAX_LSP_DIAGNOSTICS_PER_FILE = 1_000;
103
+ export const DEFAULT_MAX_LSP_PENDING_REQUESTS = 32;
104
+ export const HARD_MAX_LSP_PENDING_REQUESTS = 128;
105
+ export const DEFAULT_MAX_LSP_RESULTS_PER_QUERY = 500;
106
+ export const HARD_MAX_LSP_RESULTS_PER_QUERY = 5_000;
107
+ export const DEFAULT_MAX_LSP_TIMEOUT_MS = 30_000;
108
+ export const HARD_MAX_LSP_TIMEOUT_MS = 120_000;
109
+ export const DEFAULT_MAX_LSP_SERVERS = 4;
110
+ export const HARD_MAX_LSP_SERVERS = 8;
111
+ /** Freeze: restart budget is fixed at 3 (not host-configurable above). */
112
+ export const LSP_RESTARTS_PER_SERVER = 3;
113
+ /** Phase 9 freeze: managed process-session caps. */
114
+ export const DEFAULT_MAX_PROCESS_SESSIONS = 8;
115
+ export const HARD_MAX_PROCESS_SESSIONS = 32;
116
+ export const DEFAULT_MAX_PROCESS_INPUT_BYTES = 64 * 1024;
117
+ export const HARD_MAX_PROCESS_INPUT_BYTES = 1024 * 1024;
118
+ export const DEFAULT_MAX_PROCESS_LIFETIME_MS = 4 * 60 * 60 * 1000;
119
+ export const HARD_MAX_PROCESS_LIFETIME_MS = 24 * 60 * 60 * 1000;
120
+ export const DEFAULT_MAX_PROCESS_OUTPUT_CHUNK_BYTES = 50 * 1024;
121
+ export const HARD_MAX_PROCESS_OUTPUT_CHUNK_BYTES = 1024 * 1024;
122
+ /** Total output reuses existing accumulator ceilings (64 MiB / 1 GiB). */
123
+ export const DEFAULT_MAX_PROCESS_TOTAL_OUTPUT_BYTES = DEFAULT_MAX_TOTAL_OUTPUT_BYTES;
124
+ export const HARD_MAX_PROCESS_TOTAL_OUTPUT_BYTES = HARD_MAX_TOTAL_OUTPUT_BYTES;
125
+ /** Forge (GitHub adapter) defaults and hard caps (Phase 9 Task 5). */
126
+ export const DEFAULT_MAX_FORGE_PAGES_PER_OPERATION = 10;
127
+ export const HARD_MAX_FORGE_PAGES_PER_OPERATION = 100;
128
+ export const DEFAULT_MAX_FORGE_PAYLOAD_BYTES = 1024 * 1024;
129
+ export const HARD_MAX_FORGE_PAYLOAD_BYTES = 8 * 1024 * 1024;
130
+ export const DEFAULT_MAX_FORGE_COMMENTS_PER_REVIEW = 100;
131
+ export const HARD_MAX_FORGE_COMMENTS_PER_REVIEW = 1000;
132
+ export const DEFAULT_MAX_FORGE_REQUEST_CONCURRENCY = 4;
133
+ export const HARD_MAX_FORGE_REQUEST_CONCURRENCY = 8;
134
+ export const DEFAULT_MAX_FORGE_REQUEST_TIMEOUT_MS = 30_000;
135
+ export const HARD_MAX_FORGE_REQUEST_TIMEOUT_MS = 120_000;
95
136
  /** Validate one configurable coding resource limit. Invalid values fail instead of clamping. */
96
137
  export function validateCodingLimit(name, value, hardCap) {
97
138
  if (!Number.isSafeInteger(value) || value < 1 || value > hardCap) {
package/dist/move.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { ExecutionPolicy, ToolDefinition } from "@arnilo/prism";
2
2
  import type { MutationStat } from "./delete.js";
3
+ import type { CodingLifecycleEvent } from "./lifecycle.js";
3
4
  export interface MoveOperations {
4
5
  lstat: (absolutePath: string, options?: {
5
6
  signal?: AbortSignal;
@@ -17,5 +18,7 @@ export interface MoveOperations {
17
18
  export interface MoveToolOptions {
18
19
  executionPolicy?: ExecutionPolicy;
19
20
  operations?: MoveOperations;
21
+ /** Optional consumer-gated lifecycle listener (file_changed / permission_denied). */
22
+ onEvent?: (event: CodingLifecycleEvent) => void;
20
23
  }
21
24
  export declare function createMoveTool(cwd: string, options?: MoveToolOptions): ToolDefinition;
package/dist/move.js CHANGED
@@ -79,7 +79,7 @@ export function createMoveTool(cwd, options) {
79
79
  paths: [fromPath, toPath],
80
80
  risk: "high",
81
81
  metadata: { overwrite, sessionId: context.sessionId, runId: context.runId, signal: context.signal },
82
- }, toolCallId, "move");
82
+ }, toolCallId, "move", (denied) => options?.onEvent?.({ type: "permission_denied", ...denied }));
83
83
  if (!policyCheck.allowed)
84
84
  return policyCheck.result;
85
85
  const allowedFrom = policyCheck.action.paths?.[0] ?? fromPath;
@@ -126,6 +126,7 @@ export function createMoveTool(cwd, options) {
126
126
  if (context.signal?.aborted)
127
127
  return errorResult(toolCallId, "Operation aborted");
128
128
  await ops.rename(allowedFrom, allowedTo, { signal: context.signal });
129
+ options?.onEvent?.({ type: "file_changed", path: allowedTo, op: "move", toolCallId });
129
130
  return {
130
131
  toolCallId,
131
132
  name: "move",
@@ -46,6 +46,14 @@ export declare class OutputAccumulator {
46
46
  cleanupTempFile(): Promise<void>;
47
47
  getLastLineBytes(): number;
48
48
  getTotalRawBytes(): number;
49
+ /**
50
+ * Cursor-paged raw bytes for process sessions.
51
+ * Reads from spill file when present, otherwise from in-memory chunks.
52
+ */
53
+ readRaw(cursor: number, maxBytes: number): {
54
+ readonly data: Buffer;
55
+ readonly nextCursor: number;
56
+ };
49
57
  isOutputLimitExceeded(): boolean;
50
58
  hasStorageError(): boolean;
51
59
  private appendDecodedText;
@@ -1,6 +1,6 @@
1
1
  /** Streaming UTF-8 output retention with bounded memory and spill storage. */
2
2
  import { randomBytes } from "node:crypto";
3
- import { closeSync, openSync, writeSync } from "node:fs";
3
+ import { closeSync, openSync, readSync, writeSync } from "node:fs";
4
4
  import { rm } from "node:fs/promises";
5
5
  import { tmpdir } from "node:os";
6
6
  import { join } from "node:path";
@@ -144,6 +144,50 @@ export class OutputAccumulator {
144
144
  getTotalRawBytes() {
145
145
  return this.totalRawBytes;
146
146
  }
147
+ /**
148
+ * Cursor-paged raw bytes for process sessions.
149
+ * Reads from spill file when present, otherwise from in-memory chunks.
150
+ */
151
+ readRaw(cursor, maxBytes) {
152
+ if (!Number.isSafeInteger(cursor) || cursor < 0) {
153
+ throw new Error("cursor must be a non-negative safe integer");
154
+ }
155
+ if (!Number.isSafeInteger(maxBytes) || maxBytes < 1) {
156
+ throw new Error("maxBytes must be a positive safe integer");
157
+ }
158
+ const total = this.totalRawBytes;
159
+ if (cursor >= total)
160
+ return { data: Buffer.alloc(0), nextCursor: cursor };
161
+ const length = Math.min(maxBytes, total - cursor);
162
+ if (this.tempFilePath) {
163
+ const fd = openSync(this.tempFilePath, "r");
164
+ try {
165
+ const data = Buffer.alloc(length);
166
+ const n = readSync(fd, data, 0, length, cursor);
167
+ return { data: n === length ? data : data.subarray(0, n), nextCursor: cursor + n };
168
+ }
169
+ finally {
170
+ closeSync(fd);
171
+ }
172
+ }
173
+ const data = Buffer.alloc(length);
174
+ let offset = 0;
175
+ let skipped = 0;
176
+ for (const chunk of this.rawChunks) {
177
+ if (offset >= length)
178
+ break;
179
+ if (skipped + chunk.length <= cursor) {
180
+ skipped += chunk.length;
181
+ continue;
182
+ }
183
+ const start = Math.max(0, cursor - skipped);
184
+ const take = Math.min(chunk.length - start, length - offset);
185
+ chunk.copy(data, offset, start, start + take);
186
+ offset += take;
187
+ skipped += chunk.length;
188
+ }
189
+ return { data: offset === length ? data : data.subarray(0, offset), nextCursor: cursor + offset };
190
+ }
147
191
  isOutputLimitExceeded() {
148
192
  return this.exceeded;
149
193
  }
@@ -0,0 +1,3 @@
1
+ export type { CodingProcessEvent, CreateProcessSessionsOptions, ProcessExitResult, ProcessOutputChunk, ProcessSandboxBackend, ProcessSandboxHandle, ProcessSandboxStartRequest, ProcessSession, ProcessSessionLimits, ProcessSessionMetadata, ProcessSessions, ProcessSessionState, ProcessStartRequest, ResolvedProcessSessionLimits, } from "./types.js";
2
+ export { ProcessSessionError, resolveProcessSessionLimits } from "./types.js";
3
+ export { createProcessSessions } from "./sessions.js";
@@ -0,0 +1,3 @@
1
+ export { ProcessSessionError, resolveProcessSessionLimits } from "./types.js";
2
+ export { createProcessSessions } from "./sessions.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,2 @@
1
+ import { type CreateProcessSessionsOptions, type ProcessSessions } from "./types.js";
2
+ export declare function createProcessSessions(options: CreateProcessSessionsOptions): ProcessSessions;