@moxxy/sdk 0.43.0 → 0.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-account-limit.d.ts +41 -0
- package/dist/agent-account-limit.d.ts.map +1 -0
- package/dist/agent-account-limit.js +64 -0
- package/dist/agent-account-limit.js.map +1 -0
- package/dist/agent-computer-use.d.ts +10 -0
- package/dist/agent-computer-use.d.ts.map +1 -0
- package/dist/agent-computer-use.js +24 -0
- package/dist/agent-computer-use.js.map +1 -0
- package/dist/agent-context-window.d.ts +22 -0
- package/dist/agent-context-window.d.ts.map +1 -0
- package/dist/agent-context-window.js +40 -0
- package/dist/agent-context-window.js.map +1 -0
- package/dist/agent-no-reply.d.ts +11 -0
- package/dist/agent-no-reply.d.ts.map +1 -0
- package/dist/agent-no-reply.js +13 -0
- package/dist/agent-no-reply.js.map +1 -0
- package/dist/agent-step.d.ts +14 -0
- package/dist/agent-step.d.ts.map +1 -0
- package/dist/agent-step.js +26 -0
- package/dist/agent-step.js.map +1 -0
- package/dist/agent-work.d.ts +34 -0
- package/dist/agent-work.d.ts.map +1 -0
- package/dist/agent-work.js +80 -0
- package/dist/agent-work.js.map +1 -0
- package/dist/attachment-payload.d.ts +95 -0
- package/dist/attachment-payload.d.ts.map +1 -0
- package/dist/attachment-payload.js +155 -0
- package/dist/attachment-payload.js.map +1 -0
- package/dist/auto-approve.d.ts +9 -0
- package/dist/auto-approve.d.ts.map +1 -1
- package/dist/auto-approve.js +18 -0
- package/dist/auto-approve.js.map +1 -1
- package/dist/channel-auth.d.ts +3 -3
- package/dist/channel-auth.d.ts.map +1 -1
- package/dist/channel-auth.js +1 -1
- package/dist/channel.d.ts +1 -1
- package/dist/client-session.d.ts +9 -5
- package/dist/client-session.d.ts.map +1 -1
- package/dist/computer-control.d.ts +11 -11
- package/dist/computer-control.d.ts.map +1 -1
- package/dist/computer-control.js +1 -1
- package/dist/computer-control.js.map +1 -1
- package/dist/conversation-history.d.ts +50 -0
- package/dist/conversation-history.d.ts.map +1 -0
- package/dist/conversation-history.js +227 -0
- package/dist/conversation-history.js.map +1 -0
- package/dist/cron.d.ts +58 -0
- package/dist/cron.d.ts.map +1 -0
- package/dist/cron.js +320 -0
- package/dist/cron.js.map +1 -0
- package/dist/define.d.ts +2 -1
- package/dist/define.d.ts.map +1 -1
- package/dist/define.js +1 -0
- package/dist/define.js.map +1 -1
- package/dist/event-store.d.ts +1 -1
- package/dist/event-store.d.ts.map +1 -1
- package/dist/event-store.js +1 -0
- package/dist/event-store.js.map +1 -1
- package/dist/events.d.ts +23 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/file-diff.d.ts +31 -0
- package/dist/file-diff.d.ts.map +1 -0
- package/dist/file-diff.js +196 -0
- package/dist/file-diff.js.map +1 -0
- package/dist/index.d.ts +23 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -4
- package/dist/index.js.map +1 -1
- package/dist/mode/agent-step-loop.d.ts +13 -0
- package/dist/mode/agent-step-loop.d.ts.map +1 -0
- package/dist/mode/agent-step-loop.js +578 -0
- package/dist/mode/agent-step-loop.js.map +1 -0
- package/dist/mode/checkpoint-gate.d.ts +25 -0
- package/dist/mode/checkpoint-gate.d.ts.map +1 -0
- package/dist/mode/checkpoint-gate.js +150 -0
- package/dist/mode/checkpoint-gate.js.map +1 -0
- package/dist/mode/checkpoint.d.ts +6 -0
- package/dist/mode/checkpoint.d.ts.map +1 -1
- package/dist/mode/collect-stream.d.ts +2 -0
- package/dist/mode/collect-stream.d.ts.map +1 -1
- package/dist/mode/collect-stream.js +1 -1
- package/dist/mode/collect-stream.js.map +1 -1
- package/dist/mode/project-messages.d.ts +3 -1
- package/dist/mode/project-messages.d.ts.map +1 -1
- package/dist/mode/project-messages.js +122 -81
- package/dist/mode/project-messages.js.map +1 -1
- package/dist/mode/react-loop-options.d.ts +113 -0
- package/dist/mode/react-loop-options.d.ts.map +1 -0
- package/dist/mode/react-loop-options.js +2 -0
- package/dist/mode/react-loop-options.js.map +1 -0
- package/dist/mode/react-loop.d.ts +2 -99
- package/dist/mode/react-loop.d.ts.map +1 -1
- package/dist/mode/react-loop.js +7 -145
- package/dist/mode/react-loop.js.map +1 -1
- package/dist/mode.d.ts +19 -7
- package/dist/mode.d.ts.map +1 -1
- package/dist/mode.js +1 -1
- package/dist/mode.js.map +1 -1
- package/dist/npm-registry.d.ts +22 -0
- package/dist/npm-registry.d.ts.map +1 -0
- package/dist/npm-registry.js +54 -0
- package/dist/npm-registry.js.map +1 -0
- package/dist/permission.d.ts +31 -0
- package/dist/permission.d.ts.map +1 -1
- package/dist/process-invocation.d.ts +2 -0
- package/dist/process-invocation.d.ts.map +1 -1
- package/dist/process-invocation.js +2 -2
- package/dist/process-invocation.js.map +1 -1
- package/dist/process-tree.d.ts +9 -0
- package/dist/process-tree.d.ts.map +1 -0
- package/dist/process-tree.js +40 -0
- package/dist/process-tree.js.map +1 -0
- package/dist/provider-login-bridge.js +1 -1
- package/dist/provider-login-bridge.js.map +1 -1
- package/dist/provider.d.ts +408 -0
- package/dist/provider.d.ts.map +1 -1
- package/dist/question-draft.d.ts +19 -0
- package/dist/question-draft.d.ts.map +1 -0
- package/dist/question-draft.js +30 -0
- package/dist/question-draft.js.map +1 -0
- package/dist/question.d.ts +204 -0
- package/dist/question.d.ts.map +1 -0
- package/dist/question.js +141 -0
- package/dist/question.js.map +1 -0
- package/dist/questions.d.ts +7 -0
- package/dist/questions.d.ts.map +1 -0
- package/dist/questions.js +7 -0
- package/dist/questions.js.map +1 -0
- package/dist/resolvers.d.ts +14 -1
- package/dist/resolvers.d.ts.map +1 -1
- package/dist/resolvers.js +33 -21
- package/dist/resolvers.js.map +1 -1
- package/dist/schemas.d.ts +53 -53
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +3 -2
- package/dist/schemas.js.map +1 -1
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +3 -0
- package/dist/server.js.map +1 -1
- package/dist/session-like.d.ts +19 -1
- package/dist/session-like.d.ts.map +1 -1
- package/dist/starting-model.d.ts +12 -0
- package/dist/starting-model.d.ts.map +1 -0
- package/dist/starting-model.js +9 -0
- package/dist/starting-model.js.map +1 -0
- package/dist/tool-dispatch.d.ts.map +1 -1
- package/dist/tool-dispatch.js +10 -4
- package/dist/tool-dispatch.js.map +1 -1
- package/dist/tool-display.d.ts +79 -3
- package/dist/tool-display.d.ts.map +1 -1
- package/dist/tool-display.js +117 -3
- package/dist/tool-display.js.map +1 -1
- package/dist/tool-modes.d.ts +1 -1
- package/dist/tool-modes.d.ts.map +1 -1
- package/dist/tool-modes.js +8 -2
- package/dist/tool-modes.js.map +1 -1
- package/dist/tool-output.d.ts +15 -0
- package/dist/tool-output.d.ts.map +1 -0
- package/dist/tool-output.js +39 -0
- package/dist/tool-output.js.map +1 -0
- package/dist/tool.d.ts +14 -1
- package/dist/tool.d.ts.map +1 -1
- package/dist/tunnel.d.ts +3 -3
- package/dist/tunnel.d.ts.map +1 -1
- package/dist/tunnel.js +2 -2
- package/dist/workflow-approval.d.ts +9 -9
- package/dist/workflow-approval.d.ts.map +1 -1
- package/dist/workflow-approval.js +1 -1
- package/dist/workflow-approval.js.map +1 -1
- package/package.json +37 -5
- package/src/agent-account-limit.test.ts +87 -0
- package/src/agent-account-limit.ts +89 -0
- package/src/agent-computer-use.test.ts +26 -0
- package/src/agent-computer-use.ts +29 -0
- package/src/agent-context-window.ts +51 -0
- package/src/agent-no-reply.ts +16 -0
- package/src/agent-step.ts +26 -0
- package/src/agent-work.ts +102 -0
- package/src/attachment-payload.test.ts +165 -0
- package/src/attachment-payload.ts +187 -0
- package/src/auto-approve.test.ts +13 -1
- package/src/auto-approve.ts +19 -0
- package/src/channel-auth.ts +3 -3
- package/src/channel.ts +1 -1
- package/src/client-session.ts +9 -2
- package/src/computer-control.ts +1 -1
- package/src/conversation-history.test.ts +184 -0
- package/src/conversation-history.ts +272 -0
- package/src/cron.test.ts +280 -0
- package/src/cron.ts +355 -0
- package/src/define.test.ts +1 -1
- package/src/define.ts +3 -1
- package/src/event-store.ts +2 -1
- package/src/events.ts +23 -1
- package/src/file-diff.test.ts +103 -0
- package/src/file-diff.ts +208 -0
- package/src/index.ts +140 -1
- package/src/json-file-store.test.ts +1 -1
- package/src/loop-helpers.test.ts +15 -0
- package/src/mode/agent-step-loop.ts +645 -0
- package/src/mode/checkpoint-gate.ts +198 -0
- package/src/mode/checkpoint.ts +6 -0
- package/src/mode/collect-stream.ts +1 -1
- package/src/mode/project-messages.test.ts +118 -1
- package/src/mode/project-messages.ts +136 -77
- package/src/mode/react-loop-options.ts +124 -0
- package/src/mode/react-loop.ts +10 -296
- package/src/mode.ts +19 -7
- package/src/npm-registry.test.ts +95 -0
- package/src/npm-registry.ts +57 -0
- package/src/permission.ts +30 -0
- package/src/process-invocation.test.ts +25 -0
- package/src/process-invocation.ts +8 -3
- package/src/process-tree.ts +37 -0
- package/src/provider-login-bridge.ts +1 -1
- package/src/provider-schema-constraints.test.ts +1 -1
- package/src/provider-utils.test.ts +1 -1
- package/src/provider.ts +346 -0
- package/src/question-draft.test.ts +57 -0
- package/src/question-draft.ts +47 -0
- package/src/question.test.ts +130 -0
- package/src/question.ts +229 -0
- package/src/questions.ts +6 -0
- package/src/resolvers.test.ts +84 -1
- package/src/resolvers.ts +40 -27
- package/src/schemas.test.ts +5 -0
- package/src/schemas.ts +3 -2
- package/src/server.ts +3 -0
- package/src/session-like.ts +19 -1
- package/src/skill-mentions.test.ts +1 -1
- package/src/starting-model.test.ts +19 -0
- package/src/starting-model.ts +11 -0
- package/src/token-efficiency.test.ts +1 -1
- package/src/tool-dispatch.ts +10 -4
- package/src/tool-display.test.ts +119 -0
- package/src/tool-display.ts +162 -4
- package/src/tool-gating.test.ts +1 -1
- package/src/tool-icon.test.ts +1 -1
- package/src/tool-modes.test.ts +18 -1
- package/src/tool-modes.ts +6 -2
- package/src/tool-output.test.ts +46 -0
- package/src/tool-output.ts +46 -0
- package/src/tool.ts +14 -1
- package/src/tunnel.ts +3 -3
- package/src/workflow-approval.ts +1 -1
package/src/file-diff.ts
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import type { DiffHunk, DiffLine, FileDiffDisplay } from './tool-display.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* File changes as `file-diff` displays, from what is at hand: the text before
|
|
5
|
+
* and after (Moxxy's Write/Edit, OpenCode), or patch hunks the agent already
|
|
6
|
+
* made (Claude's structured patch, Codex's unified diff). Only the changed
|
|
7
|
+
* slices are kept, so a display stays small whatever the file's size.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** A hunk as patches write it: lines prefixed with ' ', '+' or '-'. */
|
|
11
|
+
export interface PatchHunk {
|
|
12
|
+
readonly oldStart: number;
|
|
13
|
+
readonly newStart: number;
|
|
14
|
+
readonly lines: ReadonlyArray<string>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface FileDiffTarget {
|
|
18
|
+
/** As the diff shows it; see `diffPathIn`. */
|
|
19
|
+
readonly path: string;
|
|
20
|
+
readonly mode: 'create' | 'update';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Context lines kept around each change. */
|
|
24
|
+
const CONTEXT = 2;
|
|
25
|
+
/** Diff lines shown at most; the counts still cover every line. */
|
|
26
|
+
const MAX_DIFF_LINES = 400;
|
|
27
|
+
/** Above this combined size (~2 MB) only the counts are given. */
|
|
28
|
+
const MAX_DIFF_BYTES = 2_000_000;
|
|
29
|
+
/** LCS table cell budget; above it the changed middle is one replace block. */
|
|
30
|
+
const LCS_CELL_BUDGET = 1_000_000;
|
|
31
|
+
|
|
32
|
+
type Change = { readonly kind: DiffLine['kind']; readonly text: string };
|
|
33
|
+
|
|
34
|
+
export function fileDiffFromText(args: FileDiffTarget & { readonly before: string; readonly after: string }): FileDiffDisplay {
|
|
35
|
+
const before = toLines(args.before);
|
|
36
|
+
const after = toLines(args.after);
|
|
37
|
+
if (args.before.length + args.after.length > MAX_DIFF_BYTES) {
|
|
38
|
+
return { kind: 'file-diff', path: args.path, mode: args.mode, added: after.length, removed: before.length, hunks: [], truncated: true };
|
|
39
|
+
}
|
|
40
|
+
const lines = numberLines(1, 1, changesBetween(before, after));
|
|
41
|
+
const { hunks, truncated } = hunksAround(lines);
|
|
42
|
+
return display(args, lines, hunks, truncated);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function fileDiffFromPatch(args: FileDiffTarget & { readonly hunks: ReadonlyArray<PatchHunk> }): FileDiffDisplay {
|
|
46
|
+
const all: DiffLine[] = [];
|
|
47
|
+
const hunks: DiffHunk[] = [];
|
|
48
|
+
let shown = 0;
|
|
49
|
+
let truncated = false;
|
|
50
|
+
for (const hunk of args.hunks) {
|
|
51
|
+
const lines = numberLines(hunk.oldStart, hunk.newStart, hunk.lines.flatMap(patchChange));
|
|
52
|
+
all.push(...lines);
|
|
53
|
+
if (truncated) continue;
|
|
54
|
+
const kept = lines.slice(0, MAX_DIFF_LINES - shown);
|
|
55
|
+
shown += kept.length;
|
|
56
|
+
if (kept.length < lines.length) truncated = true;
|
|
57
|
+
if (kept.length > 0) hunks.push(hunkOf(kept));
|
|
58
|
+
}
|
|
59
|
+
return display(args, all, hunks, truncated);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** The hunks of a unified diff; file headers and anything outside a hunk are left out. */
|
|
63
|
+
export function parseUnifiedDiff(text: string): PatchHunk[] {
|
|
64
|
+
const hunks: PatchHunk[] = [];
|
|
65
|
+
let current: { lines: string[]; oldLeft: number; newLeft: number } | undefined;
|
|
66
|
+
for (const line of text.split('\n')) {
|
|
67
|
+
if (current && (current.oldLeft > 0 || current.newLeft > 0 || line.startsWith('\\'))) {
|
|
68
|
+
// The header's counts say where the hunk ends; an empty line inside it is context written without its space.
|
|
69
|
+
if (line.startsWith('+')) current.newLeft -= 1;
|
|
70
|
+
else if (line.startsWith('-')) current.oldLeft -= 1;
|
|
71
|
+
else if (!line.startsWith('\\')) {
|
|
72
|
+
current.oldLeft -= 1;
|
|
73
|
+
current.newLeft -= 1;
|
|
74
|
+
}
|
|
75
|
+
current.lines.push(line);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const header = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/.exec(line);
|
|
79
|
+
if (!header) continue;
|
|
80
|
+
current = { lines: [], oldLeft: Number(header[2] ?? 1), newLeft: Number(header[4] ?? 1) };
|
|
81
|
+
hunks.push({ oldStart: Number(header[1]), newStart: Number(header[3]), lines: current.lines });
|
|
82
|
+
}
|
|
83
|
+
return hunks;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** `file` relative to the project folder `cwd` when inside it, else as given; either separator. */
|
|
87
|
+
export function diffPathIn(cwd: string, file: string): string {
|
|
88
|
+
let end = cwd.length;
|
|
89
|
+
while (end > 0 && (cwd[end - 1] === '/' || cwd[end - 1] === '\\')) end -= 1;
|
|
90
|
+
const root = cwd.slice(0, end);
|
|
91
|
+
if (root && file.startsWith(root) && (file[root.length] === '/' || file[root.length] === '\\')) return file.slice(root.length + 1);
|
|
92
|
+
return file;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function display(target: FileDiffTarget, lines: ReadonlyArray<DiffLine>, hunks: DiffHunk[], truncated: boolean): FileDiffDisplay {
|
|
96
|
+
return {
|
|
97
|
+
kind: 'file-diff',
|
|
98
|
+
path: target.path,
|
|
99
|
+
mode: target.mode,
|
|
100
|
+
added: lines.filter((line) => line.kind === 'add').length,
|
|
101
|
+
removed: lines.filter((line) => line.kind === 'del').length,
|
|
102
|
+
hunks,
|
|
103
|
+
...(truncated ? { truncated: true } : {}),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Lines of a text; a single trailing newline ends the last line, as in diffs. */
|
|
108
|
+
function toLines(text: string): string[] {
|
|
109
|
+
if (text.length === 0) return [];
|
|
110
|
+
return (text.endsWith('\n') ? text.slice(0, -1) : text).split('\n');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function patchChange(line: string): Change[] {
|
|
114
|
+
if (line.startsWith('+')) return [{ kind: 'add', text: line.slice(1) }];
|
|
115
|
+
if (line.startsWith('-')) return [{ kind: 'del', text: line.slice(1) }];
|
|
116
|
+
if (line.startsWith('\\')) return [];
|
|
117
|
+
return [{ kind: 'context', text: line.startsWith(' ') ? line.slice(1) : line }];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function numberLines(oldStart: number, newStart: number, changes: ReadonlyArray<Change>): DiffLine[] {
|
|
121
|
+
let oldNo = oldStart;
|
|
122
|
+
let newNo = newStart;
|
|
123
|
+
return changes.map((change) => {
|
|
124
|
+
if (change.kind === 'add') return { kind: 'add', text: change.text, newNo: newNo++ };
|
|
125
|
+
if (change.kind === 'del') return { kind: 'del', text: change.text, oldNo: oldNo++ };
|
|
126
|
+
return { kind: 'context', text: change.text, oldNo: oldNo++, newNo: newNo++ };
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Every line of both texts in order, the common prefix and suffix trimmed before the LCS pass. */
|
|
131
|
+
function changesBetween(before: ReadonlyArray<string>, after: ReadonlyArray<string>): Change[] {
|
|
132
|
+
let start = 0;
|
|
133
|
+
while (start < before.length && start < after.length && before[start] === after[start]) start += 1;
|
|
134
|
+
let endBefore = before.length;
|
|
135
|
+
let endAfter = after.length;
|
|
136
|
+
while (endBefore > start && endAfter > start && before[endBefore - 1] === after[endAfter - 1]) {
|
|
137
|
+
endBefore -= 1;
|
|
138
|
+
endAfter -= 1;
|
|
139
|
+
}
|
|
140
|
+
const context = (text: string): Change => ({ kind: 'context', text });
|
|
141
|
+
return [
|
|
142
|
+
...before.slice(0, start).map(context),
|
|
143
|
+
...lcs(before.slice(start, endBefore), after.slice(start, endAfter)),
|
|
144
|
+
...before.slice(endBefore).map(context),
|
|
145
|
+
];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function lcs(a: ReadonlyArray<string>, b: ReadonlyArray<string>): Change[] {
|
|
149
|
+
const removed = (text: string): Change => ({ kind: 'del', text });
|
|
150
|
+
const added = (text: string): Change => ({ kind: 'add', text });
|
|
151
|
+
if (a.length === 0 || b.length === 0 || a.length * b.length > LCS_CELL_BUDGET) return [...a.map(removed), ...b.map(added)];
|
|
152
|
+
// common[i * width + j] = length of the longest common run of a[i:] and b[j:].
|
|
153
|
+
const width = b.length + 1;
|
|
154
|
+
const common = new Uint32Array((a.length + 1) * width);
|
|
155
|
+
const at = (i: number, j: number): number => common[i * width + j] ?? 0;
|
|
156
|
+
for (let i = a.length - 1; i >= 0; i -= 1) {
|
|
157
|
+
for (let j = b.length - 1; j >= 0; j -= 1) {
|
|
158
|
+
common[i * width + j] = a[i] === b[j] ? at(i + 1, j + 1) + 1 : Math.max(at(i + 1, j), at(i, j + 1));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
const changes: Change[] = [];
|
|
162
|
+
let i = 0;
|
|
163
|
+
let j = 0;
|
|
164
|
+
while (i < a.length && j < b.length) {
|
|
165
|
+
const left = a[i] ?? '';
|
|
166
|
+
const right = b[j] ?? '';
|
|
167
|
+
if (left === right) {
|
|
168
|
+
changes.push({ kind: 'context', text: left });
|
|
169
|
+
i += 1;
|
|
170
|
+
j += 1;
|
|
171
|
+
} else if (at(i + 1, j) >= at(i, j + 1)) {
|
|
172
|
+
changes.push(removed(left));
|
|
173
|
+
i += 1;
|
|
174
|
+
} else {
|
|
175
|
+
changes.push(added(right));
|
|
176
|
+
j += 1;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return [...changes, ...a.slice(i).map(removed), ...b.slice(j).map(added)];
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/** The changed lines with CONTEXT lines around them, grouped into hunks and capped at MAX_DIFF_LINES. */
|
|
183
|
+
function hunksAround(lines: ReadonlyArray<DiffLine>): { hunks: DiffHunk[]; truncated: boolean } {
|
|
184
|
+
const ranges: Array<[number, number]> = [];
|
|
185
|
+
lines.forEach((line, index) => {
|
|
186
|
+
if (line.kind === 'context') return;
|
|
187
|
+
const lo = Math.max(0, index - CONTEXT);
|
|
188
|
+
const hi = Math.min(lines.length - 1, index + CONTEXT);
|
|
189
|
+
const last = ranges[ranges.length - 1];
|
|
190
|
+
if (last && lo <= last[1] + 1) last[1] = Math.max(last[1], hi);
|
|
191
|
+
else ranges.push([lo, hi]);
|
|
192
|
+
});
|
|
193
|
+
const hunks: DiffHunk[] = [];
|
|
194
|
+
let shown = 0;
|
|
195
|
+
for (const [lo, hi] of ranges) {
|
|
196
|
+
const kept = lines.slice(lo, Math.min(hi + 1, lo + MAX_DIFF_LINES - shown));
|
|
197
|
+
shown += kept.length;
|
|
198
|
+
if (kept.length > 0) hunks.push(hunkOf(kept));
|
|
199
|
+
if (kept.length < hi + 1 - lo) return { hunks, truncated: true };
|
|
200
|
+
}
|
|
201
|
+
return { hunks, truncated: false };
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function hunkOf(lines: ReadonlyArray<DiffLine>): DiffHunk {
|
|
205
|
+
const olds = lines.flatMap((line) => (line.oldNo === undefined ? [] : [line.oldNo]));
|
|
206
|
+
const news = lines.flatMap((line) => (line.newNo === undefined ? [] : [line.newNo]));
|
|
207
|
+
return { oldStart: olds[0] ?? 0, oldLines: olds.length, newStart: news[0] ?? 0, newLines: news.length, lines };
|
|
208
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -137,10 +137,46 @@ export type {
|
|
|
137
137
|
export {
|
|
138
138
|
AUTO_APPROVE_PLUGIN_ID,
|
|
139
139
|
AUTO_APPROVE_SUBTYPE,
|
|
140
|
+
AUTO_APPROVE_RESTORED_SUBTYPE,
|
|
141
|
+
autoApproveFromAgent,
|
|
140
142
|
autoApproveFromEvents,
|
|
143
|
+
autoApproveRecorded,
|
|
141
144
|
autoApproveSwitch,
|
|
142
145
|
} from './auto-approve.js';
|
|
143
146
|
|
|
147
|
+
export {
|
|
148
|
+
QUESTION_PLUGIN_ID,
|
|
149
|
+
QUESTION_ASKED,
|
|
150
|
+
QUESTION_RESOLVED,
|
|
151
|
+
QUESTION_CLOSED_AGENT_WENT_ON,
|
|
152
|
+
QUESTION_CLOSED_NEW_MESSAGE,
|
|
153
|
+
questionCloseNote,
|
|
154
|
+
questionOptionSchema,
|
|
155
|
+
questionItemSchema,
|
|
156
|
+
questionAnswerSchema,
|
|
157
|
+
questionAnswersSchema,
|
|
158
|
+
questionRecord,
|
|
159
|
+
openQuestionsFromEvents,
|
|
160
|
+
questionAnswersProblem,
|
|
161
|
+
describeQuestionAnswers,
|
|
162
|
+
questionAnswerDisplay,
|
|
163
|
+
} from './question.js';
|
|
164
|
+
export type {
|
|
165
|
+
QuestionOption,
|
|
166
|
+
QuestionItem,
|
|
167
|
+
QuestionAnswer,
|
|
168
|
+
QuestionAnswers,
|
|
169
|
+
QuestionCloseNote,
|
|
170
|
+
QuestionAskOptions,
|
|
171
|
+
QuestionOutcome,
|
|
172
|
+
QuestionRecord,
|
|
173
|
+
OpenQuestion,
|
|
174
|
+
QuestionAsker,
|
|
175
|
+
SessionQuestions,
|
|
176
|
+
} from './question.js';
|
|
177
|
+
export { emptyDraft, chooseOption, typeOwnAnswer, draftAnswers } from './question-draft.js';
|
|
178
|
+
export type { QuestionDraft } from './question-draft.js';
|
|
179
|
+
|
|
144
180
|
export type {
|
|
145
181
|
ClientSession,
|
|
146
182
|
ProvidersClientView,
|
|
@@ -162,6 +198,7 @@ export type {
|
|
|
162
198
|
PendingToolCall,
|
|
163
199
|
PermissionContext,
|
|
164
200
|
PermissionResolver,
|
|
201
|
+
StandingAllowRule,
|
|
165
202
|
} from './permission.js';
|
|
166
203
|
|
|
167
204
|
export type {
|
|
@@ -221,7 +258,69 @@ export type {
|
|
|
221
258
|
ProviderOAuthResult,
|
|
222
259
|
ProviderOAuthStatus,
|
|
223
260
|
ProviderAuthDescriptor,
|
|
261
|
+
AgentCliState,
|
|
262
|
+
AgentCliOrigin,
|
|
263
|
+
AgentCliReport,
|
|
264
|
+
ProviderAgentCli,
|
|
265
|
+
} from './provider.js';
|
|
266
|
+
export type {
|
|
267
|
+
AgentStepRequest,
|
|
268
|
+
AgentStepHost,
|
|
269
|
+
AgentTurnStart,
|
|
270
|
+
AgentActivity,
|
|
271
|
+
AgentBackgroundWork,
|
|
272
|
+
AgentScheduledWakeup,
|
|
273
|
+
AgentWorkEnd,
|
|
274
|
+
AgentStepEvent,
|
|
275
|
+
AgentGoalStatus,
|
|
276
|
+
AgentOwnModes,
|
|
277
|
+
AgentToolCall,
|
|
278
|
+
AgentToolOutcome,
|
|
279
|
+
AgentApprovalRequest,
|
|
280
|
+
AgentApprovalDecision,
|
|
224
281
|
} from './provider.js';
|
|
282
|
+
export { startingModel } from './starting-model.js';
|
|
283
|
+
export {
|
|
284
|
+
ACCOUNT_LIMIT_NEAR_PERCENT,
|
|
285
|
+
AGENT_ACCOUNT_LIMIT_SUBTYPE,
|
|
286
|
+
accountLimitInForce,
|
|
287
|
+
accountLimitOfEvent,
|
|
288
|
+
recordedAccountLimit,
|
|
289
|
+
sameAccountLimit,
|
|
290
|
+
withKnownReset,
|
|
291
|
+
type AgentAccountLimit,
|
|
292
|
+
type RecordedAccountLimit,
|
|
293
|
+
} from './agent-account-limit.js';
|
|
294
|
+
export {
|
|
295
|
+
AGENT_CONTEXT_WINDOW_SUBTYPE,
|
|
296
|
+
contextWindowOfEvent,
|
|
297
|
+
isContextWindowSize,
|
|
298
|
+
recordedContextWindows,
|
|
299
|
+
withRecordedContextWindows,
|
|
300
|
+
type RecordedContextWindow,
|
|
301
|
+
} from './agent-context-window.js';
|
|
302
|
+
export { AGENT_NO_REPLY_SUBTYPE, AGENT_NO_REPLY_TEXT, isAgentNoReplyEvent } from './agent-no-reply.js';
|
|
303
|
+
export {
|
|
304
|
+
AGENT_BACKGROUND_WORK_ENDED_SUBTYPE,
|
|
305
|
+
AGENT_BACKGROUND_WORK_SUBTYPE,
|
|
306
|
+
AGENT_WORK_OUTPUT_LIMIT,
|
|
307
|
+
SUBAGENT_MESSAGE_SUBTYPE,
|
|
308
|
+
agentActivityRecord,
|
|
309
|
+
isAgentWorkEvent,
|
|
310
|
+
isSubagentEvent,
|
|
311
|
+
type AgentActivityRecord,
|
|
312
|
+
type SubagentNames,
|
|
313
|
+
} from './agent-work.js';
|
|
314
|
+
export { AGENT_CONNECTION_PLUGIN_ID, AGENT_GOAL_SUBTYPE, AGENT_SESSION_SUBTYPE, SUBAGENTS_PLUGIN_ID, agentSessionFromEvents } from './agent-step.js';
|
|
315
|
+
export {
|
|
316
|
+
conversationTurns,
|
|
317
|
+
EARLIER_CONVERSATION_CHARS,
|
|
318
|
+
renderEarlierConversation,
|
|
319
|
+
renderMissedTurns,
|
|
320
|
+
searchConversation,
|
|
321
|
+
type ConversationMatch,
|
|
322
|
+
type ConversationTurn,
|
|
323
|
+
} from './conversation-history.js';
|
|
225
324
|
export {
|
|
226
325
|
encodeLoginAuthUrl,
|
|
227
326
|
decodeLoginAuthUrl,
|
|
@@ -236,18 +335,36 @@ export type {
|
|
|
236
335
|
DiffHunk,
|
|
237
336
|
DiffRow,
|
|
238
337
|
FileDiffDisplay,
|
|
338
|
+
AnsweredQuestion,
|
|
339
|
+
QuestionAnswerDisplay,
|
|
340
|
+
ListedStep,
|
|
341
|
+
StepListDisplay,
|
|
342
|
+
StepStatus,
|
|
239
343
|
ToolDisplay,
|
|
240
344
|
ToolDisplayResult,
|
|
345
|
+
ToolImage,
|
|
241
346
|
} from './tool-display.js';
|
|
242
347
|
export {
|
|
243
348
|
isToolDisplayResult,
|
|
244
349
|
isToolDisplay,
|
|
245
350
|
isFileDiffDisplay,
|
|
351
|
+
isQuestionAnswerDisplay,
|
|
352
|
+
isStepListDisplay,
|
|
353
|
+
stepStatusOf,
|
|
354
|
+
stepsFromTodos,
|
|
355
|
+
stepListOutput,
|
|
356
|
+
stepListProgress,
|
|
357
|
+
questionAnswerLines,
|
|
246
358
|
fileDiffSummary,
|
|
247
359
|
fileDiffVerb,
|
|
248
360
|
diffGutterNo,
|
|
249
361
|
toDiffRows,
|
|
362
|
+
toolImagesOf,
|
|
363
|
+
imageToolOutput,
|
|
250
364
|
} from './tool-display.js';
|
|
365
|
+
export { fileDiffFromText, fileDiffFromPatch, parseUnifiedDiff, diffPathIn, type PatchHunk } from './file-diff.js';
|
|
366
|
+
export { agentComputerUseOf, type AgentComputerUse } from './agent-computer-use.js';
|
|
367
|
+
export { toolOutputForModel, type ToolOutputForModel, type ToolImageBlock } from './tool-output.js';
|
|
251
368
|
export type {
|
|
252
369
|
ViewNode,
|
|
253
370
|
ViewAction,
|
|
@@ -312,6 +429,25 @@ export {
|
|
|
312
429
|
type JsonFileStoreOptions,
|
|
313
430
|
} from './json-file-store.js';
|
|
314
431
|
export { assertDefined, assertNever, invariant } from './assert.js';
|
|
432
|
+
export {
|
|
433
|
+
ATTACHMENT_READ_CHUNK_CHARS,
|
|
434
|
+
CLIENT_INLINE_ATTACHMENT_CHARS,
|
|
435
|
+
CLIENT_INLINE_EVENT_CHARS,
|
|
436
|
+
HISTORY_PAGE_MAX_CHARS,
|
|
437
|
+
MODEL_ATTACHMENT_BUDGET_CHARS,
|
|
438
|
+
attachmentBytes,
|
|
439
|
+
attachmentKey,
|
|
440
|
+
eventForClient,
|
|
441
|
+
findAttachment,
|
|
442
|
+
historyPageForClient,
|
|
443
|
+
listAttachments,
|
|
444
|
+
readAttachmentChunk,
|
|
445
|
+
restoredAttachmentRef,
|
|
446
|
+
type AttachmentChunk,
|
|
447
|
+
type FoundAttachment,
|
|
448
|
+
type HistoryPage,
|
|
449
|
+
type RestoredAttachmentOutput,
|
|
450
|
+
} from './attachment-payload.js';
|
|
315
451
|
export { compareSemver, parseSemverCore } from './semver.js';
|
|
316
452
|
// readRequestBody/bearerTokenMatches (http-utils) and the channel-auth value
|
|
317
453
|
// helpers live on the './server' subpath — they reach node:http/crypto/fs/path.
|
|
@@ -322,7 +458,10 @@ export {
|
|
|
322
458
|
createCallbackResolver,
|
|
323
459
|
createAllowListResolver,
|
|
324
460
|
createDeferredPermissionResolver,
|
|
461
|
+
createSessionGrants,
|
|
462
|
+
alwaysAllowRule,
|
|
325
463
|
evaluateToolRule,
|
|
464
|
+
type SessionGrants,
|
|
326
465
|
type CallbackResolverOptions,
|
|
327
466
|
type PermissionPromptHandler,
|
|
328
467
|
type DeferredPermissionResolver,
|
|
@@ -644,5 +783,5 @@ export {
|
|
|
644
783
|
type InstallTarget,
|
|
645
784
|
} from './install-hints.js';
|
|
646
785
|
|
|
647
|
-
export { z } from 'zod';
|
|
786
|
+
export { z } from 'zod/v3';
|
|
648
787
|
export { workflowApprovalItemSchema, workflowApprovalItemsSchema } from './workflow-approval.js';
|
|
@@ -3,7 +3,7 @@ import { tmpdir } from 'node:os';
|
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
5
5
|
import { posixFileModes } from '@moxxy/vitest-preset/platform';
|
|
6
|
-
import { z } from 'zod';
|
|
6
|
+
import { z } from 'zod/v3';
|
|
7
7
|
import { createJsonFileStore } from './json-file-store.js';
|
|
8
8
|
import { removeDir } from '@moxxy/vitest-preset/fs';
|
|
9
9
|
|
package/src/loop-helpers.test.ts
CHANGED
|
@@ -192,6 +192,21 @@ describe('projectMessagesFromLog', () => {
|
|
|
192
192
|
}
|
|
193
193
|
});
|
|
194
194
|
|
|
195
|
+
it('projects only the text of an answered Question, not the copy kept for the transcript', () => {
|
|
196
|
+
const output = {
|
|
197
|
+
forModel: 'The user answered:\n- "Which colour?" → Blue',
|
|
198
|
+
display: { kind: 'question-answer' as const, questions: [{ question: 'Which colour?', chosen: ['Blue'] }] },
|
|
199
|
+
};
|
|
200
|
+
const log = reader([
|
|
201
|
+
event(0, { type: 'user_prompt', turnId: t1, source: 'user', text: 'make a button' }),
|
|
202
|
+
event(1, { type: 'tool_call_requested', turnId: t1, source: 'model', callId: 'c1', name: 'ask_user', input: {} }),
|
|
203
|
+
event(2, { type: 'tool_result', turnId: t1, source: 'tool', callId: 'c1', ok: true, output }),
|
|
204
|
+
]);
|
|
205
|
+
|
|
206
|
+
const toolResult = projectMessagesFromLog({ log }).find((m) => m.role === 'tool_result');
|
|
207
|
+
expect(toolResult?.content[0]).toMatchObject({ type: 'tool_result', content: output.forModel });
|
|
208
|
+
});
|
|
209
|
+
|
|
195
210
|
it('projects an image-shaped tool result as an image block, not stringified text', () => {
|
|
196
211
|
// A screenshot/clipboard tool returns { mediaType, base64 }. The model must
|
|
197
212
|
// SEE the pixels (image block), not a giant base64 string JSON-stringified
|