@orion-agents/orion-code 0.3.25 → 0.3.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.
- package/CHANGELOG.md +74 -9
- package/README.md +10 -8
- package/README.zh-CN.md +7 -6
- package/dist/runtime/legacy-thread-materializer.d.ts +13 -0
- package/dist/runtime/legacy-thread-materializer.js +72 -0
- package/dist/services/code-review/constraints.d.ts +25 -0
- package/dist/services/code-review/constraints.js +79 -0
- package/dist/services/code-review/contract.d.ts +172 -0
- package/dist/services/code-review/contract.js +184 -0
- package/dist/services/code-review/snapshot.d.ts +64 -0
- package/dist/services/code-review/snapshot.js +321 -0
- package/dist/services/session-storage.js +21 -0
- package/dist/web/git-diff-document.d.ts +19 -0
- package/dist/web/git-diff-document.js +46 -2
- package/dist/web/git-read-model-service.js +76 -5
- package/npm-shrinkwrap.json +12 -12
- package/package.json +1 -1
|
@@ -75,6 +75,31 @@ function parseGitDiffDocument(input) {
|
|
|
75
75
|
let additions = 0;
|
|
76
76
|
let deletions = 0;
|
|
77
77
|
let current;
|
|
78
|
+
const openHunk = (header, index, oldCursor, newCursor) => {
|
|
79
|
+
const headerMatch = HUNK_HEADER.exec(header);
|
|
80
|
+
if (!headerMatch)
|
|
81
|
+
return;
|
|
82
|
+
const oldStart = Number(headerMatch[1]);
|
|
83
|
+
const newStart = Number(headerMatch[3]);
|
|
84
|
+
current = {
|
|
85
|
+
header,
|
|
86
|
+
oldStart,
|
|
87
|
+
oldLines: headerMatch[2] === undefined ? 1 : Number(headerMatch[2]),
|
|
88
|
+
newStart,
|
|
89
|
+
newLines: headerMatch[4] === undefined ? 1 : Number(headerMatch[4]),
|
|
90
|
+
contextLabel: (headerMatch[5] ?? '').trim(),
|
|
91
|
+
lines: [],
|
|
92
|
+
oldCursor,
|
|
93
|
+
newCursor,
|
|
94
|
+
index,
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
// v0.3.26 #275 — a continuation page starts mid-hunk: re-open it from the
|
|
98
|
+
// resume state before the first line is classified. A page that happens to
|
|
99
|
+
// start with its own `@@` header simply ignores the resume state.
|
|
100
|
+
if (input.resume && !HUNK_HEADER.test(input.lines[0] ?? '')) {
|
|
101
|
+
openHunk(input.resume.header, input.resume.index, input.resume.oldCursor, input.resume.newCursor);
|
|
102
|
+
}
|
|
78
103
|
const closeHunk = () => {
|
|
79
104
|
if (!current)
|
|
80
105
|
return;
|
|
@@ -134,14 +159,22 @@ function parseGitDiffDocument(input) {
|
|
|
134
159
|
}));
|
|
135
160
|
continue;
|
|
136
161
|
}
|
|
137
|
-
|
|
162
|
+
// v0.3.26 #274 — the body marker decides first. A deletion of a line that
|
|
163
|
+
// itself starts with `-- ` produces the body row `--- old comment`, which a
|
|
164
|
+
// header-first check mistook for the old-file header, closing the hunk and
|
|
165
|
+
// demoting the remaining body to document meta. Genuine document-level lines
|
|
166
|
+
// carry no body marker by construction: context rows start with a space,
|
|
167
|
+
// additions with `+`, deletions with `-`, and file boundaries are announced
|
|
168
|
+
// by a markerless `diff --git` line.
|
|
169
|
+
const marker = raw[0];
|
|
170
|
+
const isBodyRow = marker === '+' || marker === '-' || marker === ' ' || raw === '';
|
|
171
|
+
if (!isBodyRow && isMetaLine(raw)) {
|
|
138
172
|
// A file boundary inside one page (multi-command reads) closes the current hunk.
|
|
139
173
|
closeHunk();
|
|
140
174
|
if (raw)
|
|
141
175
|
meta.push(raw);
|
|
142
176
|
continue;
|
|
143
177
|
}
|
|
144
|
-
const marker = raw[0];
|
|
145
178
|
const text = raw.length > 0 ? raw.slice(1) : '';
|
|
146
179
|
let lineKind;
|
|
147
180
|
let oldLineNumber = null;
|
|
@@ -185,6 +218,16 @@ function parseGitDiffDocument(input) {
|
|
|
185
218
|
raw,
|
|
186
219
|
}));
|
|
187
220
|
}
|
|
221
|
+
// v0.3.26 #275 — a page that ends inside a hunk publishes the hunk state for
|
|
222
|
+
// the continuation cursor; a page ending on a boundary has nothing to resume.
|
|
223
|
+
const pendingHunk = input.hasMore && current
|
|
224
|
+
? Object.freeze({
|
|
225
|
+
header: current.header,
|
|
226
|
+
index: current.index,
|
|
227
|
+
oldCursor: current.oldCursor,
|
|
228
|
+
newCursor: current.newCursor,
|
|
229
|
+
})
|
|
230
|
+
: null;
|
|
188
231
|
closeHunk();
|
|
189
232
|
const frozenHunks = Object.freeze(hunks);
|
|
190
233
|
let completeness = 'complete';
|
|
@@ -203,6 +246,7 @@ function parseGitDiffDocument(input) {
|
|
|
203
246
|
binary,
|
|
204
247
|
hunks: frozenHunks,
|
|
205
248
|
meta: Object.freeze(meta),
|
|
249
|
+
pendingHunk,
|
|
206
250
|
completeness,
|
|
207
251
|
additions,
|
|
208
252
|
deletions,
|
|
@@ -236,7 +236,13 @@ class GitReadModelServiceV1 {
|
|
|
236
236
|
*/
|
|
237
237
|
async diffDocument(input) {
|
|
238
238
|
const page = await this.diff(input);
|
|
239
|
-
|
|
239
|
+
// v0.3.26 #275 — the incoming cursor may carry the hunk state this page
|
|
240
|
+
// continues; diff() already validated the cursor, so decoding it here only
|
|
241
|
+
// reads the resume state.
|
|
242
|
+
const resumeHunk = input.cursor
|
|
243
|
+
? this.decodeCursor(input.cursor, 'diff', page.repositoryRevision, page.fileId, diffScope(input.ignoreWhitespace === true, input.wordDiff === true)).resumeHunk
|
|
244
|
+
: undefined;
|
|
245
|
+
const document = (0, git_diff_document_1.parseGitDiffDocument)({
|
|
240
246
|
fileToken: page.fileId,
|
|
241
247
|
path: page.path,
|
|
242
248
|
source: page.source,
|
|
@@ -244,7 +250,18 @@ class GitReadModelServiceV1 {
|
|
|
244
250
|
lines: page.lines,
|
|
245
251
|
hasMore: page.nextCursor !== null,
|
|
246
252
|
nextCursor: page.nextCursor,
|
|
253
|
+
...(resumeHunk ? { resume: resumeHunk } : {}),
|
|
247
254
|
});
|
|
255
|
+
// A page that ends inside a hunk re-mints the cursor with the hunk state so
|
|
256
|
+
// the next page resumes it instead of demoting the rows to meta.
|
|
257
|
+
if (page.nextCursor && document.pendingHunk) {
|
|
258
|
+
const decoded = this.decodeCursor(page.nextCursor, 'diff', page.repositoryRevision, page.fileId, diffScope(input.ignoreWhitespace === true, input.wordDiff === true));
|
|
259
|
+
return Object.freeze({
|
|
260
|
+
...document,
|
|
261
|
+
nextCursor: this.encodeCursor({ ...decoded, resumeHunk: document.pendingHunk }),
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
return document;
|
|
248
265
|
}
|
|
249
266
|
historyReader() {
|
|
250
267
|
this.historyReaderInstance ?? (this.historyReaderInstance = (0, git_history_service_1.createGitHistoryReader)({
|
|
@@ -300,7 +317,8 @@ class GitReadModelServiceV1 {
|
|
|
300
317
|
.update(`compare-diff:${input.baseOid}:${input.headOid}:${path}:${snapshot.revision}`)
|
|
301
318
|
.digest('hex')
|
|
302
319
|
.slice(0, 24);
|
|
303
|
-
const
|
|
320
|
+
const cursorState = input.cursor ? decodeCommitDiffCursor(input.cursor, margin) : null;
|
|
321
|
+
const offset = cursorState?.offset ?? 0;
|
|
304
322
|
const page = await streamDiffPage({
|
|
305
323
|
cwd: root,
|
|
306
324
|
commands: Object.freeze([
|
|
@@ -339,9 +357,19 @@ class GitReadModelServiceV1 {
|
|
|
339
357
|
nextCursor: page.hasMore
|
|
340
358
|
? encodeCommitDiffCursor({ margin, offset: offset + page.returnedLines })
|
|
341
359
|
: null,
|
|
360
|
+
...(cursorState?.resumeHunk ? { resume: cursorState.resumeHunk } : {}),
|
|
342
361
|
});
|
|
362
|
+
// v0.3.26 #275 — re-mint the continuation cursor with the split hunk state.
|
|
363
|
+
const nextCursor = page.hasMore && document.pendingHunk
|
|
364
|
+
? encodeCommitDiffCursor({
|
|
365
|
+
margin,
|
|
366
|
+
offset: offset + page.returnedLines,
|
|
367
|
+
resumeHunk: document.pendingHunk,
|
|
368
|
+
})
|
|
369
|
+
: document.nextCursor;
|
|
343
370
|
return Object.freeze({
|
|
344
371
|
...document,
|
|
372
|
+
nextCursor,
|
|
345
373
|
baseOid: input.baseOid,
|
|
346
374
|
baseLabel: `比较 ${input.baseOid.slice(0, 10)} → ${input.headOid.slice(0, 10)}`,
|
|
347
375
|
});
|
|
@@ -450,7 +478,8 @@ class GitReadModelServiceV1 {
|
|
|
450
478
|
.update(`commit-diff:${detail.id}:${detail.baseOid}:${parentIndex}:${snapshot.revision}`)
|
|
451
479
|
.digest('hex')
|
|
452
480
|
.slice(0, 24);
|
|
453
|
-
const
|
|
481
|
+
const cursorState = input.cursor ? decodeCommitDiffCursor(input.cursor, margin) : null;
|
|
482
|
+
const offset = cursorState?.offset ?? 0;
|
|
454
483
|
const page = await streamDiffPage({
|
|
455
484
|
cwd: root,
|
|
456
485
|
commands: Object.freeze([
|
|
@@ -489,8 +518,22 @@ class GitReadModelServiceV1 {
|
|
|
489
518
|
nextCursor: page.hasMore
|
|
490
519
|
? encodeCommitDiffCursor({ margin, offset: offset + page.returnedLines })
|
|
491
520
|
: null,
|
|
521
|
+
...(cursorState?.resumeHunk ? { resume: cursorState.resumeHunk } : {}),
|
|
522
|
+
});
|
|
523
|
+
// v0.3.26 #275 — re-mint the continuation cursor with the split hunk state.
|
|
524
|
+
const nextCursor = page.hasMore && document.pendingHunk
|
|
525
|
+
? encodeCommitDiffCursor({
|
|
526
|
+
margin,
|
|
527
|
+
offset: offset + page.returnedLines,
|
|
528
|
+
resumeHunk: document.pendingHunk,
|
|
529
|
+
})
|
|
530
|
+
: document.nextCursor;
|
|
531
|
+
return Object.freeze({
|
|
532
|
+
...document,
|
|
533
|
+
nextCursor,
|
|
534
|
+
baseLabel: detail.baseLabel,
|
|
535
|
+
baseOid: detail.baseOid,
|
|
492
536
|
});
|
|
493
|
-
return Object.freeze({ ...document, baseLabel: detail.baseLabel, baseOid: detail.baseOid });
|
|
494
537
|
}
|
|
495
538
|
async capture() {
|
|
496
539
|
let root;
|
|
@@ -1211,6 +1254,9 @@ class GitReadModelServiceV1 {
|
|
|
1211
1254
|
parsed.offset < 0) {
|
|
1212
1255
|
return invalidCursor();
|
|
1213
1256
|
}
|
|
1257
|
+
if (parsed.resumeHunk !== undefined && !isDiffHunkResume(parsed.resumeHunk)) {
|
|
1258
|
+
return invalidCursor();
|
|
1259
|
+
}
|
|
1214
1260
|
if (parsed.revision !== revision) {
|
|
1215
1261
|
throw new errors_1.WebWorkbenchError(409, 'Git cursor revision is stale.', 'git_revision_conflict');
|
|
1216
1262
|
}
|
|
@@ -1224,6 +1270,22 @@ class GitReadModelServiceV1 {
|
|
|
1224
1270
|
}
|
|
1225
1271
|
}
|
|
1226
1272
|
exports.GitReadModelServiceV1 = GitReadModelServiceV1;
|
|
1273
|
+
/** v0.3.26 #275 — the hunk header shape, mirrored for cursor validation. */
|
|
1274
|
+
const HUNK_HEADER_PATTERN = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(.*)$/u;
|
|
1275
|
+
/** v0.3.26 #275 — validates a cursor-carried hunk resume state. */
|
|
1276
|
+
function isDiffHunkResume(value) {
|
|
1277
|
+
if (!value || typeof value !== 'object')
|
|
1278
|
+
return false;
|
|
1279
|
+
const candidate = value;
|
|
1280
|
+
return (typeof candidate.header === 'string' &&
|
|
1281
|
+
HUNK_HEADER_PATTERN.test(candidate.header) &&
|
|
1282
|
+
Number.isSafeInteger(candidate.index) &&
|
|
1283
|
+
candidate.index >= 0 &&
|
|
1284
|
+
Number.isSafeInteger(candidate.oldCursor) &&
|
|
1285
|
+
candidate.oldCursor >= 1 &&
|
|
1286
|
+
Number.isSafeInteger(candidate.newCursor) &&
|
|
1287
|
+
candidate.newCursor >= 1);
|
|
1288
|
+
}
|
|
1227
1289
|
function parsePorcelainV1(output) {
|
|
1228
1290
|
const fields = output.split('\0');
|
|
1229
1291
|
const records = [];
|
|
@@ -1692,7 +1754,16 @@ function decodeCommitDiffCursor(cursor, margin) {
|
|
|
1692
1754
|
candidate.offset < 0) {
|
|
1693
1755
|
throw new errors_1.WebWorkbenchError(409, 'Diff changed; reload before paginating.', 'git_cursor_invalid');
|
|
1694
1756
|
}
|
|
1695
|
-
|
|
1757
|
+
if (candidate.resumeHunk !== undefined && !isDiffHunkResume(candidate.resumeHunk)) {
|
|
1758
|
+
throw new errors_1.WebWorkbenchError(400, 'Diff cursor is not valid.', 'git_cursor_invalid');
|
|
1759
|
+
}
|
|
1760
|
+
return {
|
|
1761
|
+
margin,
|
|
1762
|
+
offset: candidate.offset,
|
|
1763
|
+
...(candidate.resumeHunk !== undefined
|
|
1764
|
+
? { resumeHunk: candidate.resumeHunk }
|
|
1765
|
+
: {}),
|
|
1766
|
+
};
|
|
1696
1767
|
}
|
|
1697
1768
|
/**
|
|
1698
1769
|
* Kills a detached child and everything it spawned.
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orion-agents/orion-code",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.27",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@orion-agents/orion-code",
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.27",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@clack/prompts": "^0.7.0",
|
|
@@ -4293,9 +4293,9 @@
|
|
|
4293
4293
|
"license": "ISC"
|
|
4294
4294
|
},
|
|
4295
4295
|
"node_modules/follow-redirects": {
|
|
4296
|
-
"version": "1.16.
|
|
4297
|
-
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.
|
|
4298
|
-
"integrity": "sha512-
|
|
4296
|
+
"version": "1.16.1",
|
|
4297
|
+
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.1.tgz",
|
|
4298
|
+
"integrity": "sha512-FNvFGzoMLWmE6Yj9spb/zjd7yiNCHiAW9/Tg9CXrQ8wuu32HtlJOwWO11OJafl5FfY3DxTdQ0vj42zU1kvv5jg==",
|
|
4299
4299
|
"funding": [
|
|
4300
4300
|
{
|
|
4301
4301
|
"type": "individual",
|
|
@@ -4563,13 +4563,13 @@
|
|
|
4563
4563
|
"license": "MIT"
|
|
4564
4564
|
},
|
|
4565
4565
|
"node_modules/handlebars": {
|
|
4566
|
-
"version": "4.7.
|
|
4567
|
-
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.
|
|
4568
|
-
"integrity": "sha512-
|
|
4566
|
+
"version": "4.7.10",
|
|
4567
|
+
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.10.tgz",
|
|
4568
|
+
"integrity": "sha512-P5VJMVM7qgBn6vjXMw8WG9uVI+ncf2pi72j4de4yz5ZULLj2RGqLYaKOYGsgyrViQ0tePOVlN1tDCCXXtFqXKg==",
|
|
4569
4569
|
"dev": true,
|
|
4570
4570
|
"license": "MIT",
|
|
4571
4571
|
"dependencies": {
|
|
4572
|
-
"minimist": "^1.2.
|
|
4572
|
+
"minimist": "^1.2.8",
|
|
4573
4573
|
"neo-async": "^2.6.2",
|
|
4574
4574
|
"source-map": "^0.6.1",
|
|
4575
4575
|
"wordwrap": "^1.0.0"
|
|
@@ -7147,9 +7147,9 @@
|
|
|
7147
7147
|
}
|
|
7148
7148
|
},
|
|
7149
7149
|
"node_modules/source-map-js": {
|
|
7150
|
-
"version": "1.2.
|
|
7151
|
-
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.
|
|
7152
|
-
"integrity": "sha512-
|
|
7150
|
+
"version": "1.2.2",
|
|
7151
|
+
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz",
|
|
7152
|
+
"integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==",
|
|
7153
7153
|
"dev": true,
|
|
7154
7154
|
"license": "BSD-3-Clause",
|
|
7155
7155
|
"engines": {
|