오픈 소스 AI 코드 편집기
웹, Insider 에디션 또는 기타 플랫폼
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 컴포넌트로 추출 - 프로젝트를 빌드하여 변경 사항이 올바르게 컴파일되는지 확인
- 응용 프로그램 테스트를 실행하여 기능이 그대로 유지되는지 확인
- 개별 메일 목록 항목 렌더링을 위한 재사용 가능한 컴포넌트 생성
- 받는 prop:
email ,isSelected , 및onSelect prop - 모든 접근성 기능(ARIA 역할, 키보드 탐색) 유지
- 스타일 및 상호 작용 동작 보존
- 인라인 메일 항목 렌더링 로직을 제거하여 단순화
- 이제 깨끗한 prop 전달로
MailListItem 컴포넌트를 사용합니다. - 컴포넌트 복잡성을 줄이고 가독성을 향상시킴
- ✅ 빌드 성공
- ✅ 모든 기능이 올바르게 작동함 (필터링, 선택, 탐색)
- ✅ 키보드 접근성 보존 (Enter 키 탐색)
- ✅ 시각적 선택 상태가 올바르게 작동함
모든 팀을 위한 모든 모델
다양한 즉시 사용 가능한 모델 중에서 선택하거나 선호하는 모델 및 호스팅 제공업체의 모델에 액세스하기 위한 자체 키를 가져오세요.
코드베이스에 대한 전문가
코드베이스는 로컬 및 원격으로 색인되어 관련성 있는 내용을 이해하여 빠르고 상황 인식적인 상호 작용을 가능하게 합니다.
팀이 일하는 방식대로 작동하는 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.
에이전트 모드
복잡하고 여러 단계로 이루어진 작업을 처리합니다. 에이전트 모드는 코드베이스를 읽고, 파일 간 편집을 제안하고, 터미널 명령을 실행하고, 컴파일 또는 테스트 실패에 응답합니다. 이 모든 작업을 작업이 완료될 때까지 반복합니다. VS Code 확장 및 모델 컨텍스트 프로토콜(MCP) 서버를 사용하여 에이전트 모드를 팀의 워크플로에 맞게 더욱 세밀하게 조정할 수 있습니다.
에이전트 모드로 빌드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)
}
할 일 목록 만들기
기존 서버 및 프로세서 코드를 읽고, 배치 엔드포인트 계약을 설계하고, 새 파일에 핸들러를 구현하는 것과 같은 작업을 관리하면서 할 일 목록 만들기로 시작합니다. 핸들러를 서버 라우트에 연결하고 싶고, 선택 사항이지만 배치 엔드포인트에 대한 최소한의 테스트를 추가할 수 있습니다. 또한 테스트를 실행하고 모든 것을 빌드할 계획입니다. 실행해 봅시다!파일 처리 개선 중...
server.go를 수정할 수도 있지만, 새 파일이 요청되었으므로 /process/batch라는 라우트를 생성해야 합니다. 최대 본문 크기를 강제하고 콘텐츠 유형이 multipart/form-data인지 확인합니다. 다음으로 폼을 파싱하고 form.File["files"]을 반복합니다. 각 FileHeader에 대해 열고 바이트를 읽은 다음 ExtractMetadata를 호출하여 결과를 수집합니다. 마지막으로 결과와 함께 구조화된 JSON 응답을 반환하고 파일 없음 및 최대 배치 제한에 대한 에지 케이스를 처리합니다. 절대적으로 필요하지는 않다고 생각하지만, 각 파일을 순차적으로 처리하는 동시에 동시성을 제한하기 위해 sync.WaitGroup을 사용하는 약간의 개선을 고려하고 있습니다. 이렇게 하면 첫 번째 커밋이 더 간단해집니다. 코드 파일을 추가하고 내부/이미지를 참조하는 별칭을 가져와야 합니다. 다음으로 tests/image_processor_test.go의 기존 테스트를 확인하여 스타일을 파악하고 배치 핸들러에 대한 새 테스트 파일을 만들어야 하는지 결정합니다. 이를 읽은 다음 할 일 상태를 업데이트하고 작업 1과 2를 완료로 표시합니다.HTTP 테스트 준비
HTTP 테스트를 실행해야 하지만 현재 테스트 패키지가 'tests'에 있고 메인 모듈 내에 있지 않다는 것을 발견했습니다. HTTP 테스트를 수행하려면 config, processor, logger, server와 같은 몇 가지 사항을 설정하고 multipart 요청을 보내야 합니다. 다음 단계는 config.go의 구성을 확인하여 필요한 필드를 파악하는 것입니다. 바로 시작해 봅시다!업데이트 및 패치 관리
모든 것을 정리하기 위해 manage_todo_list를 사용해야 하며, 어떤 작업도 놓치지 않도록 해야 합니다. 그렇게 한 후에 패치를 적용할 수 있습니다. 새 파일을 추가하고 server.go를 수정하는 작업이 포함됩니다. 이 과정에서 실수를 피하기 위해 모든 것이 명확하고 정확한지 확인하고 싶습니다. 계속 나아갑시다!업데이트 및 테스트 구현
디자인 계약을 완료로 표시하고 업데이트를 구현해야 합니다. 할 일 목록을 계속 관리하고 새 파일과 server.go를 업데이트하기 위해 패치를 적용할 것입니다. server.go에 /process/batch 라우트를 추가하고 internal/http/batch.go라는 새 파일을 구현해야 할 것 같습니다. 코드를 작성한 후 테스트 파일을 추가하고 go test로 테스트를 실행하고 run_in_terminal 명령을 사용합니다. 시작합시다!-
server.go : 새 라우트 POST /process/batch 등록. batch.go : 새 핸들러 handleProcessBatch가-
- multipart/form-data를 수락합니다.
- files 키 아래의 여러 파일을 읽습니다 (파일이 누락된 경우 모든 파일 파트로 대체).
- 전체 배치를 실패시키지 않고 파일별 성공/오류를 반환합니다.
- 집계: count, success, failed.
-
batch_endpoint_test.go : happy path (유효 파일 1개 + 유효하지 않은 파일 1개) 및 누락된 파일 오류 사례를 테스트합니다.
- 구성 가능한 최대 배치 파일 수 추가 (예: 구성을 통해).
- 매우 큰 이미지를 위한 제한된 메모리(처리 + 삭제)로 스트림 처리.
- 워커 풀 및 컨텍스트 취소를 통한 선택적 병렬 처리.
- 디코딩 전에 파일별 크기 유효성 검사 추가.
- 멀티파트가 아닌 클라이언트를 위한 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()
확장 기능으로 코딩
채팅에서 사용하기 위해 확장 기능과 모델 컨텍스트 프로토콜 서버에서 AI 기반 기능으로 VS Code를 사용자 지정하세요. 또는 고유한 시나리오를 지원하기 위해 팀을 위한 자체 확장 기능을 빌드하세요. 자체 확장 기능 빌드.
모든 언어로 코딩
VS Code는 거의 모든 주요 프로그래밍 언어를 지원합니다. JavaScript, TypeScript, CSS, HTML과 같이 기본적으로 제공되는 것도 있지만, 다른 언어에 대한 확장 프로그램은 VS Code 마켓플레이스에서 찾을 수 있습니다.

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 내에서 도구를 실행하고 결과를 분석하세요.
로컬 기록
자동으로 추적되는 로컬 기록으로 변경 사항을 잃지 마세요.
테마
테마는 개성의 확장입니다. 편집기에 개성을 더하고 나만의 색을 입히세요.
접근성
스크린 리더, 고대비 테마 및 키보드 전용 탐색을 위한 최적화된 경험.
웹 지원
휴대폰, 태블릿 또는 데스크톱에서 어디서든 코드에 액세스할 수 있습니다.