feat(vscode): show thread git metadata
This commit is contained in:
@@ -225,6 +225,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
cross-tab events, and corruption-tolerant persisted state, while leaving the
|
||||
broader collaboration UI wiring to follow-up work (#2864). Thanks
|
||||
@ljm3790865 for the tab-core implementation and #2753 direction.
|
||||
- The VS Code Agent View now renders the runtime thread summary's Git `head`
|
||||
and dirty-worktree flag alongside branch metadata, keeping branch switches
|
||||
visible without adding retry/undo/restore mutation endpoints yet (#2580,
|
||||
#2862). Thanks @AiurArtanis and @nasus9527 for the IDE/agent-view requests
|
||||
and @gaord for the runtime metadata direction.
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@@ -225,6 +225,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
cross-tab events, and corruption-tolerant persisted state, while leaving the
|
||||
broader collaboration UI wiring to follow-up work (#2864). Thanks
|
||||
@ljm3790865 for the tab-core implementation and #2753 direction.
|
||||
- The VS Code Agent View now renders the runtime thread summary's Git `head`
|
||||
and dirty-worktree flag alongside branch metadata, keeping branch switches
|
||||
visible without adding retry/undo/restore mutation endpoints yet (#2580,
|
||||
#2862). Thanks @AiurArtanis and @nasus9527 for the IDE/agent-view requests
|
||||
and @gaord for the runtime metadata direction.
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@@ -200,6 +200,8 @@ function readThreadSummaries(value) {
|
||||
mode: readString(record.mode) ?? "agent",
|
||||
workspace: readString(record.workspace),
|
||||
branch: readString(record.branch),
|
||||
head: readString(record.head),
|
||||
dirty: readBoolean(record.dirty),
|
||||
archived: record.archived === true,
|
||||
updatedAt: readString(record.updated_at) ?? "",
|
||||
latestTurnStatus: readString(record.latest_turn_status),
|
||||
@@ -231,6 +233,9 @@ function readString(value) {
|
||||
function readNumber(value) {
|
||||
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
||||
}
|
||||
function readBoolean(value) {
|
||||
return value === true;
|
||||
}
|
||||
function clampRefreshInterval(value) {
|
||||
if (!Number.isFinite(value)) {
|
||||
return 15;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -148,15 +148,31 @@ function renderSnapshot(snapshot) {
|
||||
function renderThread(thread) {
|
||||
const status = thread.latestTurnStatus ? ` · ${thread.latestTurnStatus}` : "";
|
||||
const archived = thread.archived ? " · archived" : "";
|
||||
const branch = thread.branch ? ` · branch ${thread.branch}` : "";
|
||||
const git = renderGitMetadata(thread);
|
||||
const workspace = thread.workspace ? ` · ${thread.workspace}` : "";
|
||||
const updated = thread.updatedAt ? ` · ${formatTimestamp(thread.updatedAt)}` : "";
|
||||
return `<div class="thread">
|
||||
<div class="thread-title">${escapeHtml(thread.title)}</div>
|
||||
<div class="thread-preview">${escapeHtml(thread.preview || "No recent message.")}</div>
|
||||
<div class="thread-meta">${escapeHtml(`${thread.mode} · ${thread.model}${status}${branch}${archived}${updated}${workspace}`)}</div>
|
||||
<div class="thread-meta">${escapeHtml(`${thread.mode} · ${thread.model}${status}${git}${archived}${updated}${workspace}`)}</div>
|
||||
</div>`;
|
||||
}
|
||||
function renderGitMetadata(thread) {
|
||||
if (!thread.branch && !thread.head && !thread.dirty) {
|
||||
return "";
|
||||
}
|
||||
const parts = [];
|
||||
if (thread.branch) {
|
||||
parts.push(`branch ${thread.branch}`);
|
||||
}
|
||||
if (thread.head) {
|
||||
parts.push(`@ ${thread.head}`);
|
||||
}
|
||||
if (thread.dirty) {
|
||||
parts.push("dirty");
|
||||
}
|
||||
return ` · ${parts.join(" ")}`;
|
||||
}
|
||||
function labelFor(kind) {
|
||||
switch (kind) {
|
||||
case "connected":
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -18,6 +18,8 @@ export interface ThreadSummary {
|
||||
mode: string;
|
||||
workspace?: string;
|
||||
branch?: string;
|
||||
head?: string;
|
||||
dirty: boolean;
|
||||
archived: boolean;
|
||||
updatedAt: string;
|
||||
latestTurnStatus?: string;
|
||||
@@ -228,6 +230,8 @@ function readThreadSummaries(value: unknown): ThreadSummary[] {
|
||||
mode: readString(record.mode) ?? "agent",
|
||||
workspace: readString(record.workspace),
|
||||
branch: readString(record.branch),
|
||||
head: readString(record.head),
|
||||
dirty: readBoolean(record.dirty),
|
||||
archived: record.archived === true,
|
||||
updatedAt: readString(record.updated_at) ?? "",
|
||||
latestTurnStatus: readString(record.latest_turn_status),
|
||||
@@ -265,6 +269,10 @@ function readNumber(value: unknown): number | undefined {
|
||||
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
||||
}
|
||||
|
||||
function readBoolean(value: unknown): boolean {
|
||||
return value === true;
|
||||
}
|
||||
|
||||
function clampRefreshInterval(value: number): number {
|
||||
if (!Number.isFinite(value)) {
|
||||
return 15;
|
||||
|
||||
@@ -120,16 +120,34 @@ function renderSnapshot(snapshot: SnapshotEntry): string {
|
||||
function renderThread(thread: ThreadSummary): string {
|
||||
const status = thread.latestTurnStatus ? ` · ${thread.latestTurnStatus}` : "";
|
||||
const archived = thread.archived ? " · archived" : "";
|
||||
const branch = thread.branch ? ` · branch ${thread.branch}` : "";
|
||||
const git = renderGitMetadata(thread);
|
||||
const workspace = thread.workspace ? ` · ${thread.workspace}` : "";
|
||||
const updated = thread.updatedAt ? ` · ${formatTimestamp(thread.updatedAt)}` : "";
|
||||
return `<div class="thread">
|
||||
<div class="thread-title">${escapeHtml(thread.title)}</div>
|
||||
<div class="thread-preview">${escapeHtml(thread.preview || "No recent message.")}</div>
|
||||
<div class="thread-meta">${escapeHtml(`${thread.mode} · ${thread.model}${status}${branch}${archived}${updated}${workspace}`)}</div>
|
||||
<div class="thread-meta">${escapeHtml(`${thread.mode} · ${thread.model}${status}${git}${archived}${updated}${workspace}`)}</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function renderGitMetadata(thread: ThreadSummary): string {
|
||||
if (!thread.branch && !thread.head && !thread.dirty) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const parts: string[] = [];
|
||||
if (thread.branch) {
|
||||
parts.push(`branch ${thread.branch}`);
|
||||
}
|
||||
if (thread.head) {
|
||||
parts.push(`@ ${thread.head}`);
|
||||
}
|
||||
if (thread.dirty) {
|
||||
parts.push("dirty");
|
||||
}
|
||||
return ` · ${parts.join(" ")}`;
|
||||
}
|
||||
|
||||
function labelFor(kind: RuntimeState["kind"]): string {
|
||||
switch (kind) {
|
||||
case "connected":
|
||||
|
||||
Reference in New Issue
Block a user