@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/cli.js
CHANGED
|
@@ -593,6 +593,92 @@ function ensureGitRepo(repo) {
|
|
|
593
593
|
function gitStatusShort(worktreePath) {
|
|
594
594
|
return git(worktreePath, ["status", "--short"], { allowFailure: true }).split("\n").map((line) => line.trim()).filter(Boolean);
|
|
595
595
|
}
|
|
596
|
+
function gitCapture(cwd, args) {
|
|
597
|
+
try {
|
|
598
|
+
const res = spawnSync("git", args, { cwd, encoding: "utf8" });
|
|
599
|
+
return {
|
|
600
|
+
status: res.status,
|
|
601
|
+
stdout: res.stdout || "",
|
|
602
|
+
stderr: res.stderr || "",
|
|
603
|
+
error: res.error ? res.error.message : null
|
|
604
|
+
};
|
|
605
|
+
} catch (error) {
|
|
606
|
+
return {
|
|
607
|
+
status: null,
|
|
608
|
+
stdout: "",
|
|
609
|
+
stderr: "",
|
|
610
|
+
error: error.message
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
function gitIsAncestor(cwd, ancestor, descendant) {
|
|
615
|
+
const res = gitCapture(cwd, ["merge-base", "--is-ancestor", ancestor, descendant]);
|
|
616
|
+
if (res.status === 0) return { isAncestor: true, error: null };
|
|
617
|
+
if (res.status === 1) return { isAncestor: false, error: null };
|
|
618
|
+
return { isAncestor: null, error: res.error || res.stderr || res.stdout || `git exited ${res.status}` };
|
|
619
|
+
}
|
|
620
|
+
function computeGitAncestry(worktreePath, base = "origin/main") {
|
|
621
|
+
if (!worktreePath) {
|
|
622
|
+
return unknownAncestry(base, "missing worktree path");
|
|
623
|
+
}
|
|
624
|
+
const head = gitCapture(worktreePath, ["rev-parse", "HEAD"]);
|
|
625
|
+
if (head.status !== 0) return unknownAncestry(base, head.error || head.stderr || head.stdout || "failed to resolve HEAD");
|
|
626
|
+
const baseHead = gitCapture(worktreePath, ["rev-parse", base]);
|
|
627
|
+
if (baseHead.status !== 0) {
|
|
628
|
+
return unknownAncestry(base, baseHead.error || baseHead.stderr || baseHead.stdout || `failed to resolve ${base}`, head.stdout.trim());
|
|
629
|
+
}
|
|
630
|
+
const headSha = head.stdout.trim();
|
|
631
|
+
const baseSha = baseHead.stdout.trim();
|
|
632
|
+
if (headSha === baseSha) {
|
|
633
|
+
return {
|
|
634
|
+
checked: true,
|
|
635
|
+
base,
|
|
636
|
+
head: headSha,
|
|
637
|
+
baseHead: baseSha,
|
|
638
|
+
baseIsAncestorOfHead: true,
|
|
639
|
+
headIsAncestorOfBase: true,
|
|
640
|
+
relation: "synced"
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
const baseIsAncestorOfHead = gitIsAncestor(worktreePath, baseSha, headSha);
|
|
644
|
+
const headIsAncestorOfBase = gitIsAncestor(worktreePath, headSha, baseSha);
|
|
645
|
+
const error = baseIsAncestorOfHead.error || headIsAncestorOfBase.error || void 0;
|
|
646
|
+
if (baseIsAncestorOfHead.isAncestor == null || headIsAncestorOfBase.isAncestor == null) {
|
|
647
|
+
return {
|
|
648
|
+
checked: false,
|
|
649
|
+
base,
|
|
650
|
+
head: headSha,
|
|
651
|
+
baseHead: baseSha,
|
|
652
|
+
baseIsAncestorOfHead: baseIsAncestorOfHead.isAncestor,
|
|
653
|
+
headIsAncestorOfBase: headIsAncestorOfBase.isAncestor,
|
|
654
|
+
relation: "unknown",
|
|
655
|
+
...error ? { error } : {}
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
const relation = baseIsAncestorOfHead.isAncestor ? "ahead" : headIsAncestorOfBase.isAncestor ? "merged" : "diverged";
|
|
659
|
+
return {
|
|
660
|
+
checked: true,
|
|
661
|
+
base,
|
|
662
|
+
head: headSha,
|
|
663
|
+
baseHead: baseSha,
|
|
664
|
+
baseIsAncestorOfHead: baseIsAncestorOfHead.isAncestor,
|
|
665
|
+
headIsAncestorOfBase: headIsAncestorOfBase.isAncestor,
|
|
666
|
+
relation,
|
|
667
|
+
...error ? { error } : {}
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
function unknownAncestry(base, error, head = null) {
|
|
671
|
+
return {
|
|
672
|
+
checked: false,
|
|
673
|
+
base,
|
|
674
|
+
head,
|
|
675
|
+
baseHead: null,
|
|
676
|
+
baseIsAncestorOfHead: null,
|
|
677
|
+
headIsAncestorOfBase: null,
|
|
678
|
+
relation: "unknown",
|
|
679
|
+
error
|
|
680
|
+
};
|
|
681
|
+
}
|
|
596
682
|
function scrubClaudeEnv(env) {
|
|
597
683
|
const next = { ...env };
|
|
598
684
|
delete next.ANTHROPIC_API_KEY;
|
|
@@ -619,7 +705,7 @@ function computeAttention(input) {
|
|
|
619
705
|
}
|
|
620
706
|
return { state: "ok", reason: "recent activity" };
|
|
621
707
|
}
|
|
622
|
-
function computeWorkerStatus(worker) {
|
|
708
|
+
function computeWorkerStatus(worker, options = {}) {
|
|
623
709
|
const parsed = parseClaudeStream(worker.stdoutPath);
|
|
624
710
|
const heartbeat = parseHeartbeat(worker.heartbeatPath);
|
|
625
711
|
const alive = isPidAlive(worker.pid);
|
|
@@ -627,6 +713,7 @@ function computeWorkerStatus(worker) {
|
|
|
627
713
|
const stderrBytes = fileSize(worker.stderrPath);
|
|
628
714
|
const heartbeatBytes = fileSize(worker.heartbeatPath);
|
|
629
715
|
const changedFiles = gitStatusShort(worker.worktreePath);
|
|
716
|
+
const gitAncestry = computeGitAncestry(worker.worktreePath, options.base);
|
|
630
717
|
const lastActivityAt = latestIso([
|
|
631
718
|
parsed.lastEventAt,
|
|
632
719
|
heartbeat.lastHeartbeatAt,
|
|
@@ -668,7 +755,8 @@ function computeWorkerStatus(worker) {
|
|
|
668
755
|
heartbeatBlocker: heartbeat.heartbeatBlocker,
|
|
669
756
|
finalResult: parsed.finalResult,
|
|
670
757
|
error: parsed.error || (!alive && !parsed.finalResult ? tailFile(worker.stderrPath, 10).trim() || void 0 : void 0),
|
|
671
|
-
changedFiles
|
|
758
|
+
changedFiles,
|
|
759
|
+
gitAncestry
|
|
672
760
|
};
|
|
673
761
|
}
|
|
674
762
|
function isFinishedWorkerStatus(status) {
|
|
@@ -1430,7 +1518,7 @@ function runStatus(args) {
|
|
|
1430
1518
|
if (!worker) {
|
|
1431
1519
|
return { worker: name, status: "missing", attention: "needs_attention", attentionReason: "worker.json not found" };
|
|
1432
1520
|
}
|
|
1433
|
-
const status = computeWorkerStatus(worker);
|
|
1521
|
+
const status = computeWorkerStatus(worker, { base: run.base });
|
|
1434
1522
|
return {
|
|
1435
1523
|
worker: status.worker,
|
|
1436
1524
|
status: status.status,
|
|
@@ -1444,7 +1532,9 @@ function runStatus(args) {
|
|
|
1444
1532
|
lastHeartbeatSummary: status.lastHeartbeatSummary,
|
|
1445
1533
|
heartbeatBlocker: status.heartbeatBlocker,
|
|
1446
1534
|
changedFileCount: status.changedFiles.length,
|
|
1447
|
-
branch: status.branch
|
|
1535
|
+
branch: status.branch,
|
|
1536
|
+
ancestry: status.gitAncestry.relation,
|
|
1537
|
+
ancestryChecked: status.gitAncestry.checked
|
|
1448
1538
|
};
|
|
1449
1539
|
});
|
|
1450
1540
|
const board = {
|