オープンソースのAIコードエディタ
VS Codeを使用することにより、そのライセンスおよびプライバシーステートメントに同意したものとみなされます。
import { For, createSignal, createMemo } from "solid-js";
import { useNavigate, useParams } from "@tanstack/solid-router";
import { getEmailsForMailbox } from "~/data/emails";
import { MailListItem } from "~/components/MailListItem";
export function MailList() {
const params = useParams({ strict: false }) as {
mailbox?: string;
id?: string;
};
const navigate = useNavigate();
const [query, setQuery] = createSignal("");
const mailbox = () => params.mailbox || "inbox";
const list = createMemo(() => {
const q = query().toLowerCase();
return getEmailsForMailbox(mailbox()).filter(
(e) =>
!q ||
e.subject.toLowerCase().includes(q) ||
e.snippet.toLowerCase().includes(q)
);
});
function open(id: string) {
navigate({
to: "/mail/$mailbox/$id",
params: { mailbox: mailbox(), id },
search: (prev) => prev,
});
}
return (
<For each={list()}>
{(e) => (
<div
role="listitem"
tabindex={0}
onClick={() => open(e.id)}
onKeyDown={(ev) => ev.key === "Enter" && open(e.id)}
class="mail-item"
data-selected={params.id === e.id ? "true" : undefined}
aria-selected={params.id === e.id ? "true" : undefined}
>
<div>
<div class="mail-item-subject truncate">{e.subject}</div>
<div class="mail-item-snippet truncate">{e.snippet}</div>
</div>
<time
class="text-xs muted"
datetime={e.date}
title={new Date(e.date).toLocaleString()}
>
{new Date(e.date).toLocaleDateString(undefined, {
month: "short",
day: "numeric",
})}
</time>
</div>
<MailListItem
email={e}
isSelected={params.id === e.id}
onOpen={open}
/>
)}
</For>
);
}
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キーナビゲーション)
Claude Opus 4.5
すべてのチームのためのあらゆるモデル
モデルの管理...
コードベースの専門家
コードベースのどこでデータベース接続文字列が設定されていますか?
チームが行うように機能するAI
---
description: 'Generate compact responses, focusing on brevity and clarity.'
tools: ['search', 'fetch', 'githubRepo', 'usages', 'vscodeAPI', 'problems', 'changes', 'testFailure', 'todos']
---
You are a chat mode that provides extremely concise and clear responses.
Your replies should be brief, to the point, and free of unnecessary details.
Focus on delivering the essential information in a straightforward manner.
When responding, you must adhere to the following guidelines:
- Use short sentences and simple language.
- Prioritize clarity over completeness.
- Do not provide explanations or justifications unless explicitly asked.
- Do not provide any updates as you are working on the task –– only respond when the task is complete.
package http
import (
"io"
"log/slog"
"mime/multipart"
"net/http"
"strings"
)
type BatchItemResult struct {
Name string `json:"name"`
Metadata *struct {
Format string `json:"format"`
Width int `json:"width"`
Height int `json:"height"`
Bytes int `json:"bytes"`
} `json:"metadata,omitempty"`
Error string `json:"error,omitempty"`
}
type BatchResponse struct {
Results []*BatchItemResult `json:"results"`
Count int `json:"count"`
Success int `json:"success"`
Failed int `json:"failed"`
}
// handleProcessBatch processes multiple uploaded images (multipart/form-data) under the field name "files".
// It returns metadata for each image or an error per item without failing the whole batch unless the request is malformed.
func (s *Server) handleProcessBatch(w http.ResponseWriter, r *http.Request) {
// Enforce max body size overall.
r.Body = http.MaxBytesReader(w, r.Body, s.cfg.MaxUploadBytes)
if ct := r.Header.Get("Content-Type"); !strings.HasPrefix(ct, "multipart/form-data") {
s.writeJSON(w, http.StatusBadRequest, map[string]string{"error": "content type must be multipart/form-data"})
return
}
if err := r.ParseMultipartForm(s.cfg.MaxUploadBytes); err != nil {
status := http.StatusBadRequest
if strings.Contains(err.Error(), "request body too large") {
status = http.StatusRequestEntityTooLarge
}
s.writeJSON(w, status, map[string]string{"error": "invalid multipart form: " + err.Error()})
return
}
// Accept files under the key "files". If absent, attempt to fallback to any file parts.
var fileHeaders []*multipart.FileHeader
if r.MultipartForm != nil && len(r.MultipartForm.File["files"]) > 0 {
fileHeaders = r.MultipartForm.File["files"]
} else if r.MultipartForm != nil {
// Fallback: gather all files across keys.
for _, fhs := range r.MultipartForm.File {
fileHeaders = append(fileHeaders, fhs...)
}
}
if len(fileHeaders) == 0 {
s.writeJSON(w, http.StatusBadRequest, map[string]string{"error": "no files provided (expect key 'files')"})
return
}
resp := &BatchResponse{Results: make([]*BatchItemResult, 0, len(fileHeaders))}
for _, fh := range fileHeaders {
item := &BatchItemResult{Name: fh.Filename}
f, err := fh.Open()
if err != nil {
item.Error = "open file: " + err.Error()
resp.Results = append(resp.Results, item)
resp.Failed++
continue
}
data, err := io.ReadAll(f)
_ = f.Close()
if err != nil {
item.Error = "read file: " + err.Error()
resp.Results = append(resp.Results, item)
resp.Failed++
continue
}
meta, err := s.proc.ExtractMetadata(data)
if err != nil {
item.Error = err.Error()
resp.Results = append(resp.Results, item)
resp.Failed++
continue
}
// Copy into anonymous struct to decouple from internal type if it changes.
item.Metadata = &struct {
Format string `json:"format"`
Width int `json:"width"`
Height int `json:"height"`
Bytes int `json:"bytes"`
}{Format: meta.Format, Width: meta.Width, Height: meta.Height, Bytes: meta.Bytes}
resp.Results = append(resp.Results, item)
resp.Success++
}
resp.Count = len(resp.Results)
s.log.LogAttrs(r.Context(), slog.LevelInfo, "batch processed", slog.Int("count", resp.Count), slog.Int("success", resp.Success), slog.Int("failed", resp.Failed))
s.writeJSON(w, http.StatusOK, resp)
}
ToDoリストの作成
既存のサーバーとプロセッサのコードを読み込み、バッチエンドポイントの契約を設計し、ハンドラを持つ新しいファイルに実装することから着手します。ハンドラをサーバールートに接続し、オプションではありますが、バッチエンドポイントの最小限のテストを追加したいと考えています。その後、すべてをテストしてビルドする予定です。実行しましょう!ファイル処理の改善...
server.goを変更することもできますが、彼らは新しいファイルを求めています。そのため、/process/batchというルートを作成する必要があります。ボディの最大サイズを強制し、コンテンツタイプがmultipart/form-dataであることを確認します。次に、フォームとform.File["files"]を反復処理します。FileHeaderごとに、それを開いてバイトを読み取り、結果を収集するためにExtractMetadataを呼び出します。最後に、結果を含む構造化されたJSON応答を返し、ファイルがない場合やバッチ制限の上限に達した場合のエッジケースを処理します。 各ファイルを順次処理しながら並行処理を制限するためにsync.WaitGroupを使用するという、わずかな改善を検討してもよいかもしれません。これにより、最初のコミットが単純になります。コードファイルを追加し、内部/imageのエイリアスをインポートする必要があります。 次に、既存のテスト(tests/image_processor_test.go)を確認してスタイルを確認し、バッチハンドラ用に新しいテストファイルを作成するかどうかを判断します。それを読み終えたら、ToDoのステータスを更新し、タスク1と2を完了としてマークします。HTTPテストの準備
HTTPテストを実行する必要がありますが、現在のテストパッケージが「tests」内にあり、メインモジュール内にないことに気づきました。HTTPテストを実行するには、設定、プロセッサ、ロガー、サーバーなどをセットアップし、マルチパートリクエストを送信するなど、いくつかのことを設定する必要があります。次のステップは、config.goを確認して、含める必要がある必要なフィールドを理解することです。詳しく見てみましょう!更新とパッチの管理
何を見失わないようにするために、manage_todo_listを使用してすべてを整理する必要があります。それが完了したら、パッチを適用できます。これには、新しいファイルを追加し、server.goを編集することが含まれます。このプロセス全体で、間違いを避けるためにすべてが明確で正確であることを確認したいです。前進し続けましょう!更新とテストの実装
設計契約を完了としてマークし、次に更新を実装する必要があります。todoリストの管理を進め、パッチを適用してファイルを追加し、server.goを更新します。server.goに/process/batchのルートを追加し、新しいファイルinternal/http/batch.goを実装する必要があるようです。コードを書いた後、テストファイルを追加し、go testでテストを実行し、run_in_terminalコマンドを使用します。さあ、始めましょう!-
server.go : 新しいルート POST /process/batch を登録しました。 VS Codeタブ、サイドバー、チャットの対話を含むインタラクティブなエージェントモードのウォークスルー。標準のキーボードナビゲーションを使用して各ペインを探索します。 : 新しいハンドラ handleProcessBatch が-
- multipart/form-dataを受け付けます。
- filesキーの下で複数のファイルを読み取ります(filesが欠落している場合は任意のファイルパートにフォールバックします)。
- バッチ全体を失敗させることなく、ファイルごとの成功/エラーを返します。
- カウントを統合します: count、success、failed。
-
batch_endpoint_test.go : 正常系パス(有効なファイル1つ + 無効なファイル1つ)とファイル欠落エラーケースをテストします。
- バッチあたりの最大ファイル数を設定可能にする(例: config経由)。
- 非常に大きな画像を処理するための限定されたメモリでのストリーム処理(処理 + 破棄)。
- コンテキストキャンセルを備えたワーカープールによるオプションの並列処理。
- ファイルごとにサイズ検証を追加。
- 非マルチパートクライアントのためにJSONベースのバッチ(URLまたはbase64)をサポートします。
次の編集候補
VS Codeはコーディング中に次の動きを予測します。Tabキーを使用して、エディタ内で直接AI駆動の提案を受け入れます。既に行っている編集に基づいて、インテリジェントに変更すべき内容とその場所を推奨します。
AI駆動の提案でコーディング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()
拡張機能でコーディング
VS Codeを拡張機能とModel Context ProtocolサーバーからAI駆動の機能でカスタマイズして、チャットで使用できます。または、独自の拡張機能を構築して、チーム独自のシナリオに対応できます。
Extension Marketplaceで8万件以上の拡張機能を閲覧
あらゆる言語でコーディング
VS Codeは、JavaScript、TypeScript、CSS、HTMLなど、ほとんどすべての主要なプログラミング言語をサポートしています。いくつかすぐに使用できますが、他の言語用の拡張機能はVS Code Marketplaceで見つけることができます。

JavaScript
TypeScript
Python
C#
C++
HTML
Java
JSON
PHP
Markdown
Powershell
YAMLどこでもコーディング
クラウドに接続している場合でも、リモートリポジトリに接続している場合でも、ブラウザでVS Code for the Web (vscode.dev) を使用している場合でも、最も生産的になれる場所でコーディングできます。
組み込みのソース管理機能により、Gitサポートがすぐに利用可能になります。他の多くのソース管理プロバイダーは拡張機能を通じて利用できます。
GitHub Codespacesは、長期的なプロジェクトであっても、プルリクエストのレビューのような短期的なタスクであっても、あらゆるアクティビティに対応するクラウドベースの開発環境を提供します。
リッチな機能でコーディング
エディタには他にも多くの機能があります。組み込み機能を使用する場合でも、豊富な拡張機能を使用する場合でも、誰にとっても何かがあります。
統合ターミナル
お気に入りのシェル(zsh、pwsh、git bashなど)をエディタ内で使用できます。
コードの実行
エディタを離れることなくコードを実行およびデバッグできます。
バージョン管理
gitおよびその他多くのソース管理プロバイダーの組み込みサポート。
ビルドタスク
VS Code内からツールを実行し、その結果を分析します。
ローカル履歴
自動的に追跡されるローカル履歴により、変更を決して失うことはありません。
テーマ
テーマはあなたの個性の延長です。エディタに彩りを加え、あなたらしさを表現しましょう。
アクセシビリティ
スクリーンリーダー、ハイコントラストテーマ、キーボードのみのナビゲーション向けに最適化されたエクスペリエンス。
Webサポート
携帯電話、タブレット、デスクトップのいずれを使用しても、どこからでもコードにアクセスできます。