Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
15d115e
트리에서 git 상태를 색으로 보여준다
Seungpyo1007 Jul 31, 2026
e3bf162
Alt+← / Alt+→ 로 방금 있던 자리로 돌아간다
Seungpyo1007 Jul 31, 2026
edfd52f
확장이 IDE 에서 벌어지는 일을 구독할 수 있게 한다
Seungpyo1007 Jul 31, 2026
7aa3571
브라우저 프리뷰 전용 데모 경로를 걷어낸다
Seungpyo1007 Jul 31, 2026
8add282
이 파일 하나를 실행한다 (Ctrl+F5)
Seungpyo1007 Aug 3, 2026
85ad61e
어느 렌더러를 실었는지 로그로 남기고, dist 를 두 번 싣지 않는다
Seungpyo1007 Aug 3, 2026
f2376ea
Monaco 위젯이 앱 테마를 따르게 한다
Seungpyo1007 Aug 3, 2026
0175a63
모드를 바꿔도 읽던 자리와 필터가 유지된다
Seungpyo1007 Aug 3, 2026
6058cdc
확인창을 OS 대화상자에서 인앱 모달로 옮긴다
Seungpyo1007 Aug 3, 2026
d6fc40d
저장소가 정의한 검사를 실제로 돌린다
Seungpyo1007 Aug 4, 2026
4b3bfff
README 를 지금 나가는 것에 맞춘다
Seungpyo1007 Aug 3, 2026
ca5ee51
README 클립을 찍는 도구를 저장소에 넣는다
Seungpyo1007 Aug 3, 2026
5b74316
녹화 시나리오가 오염된 상태로 찍지 않게 한다
Seungpyo1007 Aug 3, 2026
0f572e2
MCP 핸드셰이크 결과를 쓰고, 세 기둥을 다 읽는다
Seungpyo1007 Aug 4, 2026
6faef1e
VS Code 셰임을 실제 에디터에 연결한다
Seungpyo1007 Aug 4, 2026
05d4516
README 로드맵을 생태계 작업 뒤 상태로 고친다
Seungpyo1007 Aug 4, 2026
8a167fc
확장 폴더 이름이 id 와 다르면 파일을 하나도 못 읽던 것을 고친다
Seungpyo1007 Aug 4, 2026
338eeda
확장이 사용자에게 실제로 물어볼 수 있게 한다
Seungpyo1007 Aug 4, 2026
9bd89db
README 에서 quick-pick·input box 를 "얇은 곳" 목록에서 뺀다
Seungpyo1007 Aug 4, 2026
5552737
언어 확장이 내놓는 것을 실제로 화면까지 보낸다
Seungpyo1007 Aug 4, 2026
2148642
확장이 자기 설정을 읽고 바꿀 수 있게 한다
Seungpyo1007 Aug 4, 2026
519657c
확장이 상태바에 올린 글자를 실제로 보여 준다
Seungpyo1007 Aug 4, 2026
809ddd4
확장의 파일 감시자를 실제 디스크 변화에 연결한다
Seungpyo1007 Aug 4, 2026
bd1346d
확장이 사이드바에 뷰를 붙일 수 있게 한다
Seungpyo1007 Aug 4, 2026
96a5c40
README 를 확장 생태계 작업이 끝난 상태로 맞춘다
Seungpyo1007 Aug 4, 2026
a68e0e4
Merge branch 'main' into develop
Seungpyo1007 Aug 4, 2026
0bc40f0
확장이 편집을 만들고 적용할 수 있게 한다
Seungpyo1007 Aug 4, 2026
30ca24f
MCP 리소스와 프롬프트를 에이전트에게 준다
Seungpyo1007 Aug 4, 2026
6a0bf51
README 의 "얇은 곳" 을 다시 이름으로 적는다
Seungpyo1007 Aug 4, 2026
0c1c6e1
조용히 사라지던 비동기 실패를 보이게 하고, 터미널 예외를 없앤다
Seungpyo1007 Aug 4, 2026
8c137b6
메인이 죽어도 앱이 사라지지 않게 한다
Seungpyo1007 Aug 4, 2026
50b44ae
crashPolicy 의 타입 선언을 더한다
Seungpyo1007 Aug 4, 2026
90e1cea
투어가 두 모드를 다 가르치게 한다
Seungpyo1007 Aug 4, 2026
c454a14
밖에서 사라진 파일의 미저장 편집을 지키지 않던 것을 고친다
Seungpyo1007 Aug 4, 2026
eaae8f0
저장 안 한 채로 종료를 누르면 무엇이 일어나는지 고친다
Seungpyo1007 Aug 4, 2026
b34e6e9
프로젝트를 바꿀 때 미저장 편집을 말없이 버리던 것을 고친다
Seungpyo1007 Aug 5, 2026
4de210a
버리기가 절반만 버리던 것과, 삭제 확인창의 지키지 못할 약속을 고친다
Seungpyo1007 Aug 5, 2026
470a803
BOM 파일을 열기만 해도 고쳐 쓰던 것을 고친다
Seungpyo1007 Aug 5, 2026
a4e7b8a
UTF-8 이 아닌 파일을 열어서 원본을 파괴하던 것을 막는다
Seungpyo1007 Aug 5, 2026
c30de4e
찾아 바꾸기가 UTF-8 아닌 파일을 파괴하던 것을 막는다
Seungpyo1007 Aug 5, 2026
331113e
동시에 온 승인 물음이 앞의 실행을 영원히 매달아 두던 것을 고친다
Seungpyo1007 Aug 5, 2026
32b4209
인코딩 거절을 에이전트도 알아듣게 하고, 명령 실행을 열린 워크스페이스로 제한한다
Seungpyo1007 Aug 5, 2026
271f415
깊은 폴더의 파일이 앱 안에서 아예 안 보이던 것을 고친다
Seungpyo1007 Aug 5, 2026
1c6b7e1
점으로 시작하는 폴더 안의 파일이 안 보이던 것을 고친다
Seungpyo1007 Aug 5, 2026
dd67221
워처가 변경 목록을 말없이 자르던 것을 고친다
Seungpyo1007 Aug 5, 2026
8142566
0.3.0 계획서를 적는다
Seungpyo1007 Aug 5, 2026
0a2dfeb
확장에게 브라우저와 클립보드를 돌려주고, README 를 사실과 맞춘다
Seungpyo1007 Aug 6, 2026
64725f1
확장의 데코레이션을 실제로 그리고, 활성 편집기 사건을 제때 쏜다
Seungpyo1007 Aug 6, 2026
209f2f7
확장이 파일을 만들고 옮기고 지울 수 있게 한다
Seungpyo1007 Aug 7, 2026
ecae54c
Gemini 와 로컬 모델을 붙인다
Seungpyo1007 Aug 7, 2026
7f039d0
Phase 2 조사 결과를 적고, 끝의 정의를 확정한다
Seungpyo1007 Aug 7, 2026
281613a
제안을 코드 옆에 보여 준다 — 유령 커서·사유 툴팁·수락/거절 CodeLens
Seungpyo1007 Aug 7, 2026
0a4d0f6
0.3.0
Seungpyo1007 Aug 7, 2026
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
54 changes: 54 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,60 @@

## [Unreleased]

## [0.3.0] — What it could not see, and what it could lose

Two things ran through this release. The app was losing work it had promised to keep, and it was answering questions about files it had never actually looked at. Both failed the same way: quietly, with a successful-looking answer.

On top of that, three new things: it talks to more models, extensions can do considerably more, and a proposal now appears in the code rather than only on a card.

### Your unsaved work stops disappearing

Every one of these was reproduced in the running app before it was fixed, and each is a place where edits vanished with no warning and no undo.

- **Files deleted or renamed outside the app** took your unsaved buffer with them. They are kept now, and you are told they are orphaned so you can decide.
- **Quitting** with unsaved files did nothing visible: `beforeunload` cancels `app.quit()` in Electron with no dialog at all. There is now a real prompt with save / discard / cancel — and "save" that does not finish does not quit.
- **Switching projects** dropped unsaved edits without asking.
- **Discarding in git** only half-discarded, and the delete confirmation promised something it did not do.
- **Undo of an agent run** reloaded every open model from disk, including files the run never touched — while the screen said unsaved edits would be left alone.

### Files it could not see

- **Anything nested deeper than 8 levels was invisible** to the tree, to search, and to replace — all three walked with the same cap. `packages/app/src/features/x/components/y/z.ts` is already 8. The limit is 16 now.
- **Dot-directories were hidden wholesale.** `.vscode/settings.json`, `.claude/agents/*.md` and friends appeared in no listing and matched no search; `.github` had been carved out as a special case, which was the tell. What is hidden is now decided in one place.
- **Neither the tree nor search said when it had stopped early**, so "no results" and "never looked" arrived as the same answer. Both now say which it was — including to the agent, which had been told nothing at all.

### Files it could destroy

- **Opening a non-UTF-8 file corrupted it.** Everything was decoded as UTF-8, so a UTF-16 file grew from 16 to 20 bytes on open-and-save alone, and a CP949 Korean file turned to replacement characters the moment you edited one line. Such files are now refused, with an explanation.
- **Replace-across-files did the same thing**, on files you never opened — and reported success. Non-UTF-8 files are skipped and named.
- **A UTF-8 BOM was stripped by opening the file.** Monaco keeps the BOM outside the model, so the baseline never matched and "save all" rewrote untouched files.

### More models

Gemini, and any OpenAI-compatible server you point it at — Ollama, LM Studio, llama.cpp, or a corporate proxy. The address is a setting rather than a constant, a local server is not treated as unconfigured just because it has no API key, and its model list is read from the server, since only the server knows what you have pulled.

### Extensions

- **Decorations draw.** `createTextEditorDecorationType` used to return a working-looking handle that drew nothing — the last place in the shim that answered successfully and did nothing.
- **`onDidChangeActiveTextEditor` handed over the wrong editor.** It fired before the editor existed and the notification was dropped on the way out, so opening a file delivered either nothing or the *previous* file's editor. Extensions that draw on editor changes were drawing onto whatever was open before.
- **`WorkspaceEdit` can create, delete and rename files.** All-or-nothing: if one operation cannot be done, none are. A file with unsaved edits is neither deleted nor overwritten.
- **`env.openExternal` and `env.clipboard` do their jobs** instead of reporting success and doing nothing.

### Proposals in the code

A pending proposal is marked on the line it changes; hovering shows why. Accept and reject are CodeLens on that line, not only buttons on the card. While an edit types itself in, a ghost caret shows the exact character being written.

This completes the four editing-visualization pillars. The original plan for that phase was to fork Code-OSS; the fork never happened and should not, since this app has had its own renderer from the start. [docs/PHASE2-SURVEY.md](docs/PHASE2-SURVEY.md) audits the pillars against the code.

### Also

- The app survives a main-process crash instead of vanishing, and writes a crash log.
- Async failures that used to disappear are surfaced.
- The tour teaches both modes rather than only the one you are in.
- Shell commands run only in the open workspace.
- MCP resources and prompts are offered to the agent, not just listed.


## [0.2.0] — Everything the extension host said it could do

The previous release fixed behaviour the app claimed to have. This one does the same thing one layer out: an extension could load, report success, and then do nothing at all, because most of what it asked for was answered by a function that returned an empty value.
Expand Down
44 changes: 34 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,14 @@ same table the app dispatches from, so it cannot drift from what actually happen

**Debugging** — Breakpoints, call stack, variables, and stepping via DAP (Python/debugpy today).

**Extensions** — Install VS Code extensions from Open VSX, with TextMate grammars and icon themes. The `vscode` shim gives them the active editor for real: reading the document, moving the selection, and editing through the model so `Ctrl+Z` still works. Extensions can ask you things too — quick picks, input boxes with validation, and messages with buttons, each labelled with the extension doing the asking. Diagnostics land in the editor and the problems panel; definitions and formatters work; settings, file watchers and status bar items all do what they say. Trees and webviews contributed by an extension get their own place in the sidebar, webviews sandboxed. Schutz-native extensions can register commands, show panels, and subscribe to what happens in the IDE — files opened and saved, proposals accepted or rejected, agent turns starting and ending.
**Extensions** — Install VS Code extensions from Open VSX, with TextMate grammars and icon themes. The `vscode` shim gives them the active editor for real: reading the document, moving the selection, and editing through the model so `Ctrl+Z` still works. Extensions can ask you things too — quick picks, input boxes with validation, and messages with buttons, each labelled with the extension doing the asking. Diagnostics land in the editor and the problems panel; definitions and formatters work; settings, file watchers and status bar items all do what they say. Trees and webviews contributed by an extension get their own place in the sidebar, webviews sandboxed. Quick fixes appear in the editor's own menu and apply through the model, so one `Ctrl+Z` takes them back. Schutz-native extensions can register commands, show panels, and subscribe to what happens in the IDE — files opened and saved, proposals accepted or rejected, agent turns starting and ending.

**Localization** — The full UI ships in Korean, English, German, and Japanese.

## Design principles

- **Provider-agnostic** — Claude, OpenAI, Grok, and GLM today, behind a swappable adapter
- **Provider-agnostic** — Claude, OpenAI, Grok, GLM and Gemini today, plus any OpenAI-compatible
server you point it at, all behind a swappable adapter
- **Observable by default** — every AI action surfaces in the UI
- **Human-in-the-loop** — every change can be accepted, rejected, or reverted
- **Progressive fidelity** — validate the experience first, then deepen it at the editor core
Expand All @@ -121,21 +122,44 @@ npm run dist:linux # Linux build
## Roadmap

- **Phase 1** — validate the core experience *(done)*
- **Phase 2** — deepen renderer-level visual effects at the editor core *(in progress)*
- **Phase 3** — more providers (Gemini, local/OpenAI-compatible endpoints) and codebase indexing
- **Phase 2** — the four editing-visualization pillars *(done)*
- **Phase 3** — more providers *(done)* and codebase indexing *(next, as a 0.4 preview)*

Phase 2 was originally written as "fork Code-OSS", on the assumption that the visual effects
were impossible through the extension API. That fork never happened and should not: the app
has its own renderer already (Electron + React + Monaco), so the reason for forking never
applied. [docs/PHASE2-SURVEY.md](docs/PHASE2-SURVEY.md) audits the four pillars against the
code and closes the fork item as not-applicable. The three things the design named and the
code lacked — a ghost cursor, a rationale tooltip on the changed line, and accept/reject
CodeLens — now exist.

Providers: Claude, GPT, Grok, GLM, Gemini, and any OpenAI-compatible server you point it at —
Ollama, LM Studio, llama.cpp, or a corporate proxy. A local server needs an address, not a key.

The ecosystem work that used to sit in Phase 3 has shipped: VS Code extensions, Claude Code
skills and subagents, MCP servers over stdio and HTTP, and `.mcpb` bundles are all in the app
today. A VS Code extension can read and edit the active document, publish diagnostics, ask
you a question, read its own settings, watch files, show status, and contribute a tree or
webview to the sidebar. MCP speaks all three of its pillars rather than tools alone.

Where it is still thin, specifically: code actions are not wired (the shim does not expose
`WorkspaceEdit`, so an extension cannot build one), `TreeView.reveal` and `document.save()`
are unimplemented, and a file that is not already in a tab cannot be opened. Each of those
returns an error rather than an empty value, so an extension that needs one fails loudly
instead of doing nothing. MCP resources and prompts are readable and shown in the panel, but
are not yet offered to the agent as tools.
MCP resources and prompts are offered to the agent, not just listed in a panel.

Where it is still thin, specifically: a `WorkspaceEdit` cannot create, delete or rename
files, and the shim has no custom editors and no debug adapter API. Those three fail loudly —
`WorkspaceEdit` throws, and the other two are absent from the API object, so calling one is a
`TypeError` rather than a quiet nothing.

Decorations used to sit in that list as the one gap that answered successfully and drew
nothing. They now draw: `createTextEditorDecorationType` compiles the requested styling into
a real rule, `setDecorations` puts it on the Monaco editor, and passing an empty array clears
what that type drew. Inline blame and coverage highlighting work, `before`/`after` content
included.

Fixing it surfaced the reason such an extension would have appeared broken anyway:
`onDidChangeActiveTextEditor` fired before the editor existed, and the notification was
dropped on the way out, so opening a file delivered either nothing or the *previous* file's
editor. Extensions that draw on editor changes — which is most of them — were being handed
the wrong editor. The event now waits for the pane and fires once per file.

## Contributing

Expand Down
26 changes: 18 additions & 8 deletions docs/DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,22 @@ AI의 편집은 즉시 파일에 쓰이지 않고 **트랜잭션**으로 관리
- 멀티파일 오버뷰 Webview (2.4)
- **검증 질문**: 확장 API로 어디까지 "멋지게" 되는가? 무엇이 답답한가?

### Phase 2 — 포크(Fork)로 이전
> 목표: 확장으로 불가능했던 시각 효과를 위해 Code-OSS 포크. 진짜 차별화 완성.
- Code-OSS / VSCodium 기반 브랜딩·빌드 파이프라인
- 에디터 렌더러 레벨의 부드러운 타이핑 애니메이션 (2.1 완성)
- 확장 코드를 코어 기능으로 통합
- 배포(자동 업데이트, 서명 등)
### Phase 2 — 자체 렌더러 위의 시각화 *(완료, 2026-08-05)*
> 원래 계획은 "Code-OSS 포크" 였다. **하지 않았고, 하지 않는 것이 맞다.**
> 확장 API 로 렌더러에 손댈 수 없다는 것이 포크의 이유였는데, 이 앱은
> Electron + React + Monaco 로 처음부터 자기 렌더러를 갖고 있어 그 이유가 없다.
> 판정과 근거는 [PHASE2-SURVEY.md](PHASE2-SURVEY.md).

- ~~Code-OSS / VSCodium 기반 브랜딩·빌드 파이프라인~~ — 해당 없음(포크 안 함)
- 타이핑 애니메이션 + 글로우·잔광 + **유령 커서** (2.1)
- **변경 사유 툴팁**과 **수락/거절 CodeLens** — 바뀌는 그 줄에서 (2.2)
- 작업 상태·계획 패널 (2.3)
- 멀티파일 변경 개요 (2.4)
- 배포: 설치본 5종(서명은 아직, 자동 업데이트는 의도적으로 안 씀)

남은 것 하나 — 2.1 의 "스트리밍 삽입" 은 지금 **완성된 텍스트의 재생**이라 모델이
실제로 쓰는 속도와 무관하다. 진짜 토큰 스트림을 흘리려면 제안·승인 흐름 자체를
바꿔야 해서, 시각 효과가 아니라 별건으로 남긴다.

### Phase 3 — 확장·생태계
- 멀티 프로바이더 완성
Expand All @@ -162,7 +172,7 @@ AI의 편집은 즉시 파일에 쓰이지 않고 **트랜잭션**으로 관리
|---|---|---|
| 언어 | TypeScript | VSCode 생태계 표준 |
| Phase 1 베이스 | VSCode Extension API | 빠른 검증 |
| Phase 2 베이스 | Code-OSS (VSCodium 방식) | 포크 |
| Phase 2 베이스 | ~~Code-OSS (VSCodium 방식)~~ → Electron + React + Monaco | 포크하지 않음 — 렌더러가 이미 우리 것 |
| UI (패널·오버뷰) | Webview + (React 등) | 커스텀 시각화 자유도 |
| AI 통신 | 스트리밍 HTTP/SSE | 실시간성 필수 |
| 상태 관리 | (미정) | 오케스트레이터 이벤트 기반 |
Expand All @@ -172,7 +182,7 @@ AI의 편집은 즉시 파일에 쓰이지 않고 **트랜잭션**으로 관리
## 6. 리스크 & 열린 질문

**리스크**
- **R1. 확장 API의 시각 표현 한계** — 2.1의 매끄러운 애니메이션이 확장에서 기대만큼 안 나올 수 있음. → Phase 1에서 조기 검증, 안 되면 Phase 2 앞당김.
- **R1. 확장 API의 시각 표현 한계** — 2.1의 매끄러운 애니메이션이 확장에서 기대만큼 안 나올 수 있음. → Phase 1에서 조기 검증, 안 되면 Phase 2 앞당김. **(해소: 확장이 아니라 자체 렌더러로 갔다. 애니메이션·유령 커서·CodeLens 모두 우리 코드다.)**
- **R2. 포크 유지보수 부담** — VSCode 업스트림 추종 비용. VSCodium 사례 참고로 최소화.
- **R3. 실시간 스트리밍 편집의 충돌** — 사용자가 편집 중인데 AI도 편집하면? → 트랜잭션 모델 + 락/머지 정책 필요.

Expand Down
Loading
Loading