@kynver-app/runtime 0.1.10 → 0.1.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/dist/cli.js +94 -4
- package/dist/cli.js.map +2 -2
- package/dist/index.js +94 -4
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -594,6 +594,92 @@ function ensureGitRepo(repo) {
|
|
|
594
594
|
function gitStatusShort(worktreePath) {
|
|
595
595
|
return git(worktreePath, ["status", "--short"], { allowFailure: true }).split("\n").map((line) => line.trim()).filter(Boolean);
|
|
596
596
|
}
|
|
597
|
+
function gitCapture(cwd, args) {
|
|
598
|
+
try {
|
|
599
|
+
const res = spawnSync("git", args, { cwd, encoding: "utf8" });
|
|
600
|
+
return {
|
|
601
|
+
status: res.status,
|
|
602
|
+
stdout: res.stdout || "",
|
|
603
|
+
stderr: res.stderr || "",
|
|
604
|
+
error: res.error ? res.error.message : null
|
|
605
|
+
};
|
|
606
|
+
} catch (error) {
|
|
607
|
+
return {
|
|
608
|
+
status: null,
|
|
609
|
+
stdout: "",
|
|
610
|
+
stderr: "",
|
|
611
|
+
error: error.message
|
|
612
|
+
};
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
function gitIsAncestor(cwd, ancestor, descendant) {
|
|
616
|
+
const res = gitCapture(cwd, ["merge-base", "--is-ancestor", ancestor, descendant]);
|
|
617
|
+
if (res.status === 0) return { isAncestor: true, error: null };
|
|
618
|
+
if (res.status === 1) return { isAncestor: false, error: null };
|
|
619
|
+
return { isAncestor: null, error: res.error || res.stderr || res.stdout || `git exited ${res.status}` };
|
|
620
|
+
}
|
|
621
|
+
function computeGitAncestry(worktreePath, base = "origin/main") {
|
|
622
|
+
if (!worktreePath) {
|
|
623
|
+
return unknownAncestry(base, "missing worktree path");
|
|
624
|
+
}
|
|
625
|
+
const head = gitCapture(worktreePath, ["rev-parse", "HEAD"]);
|
|
626
|
+
if (head.status !== 0) return unknownAncestry(base, head.error || head.stderr || head.stdout || "failed to resolve HEAD");
|
|
627
|
+
const baseHead = gitCapture(worktreePath, ["rev-parse", base]);
|
|
628
|
+
if (baseHead.status !== 0) {
|
|
629
|
+
return unknownAncestry(base, baseHead.error || baseHead.stderr || baseHead.stdout || `failed to resolve ${base}`, head.stdout.trim());
|
|
630
|
+
}
|
|
631
|
+
const headSha = head.stdout.trim();
|
|
632
|
+
const baseSha = baseHead.stdout.trim();
|
|
633
|
+
if (headSha === baseSha) {
|
|
634
|
+
return {
|
|
635
|
+
checked: true,
|
|
636
|
+
base,
|
|
637
|
+
head: headSha,
|
|
638
|
+
baseHead: baseSha,
|
|
639
|
+
baseIsAncestorOfHead: true,
|
|
640
|
+
headIsAncestorOfBase: true,
|
|
641
|
+
relation: "synced"
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
const baseIsAncestorOfHead = gitIsAncestor(worktreePath, baseSha, headSha);
|
|
645
|
+
const headIsAncestorOfBase = gitIsAncestor(worktreePath, headSha, baseSha);
|
|
646
|
+
const error = baseIsAncestorOfHead.error || headIsAncestorOfBase.error || void 0;
|
|
647
|
+
if (baseIsAncestorOfHead.isAncestor == null || headIsAncestorOfBase.isAncestor == null) {
|
|
648
|
+
return {
|
|
649
|
+
checked: false,
|
|
650
|
+
base,
|
|
651
|
+
head: headSha,
|
|
652
|
+
baseHead: baseSha,
|
|
653
|
+
baseIsAncestorOfHead: baseIsAncestorOfHead.isAncestor,
|
|
654
|
+
headIsAncestorOfBase: headIsAncestorOfBase.isAncestor,
|
|
655
|
+
relation: "unknown",
|
|
656
|
+
...error ? { error } : {}
|
|
657
|
+
};
|
|
658
|
+
}
|
|
659
|
+
const relation = baseIsAncestorOfHead.isAncestor ? "ahead" : headIsAncestorOfBase.isAncestor ? "merged" : "diverged";
|
|
660
|
+
return {
|
|
661
|
+
checked: true,
|
|
662
|
+
base,
|
|
663
|
+
head: headSha,
|
|
664
|
+
baseHead: baseSha,
|
|
665
|
+
baseIsAncestorOfHead: baseIsAncestorOfHead.isAncestor,
|
|
666
|
+
headIsAncestorOfBase: headIsAncestorOfBase.isAncestor,
|
|
667
|
+
relation,
|
|
668
|
+
...error ? { error } : {}
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
function unknownAncestry(base, error, head = null) {
|
|
672
|
+
return {
|
|
673
|
+
checked: false,
|
|
674
|
+
base,
|
|
675
|
+
head,
|
|
676
|
+
baseHead: null,
|
|
677
|
+
baseIsAncestorOfHead: null,
|
|
678
|
+
headIsAncestorOfBase: null,
|
|
679
|
+
relation: "unknown",
|
|
680
|
+
error
|
|
681
|
+
};
|
|
682
|
+
}
|
|
597
683
|
function scrubClaudeEnv(env) {
|
|
598
684
|
const next = { ...env };
|
|
599
685
|
delete next.ANTHROPIC_API_KEY;
|
|
@@ -620,7 +706,7 @@ function computeAttention(input) {
|
|
|
620
706
|
}
|
|
621
707
|
return { state: "ok", reason: "recent activity" };
|
|
622
708
|
}
|
|
623
|
-
function computeWorkerStatus(worker) {
|
|
709
|
+
function computeWorkerStatus(worker, options = {}) {
|
|
624
710
|
const parsed = parseClaudeStream(worker.stdoutPath);
|
|
625
711
|
const heartbeat = parseHeartbeat(worker.heartbeatPath);
|
|
626
712
|
const alive = isPidAlive(worker.pid);
|
|
@@ -628,6 +714,7 @@ function computeWorkerStatus(worker) {
|
|
|
628
714
|
const stderrBytes = fileSize(worker.stderrPath);
|
|
629
715
|
const heartbeatBytes = fileSize(worker.heartbeatPath);
|
|
630
716
|
const changedFiles = gitStatusShort(worker.worktreePath);
|
|
717
|
+
const gitAncestry = computeGitAncestry(worker.worktreePath, options.base);
|
|
631
718
|
const lastActivityAt = latestIso([
|
|
632
719
|
parsed.lastEventAt,
|
|
633
720
|
heartbeat.lastHeartbeatAt,
|
|
@@ -669,7 +756,8 @@ function computeWorkerStatus(worker) {
|
|
|
669
756
|
heartbeatBlocker: heartbeat.heartbeatBlocker,
|
|
670
757
|
finalResult: parsed.finalResult,
|
|
671
758
|
error: parsed.error || (!alive && !parsed.finalResult ? tailFile(worker.stderrPath, 10).trim() || void 0 : void 0),
|
|
672
|
-
changedFiles
|
|
759
|
+
changedFiles,
|
|
760
|
+
gitAncestry
|
|
673
761
|
};
|
|
674
762
|
}
|
|
675
763
|
function isFinishedWorkerStatus(status) {
|
|
@@ -1458,7 +1546,7 @@ function runStatus(args) {
|
|
|
1458
1546
|
if (!worker) {
|
|
1459
1547
|
return { worker: name, status: "missing", attention: "needs_attention", attentionReason: "worker.json not found" };
|
|
1460
1548
|
}
|
|
1461
|
-
const status = computeWorkerStatus(worker);
|
|
1549
|
+
const status = computeWorkerStatus(worker, { base: run.base });
|
|
1462
1550
|
return {
|
|
1463
1551
|
worker: status.worker,
|
|
1464
1552
|
status: status.status,
|
|
@@ -1472,7 +1560,9 @@ function runStatus(args) {
|
|
|
1472
1560
|
lastHeartbeatSummary: status.lastHeartbeatSummary,
|
|
1473
1561
|
heartbeatBlocker: status.heartbeatBlocker,
|
|
1474
1562
|
changedFileCount: status.changedFiles.length,
|
|
1475
|
-
branch: status.branch
|
|
1563
|
+
branch: status.branch,
|
|
1564
|
+
ancestry: status.gitAncestry.relation,
|
|
1565
|
+
ancestryChecked: status.gitAncestry.checked
|
|
1476
1566
|
};
|
|
1477
1567
|
});
|
|
1478
1568
|
const board = {
|