getgloss 0.12.1 → 0.13.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/README.md +14 -6
- package/dist/cli/index.js +51 -9
- package/dist/cli/index.js.map +1 -1
- package/dist/server/daemon.js +173 -19
- package/dist/server/daemon.js.map +1 -1
- package/dist/web/assets/index-0IC9C6Wd.js +307 -0
- package/dist/web/assets/index-acdiHHul.css +1 -0
- package/dist/web/assets/{syntax-UR_bDbhr.js → syntax-CvRmtNgl.js} +1 -1
- package/dist/web/index.html +2 -2
- package/dist/web/prompt.md +3 -2
- package/dist/web/setup/index.html +5 -1
- package/dist/web/setup.md +8 -3
- package/package.json +3 -3
- package/skill/SKILL.md +2 -2
- package/dist/web/assets/index-BYtByjSm.js +0 -306
- package/dist/web/assets/index-Bn84l3Zr.css +0 -1
package/README.md
CHANGED
|
@@ -122,9 +122,16 @@ choose a different retention window.
|
|
|
122
122
|
## Review UI
|
|
123
123
|
|
|
124
124
|
In the browser review, drag over a changed line or range to open a draft
|
|
125
|
-
comment.
|
|
126
|
-
`Command+
|
|
127
|
-
|
|
125
|
+
comment. Add review-level general comments from the submit bar when the feedback
|
|
126
|
+
is not tied to one line. Use `Command+Enter` to save the active draft comment.
|
|
127
|
+
Use `Command+Shift+Enter` to submit the review; this matches the Submit button
|
|
128
|
+
and includes already-saved comments only.
|
|
129
|
+
|
|
130
|
+
Lockfiles are hidden by default in the browser review and stay one click away in
|
|
131
|
+
the hidden-files banner. Use the file filter menu to also hide boring files such
|
|
132
|
+
as snapshots, generated files, and vendored files. These filters affect only the
|
|
133
|
+
browser view: submitted feedback and review artifacts still keep the full
|
|
134
|
+
captured diff.
|
|
128
135
|
|
|
129
136
|
When branch reviews include per-commit diffs, the commit picker changes only the
|
|
130
137
|
current preview. Gloss persists that selected scope when the review is submitted,
|
|
@@ -148,9 +155,10 @@ Submitted reviews are written to:
|
|
|
148
155
|
```
|
|
149
156
|
|
|
150
157
|
`feedback.json` is the machine-readable payload and includes `reviewScope` for
|
|
151
|
-
submitted commit-preview scope. `feedback.md` is a readable summary
|
|
152
|
-
|
|
153
|
-
|
|
158
|
+
submitted commit-preview scope. `feedback.md` is a readable summary with
|
|
159
|
+
general comments first, then file comments ordered by path and line.
|
|
160
|
+
`resolved.json` is mutable resolution progress for individual comments and the
|
|
161
|
+
turn. After applying feedback, use
|
|
154
162
|
`gloss resolve <reviewId> --comment <commentId> --summary "..."` for a single
|
|
155
163
|
comment or `gloss resolve <reviewId> --turn <id-or-index> --summary "..."` for a
|
|
156
164
|
specific turn. Without `--turn`, whole-review resolution targets the latest
|
package/dist/cli/index.js
CHANGED
|
@@ -30,7 +30,7 @@ import path from "path";
|
|
|
30
30
|
// package.json
|
|
31
31
|
var package_default = {
|
|
32
32
|
name: "getgloss",
|
|
33
|
-
version: "0.
|
|
33
|
+
version: "0.13.0",
|
|
34
34
|
description: "Local browser-based diff review for coding-agent loops.",
|
|
35
35
|
type: "module",
|
|
36
36
|
packageManager: "pnpm@10.33.2",
|
|
@@ -87,8 +87,8 @@ var package_default = {
|
|
|
87
87
|
tsup: "8.5.1",
|
|
88
88
|
tsx: "4.22.3",
|
|
89
89
|
typescript: "5.9.3",
|
|
90
|
-
vite: "6.4.
|
|
91
|
-
vitest: "3.2.
|
|
90
|
+
vite: "6.4.3",
|
|
91
|
+
vitest: "3.2.6"
|
|
92
92
|
},
|
|
93
93
|
keywords: [
|
|
94
94
|
"diff",
|
|
@@ -339,7 +339,13 @@ function isDiffLine(value) {
|
|
|
339
339
|
return isRecord(value) && isOneOf(value.type, DIFF_LINE_TYPES) && isNullableNumber(value.oldLine) && isNullableNumber(value.newLine) && isString(value.content);
|
|
340
340
|
}
|
|
341
341
|
function isComment(value) {
|
|
342
|
-
|
|
342
|
+
if (!isRecord(value)) {
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
if (value.kind === "general") {
|
|
346
|
+
return isString(value.id) && isString(value.body) && isString(value.createdAt);
|
|
347
|
+
}
|
|
348
|
+
return isString(value.id) && (value.kind === void 0 || value.kind === "line") && isString(value.filePath) && isNumber(value.startLine) && isNumber(value.endLine) && isOneOf(value.side, SIDES) && isString(value.body) && isString(value.originalSnippet) && isString(value.createdAt);
|
|
343
349
|
}
|
|
344
350
|
function isResolvedComment(value) {
|
|
345
351
|
return isRecord(value) && isString(value.commentId) && value.status === "resolved" && isOptionalString(value.summary) && isString(value.resolvedAt);
|
|
@@ -892,6 +898,17 @@ function summarizeDiffFiles(files) {
|
|
|
892
898
|
);
|
|
893
899
|
}
|
|
894
900
|
|
|
901
|
+
// src/shared/file-order.ts
|
|
902
|
+
function compareFilePaths(leftPath, rightPath, leftTieBreaker = "", rightTieBreaker = "") {
|
|
903
|
+
return leftPath.localeCompare(rightPath, void 0, { sensitivity: "base" }) || leftPath.localeCompare(rightPath) || leftTieBreaker.localeCompare(rightTieBreaker, void 0, { sensitivity: "base" }) || leftTieBreaker.localeCompare(rightTieBreaker);
|
|
904
|
+
}
|
|
905
|
+
function compareDiffFiles(left, right) {
|
|
906
|
+
return compareFilePaths(left.path, right.path, left.oldPath ?? "", right.oldPath ?? "");
|
|
907
|
+
}
|
|
908
|
+
function sortDiffFiles(files) {
|
|
909
|
+
return files.toSorted(compareDiffFiles);
|
|
910
|
+
}
|
|
911
|
+
|
|
895
912
|
// src/cli/git.ts
|
|
896
913
|
var DIFF_ARGS = ["diff", "--no-color", "--find-renames", "--find-copies"];
|
|
897
914
|
async function git(args, cwd = process.cwd()) {
|
|
@@ -923,7 +940,7 @@ function buildPayload({
|
|
|
923
940
|
fallbackReason,
|
|
924
941
|
commitDiffs
|
|
925
942
|
}) {
|
|
926
|
-
const files = parseUnifiedDiff(rawDiff);
|
|
943
|
+
const files = sortDiffFiles(parseUnifiedDiff(rawDiff));
|
|
927
944
|
return {
|
|
928
945
|
base,
|
|
929
946
|
branch,
|
|
@@ -1030,7 +1047,7 @@ async function captureCommitDiffs(baseSha, comparisonRef, repoRoot) {
|
|
|
1030
1047
|
const commitDiffs = [];
|
|
1031
1048
|
for (const commit of commits) {
|
|
1032
1049
|
const rawDiff = await git([...DIFF_ARGS, `${commit.sha}^`, commit.sha, "--"], repoRoot);
|
|
1033
|
-
const files = parseUnifiedDiff(rawDiff);
|
|
1050
|
+
const files = sortDiffFiles(parseUnifiedDiff(rawDiff));
|
|
1034
1051
|
commitDiffs.push({
|
|
1035
1052
|
commit,
|
|
1036
1053
|
stats: summarizeDiffFiles(files),
|
|
@@ -1662,11 +1679,28 @@ import path6 from "path";
|
|
|
1662
1679
|
import { ulid } from "ulid";
|
|
1663
1680
|
|
|
1664
1681
|
// src/shared/comments.ts
|
|
1682
|
+
function isLineComment(comment) {
|
|
1683
|
+
return comment.kind === void 0 || comment.kind === "line";
|
|
1684
|
+
}
|
|
1665
1685
|
function compareCommentsByLocation(a, b) {
|
|
1686
|
+
const aIsLine = isLineComment(a);
|
|
1687
|
+
const bIsLine = isLineComment(b);
|
|
1688
|
+
if (!aIsLine || !bIsLine) {
|
|
1689
|
+
if (aIsLine !== bIsLine) {
|
|
1690
|
+
return aIsLine ? 1 : -1;
|
|
1691
|
+
}
|
|
1692
|
+
return a.createdAt.localeCompare(b.createdAt) || a.id.localeCompare(b.id);
|
|
1693
|
+
}
|
|
1666
1694
|
return a.filePath.localeCompare(b.filePath) || a.startLine - b.startLine || a.endLine - b.endLine || a.side.localeCompare(b.side);
|
|
1667
1695
|
}
|
|
1668
1696
|
function countCommentFiles(comments) {
|
|
1669
|
-
|
|
1697
|
+
const filePaths = /* @__PURE__ */ new Set();
|
|
1698
|
+
for (const comment of comments) {
|
|
1699
|
+
if (isLineComment(comment)) {
|
|
1700
|
+
filePaths.add(comment.filePath);
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
return filePaths.size;
|
|
1670
1704
|
}
|
|
1671
1705
|
function formatLineRange(range, options = {}) {
|
|
1672
1706
|
const startLine = Math.min(range.startLine, range.endLine);
|
|
@@ -1757,9 +1791,11 @@ function languageForSnippet(filePath, snippet) {
|
|
|
1757
1791
|
}
|
|
1758
1792
|
function serializeFeedbackMarkdown(bundle) {
|
|
1759
1793
|
const comments = bundle.comments.toSorted(compareCommentsByLocation);
|
|
1794
|
+
const generalComments = comments.filter((comment) => !isLineComment(comment));
|
|
1795
|
+
const lineComments = comments.filter(isLineComment);
|
|
1760
1796
|
const commentsByFile = /* @__PURE__ */ new Map();
|
|
1761
1797
|
const files = [];
|
|
1762
|
-
for (const comment of
|
|
1798
|
+
for (const comment of lineComments) {
|
|
1763
1799
|
const fileComments = commentsByFile.get(comment.filePath);
|
|
1764
1800
|
if (fileComments) {
|
|
1765
1801
|
fileComments.push(comment);
|
|
@@ -1777,6 +1813,12 @@ function serializeFeedbackMarkdown(bundle) {
|
|
|
1777
1813
|
`Files: ${files.length} Comments: ${comments.length}`,
|
|
1778
1814
|
""
|
|
1779
1815
|
];
|
|
1816
|
+
if (generalComments.length > 0) {
|
|
1817
|
+
lines.push("## General comments", "");
|
|
1818
|
+
for (const comment of generalComments) {
|
|
1819
|
+
lines.push(`### ${comment.id}`, comment.body.trim(), "");
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1780
1822
|
for (const filePath of files) {
|
|
1781
1823
|
lines.push(`## ${filePath}`, "");
|
|
1782
1824
|
for (const comment of commentsByFile.get(filePath) ?? []) {
|
|
@@ -2748,7 +2790,7 @@ async function watchReviewWithReconnect(reviewId, initialInfo, timeoutSeconds, o
|
|
|
2748
2790
|
return { event, info };
|
|
2749
2791
|
} catch (error) {
|
|
2750
2792
|
if (isWatchTimeout(error)) {
|
|
2751
|
-
throw
|
|
2793
|
+
throw new Error(`watch timed out after ${timeoutSeconds} seconds`);
|
|
2752
2794
|
}
|
|
2753
2795
|
if (!isReconnectableWatchError(error)) {
|
|
2754
2796
|
throw error;
|