@grifhinz/logics-manager 2.5.1 → 2.5.2
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 +1 -1
- package/VERSION +1 -1
- package/clients/shared-web/media/css/layout.css +1 -0
- package/clients/viewer/browser-host.js +33 -1
- package/clients/viewer/viewer.css +46 -0
- package/logics_manager/viewer.py +41 -2
- package/package.json +1 -1
- package/pyproject.toml +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/AlexAgo83/logics-manager/actions/workflows/ci.yml)
|
|
4
4
|
[](LICENSE)
|
|
5
|
-

|
|
6
6
|

|
|
7
7
|

|
|
8
8
|

|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.5.
|
|
1
|
+
2.5.2
|
|
@@ -1751,6 +1751,14 @@
|
|
|
1751
1751
|
<span class="viewer-git__domain-label">${escapeHtml(label)}${key === "changes" ? gitBadgeHtml("changes") : ""}${key === "history" ? gitBadgeHtml("history") : ""}</span><strong>${escapeHtml(count)}</strong>
|
|
1752
1752
|
</button>
|
|
1753
1753
|
`).join("");
|
|
1754
|
+
const renderChangeStats = (entry) => {
|
|
1755
|
+
const additions = Number(entry?.additions);
|
|
1756
|
+
const deletions = Number(entry?.deletions);
|
|
1757
|
+
if (!Number.isFinite(additions) || !Number.isFinite(deletions)) {
|
|
1758
|
+
return "";
|
|
1759
|
+
}
|
|
1760
|
+
return `<span class="viewer-git__file-changes" title="Line changes"><span class="viewer-git__file-additions">+${escapeHtml(additions)}</span><span class="viewer-git__file-deletions">-${escapeHtml(deletions)}</span></span>`;
|
|
1761
|
+
};
|
|
1754
1762
|
const renderFileSections = (allowedKeys) => groupDefs.filter(([key]) => allowedKeys.includes(key)).map(([key, label]) => {
|
|
1755
1763
|
const entries = Array.isArray(payload.groups?.[key]) ? payload.groups[key] : [];
|
|
1756
1764
|
if (!entries.length) {
|
|
@@ -1763,6 +1771,7 @@
|
|
|
1763
1771
|
<li>
|
|
1764
1772
|
<button class="viewer-git__file" type="button" data-viewer-git-file="${escapeHtml(entry.path)}" data-viewer-git-cached="${key === "staged" ? "1" : "0"}">
|
|
1765
1773
|
<span class="viewer-git__file-path">${escapeHtml(entry.from ? `${entry.from} -> ${entry.path}` : entry.path)}</span>
|
|
1774
|
+
${renderChangeStats(entry)}
|
|
1766
1775
|
${entry.logicsType ? `<span class="viewer-git__file-kind">${escapeHtml(entry.logicsType)}</span>` : ""}
|
|
1767
1776
|
</button>
|
|
1768
1777
|
</li>
|
|
@@ -1852,6 +1861,29 @@
|
|
|
1852
1861
|
});
|
|
1853
1862
|
}
|
|
1854
1863
|
|
|
1864
|
+
function gitDiffLineKind(line) {
|
|
1865
|
+
if (line.startsWith("+") && !line.startsWith("+++")) {
|
|
1866
|
+
return "add";
|
|
1867
|
+
}
|
|
1868
|
+
if (line.startsWith("-") && !line.startsWith("---")) {
|
|
1869
|
+
return "delete";
|
|
1870
|
+
}
|
|
1871
|
+
if (line.startsWith("@@")) {
|
|
1872
|
+
return "hunk";
|
|
1873
|
+
}
|
|
1874
|
+
if (line.startsWith("diff --git") || line.startsWith("index ") || line.startsWith("+++") || line.startsWith("---")) {
|
|
1875
|
+
return "meta";
|
|
1876
|
+
}
|
|
1877
|
+
return "context";
|
|
1878
|
+
}
|
|
1879
|
+
|
|
1880
|
+
function renderGitDiffPreview(content) {
|
|
1881
|
+
return String(content)
|
|
1882
|
+
.split("\n")
|
|
1883
|
+
.map((line) => `<span class="viewer-git__diff-line viewer-git__diff-line--${gitDiffLineKind(line)}">${escapeHtml(line || " ")}</span>`)
|
|
1884
|
+
.join("");
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1855
1887
|
async function loadGitDiff(path, cached, button = null) {
|
|
1856
1888
|
const diffPanel = document.querySelector("[data-viewer-git-diff]");
|
|
1857
1889
|
if (!(diffPanel instanceof HTMLElement) || !path) {
|
|
@@ -1873,7 +1905,7 @@
|
|
|
1873
1905
|
return;
|
|
1874
1906
|
}
|
|
1875
1907
|
const content = payload.diff || payload.message || "No diff is available for this file.";
|
|
1876
|
-
diffPanel.innerHTML = `<div class="viewer-git__diff-meta">${escapeHtml(payload.path || path)} · ${escapeHtml(payload.mode || "worktree")}${payload.truncated ? " · truncated" : ""}</div><pre><code>${
|
|
1908
|
+
diffPanel.innerHTML = `<div class="viewer-git__diff-meta">${escapeHtml(payload.path || path)} · ${escapeHtml(payload.mode || "worktree")}${payload.truncated ? " · truncated" : ""}</div><pre><code>${renderGitDiffPreview(content)}</code></pre>`;
|
|
1877
1909
|
}
|
|
1878
1910
|
|
|
1879
1911
|
function applyGitDomain(domain) {
|
|
@@ -829,6 +829,23 @@
|
|
|
829
829
|
overflow-wrap: anywhere;
|
|
830
830
|
}
|
|
831
831
|
|
|
832
|
+
.viewer-git__file-changes {
|
|
833
|
+
display: inline-flex;
|
|
834
|
+
align-items: center;
|
|
835
|
+
gap: 5px;
|
|
836
|
+
flex: 0 0 auto;
|
|
837
|
+
font-family: var(--vscode-editor-font-family, ui-monospace, SFMono-Regular, Menlo, monospace);
|
|
838
|
+
font-size: 11px;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
.viewer-git__file-additions {
|
|
842
|
+
color: #7ee787;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
.viewer-git__file-deletions {
|
|
846
|
+
color: #ffaaa5;
|
|
847
|
+
}
|
|
848
|
+
|
|
832
849
|
.viewer-git__file-kind {
|
|
833
850
|
flex: 0 0 auto;
|
|
834
851
|
padding: 2px 6px;
|
|
@@ -871,6 +888,35 @@
|
|
|
871
888
|
white-space: pre;
|
|
872
889
|
}
|
|
873
890
|
|
|
891
|
+
.viewer-git__diff-line {
|
|
892
|
+
display: block;
|
|
893
|
+
min-height: 1.35em;
|
|
894
|
+
padding: 0 8px;
|
|
895
|
+
border-left: 3px solid transparent;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
.viewer-git__diff-line--add {
|
|
899
|
+
border-left-color: #2ea043;
|
|
900
|
+
background: rgba(46, 160, 67, 0.16);
|
|
901
|
+
color: #7ee787;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
.viewer-git__diff-line--delete {
|
|
905
|
+
border-left-color: #f85149;
|
|
906
|
+
background: rgba(248, 81, 73, 0.16);
|
|
907
|
+
color: #ffaaa5;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
.viewer-git__diff-line--hunk {
|
|
911
|
+
border-left-color: var(--vscode-textLink-foreground, #4ea1ff);
|
|
912
|
+
background: color-mix(in srgb, var(--vscode-textLink-foreground, #4ea1ff) 14%, transparent);
|
|
913
|
+
color: var(--vscode-textLink-foreground, #4ea1ff);
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
.viewer-git__diff-line--meta {
|
|
917
|
+
color: var(--vscode-descriptionForeground, #aaaaaa);
|
|
918
|
+
}
|
|
919
|
+
|
|
874
920
|
.viewer-git__commit,
|
|
875
921
|
.viewer-git__state {
|
|
876
922
|
margin: 0;
|
package/logics_manager/viewer.py
CHANGED
|
@@ -496,7 +496,38 @@ def _parse_recent_git_commits(output: str) -> list[dict[str, str]]:
|
|
|
496
496
|
return commits
|
|
497
497
|
|
|
498
498
|
|
|
499
|
-
def
|
|
499
|
+
def _parse_git_numstat(output: str) -> dict[str, dict[str, int]]:
|
|
500
|
+
stats: dict[str, dict[str, int]] = {}
|
|
501
|
+
for line in output.splitlines():
|
|
502
|
+
parts = line.split("\t")
|
|
503
|
+
if len(parts) < 3:
|
|
504
|
+
continue
|
|
505
|
+
raw_additions, raw_deletions, raw_path = parts[:3]
|
|
506
|
+
try:
|
|
507
|
+
additions = int(raw_additions)
|
|
508
|
+
deletions = int(raw_deletions)
|
|
509
|
+
except ValueError:
|
|
510
|
+
continue
|
|
511
|
+
path = raw_path.strip()
|
|
512
|
+
if " => " in path:
|
|
513
|
+
path = path.split(" => ", 1)[1].strip("{}")
|
|
514
|
+
if path:
|
|
515
|
+
stats[path] = {"additions": additions, "deletions": deletions}
|
|
516
|
+
return stats
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
def _attach_git_change_stats(groups: dict[str, list[dict[str, Any]]], staged_stats: dict[str, dict[str, int]], worktree_stats: dict[str, dict[str, int]]) -> None:
|
|
520
|
+
for key, entries in groups.items():
|
|
521
|
+
stats_source = staged_stats if key == "staged" else worktree_stats
|
|
522
|
+
for entry in entries:
|
|
523
|
+
path = str(entry.get("path", ""))
|
|
524
|
+
stats = stats_source.get(path) or staged_stats.get(path) or worktree_stats.get(path)
|
|
525
|
+
if stats:
|
|
526
|
+
entry["additions"] = stats["additions"]
|
|
527
|
+
entry["deletions"] = stats["deletions"]
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
def _count_unique_git_status_paths(groups: dict[str, list[dict[str, Any]]]) -> int:
|
|
500
531
|
paths: set[str] = set()
|
|
501
532
|
for entries in groups.values():
|
|
502
533
|
for entry in entries:
|
|
@@ -543,6 +574,8 @@ def git_status_payload(repo_root: Path, *, runner: Any | None = None, which: Any
|
|
|
543
574
|
|
|
544
575
|
try:
|
|
545
576
|
status = _run_read_only_git(repo_root, ["status", "--porcelain=v1", "-b"], runner=runner)
|
|
577
|
+
staged_numstat = _run_read_only_git(repo_root, ["diff", "--no-ext-diff", "--numstat", "--cached"], runner=runner)
|
|
578
|
+
worktree_numstat = _run_read_only_git(repo_root, ["diff", "--no-ext-diff", "--numstat"], runner=runner)
|
|
546
579
|
commit = _run_read_only_git(repo_root, ["log", "-1", "--pretty=format:%h %s"], runner=runner)
|
|
547
580
|
recent_commits = _run_read_only_git(
|
|
548
581
|
repo_root,
|
|
@@ -558,12 +591,18 @@ def git_status_payload(repo_root: Path, *, runner: Any | None = None, which: Any
|
|
|
558
591
|
|
|
559
592
|
lines = status.stdout.splitlines()
|
|
560
593
|
branch_info = _parse_git_branch_line(lines[0]) if lines else {"branch": "HEAD", "tracking": "", "ahead": 0, "behind": 0}
|
|
561
|
-
groups: dict[str, list[dict[str,
|
|
594
|
+
groups: dict[str, list[dict[str, Any]]] = {key: [] for key in ("staged", "modified", "deleted", "renamed", "untracked")}
|
|
562
595
|
for line in lines[1:]:
|
|
563
596
|
classified = _classify_porcelain_entry(line)
|
|
564
597
|
if classified:
|
|
565
598
|
group, entry = classified
|
|
566
599
|
groups[group].append(entry)
|
|
600
|
+
if staged_numstat.returncode == 0 or worktree_numstat.returncode == 0:
|
|
601
|
+
_attach_git_change_stats(
|
|
602
|
+
groups,
|
|
603
|
+
_parse_git_numstat(staged_numstat.stdout if staged_numstat.returncode == 0 else ""),
|
|
604
|
+
_parse_git_numstat(worktree_numstat.stdout if worktree_numstat.returncode == 0 else ""),
|
|
605
|
+
)
|
|
567
606
|
counts = {key: len(value) for key, value in groups.items()}
|
|
568
607
|
uncommitted_files = _count_unique_git_status_paths(groups)
|
|
569
608
|
dirty = any(counts.values())
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@grifhinz/logics-manager",
|
|
3
3
|
"displayName": "Logics Orchestrator",
|
|
4
4
|
"description": "Visual orchestration for Logics workflows inside VS Code.",
|
|
5
|
-
"version": "2.5.
|
|
5
|
+
"version": "2.5.2",
|
|
6
6
|
"publisher": "cdx-logics",
|
|
7
7
|
"icon": "clients/shared-web/media/icon.png",
|
|
8
8
|
"repository": {
|