@mrsf/cli 0.7.0 → 0.8.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/LICENSE +21 -21
- package/README.md +513 -513
- package/dist/bin.js +6 -6
- package/dist/browser.cjs +2 -2
- package/dist/browser.cjs.map +1 -1
- package/dist/commands/add.js +15 -7
- package/dist/index.cjs +34 -6
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/lib/comments.d.ts +2 -1
- package/dist/lib/comments.js +2 -1
- package/dist/lib/git.d.ts +7 -0
- package/dist/lib/git.js +18 -0
- package/dist/lib/reanchor.js +1 -1
- package/dist/lib/types.d.ts +2 -0
- package/dist/lib/writer.js +15 -1
- package/mrsf.schema.json +113 -113
- package/package.json +95 -95
package/dist/commands/add.js
CHANGED
|
@@ -7,7 +7,7 @@ import { discoverSidecar, findWorkspaceRoot } from "../lib/discovery.js";
|
|
|
7
7
|
import { parseSidecar, readDocumentLines } from "../lib/parser.js";
|
|
8
8
|
import { writeSidecar } from "../lib/writer.js";
|
|
9
9
|
import { addComment, populateSelectedText } from "../lib/comments.js";
|
|
10
|
-
import { findRepoRoot } from "../lib/git.js";
|
|
10
|
+
import { findRepoRoot, getGitUserName } from "../lib/git.js";
|
|
11
11
|
function collectOptionValues(value, previous) {
|
|
12
12
|
previous.push(value);
|
|
13
13
|
return previous;
|
|
@@ -52,12 +52,12 @@ export function registerAdd(program) {
|
|
|
52
52
|
program
|
|
53
53
|
.command("add <document>")
|
|
54
54
|
.description("Add a review comment to a document's sidecar")
|
|
55
|
-
.
|
|
55
|
+
.option("-a, --author <name>", "Comment author (defaults to repository-local Git user.name)")
|
|
56
56
|
.requiredOption("-t, --text <text>", "Comment text")
|
|
57
57
|
.option("-l, --line <n>", "Line number (1-based)")
|
|
58
58
|
.option("--end-line <n>", "End line (inclusive)")
|
|
59
|
-
.option("--start-column <n>", "
|
|
60
|
-
.option("--end-column <n>", "
|
|
59
|
+
.option("--start-column <n>", "Inclusive UTF-16 column (0-based)")
|
|
60
|
+
.option("--end-column <n>", "Exclusive UTF-16 column (0-based)")
|
|
61
61
|
.option("--type <type>", "Comment type (e.g. suggestion, issue)")
|
|
62
62
|
.option("--severity <level>", "Severity: low | medium | high")
|
|
63
63
|
.option("--reply-to <id>", "Reply to an existing comment")
|
|
@@ -84,9 +84,17 @@ export function registerAdd(program) {
|
|
|
84
84
|
comments: [],
|
|
85
85
|
};
|
|
86
86
|
}
|
|
87
|
-
const repoRoot = await findRepoRoot(
|
|
87
|
+
const repoRoot = await findRepoRoot(path.dirname(docPath));
|
|
88
|
+
const author = opts.author?.trim()
|
|
89
|
+
|| (repoRoot ? await getGitUserName(repoRoot) : null);
|
|
90
|
+
if (!author) {
|
|
91
|
+
console.error(chalk.red("Comment author is required. Pass --author or configure "
|
|
92
|
+
+ "repository-local Git identity with: "
|
|
93
|
+
+ "git config --local user.name \"Your Name\""));
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
88
96
|
const comment = await addComment(doc, {
|
|
89
|
-
author
|
|
97
|
+
author,
|
|
90
98
|
text: opts.text,
|
|
91
99
|
line: opts.line ? parseInt(opts.line, 10) : undefined,
|
|
92
100
|
end_line: opts.endLine ? parseInt(opts.endLine, 10) : undefined,
|
|
@@ -108,7 +116,7 @@ export function registerAdd(program) {
|
|
|
108
116
|
else if (comment.line != null) {
|
|
109
117
|
try {
|
|
110
118
|
const lines = await readDocumentLines(docPath);
|
|
111
|
-
populateSelectedText(comment, lines);
|
|
119
|
+
populateSelectedText(comment, lines.slice(1));
|
|
112
120
|
}
|
|
113
121
|
catch {
|
|
114
122
|
// Document file may not exist yet, skip
|
package/dist/index.cjs
CHANGED
|
@@ -221,6 +221,7 @@ __export(index_exports, {
|
|
|
221
221
|
getCurrentCommit: () => getCurrentCommit2,
|
|
222
222
|
getDiff: () => getDiff2,
|
|
223
223
|
getFileAtCommit: () => getFileAtCommit2,
|
|
224
|
+
getGitUserName: () => getGitUserName2,
|
|
224
225
|
getLineShift: () => getLineShift4,
|
|
225
226
|
getStagedFiles: () => getStagedFiles2,
|
|
226
227
|
getThreads: () => getThreads2,
|
|
@@ -380,6 +381,7 @@ init_parser();
|
|
|
380
381
|
var import_promises3 = require("node:fs/promises");
|
|
381
382
|
var import_node_fs2 = require("node:fs");
|
|
382
383
|
var import_node_crypto = require("node:crypto");
|
|
384
|
+
var import_promises4 = require("node:timers/promises");
|
|
383
385
|
var import_node_path4 = __toESM(require("node:path"), 1);
|
|
384
386
|
var import_yaml2 = require("yaml");
|
|
385
387
|
init_serialize();
|
|
@@ -400,7 +402,17 @@ async function atomicWriteFile(filePath, content) {
|
|
|
400
402
|
const tmp = filePath + "." + (0, import_node_crypto.randomBytes)(6).toString("hex") + ".tmp";
|
|
401
403
|
try {
|
|
402
404
|
await (0, import_promises3.writeFile)(tmp, content, "utf-8");
|
|
403
|
-
|
|
405
|
+
for (let attempt = 0; ; attempt++) {
|
|
406
|
+
try {
|
|
407
|
+
await (0, import_promises3.rename)(tmp, filePath);
|
|
408
|
+
break;
|
|
409
|
+
} catch (error) {
|
|
410
|
+
if (attempt >= 5 || !(error instanceof Error) || !("code" in error) || !["EPERM", "EACCES", "EBUSY"].some((code) => code === error.code)) {
|
|
411
|
+
throw error;
|
|
412
|
+
}
|
|
413
|
+
await (0, import_promises4.setTimeout)(50 * (attempt + 1));
|
|
414
|
+
}
|
|
415
|
+
}
|
|
404
416
|
} catch (err) {
|
|
405
417
|
try {
|
|
406
418
|
await (0, import_promises3.unlink)(tmp);
|
|
@@ -710,7 +722,7 @@ async function writeSidecarInternal(abs, doc) {
|
|
|
710
722
|
}
|
|
711
723
|
|
|
712
724
|
// src/lib/validator.ts
|
|
713
|
-
var
|
|
725
|
+
var import_promises5 = require("node:fs/promises");
|
|
714
726
|
var import_node_path5 = __toESM(require("node:path"), 1);
|
|
715
727
|
var import_node_url = require("node:url");
|
|
716
728
|
|
|
@@ -804,12 +816,12 @@ var mrsf_schema_default = {
|
|
|
804
816
|
start_column: {
|
|
805
817
|
type: "integer",
|
|
806
818
|
minimum: 0,
|
|
807
|
-
description: "
|
|
819
|
+
description: "Inclusive starting UTF-16 code-unit offset (0-based) within the starting line."
|
|
808
820
|
},
|
|
809
821
|
end_column: {
|
|
810
822
|
type: "integer",
|
|
811
823
|
minimum: 0,
|
|
812
|
-
description: "
|
|
824
|
+
description: "Exclusive ending UTF-16 code-unit offset (0-based) within the ending line. MUST be >= start_column when on the same line."
|
|
813
825
|
},
|
|
814
826
|
selected_text: {
|
|
815
827
|
type: "string",
|
|
@@ -974,7 +986,7 @@ async function loadSchema() {
|
|
|
974
986
|
];
|
|
975
987
|
for (const candidate of candidates) {
|
|
976
988
|
try {
|
|
977
|
-
const raw = await (0,
|
|
989
|
+
const raw = await (0, import_promises5.readFile)(candidate, "utf-8");
|
|
978
990
|
_schemaCache = JSON.parse(raw);
|
|
979
991
|
return _schemaCache;
|
|
980
992
|
} catch {
|
|
@@ -1352,6 +1364,20 @@ async function findRepoRoot(cwd) {
|
|
|
1352
1364
|
return null;
|
|
1353
1365
|
}
|
|
1354
1366
|
}
|
|
1367
|
+
async function getGitUserName(repoRoot) {
|
|
1368
|
+
if (!await isGitAvailable()) return null;
|
|
1369
|
+
try {
|
|
1370
|
+
const { stdout } = await execFile(
|
|
1371
|
+
"git",
|
|
1372
|
+
["config", "--local", "--get", "user.name"],
|
|
1373
|
+
{ cwd: repoRoot, timeout: GIT_TIMEOUT }
|
|
1374
|
+
);
|
|
1375
|
+
const name = stdout.trim();
|
|
1376
|
+
return name || null;
|
|
1377
|
+
} catch {
|
|
1378
|
+
return null;
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1355
1381
|
async function getCurrentCommit(repoRoot) {
|
|
1356
1382
|
if (!await isGitAvailable()) return null;
|
|
1357
1383
|
try {
|
|
@@ -2849,7 +2875,7 @@ async function reanchorDocument(doc, documentLines, opts = {}) {
|
|
|
2849
2875
|
if (!opts.noGit && await isGitAvailable()) {
|
|
2850
2876
|
const repoRoot = opts.repoRoot ?? await findRepoRoot(opts.cwd);
|
|
2851
2877
|
if (repoRoot && opts.documentPath) {
|
|
2852
|
-
const relPath = import_node_path6.default.relative(repoRoot, opts.documentPath);
|
|
2878
|
+
const relPath = import_node_path6.default.relative(repoRoot, opts.documentPath).split(import_node_path6.default.sep).join("/");
|
|
2853
2879
|
const head = await getCurrentCommit(repoRoot);
|
|
2854
2880
|
const globalFrom = opts.fromCommit;
|
|
2855
2881
|
const diffCache = /* @__PURE__ */ new Map();
|
|
@@ -3255,6 +3281,7 @@ var fuzzySearch2 = fuzzySearch;
|
|
|
3255
3281
|
var combinedScore2 = combinedScore;
|
|
3256
3282
|
var isGitAvailable2 = isGitAvailable;
|
|
3257
3283
|
var findRepoRoot3 = findRepoRoot;
|
|
3284
|
+
var getGitUserName2 = getGitUserName;
|
|
3258
3285
|
var getCurrentCommit2 = getCurrentCommit;
|
|
3259
3286
|
var resolveCommit2 = resolveCommit;
|
|
3260
3287
|
var isStale2 = isStale;
|
|
@@ -3315,6 +3342,7 @@ var newCommentId2 = newCommentId;
|
|
|
3315
3342
|
getCurrentCommit,
|
|
3316
3343
|
getDiff,
|
|
3317
3344
|
getFileAtCommit,
|
|
3345
|
+
getGitUserName,
|
|
3318
3346
|
getLineShift,
|
|
3319
3347
|
getStagedFiles,
|
|
3320
3348
|
getThreads,
|