local-diff-reviewer 1.0.7 → 1.0.11
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 +19 -0
- package/SKILL.md +1 -0
- package/dist/cli/start.js +143 -13
- package/dist/web/assets/{arc-FnFNT5Eh.js → arc-BOpgS1XG.js} +1 -1
- package/dist/web/assets/{architectureDiagram-3BPJPVTR-Co5Z_QNw.js → architectureDiagram-3BPJPVTR-C7QsBMbs.js} +1 -1
- package/dist/web/assets/{blockDiagram-GPEHLZMM-BNsiQyLf.js → blockDiagram-GPEHLZMM-QaQaVyDL.js} +1 -1
- package/dist/web/assets/{c4Diagram-AAUBKEIU-BAZdudVw.js → c4Diagram-AAUBKEIU-CufBBkVk.js} +1 -1
- package/dist/web/assets/channel-BPEgeY7j.js +1 -0
- package/dist/web/assets/{chunk-2J33WTMH-B0vxrf0b.js → chunk-2J33WTMH-Cj_oaVb4.js} +1 -1
- package/dist/web/assets/{chunk-3OPIFGDE-DejuRnfm.js → chunk-3OPIFGDE-DmJyquPX.js} +1 -1
- package/dist/web/assets/{chunk-4BX2VUAB-Bg5xzq_y.js → chunk-4BX2VUAB-CwaF4zJY.js} +1 -1
- package/dist/web/assets/{chunk-55IACEB6-D0Fci-zx.js → chunk-55IACEB6-DqeKiemL.js} +1 -1
- package/dist/web/assets/{chunk-5ZQYHXKU-BPK5ENee.js → chunk-5ZQYHXKU-DNp0ZNVB.js} +1 -1
- package/dist/web/assets/{chunk-727SXJPM-7K2UgSc-.js → chunk-727SXJPM-BKKrSCOF.js} +1 -1
- package/dist/web/assets/{chunk-AQP2D5EJ-BWk8xaA0.js → chunk-AQP2D5EJ-BCNSIQmO.js} +1 -1
- package/dist/web/assets/{chunk-BSJP7CBP-qQ__7B7h.js → chunk-BSJP7CBP-Ce9WIScW.js} +1 -1
- package/dist/web/assets/{chunk-CSCIHK7Q-CrFKiZka.js → chunk-CSCIHK7Q-Cj2N3A_X.js} +1 -1
- package/dist/web/assets/{chunk-FMBD7UC4-DvZyaP9P.js → chunk-FMBD7UC4-BADdZIdh.js} +1 -1
- package/dist/web/assets/{chunk-KSCS5N6A-BbcBNuLx.js → chunk-KSCS5N6A-BeYyq8hv.js} +1 -1
- package/dist/web/assets/{chunk-L5ZTLDWV-D9Jpxw4I.js → chunk-L5ZTLDWV-vyV2WecR.js} +1 -1
- package/dist/web/assets/{chunk-LZXEDZCA-C0KF6zNF.js → chunk-LZXEDZCA-DFAA6FIb.js} +2 -2
- package/dist/web/assets/{chunk-ND2GUHAM-B4UYa5t-.js → chunk-ND2GUHAM-BvZh95FB.js} +1 -1
- package/dist/web/assets/{chunk-NZK2D7GU-DwIixx-H.js → chunk-NZK2D7GU-Cd_AyI2R.js} +1 -1
- package/dist/web/assets/{chunk-O5CBEL6O-B6AfXN2g.js → chunk-O5CBEL6O-BWTFeGAA.js} +1 -1
- package/dist/web/assets/chunk-QZHKN3VN-BM3ywZyg.js +1 -0
- package/dist/web/assets/chunk-WU5MYG2G-DwPzycK6.js +1 -0
- package/dist/web/assets/{chunk-XPW4576I-D15NjZ7Z.js → chunk-XPW4576I-BoQ5PHbI.js} +1 -1
- package/dist/web/assets/classDiagram-4FO5ZUOK-B-Ye1HF8.js +1 -0
- package/dist/web/assets/classDiagram-v2-Q7XG4LA2-DnIZKORc.js +1 -0
- package/dist/web/assets/{cose-bilkent-S5V4N54A-BNwgjIv3.js → cose-bilkent-S5V4N54A-DEOEnRu1.js} +1 -1
- package/dist/web/assets/{dagre-BM42HDAG-CpwwUyr_.js → dagre-BM42HDAG-3EFNtJfA.js} +1 -1
- package/dist/web/assets/{diagram-2AECGRRQ-Bw8x1vsX.js → diagram-2AECGRRQ-Dl6nD1tR.js} +1 -1
- package/dist/web/assets/{diagram-5GNKFQAL-BB2GXRx9.js → diagram-5GNKFQAL-C2ZqLXAR.js} +1 -1
- package/dist/web/assets/{diagram-KO2AKTUF-BgaaH0hW.js → diagram-KO2AKTUF-CLemszwR.js} +1 -1
- package/dist/web/assets/{diagram-LMA3HP47-BisC4uiR.js → diagram-LMA3HP47-WJtVAgyf.js} +1 -1
- package/dist/web/assets/{diagram-OG6HWLK6-BDj48Uho.js → diagram-OG6HWLK6-DLcglDzh.js} +1 -1
- package/dist/web/assets/{dist-D2UD_g6s.js → dist-BD8BTEle.js} +1 -1
- package/dist/web/assets/{erDiagram-TEJ5UH35-cBF6TfGh.js → erDiagram-TEJ5UH35-DB0o5lHM.js} +1 -1
- package/dist/web/assets/{flowDiagram-I6XJVG4X-CYc4faT9.js → flowDiagram-I6XJVG4X-DGNyzO3n.js} +1 -1
- package/dist/web/assets/{ganttDiagram-6RSMTGT7-CvZHLnnj.js → ganttDiagram-6RSMTGT7-DFcI8gjU.js} +1 -1
- package/dist/web/assets/{gitGraphDiagram-PVQCEYII-B9EFahM9.js → gitGraphDiagram-PVQCEYII-q30GMhck.js} +1 -1
- package/dist/web/assets/{index-wy40yeNf.js → index-mFrEtl6e.js} +2 -2
- package/dist/web/assets/{infoDiagram-5YYISTIA-OwyPUHlr.js → infoDiagram-5YYISTIA-Bn7G90QN.js} +1 -1
- package/dist/web/assets/{ishikawaDiagram-YF4QCWOH-DWNJFp-G.js → ishikawaDiagram-YF4QCWOH-BV3Sotps.js} +1 -1
- package/dist/web/assets/{journeyDiagram-JHISSGLW-Fx_1G-6i.js → journeyDiagram-JHISSGLW-BtSXI5Am.js} +1 -1
- package/dist/web/assets/{kanban-definition-UN3LZRKU-Dq4CooCl.js → kanban-definition-UN3LZRKU-B8tZB50Y.js} +1 -1
- package/dist/web/assets/{line-HQcA7ihX.js → line-ig55n5ES.js} +1 -1
- package/dist/web/assets/{linear-BZeIaDEq.js → linear-qGjeU4AP.js} +1 -1
- package/dist/web/assets/{mermaid-parser.core-DJsgXM22.js → mermaid-parser.core-DxxQqVaE.js} +1 -1
- package/dist/web/assets/{mermaid.core-CkAku_bb.js → mermaid.core-BBkLU4xy.js} +3 -3
- package/dist/web/assets/{mindmap-definition-RKZ34NQL-BWRzwBxY.js → mindmap-definition-RKZ34NQL-D61BQDKI.js} +1 -1
- package/dist/web/assets/{pieDiagram-4H26LBE5-woyVH6aA.js → pieDiagram-4H26LBE5-GrXCe3Mv.js} +1 -1
- package/dist/web/assets/{quadrantDiagram-W4KKPZXB-DmMwbj7N.js → quadrantDiagram-W4KKPZXB-Bmj1Zhyf.js} +1 -1
- package/dist/web/assets/{requirementDiagram-4Y6WPE33-1vUYL3sj.js → requirementDiagram-4Y6WPE33-C4Wt9tYO.js} +1 -1
- package/dist/web/assets/{sankeyDiagram-5OEKKPKP-BiRxghpn.js → sankeyDiagram-5OEKKPKP-BpEXiP3R.js} +1 -1
- package/dist/web/assets/{sequenceDiagram-3UESZ5HK-C-SgacOL.js → sequenceDiagram-3UESZ5HK-BY0QnrHB.js} +1 -1
- package/dist/web/assets/{src-DMlkBZbY.js → src-DKCcYPqn.js} +1 -1
- package/dist/web/assets/{stateDiagram-AJRCARHV-Ci958Ibo.js → stateDiagram-AJRCARHV-BNe3FO3i.js} +1 -1
- package/dist/web/assets/stateDiagram-v2-BHNVJYJU-DMtybq8y.js +1 -0
- package/dist/web/assets/{timeline-definition-PNZ67QCA-CQzVyH6s.js → timeline-definition-PNZ67QCA-BlWgTk_0.js} +1 -1
- package/dist/web/assets/{vennDiagram-CIIHVFJN-DjtlRdrY.js → vennDiagram-CIIHVFJN-Dpfbo-af.js} +1 -1
- package/dist/web/assets/{wardleyDiagram-YWT4CUSO-Braalnw5.js → wardleyDiagram-YWT4CUSO-BKnl9Arx.js} +1 -1
- package/dist/web/assets/{xychartDiagram-2RQKCTM6-YjueRiNp.js → xychartDiagram-2RQKCTM6-C5VJlVCG.js} +1 -1
- package/dist/web/index.html +1 -1
- package/docs/images/diff-review-intro.html +767 -0
- package/docs/images/diff-review-intro.png +0 -0
- package/docs/images/image.png +0 -0
- package/package.json +1 -1
- package/dist/web/assets/channel-BPbPhJj8.js +0 -1
- package/dist/web/assets/chunk-QZHKN3VN-erTNME5J.js +0 -1
- package/dist/web/assets/chunk-WU5MYG2G-CbnTR5Pg.js +0 -1
- package/dist/web/assets/classDiagram-4FO5ZUOK-CuafptIX.js +0 -1
- package/dist/web/assets/classDiagram-v2-Q7XG4LA2-BIT1gXn5.js +0 -1
- package/dist/web/assets/stateDiagram-v2-BHNVJYJU-BcqZc5a0.js +0 -1
package/README.md
CHANGED
|
@@ -42,6 +42,7 @@ npx skills add Mone-Lee/diff-review
|
|
|
42
42
|
local-diff-reviewer
|
|
43
43
|
local-diff-reviewer staged
|
|
44
44
|
local-diff-reviewer HEAD~1 HEAD
|
|
45
|
+
local-diff-reviewer stop
|
|
45
46
|
local-diff-reviewer --repo /path/to/project
|
|
46
47
|
```
|
|
47
48
|
|
|
@@ -51,6 +52,15 @@ local-diff-reviewer --repo /path/to/project
|
|
|
51
52
|
- `staged`:审查已经 `git add`、但还没有提交的改动。
|
|
52
53
|
- `revision`:审查两个 revision 之间的差异,例如 `local-diff-reviewer HEAD~1 HEAD` 会比较 `HEAD~1..HEAD`。
|
|
53
54
|
|
|
55
|
+
停止当前项目已启动的 review 进程:
|
|
56
|
+
|
|
57
|
+
- `stop`:按当前 Git 仓库范围清理该仓库启动过的 review 运行进程(包含其 API 端口进程)。
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
local-diff-reviewer stop
|
|
61
|
+
local-diff-reviewer --repo /path/to/project stop
|
|
62
|
+
```
|
|
63
|
+
|
|
54
64
|
如果命令不是在目标项目目录里启动,可以用 `--repo <path>` 显式指定要审查的 Git 仓库:
|
|
55
65
|
|
|
56
66
|
```bash
|
|
@@ -77,6 +87,7 @@ local-diff-reviewer --repo /path/to/project staged
|
|
|
77
87
|
/diff-review
|
|
78
88
|
/diff-review staged
|
|
79
89
|
/diff-review HEAD~1 HEAD
|
|
90
|
+
/diff-review stop
|
|
80
91
|
```
|
|
81
92
|
|
|
82
93
|
安装 skill:
|
|
@@ -139,12 +150,20 @@ npm run release major
|
|
|
139
150
|
|
|
140
151
|
该命令会按顺序执行:
|
|
141
152
|
|
|
153
|
+
- 发布前检查 npmjs 认证与连通性(`npm whoami --registry=https://registry.npmjs.org/` + `npm ping --registry=https://registry.npmjs.org/`)
|
|
142
154
|
- `npm run release:check`
|
|
143
155
|
- `npm version <patch|minor|major>`(默认 `patch`)
|
|
144
156
|
- `npm publish`
|
|
145
157
|
- `git push`
|
|
146
158
|
- `git push --tags`
|
|
147
159
|
|
|
160
|
+
若 npmjs 认证缺失或过期,发布会在 preflight 阶段提前失败,并提示执行:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
npm login --registry=https://registry.npmjs.org/
|
|
164
|
+
npm whoami --registry=https://registry.npmjs.org/
|
|
165
|
+
```
|
|
166
|
+
|
|
148
167
|
只有在 `npm publish` 成功后,才会自动推送提交和标签到 GitHub。
|
|
149
168
|
|
|
150
169
|
## 本地开发
|
package/SKILL.md
CHANGED
|
@@ -15,6 +15,7 @@ Use this skill when the user asks for `/diff-review`, wants to inspect current w
|
|
|
15
15
|
- `/diff-review working`: review current working tree diff.
|
|
16
16
|
- `/diff-review staged`: review staged diff.
|
|
17
17
|
- `/diff-review <base> <target>`: review diff between two Git revisions.
|
|
18
|
+
- `/diff-review stop`: stop all review runtimes created for the current workspace repository.
|
|
18
19
|
|
|
19
20
|
Do not ask the user to run a shell CLI manually. Determine the target workspace/repository from the user's active environment context, then run the package command with that repository as the command working directory:
|
|
20
21
|
|
package/dist/cli/start.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// src/cli/start.ts
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
5
5
|
import { existsSync as existsSync2 } from "node:fs";
|
|
6
|
-
import { basename as
|
|
6
|
+
import { basename as basename3, dirname as dirname3, join as join5, resolve as resolve2 } from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
|
|
9
9
|
// src/server/storage.ts
|
|
@@ -510,11 +510,96 @@ function binaryAddedDiff(path) {
|
|
|
510
510
|
return [`diff --git a/${path} b/${path}`, "new file mode 100644", "index 0000000..0000000", `Binary files /dev/null and b/${path} differ`].join("\n");
|
|
511
511
|
}
|
|
512
512
|
|
|
513
|
+
// src/cli/runtime-registry.ts
|
|
514
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
515
|
+
import { access, mkdir as mkdir2, readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
|
|
516
|
+
import { homedir as homedir2, platform as platform2 } from "node:os";
|
|
517
|
+
import { basename as basename2, dirname as dirname2, join as join3 } from "node:path";
|
|
518
|
+
async function recordRuntime(entry) {
|
|
519
|
+
const path = runtimePath(entry.repoRoot);
|
|
520
|
+
const store = await readRuntime(path);
|
|
521
|
+
const aliveEntries = store.entries.filter((item) => isPidAlive(item.pid));
|
|
522
|
+
const deduped = aliveEntries.filter((item) => item.pid !== entry.pid);
|
|
523
|
+
deduped.push(entry);
|
|
524
|
+
await writeRuntime(path, { entries: deduped });
|
|
525
|
+
}
|
|
526
|
+
async function stopRecordedRuntimes(repoRoot) {
|
|
527
|
+
const path = runtimePath(repoRoot);
|
|
528
|
+
const store = await readRuntime(path);
|
|
529
|
+
const stopped = [];
|
|
530
|
+
const stale = [];
|
|
531
|
+
for (const entry of store.entries) {
|
|
532
|
+
const parentAlive = isPidAlive(entry.pid);
|
|
533
|
+
const viteAlive = typeof entry.vitePid === "number" && isPidAlive(entry.vitePid);
|
|
534
|
+
if (!parentAlive && !viteAlive) {
|
|
535
|
+
stale.push(entry);
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
538
|
+
try {
|
|
539
|
+
if (parentAlive) process.kill(entry.pid, "SIGTERM");
|
|
540
|
+
if (viteAlive) process.kill(entry.vitePid, "SIGTERM");
|
|
541
|
+
stopped.push(entry);
|
|
542
|
+
} catch {
|
|
543
|
+
stale.push(entry);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
await writeRuntime(path, { entries: [] });
|
|
547
|
+
return { stopped, stale };
|
|
548
|
+
}
|
|
549
|
+
function runtimePath(repoRoot) {
|
|
550
|
+
const repoName = basename2(repoRoot) || "repo";
|
|
551
|
+
const repoHash = createHash3("sha256").update(repoRoot).digest("hex").slice(0, 12);
|
|
552
|
+
return join3(runtimeDir(), `${repoName}-${repoHash}.runtime.json`);
|
|
553
|
+
}
|
|
554
|
+
function runtimeDir() {
|
|
555
|
+
if (platform2() === "win32") {
|
|
556
|
+
return join3(process.env.LOCALAPPDATA ?? join3(homedir2(), "AppData", "Local"), "diff-review", "runtime");
|
|
557
|
+
}
|
|
558
|
+
return join3(homedir2(), ".local", "diff-review", "runtime");
|
|
559
|
+
}
|
|
560
|
+
async function readRuntime(path) {
|
|
561
|
+
try {
|
|
562
|
+
const text = await readFile3(path, "utf8");
|
|
563
|
+
const parsed = JSON.parse(text);
|
|
564
|
+
if (!Array.isArray(parsed.entries)) return { entries: [] };
|
|
565
|
+
return { entries: parsed.entries.filter(isRuntimeEntry) };
|
|
566
|
+
} catch {
|
|
567
|
+
return { entries: [] };
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
async function writeRuntime(path, store) {
|
|
571
|
+
await mkdir2(dirname2(path), { recursive: true });
|
|
572
|
+
await writeFile2(path, `${JSON.stringify(store, null, 2)}
|
|
573
|
+
`, "utf8");
|
|
574
|
+
}
|
|
575
|
+
function isRuntimeEntry(value) {
|
|
576
|
+
if (!value || typeof value !== "object") return false;
|
|
577
|
+
const entry = value;
|
|
578
|
+
return typeof entry.pid === "number" && (typeof entry.vitePid === "undefined" || typeof entry.vitePid === "number") && typeof entry.repoRoot === "string" && typeof entry.repoName === "string" && typeof entry.startedAt === "string" && typeof entry.apiPort === "number" && typeof entry.usesVite === "boolean";
|
|
579
|
+
}
|
|
580
|
+
function isPidAlive(pid) {
|
|
581
|
+
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
582
|
+
try {
|
|
583
|
+
process.kill(pid, 0);
|
|
584
|
+
return true;
|
|
585
|
+
} catch {
|
|
586
|
+
return false;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
async function hasRuntimeRecord(repoRoot) {
|
|
590
|
+
try {
|
|
591
|
+
await access(runtimePath(repoRoot));
|
|
592
|
+
return true;
|
|
593
|
+
} catch {
|
|
594
|
+
return false;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
513
598
|
// src/server/index.ts
|
|
514
599
|
import express from "express";
|
|
515
600
|
import { existsSync } from "node:fs";
|
|
516
601
|
import { createServer } from "node:http";
|
|
517
|
-
import { join as
|
|
602
|
+
import { join as join4, normalize as normalize2, resolve, sep } from "node:path";
|
|
518
603
|
|
|
519
604
|
// src/core/markdown-source-map.ts
|
|
520
605
|
import GithubSlugger from "github-slugger";
|
|
@@ -855,10 +940,10 @@ async function startServer(state, port = 4966) {
|
|
|
855
940
|
next(error);
|
|
856
941
|
}
|
|
857
942
|
});
|
|
858
|
-
const webDist = state.webDist ??
|
|
943
|
+
const webDist = state.webDist ?? join4(process.cwd(), "dist", "web");
|
|
859
944
|
if (existsSync(webDist)) {
|
|
860
945
|
app.use(express.static(webDist));
|
|
861
|
-
app.get(/.*/, (_req, res) => res.sendFile(
|
|
946
|
+
app.get(/.*/, (_req, res) => res.sendFile(join4(webDist, "index.html")));
|
|
862
947
|
}
|
|
863
948
|
app.use((error, _req, res, _next) => {
|
|
864
949
|
res.status(500).json({ error: error.message });
|
|
@@ -908,30 +993,41 @@ function selectPromptThreads(threads, scope) {
|
|
|
908
993
|
}
|
|
909
994
|
|
|
910
995
|
// src/cli/start.ts
|
|
911
|
-
var packageRoot = resolve2(
|
|
912
|
-
var builtWebDist =
|
|
996
|
+
var packageRoot = resolve2(dirname3(fileURLToPath(import.meta.url)), "../..");
|
|
997
|
+
var builtWebDist = join5(packageRoot, "dist", "web");
|
|
913
998
|
async function main() {
|
|
914
|
-
const { dev, repo, reviewArgs, comments } = parseCliOptions(process.argv.slice(2));
|
|
999
|
+
const { command, dev, repo, reviewArgs, comments } = parseCliOptions(process.argv.slice(2));
|
|
1000
|
+
if (command === "stop") {
|
|
1001
|
+
await stopCommand(repo);
|
|
1002
|
+
return;
|
|
1003
|
+
}
|
|
915
1004
|
const mode = parseReviewMode(reviewArgs);
|
|
916
1005
|
const repoRoot = await getRepoRoot(repo ?? process.cwd());
|
|
917
1006
|
const diff = await getDiff(mode, repoRoot);
|
|
918
1007
|
const diffFiles = parseUnifiedDiff(diff);
|
|
919
1008
|
const session = {
|
|
920
1009
|
id: crypto.randomUUID(),
|
|
921
|
-
repoName:
|
|
1010
|
+
repoName: basename3(repoRoot),
|
|
922
1011
|
repoRoot,
|
|
923
1012
|
mode,
|
|
924
1013
|
diffHash: diffHash(diff),
|
|
925
1014
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
926
1015
|
};
|
|
927
1016
|
const importResult = await importAgentComments(repoRoot, diffFiles, comments);
|
|
928
|
-
const hasBuiltWeb = existsSync2(
|
|
1017
|
+
const hasBuiltWeb = existsSync2(join5(builtWebDist, "index.html"));
|
|
929
1018
|
const apiUrl = await startServer({ session, diffFiles, webDist: hasBuiltWeb ? builtWebDist : void 0 });
|
|
930
1019
|
const useVite = dev || !hasBuiltWeb;
|
|
931
1020
|
const uiUrl = useVite ? "http://127.0.0.1:5173" : apiUrl;
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
1021
|
+
const vitePid = useVite ? startVite() : void 0;
|
|
1022
|
+
await recordRuntime({
|
|
1023
|
+
pid: process.pid,
|
|
1024
|
+
vitePid,
|
|
1025
|
+
repoRoot,
|
|
1026
|
+
repoName: session.repoName,
|
|
1027
|
+
startedAt: session.createdAt,
|
|
1028
|
+
apiPort: parsePort(apiUrl),
|
|
1029
|
+
usesVite: useVite
|
|
1030
|
+
});
|
|
935
1031
|
openBrowser(uiUrl);
|
|
936
1032
|
console.log(`Diff Review is running: ${uiUrl}`);
|
|
937
1033
|
console.log(`Repo: ${session.repoName} (${repoRoot})`);
|
|
@@ -948,6 +1044,7 @@ async function main() {
|
|
|
948
1044
|
}
|
|
949
1045
|
}
|
|
950
1046
|
function parseCliOptions(args) {
|
|
1047
|
+
let command = "review";
|
|
951
1048
|
const reviewArgs = [];
|
|
952
1049
|
const comments = [];
|
|
953
1050
|
let repo;
|
|
@@ -958,6 +1055,10 @@ function parseCliOptions(args) {
|
|
|
958
1055
|
dev = true;
|
|
959
1056
|
continue;
|
|
960
1057
|
}
|
|
1058
|
+
if (arg === "stop") {
|
|
1059
|
+
command = "stop";
|
|
1060
|
+
continue;
|
|
1061
|
+
}
|
|
961
1062
|
if (arg === "--repo") {
|
|
962
1063
|
const value = args[index + 1];
|
|
963
1064
|
if (!value) throw new Error("--repo requires a path value");
|
|
@@ -986,7 +1087,35 @@ function parseCliOptions(args) {
|
|
|
986
1087
|
}
|
|
987
1088
|
reviewArgs.push(arg);
|
|
988
1089
|
}
|
|
989
|
-
return { dev, repo, reviewArgs, comments };
|
|
1090
|
+
return { command, dev, repo, reviewArgs, comments };
|
|
1091
|
+
}
|
|
1092
|
+
async function stopCommand(repo) {
|
|
1093
|
+
const repoRoot = await getRepoRoot(repo ?? process.cwd());
|
|
1094
|
+
const hasRecord = await hasRuntimeRecord(repoRoot);
|
|
1095
|
+
const { stopped, stale } = await stopRecordedRuntimes(repoRoot);
|
|
1096
|
+
const total = stopped.length + stale.length;
|
|
1097
|
+
if (total === 0) {
|
|
1098
|
+
if (hasRecord) {
|
|
1099
|
+
console.log("No running review process found for this repo.");
|
|
1100
|
+
return;
|
|
1101
|
+
}
|
|
1102
|
+
console.log("No review runtime record found for this repo.");
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
console.log(`Stopped review runtimes: ${stopped.length}`);
|
|
1106
|
+
for (const entry of stopped) {
|
|
1107
|
+
console.log(
|
|
1108
|
+
`- pid=${entry.pid} vitePid=${entry.vitePid ?? "-"} apiPort=${entry.apiPort} vite=${entry.usesVite ? "yes" : "no"} startedAt=${entry.startedAt}`
|
|
1109
|
+
);
|
|
1110
|
+
}
|
|
1111
|
+
if (stale.length > 0) {
|
|
1112
|
+
console.log(`Skipped stale records: ${stale.length}`);
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
function parsePort(url) {
|
|
1116
|
+
const parsed = new URL(url);
|
|
1117
|
+
const port = parsed.port ? Number(parsed.port) : 80;
|
|
1118
|
+
return Number.isNaN(port) ? 0 : port;
|
|
990
1119
|
}
|
|
991
1120
|
function modeLabel(mode) {
|
|
992
1121
|
if (mode.kind === "revision") return `${mode.base}..${mode.target}`;
|
|
@@ -1001,6 +1130,7 @@ function startVite() {
|
|
|
1001
1130
|
});
|
|
1002
1131
|
process.on("SIGINT", () => child.kill("SIGINT"));
|
|
1003
1132
|
process.on("SIGTERM", () => child.kill("SIGTERM"));
|
|
1133
|
+
return child.pid;
|
|
1004
1134
|
}
|
|
1005
1135
|
function openBrowser(url) {
|
|
1006
1136
|
const child = process.platform === "darwin" ? spawn("open", [url], { stdio: "ignore", detached: true }) : process.platform === "win32" ? spawn("cmd", ["/c", "start", "", url], {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,t}from"./path-BJQEcSo7.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-
|
|
1
|
+
import{n as e,t}from"./path-BJQEcSo7.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-BD8BTEle.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i)if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
|