Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Works with any CLI agent. Built for local worktree-based development.
| **シェル履歴サジェスト** | ターミナル入力時に ~/.zsh_history からコマンド候補をドロップダウン表示。↑↓で選択、→で確定、Escで破棄。選択中コマンドのフルプレビュー付き(補完部分を緑色で強調)。8件超はスクロール、末尾到達で追加読み込み。設定画面から ON/OFF 切り替え可能 | [#24](https://github.com/MocA-Love/superset/pull/24) | 2026-03-30 |
| **Sentry エラー監視統合** | 自前の Sentry プロジェクトと連携可能。`.env` に `SENTRY_DSN_DESKTOP` を設定するだけで本番ビルドのクラッシュ・エラーを自動収集 | [#26](https://github.com/MocA-Love/superset/pull/26) | 2026-03-30 |
| **デスクトップ安定性修正** | シェル履歴サジェストが表示されないバグ(useEffect 依存配列の問題)、アプリ終了時の napi_fatal_error クラッシュ(SQLite 未クローズ)、webview パーキング後の getURL() エラー、サイドバーリサイズが webview 上で効かない問題を修正 | [#26](https://github.com/MocA-Love/superset/pull/26) | 2026-03-30 |
| **Review パネル強化** | GitHub Actions チェックを展開してジョブ内ステップの進捗を表示。レビューコメントを展開して Markdown レンダリング全文表示(GitHub Alerts 対応)。コメントのファイルパス+行番号クリックでエディタの該当行にジャンプ | [#27](https://github.com/MocA-Love/superset/pull/27) | 2026-03-30 |

## Fork のビルド方法 (macOS)

Expand Down
1 change: 1 addition & 0 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@
"rehype-raw": "^7.0.0",
"rehype-sanitize": "^6.0.0",
"remark-gfm": "^4.0.1",
"remark-github-blockquote-alert": "^2.1.0",
"semver": "^7.7.3",
"shell-env": "^4.0.3",
"shell-quote": "^1.8.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
refreshDefaultBranch,
} from "../utils/git";
import {
fetchCheckJobSteps,
fetchGitHubPRComments,
fetchGitHubPRStatus,
type PullRequestCommentsTarget,
Expand Down Expand Up @@ -335,5 +336,34 @@ export const createGitStatusProcedures = () => {
branch: wt.branch!,
}));
}),

getCheckJobSteps: publicProcedure
.input(
z.object({
workspaceId: z.string(),
detailsUrl: z.string(),
}),
)
.query(async ({ input }) => {
const workspace = getWorkspace(input.workspaceId);
if (!workspace) {
return [];
}

const worktree = workspace.worktreeId
? getWorktree(workspace.worktreeId)
: null;

let repoPath: string | null = worktree?.path ?? null;
if (!repoPath && workspace.type === "branch") {
const project = getProject(workspace.projectId);
repoPath = project?.mainRepoPath ?? null;
}
if (!repoPath) {
return [];
}

return fetchCheckJobSteps(repoPath, input.detailsUrl);
}),
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { extractNwoFromUrl, getRepoContext } from "./repo-context";
import {
GHDeploymentSchema,
GHDeploymentStatusSchema,
GHJobResponseSchema,
type RepoContext,
} from "./types";

Expand Down Expand Up @@ -374,3 +375,74 @@ async function fetchPreviewDeploymentUrl(
return undefined;
}
}

export interface JobStepInfo {
name: string;
status: "queued" | "in_progress" | "completed";
conclusion: string | null;
number: number;
}

/**
* Extracts job ID from a GitHub Actions details URL.
* URL format: https://github.com/{owner}/{repo}/actions/runs/{run_id}/job/{job_id}
*/
function parseJobIdFromUrl(detailsUrl: string): string | null {
try {
const url = new URL(detailsUrl);
const match = url.pathname.match(/\/actions\/runs\/\d+\/job\/(\d+)/);
return match?.[1] ?? null;
} catch {
return null;
}
}

/**
* Extracts nwo (owner/repo) from a GitHub Actions details URL.
*/
function parseNwoFromActionsUrl(detailsUrl: string): string | null {
try {
const url = new URL(detailsUrl);
const match = url.pathname.match(/^\/([^/]+\/[^/]+)\/actions\//);
return match?.[1] ?? null;
} catch {
return null;
}
}

/**
* Fetches job steps for a given GitHub Actions check using its details URL.
*/
export async function fetchCheckJobSteps(
worktreePath: string,
detailsUrl: string,
): Promise<JobStepInfo[]> {
const jobId = parseJobIdFromUrl(detailsUrl);
const nwo = parseNwoFromActionsUrl(detailsUrl);
if (!jobId || !nwo) {
return [];
}

try {
const { stdout } = await execWithShellEnv(
"gh",
["api", `repos/${nwo}/actions/jobs/${jobId}`],
{ cwd: worktreePath },
);

const raw: unknown = JSON.parse(stdout.trim());
const result = GHJobResponseSchema.safeParse(raw);
if (!result.success) {
return [];
}

return (result.data.steps ?? []).map((step) => ({
name: step.name,
status: step.status,
conclusion: step.conclusion ?? null,
number: step.number,
}));
} catch {
return [];
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export type { PullRequestCommentsTarget } from "./github";
export {
clearGitHubCachesForWorktree,
fetchCheckJobSteps,
fetchGitHubPRComments,
fetchGitHubPRStatus,
} from "./github";
Expand Down
32 changes: 32 additions & 0 deletions apps/desktop/src/lib/trpc/routers/workspaces/utils/github/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,38 @@ export interface RepoContext {

export type GHPRResponse = z.infer<typeof GHPRResponseSchema>;

/**
* GitHub Actions job step schema
*/
export const GHJobStepSchema = z.object({
name: z.string(),
status: z.enum(["queued", "in_progress", "completed"]),
conclusion: z
.enum(["success", "failure", "cancelled", "skipped", ""])
.nullable()
.optional(),
number: z.number(),
started_at: z.string().nullable().optional(),
completed_at: z.string().nullable().optional(),
});

export type GHJobStep = z.infer<typeof GHJobStepSchema>;

export const GHJobResponseSchema = z.object({
id: z.number(),
name: z.string(),
status: z.enum(["queued", "in_progress", "completed", "waiting"]),
conclusion: z
.enum(["success", "failure", "cancelled", "skipped", "timed_out", ""])
.nullable()
.optional(),
started_at: z.string().nullable().optional(),
completed_at: z.string().nullable().optional(),
steps: z.array(GHJobStepSchema).optional(),
});

export type GHJobResponse = z.infer<typeof GHJobResponseSchema>;

export const GHDeploymentSchema = z.object({
id: z.number(),
ref: z.string(),
Expand Down
139 changes: 139 additions & 0 deletions apps/desktop/src/renderer/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -280,4 +280,143 @@
[data-sonner-toast]:has(.update-toast) {
transform: translateY(0);
}

/* Review comment markdown body */
.review-comment-body p {
margin: 0.25rem 0;
}
.review-comment-body h1,
.review-comment-body h2,
.review-comment-body h3,
.review-comment-body h4 {
margin: 0.5rem 0 0.25rem;
font-weight: 600;
}
.review-comment-body h1 {
font-size: 1em;
}
.review-comment-body h2 {
font-size: 0.95em;
}
.review-comment-body h3 {
font-size: 0.9em;
}
.review-comment-body ul,
.review-comment-body ol {
margin: 0.25rem 0;
padding-left: 1.25rem;
}
.review-comment-body li {
margin: 0.125rem 0;
}
.review-comment-body ul {
list-style-type: disc;
}
.review-comment-body ol {
list-style-type: decimal;
}
.review-comment-body code {
font-size: 0.9em;
padding: 0.1em 0.3em;
border-radius: 3px;
background-color: var(--muted);
}
.review-comment-body pre {
margin: 0.375rem 0;
padding: 0.5rem;
border-radius: 4px;
background-color: var(--muted);
overflow-x: auto;
}
.review-comment-body pre code {
padding: 0;
background: none;
}
.review-comment-body blockquote {
margin: 0.25rem 0;
padding-left: 0.75rem;
border-left: 2px solid var(--border);
color: var(--muted-foreground);
}
.review-comment-body a {
color: #60a5fa;
text-decoration: underline;
}
.review-comment-body hr {
margin: 0.5rem 0;
border-color: var(--border);
}
.review-comment-body table {
border-collapse: collapse;
margin: 0.25rem 0;
}
.review-comment-body th,
.review-comment-body td {
border: 1px solid var(--border);
padding: 0.25rem 0.5rem;
font-size: 0.9em;
}
.review-comment-body img {
max-width: 100%;
border-radius: 4px;
}
.review-comment-body input[type="checkbox"] {
margin-right: 0.35rem;
}

/* GitHub-style alerts (> [!NOTE], > [!TIP], etc.) */
.review-comment-body .markdown-alert {
border-left: 3px solid;
padding: 0.375rem 0.75rem;
margin: 0.375rem 0;
border-radius: 0 4px 4px 0;
}
.review-comment-body .markdown-alert-title {
display: flex;
align-items: center;
gap: 0.375rem;
font-weight: 600;
font-size: 0.85em;
margin-bottom: 0.125rem;
}
.review-comment-body .markdown-alert-title svg {
width: 14px;
height: 14px;
fill: currentColor;
}
.review-comment-body .markdown-alert-note {
border-left-color: #58a6ff;
background-color: rgba(88, 166, 255, 0.06);
}
.review-comment-body .markdown-alert-note .markdown-alert-title {
color: #58a6ff;
}
.review-comment-body .markdown-alert-tip {
border-left-color: #3fb950;
background-color: rgba(63, 185, 80, 0.06);
}
.review-comment-body .markdown-alert-tip .markdown-alert-title {
color: #3fb950;
}
.review-comment-body .markdown-alert-important {
border-left-color: #a371f7;
background-color: rgba(163, 113, 247, 0.06);
}
.review-comment-body .markdown-alert-important .markdown-alert-title {
color: #a371f7;
}
.review-comment-body .markdown-alert-warning {
border-left-color: #d29922;
background-color: rgba(210, 153, 34, 0.06);
}
.review-comment-body .markdown-alert-warning .markdown-alert-title {
color: #d29922;
}
.review-comment-body .markdown-alert-caution {
border-left-color: #f85149;
background-color: rgba(248, 81, 73, 0.06);
}
.review-comment-body .markdown-alert-caution .markdown-alert-title {
color: #f85149;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ interface ChangesViewProps {
category: ChangeCategory,
commitHash?: string,
) => void;
onOpenFileAtLine?: (path: string, line?: number) => void;
isExpandedView?: boolean;
isActive?: boolean;
}
Expand Down Expand Up @@ -79,6 +80,7 @@ function eventTargetsSelectedFile(

export function ChangesView({
onFileOpen,
onOpenFileAtLine,
isExpandedView,
isActive = true,
}: ChangesViewProps) {
Expand Down Expand Up @@ -822,6 +824,7 @@ export function ChangesView({
comments={githubComments}
isLoading={isGitHubStatusLoading}
isCommentsLoading={isGitHubCommentsLoading}
onOpenFile={onOpenFileAtLine}
/>
</TabsContent>
</Tabs>
Expand Down
Loading
Loading