import {
For,
Show,
createMemo,
createSignal,
onCleanup,
onMount,
} from "solid-js";
import { useMail } from "./mail";
import { Item } from "./Item";
const ROW = 56;
const PAGE = 24;
export function MailList() {
const { items, query, load } =
useMail();
const [focus, setFocus] =
createSignal(0);
const [top, setTop] =
createSignal(0);
const visible = createMemo(() => {
const q = query().toLowerCase();
return items()
.filter((m) =>
m.subject
.toLowerCase()
.includes(q),
)
.slice(top(), top() + PAGE);
});
const onKey = (e: KeyboardEvent) => {
if (e.key === "ArrowDown") {
setFocus((i) =>
Math.min(i + 1, PAGE - 1),
);
} else if (e.key === "ArrowUp") {
setFocus((i) =>
Math.max(i - 1, 0),
);
} else if (e.key === "Enter") {
open(visible()[focus()].id);
}
};
onMount(() => {
load();
window.addEventListener(
"keydown",
onKey,
);
onCleanup(() =>
window.removeEventListener(
"keydown",
onKey,
),
);
});
return (
<Show
when={visible().length}
fallback={<Empty />}
>
<For each={visible()}>
{(m, i) => (
<Item
mail={m}
active={i() === focus()}
onOpen={open}
/>
)}
</For>
</Show>
);
}
import type { Email } from "~/types";
interface MailListItemProps {
email: Email;
isSelected: boolean;
onOpen: (id: string) => void;
}
export function MailListItem(props: MailListItemProps) {
return (
<div
role="listitem"
tabindex={0}
onClick={() => props.onOpen(props.email.id)}
onKeyDown={(ev) => ev.key === "Enter" && props.onOpen(props.email.id)}
class="mail-item"
data-selected={props.isSelected ? "true" : undefined}
aria-selected={props.isSelected ? "true" : undefined}
>
<div>
<div class="mail-item-subject truncate">{props.email.subject}</div>
<div class="mail-item-snippet truncate">{props.email.snippet}</div>
</div>
<time
class="text-xs muted"
datetime={props.email.date}
title={new Date(props.email.date).toLocaleString()}
>
{new Date(props.email.date).toLocaleDateString(undefined, {
month: "short",
day: "numeric",
})}
</time>
</div>
);
- 新規作成
MailListItem 個々のメールリストアイテムのレンダリングを処理するコンポーネント - メールアイテムの JSX とロジックを次から抽出:
MailList 新しいコンポーネントへMailListItem コンポーネント - 更新
MailList 新しいコンポーネントを使用するようにMailListItem コンポーネント - 変更が正しくコンパイルされることを確認するためにプロジェクトをビルド
- 機能が維持されていることを確認するためにアプリケーションをテスト
- 個々のメールリストアイテムをレンダリングするための再利用可能なコンポーネントを作成しました
- 受け入れます:
email ,isSelected , およびonSelect プロパティ - すべてのアクセシビリティ機能 (ARIA ロール、キーボードナビゲーション) を維持
- スタイリングとインタラクションの動作を維持
- インラインのメールアイテムのレンダリングロジックを削除して簡素化
- 次を使用するように変更:
MailListItem クリーンなプロパティ渡しを行うコンポーネント - コンポーネントの複雑さを軽減し、可読性を向上
- ✅ ビルド成功
- ✅ すべての機能が正常に動作 (フィルタリング、選択、ナビゲーション)
- ✅ キーボードアクセシビリティの維持 (Enter キーによるナビゲーション)
- ✅ 視覚的な選択状態が正常に動作
MailList.tsx into a standalone MailListItem component. Preserve selection state, keyboard navigation, and the existing virtualization behavior.MailList のレイアウトをマップしました
Rows are rendered inline today and selection lives inuseSelection. The react-window outer element wraps the list, so I'll keep its row renderer pointing at the new component to preserve virtualization.
- Create
MailListItem.tsxwith props formessage,selected, andonSelect. - Wrap it in
React.memowith a comparator onmessage.id+selected. - Lift
useSelectionintoMailListand pass handlers down.
focus() when the active index changes, then re‑run the suite.MailListToolbar component and add a Storybook story for it.あなたのためにビルドするエージェント
自律的に計画を立て、コードを変更し、コマンドを実行し、完了するまで反復処理を行う AI エージェントにタスクを引き渡します。
たとえば、CLI ベースのエージェントを割り当ててバックグラウンドでバグのトリアージと修正を行わせたり、統合ブラウザーでのライブ検証を使用して機能を実装するために別のエージェントと対話させたり、チームがレビューするためのプルリクエストを開くクラウドエージェントにホームページの再設計を委任したりできます。
エージェントを使い始めるpackage http
import (
"context"
"encoding/json"
"errors"
"io"
"log/slog"
"mime/multipart"
"net/http"
"time"
"golang.org/x/sync/errgroup"
"golang.org/x/sync/semaphore"
"go.opentelemetry.io/otel"
)
type Result[T any] struct {
Name string `json:"name"`
Value T `json:"value,omitempty"`
Error string `json:"error,omitempty"`
}
type Meta struct {
Format string `json:"format"`
Width int `json:"width"`
Height int `json:"height"`
Bytes int64 `json:"bytes"`
}
const (
perRequestTimeout = 30 * time.Second
maxParallel = 8
)
func (s *Server) handleBatch(
w http.ResponseWriter,
r *http.Request,
) {
ctx, span := otel.Tracer("http").
Start(r.Context(), "batch")
defer span.End()
ctx, cancel := context.WithTimeout(
ctx, perRequestTimeout,
)
defer cancel()
r.Body = http.MaxBytesReader(
w, r.Body, s.cfg.MaxBytes,
)
if err := r.ParseMultipartForm(
s.cfg.MaxBytes,
); err != nil {
s.fail(w, http.StatusBadRequest, err)
return
}
files := pickFiles(r.MultipartForm)
if len(files) == 0 {
s.fail(w, http.StatusBadRequest,
errors.New("no files"))
return
}
out := make(
[]Result[Meta], len(files),
)
sem := semaphore.NewWeighted(maxParallel)
g, gctx := errgroup.WithContext(ctx)
for i, fh := range files {
i, fh := i, fh
if err := sem.Acquire(gctx, 1); err != nil {
break
}
g.Go(func() error {
defer sem.Release(1)
out[i] = process(gctx, s, fh)
return nil
})
}
_ = g.Wait()
s.log.LogAttrs(ctx,
slog.LevelInfo, "batch.done",
slog.Int("count", len(out)),
slog.Duration("budget",
perRequestTimeout),
)
w.Header().Set(
"Content-Type", "application/json",
)
_ = json.NewEncoder(w).Encode(out)
}
func process(
ctx context.Context,
s *Server,
fh *multipart.FileHeader,
) Result[Meta] {
res := Result[Meta]{Name: fh.Filename}
f, err := fh.Open()
if err != nil {
res.Error = err.Error()
return res
}
defer f.Close()
data, err := io.ReadAll(
io.LimitReader(f, s.cfg.MaxBytes),
)
if err != nil {
res.Error = err.Error()
return res
}
m, err := s.proc.ExtractCtx(ctx, data)
if err != nil {
res.Error = err.Error()
return res
}
res.Value = Meta{
Format: m.Format,
Width: m.Width,
Height: m.Height,
Bytes: int64(len(data)),
}
return res
}
POST /process/batch endpoint to the image service. Process up to 8 files in parallel with per-request budget, structured logging, and OpenTelemetry spans. Return per-item results.サービスのレイアウトをマップしました
Existing handlers live ininternal/http and the processor exposes a sync Extract. I'll add an ExtractCtx variant so the worker pool can honor cancellation, then fan out with errgroup + a weighted semaphore.
http.HandleFunc を grep:- Add
handleBatchinbatch.gousing a genericResult[Meta]type. - Cap concurrency with
semaphore.NewWeighted(8)and wrap fan‑out inerrgroup. - Wrap the request in an OTel span and a 30s context deadline.
- Wire the route in
server.goand add table tests.
go test ./internal/http -run Batch -race-race clean. Throughput on a 64‑image batch (avg 1.2MB JPEG): 184ms to 31ms end‑to‑endk6 script.p99_ms Prometheus histogram and wire it into the existing Grafana dashboard.任意のエージェント、任意のモデル
ワークフローに合ったエージェントハーネスを使用できます。Copilot や、Claude、OpenAI などのサードパーティプロバイダーを使用して、ローカルまたはクラウドでエージェントを実行します。
高速な補完モデルから高度な推論モデルまで、プロバイダーを問わず多数のモデルから選択できます。あるいは、独自のキーを持ち込んで、任意のプロバイダーの任意のモデルを使用することもできます。
同じ Copilot が、VS Code、Copilot CLI、GitHub.com、モバイルなど、あらゆるサーフェスで動作します。エージェントが各サーフェスでどのように動作するかを見る。
すべてのセッションを 1 つのビューで
複数のエージェントがタスクを並行して処理している間も、生産性を維持できます。実行場所に関係なく、すべてのエージェントセッションを単一のビューで追跡できます。
別のツールやターミナルに切り替えることなく、セッションの迅速なフィルタリングと監視、または個々のエージェントとのやり取りへのドリルダウンを行うことができます。
あなたのルール、あなたのエージェント
エージェントがあなたのプラクティスやチームのワークフローに従うようにします。カスタム指示を定義したり、エージェントのスキルを追加したり、プロジェクトに合わせたカスタムエージェントを構築したりできます。
MCP サーバーを使用して外部ツールやサービスに接続したり、エージェントのプラグインや拡張機能をインストールしてエージェントの機能を拡張したりできます。
その中核にある、世界最高峰のコードエディター
VS Code は、10 年以上にわたり何百万人もの開発者に選ばれてきたエディターです。AI を活用したインライン提案、インテリジェントな補完、そして豊富な編集エクスペリエンスにより、ご自身でコードを記述する際にも同様に強力です。
エージェントとの作業とハンズオンのコーディングを、同じエディター内でシームレスに切り替えることができます。
VS Code を始めるimport numpy as np
import pandas as pd
iris_data = pd.read_csv("iris_dataset.csv")
def describe(species: str) -> pd.Series:
7
subset = data[data["species"] == species]
subset = iris_data[iris_data["species"] == species]
if subset.empty:
raise ValueError(f"{species} missing from sample")
return subset[["petal", "sepal"]].agg(["mean", "std"]).loc["mean"]
def summary():
13
for species in np.sort(data["species"].unique()):
for species in np.sort(iris_data["species"].unique()):
try:
stats = describe(species)
except ValueError:
print(f"{species}: no records")
continue
print(f"{species}: petal={stats['petal']:.2f} sepal={stats['sepal']:.2f}")
if __name__ == "__main__":
summary()
拡張機能でコードを記述
拡張機能や Model Context Protocol サーバーのツールでエージェントを拡張できます。あるいは、独自の拡張機能を構築して、チーム特有のシナリオに対応させることができます。
拡張機能マーケットプレイスで 8 万個以上の拡張機能を見る
あらゆる言語でコードを記述
VS Code は、主要なプログラミング言語のほとんどをサポートしています。JavaScript、TypeScript、CSS、HTML などは標準で付属していますが、その他の言語の拡張機能は VS Code マーケットプレイスで見つけることができます。

JavaScript
TypeScript
Python
C#
C++
HTML
Java
JSON
PHP
Markdown
Powershell
YAML完全にカスタマイズ可能
コーディングスタイルに合わせて、VS Code の UI とレイアウトをカスタマイズできます。
カラーテーマを使用すると、好みや作業環境に合わせて VS Code のユーザーインターフェイスの色を変更できます。
Settings Sync 機能を使用すると、VS Code のインスタンス間でユーザー設定を共有できます。
プロファイルを使用すると、カスタマイズのセットを作成して素早く切り替えたり、他の人と共有したりできます。
どこでもコードを記述
クラウド、リモートリポジトリに接続している場合でも、Web 版 VS Code (vscode.dev) を使用してブラウザー上で作業する場合でも、最も生産性を発揮できる場所でコードを記述できます。
組み込みのソース管理により、すぐに Git サポートを利用できます。他の多くのソース管理プロバイダーも拡張機能を通じて利用できます。
GitHub Codespaces は、長期的なプロジェクトであれ、プルリクエストのレビューなどの短期的なタスクであれ、あらゆるアクティビティに向けてクラウドベースの開発環境を提供します。
リッチな機能でコーディング
エディターには他にも多くの機能があります。組み込み機能を使用する場合でも、豊富な拡張機能を使用する場合でも、すべてのユーザーに適した機能が見つかります。
統合ターミナル
zsh、pwsh、git bash など、お気に入りのシェルをすべてエディター内で使用できます。
コードの実行
エディターを離れることなく、コードの実行とデバッグを行います。
バージョン管理
git およびその他の多くのソース管理プロバイダーの組み込みサポート。
ビルドタスク
VS Code 内からツールを実行し、その結果を分析します。
ローカル履歴
自動的に追跡されるローカル履歴により、変更内容を失うことがありません。
テーマ
テーマは個性の拡張です。エディターにセンスを加え、自分好みにカスタマイズしましょう。
アクセシビリティ
スクリーンリーダー、ハイコントラストテーマ、キーボードのみのナビゲーションに最適化されたエクスペリエンス。
Web サポート
スマートフォン、タブレット、デスクトップのいずれからでも、どこからでもコードにアクセスできます。