Skip to content

Commit 61bab36

Browse files
Yan123-techyan
andauthored
docs: document the project across six focused files plus AGENTS.md (#12)
Replaces the single PROJECT_PLAN.md with documents that each answer one question, so a reader loads only what they need: - IDEA.md what this is for, what it deliberately is not, principles - CURRENT_STATE what works, what does not, coverage, ordered next steps - STACK.md toolchain and dependency versions with the reasoning - ARCHITECTURE module boundaries, data flow, concurrency, coupling - PROCESS.md local gate, branching, PRs, definition of done, releasing - MEMORY.md constraints that are expensive to rediscover - AGENTS.md instructions for coding agents PROJECT_PLAN.md is now a pointer table so old links resolve, with the roadmap and risk table intact. MEMORY.md records what actually cost time and would again: the four failed CI attempts and why lowering swift-tools-version does not work, why FileSystemManager keys on paths rather than URLs, why Document is ambiguous next to SwiftUI.Document, the ObservableObject/@observable trap, and which two files are allowed to touch upstream SourceEditor types. AGENTS.md leads with those three documents and states that fixing a stale .md file is part of the change, with a table mapping change type to the file that must be updated. A stale document is worse than a missing one: a missing file announces ignorance, a wrong file gets trusted. Co-authored-by: yan <yan@localhost>
1 parent 5186426 commit 61bab36

10 files changed

Lines changed: 961 additions & 58 deletions

File tree

‎AGENTS.md‎

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# AGENTS.md
2+
3+
Instructions for coding agents working in this repository.
4+
5+
## Read this first
6+
7+
Before changing any code:
8+
9+
1. **[docs/MEMORY.md](docs/MEMORY.md)** — constraints that are expensive to rediscover.
10+
Entry #1 alone will cost you an hour if you touch `Package.swift` without it.
11+
2. **[docs/CURRENT_STATE.md](docs/CURRENT_STATE.md)** — what works, what does not, what is
12+
next. Do not re-implement something that already works.
13+
3. **[docs/IDEA.md](docs/IDEA.md)** — what this project is for, and what it deliberately is not.
14+
15+
---
16+
17+
## Keeping the documentation true is part of the work
18+
19+
**The `.md` files in `docs/` describe the current state of the code. If your change makes any
20+
of them wrong, fixing that file is not optional cleanup — it is part of the change.**
21+
22+
This matters more here than in most projects, because `docs/MEMORY.md` is the only record of
23+
several constraints that cost real time to discover. A stale entry does not just misinform a
24+
reader; it sends the next person — or the next agent — into the same dead end, and they have
25+
no way to tell the file is stale.
26+
27+
### When to update which file
28+
29+
| Your change | Update |
30+
|---|---|
31+
| Anything in `Sources/` or `Tests/` that changes what works | **CURRENT_STATE.md** — features, tests table, sizes |
32+
| Worked around a dependency, a toolchain limit, an SDK quirk | **MEMORY.md** — new numbered entry, or amend the relevant one |
33+
| Found a trap you fell into | **MEMORY.md** — what happened, what it cost, what to do |
34+
| Added, removed or upgraded a dependency | **STACK.md** — versions table and the rationale below it |
35+
| Added or removed a module, or changed a data flow | **ARCHITECTURE.md** |
36+
| Changed how work is expected to happen | **PROCESS.md**, **BRANCHING.md**, **COMMITTING.md** |
37+
| Changed what the project is for | **IDEA.md** |
38+
| Changed the public surface, CI, or setup | **README.md** |
39+
40+
### The rule
41+
42+
If you had to read something to understand your change, it belonged in a `.md` file and
43+
probably does not exist yet. Write it.
44+
45+
If you found something that contradicts a `.md` file, fix the file in the same commit. A
46+
stale document is a defect, not a matter of taste — and it is worse than a missing one,
47+
because a missing file announces ignorance while a wrong file is trusted.
48+
49+
### When the current state is knowingly wrong
50+
51+
Do not paper over it. Write it down as a limitation with an issue number, the way
52+
`TerminalSession`'s pipes-not-a-PTY is handled:
53+
54+
```
55+
## Not working
56+
57+
**The terminal has no PTY.** Pipes, so no job control and no TTY.
58+
[#5](https://github.com/Yan123-tech/code-editor/issues/5)
59+
```
60+
61+
An honest gap is useful. A hidden gap is a trap for whoever inherits this.
62+
63+
---
64+
65+
## Local gate — CI does not build
66+
67+
**Run all three before every push. CI checks formatting and syntax only.**
68+
69+
```bash
70+
swift build && swift test
71+
swift-format lint --recursive --strict --configuration .swift-format Sources Tests
72+
```
73+
74+
Reason: no hosted runner has SwiftPM 6.4, which `CodeEditSourceEditor` 0.15 needs to
75+
generate its resource bundles. Full details and the failed attempts in
76+
[docs/MEMORY.md](docs/MEMORY.md#1-ci-cannot-build-this-package-do-not-try-to-make-it).
77+
78+
Never imply in a commit message or PR that CI verified the build. It did not.
79+
80+
---
81+
82+
## Conventions
83+
84+
- **Conventional Commits**, scopes are modules: `core`, `themes`, `terminal`, `lsp`, `ui`,
85+
`app`, `ci`, `docs`. See [docs/COMMITTING.md](docs/COMMITTING.md).
86+
- **One concern per branch.** `main` is protected: PR required, linear history, no
87+
force-push. See [docs/BRANCHING.md](docs/BRANCHING.md).
88+
- **4-space indent, 120 columns.** Enforced by `.swift-format`.
89+
- **`CodeEditorCore` imports `Foundation` only** — no SwiftUI, no AppKit. That is what makes
90+
it testable without a window server, and what makes offset arithmetic testable at all.
91+
92+
## Traps that will bite
93+
94+
- `Document` is ambiguous inside modules that import SwiftUI. Write `CodeEditorCore.Document`.
95+
- Never key a dictionary or set by `URL` where the path is what matters. See
96+
[MEMORY.md #3](docs/MEMORY.md).
97+
- Do not add `ObservableObject` to anything. It is `@Observable` throughout.
98+
- Do not give a `@MainActor` class a `deinit` that touches its state.
99+
- `SourceEditor` takes a `Binding<String>`; there is no push path from `Document` to the
100+
view. See [MEMORY.md #4](docs/MEMORY.md).
101+
102+
## Before you call it done
103+
104+
- [ ] `swift build` passes
105+
- [ ] `swift test` passes
106+
- [ ] `swift-format lint --strict` clean
107+
- [ ] Behaviour change has a test; bug fix has a test that fails without the fix
108+
- [ ] New public APIs have doc comments that state the contract
109+
- [ ] The `.md` files above are still true
110+
111+
That last item is not a formality. It is the difference between this repository and one
112+
where the next hour is wasted.

‎PROJECT_PLAN.md‎

Lines changed: 38 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,48 @@
1-
# CodeEditor MVP — Project Plan
1+
# Project plan
22

3-
## Current state
3+
Superseded by the documents in [`docs/`](docs/). This file is kept only so old links resolve.
44

5-
The MVP is feature-complete and building green. `swift build` and `swift test` (35 tests)
6-
both pass. `PROJECT_PLAN.md` originally described an eight-week roadmap whose Phase 1 goal
7-
was to hand-roll syntax highlighting; that was replaced by
8-
[CodeEditSourceEditor](https://github.com/CodeEditApp/CodeEditSourceEditor), which provides
9-
the text view, tree-sitter highlighting, gutter and undo handling out of the box.
10-
11-
Shipped:
12-
13-
- File explorer with lazy recursive tree, create / rename / delete
14-
- Editing via `SourceEditor` with tree-sitter highlighting for ~25 languages
15-
- Document tabs, dirty tracking, save with untitled-location prompt
16-
- Line-ending detection and preservation
17-
- Embedded shell terminal with history and 2000-line scrollback
18-
- Three themes with persisted editor preferences
19-
- Menu commands and keyboard shortcuts
20-
- `CodeEditorLSP` transport with real Content-Length framing (not yet wired to the UI)
21-
22-
## Next up
23-
24-
| Issue | Scope |
5+
| Looking for | Read |
256
|---|---|
26-
| LSP completion | Connect `LSPClient` to `SourceEditor` via a `TextViewCoordinator`; fuzzy-filtered popup, Tab/Enter to accept |
27-
| Diagnostics | Consume `textDocument/publishDiagnostics`; underline plus gutter markers |
28-
| Hover and go-to-definition | Tooltips and ⌘-click navigation using `textDocument/hover` and `definition` |
29-
| Settings panel | Persisted preferences UI replacing the current menu-only controls |
7+
| What this project is for | [docs/IDEA.md](docs/IDEA.md) |
8+
| What works and what does not | [docs/CURRENT_STATE.md](docs/CURRENT_STATE.md) |
9+
| Versions and dependency rationale | [docs/STACK.md](docs/STACK.md) |
10+
| Module boundaries and data flow | [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) |
11+
| How work gets done | [docs/PROCESS.md](docs/PROCESS.md) |
12+
| Constraints worth knowing before touching anything | [docs/MEMORY.md](docs/MEMORY.md) |
13+
| Branch and commit conventions | [docs/BRANCHING.md](docs/BRANCHING.md), [docs/COMMITTING.md](docs/COMMITTING.md) |
14+
15+
The original eight-week roadmap planned to hand-roll syntax highlighting in Phase 1.
16+
CodeEditSourceEditor provides it, so that work is gone and the remaining plan is six issues
17+
tracked in GitHub, ordered in [docs/CURRENT_STATE.md](docs/CURRENT_STATE.md).
18+
19+
## Roadmap
20+
21+
| # | Issue | Scope |
22+
|---|---|---|
23+
| 1 | [LSP completion](https://github.com/Yan123-tech/code-editor/issues/1) | Connect `LSPClient` via a `TextViewCoordinator`; fuzzy-filtered popup, Tab/Enter to accept |
24+
| 2 | [Diagnostics](https://github.com/Yan123-tech/code-editor/issues/2) | Consume `textDocument/publishDiagnostics`; underline plus gutter markers |
25+
| 3 | [Hover and go-to-definition](https://github.com/Yan123-tech/code-editor/issues/3) | Tooltips and ⌘-click navigation |
26+
| 6 | [External change detection](https://github.com/Yan123-tech/code-editor/issues/6) | Reload clean files, prompt on dirty ones |
27+
| 5 | [PTY terminal](https://github.com/Yan123-tech/code-editor/issues/5) | Real pseudo-terminal, ANSI parsing, SIGINT forwarding |
28+
| 4 | [Settings panel](https://github.com/Yan123-tech/code-editor/issues/4) | Replace menu-only preference controls |
3029

31-
## Module boundaries
32-
33-
```
34-
CodeEditorCore (no dependencies)
35-
CodeEditorThemes (no dependencies)
36-
CodeEditorTerminal (no dependencies)
37-
CodeEditorLSP (no dependencies)
38-
CodeEditorUI → Core, Themes, Terminal, LSP, CodeEditSourceEditor
39-
CodeEditorApp → UI, Core, Themes, Terminal, LSP
40-
```
30+
## Quality gates
4131

42-
`CodeEditorCore` must stay UI-free so it remains testable without a window server.
32+
- [x] Builds with no warnings
33+
- [x] `swift test` passes (35 tests)
34+
- [x] `swift-format lint --strict` clean
35+
- [ ] CI builds the package — blocked, see [docs/MEMORY.md](docs/MEMORY.md#1-ci-cannot-build-this-package-do-not-try-to-make-it)
36+
- [ ] Completion works for Swift
37+
- [ ] Diagnostics render
38+
- [ ] No leaks in a 30-minute session
4339

4440
## Risks
4541

4642
| Risk | Mitigation |
4743
|---|---|
48-
| Source editor API churn (upstream is pre-1.0) | Pinned to `from: 0.15.2`; the `Theme.editorTheme` bridge in `Sources/CodeEditorUI/Sources/Editor/EditorTheme+Bridge.swift` isolates the surface we depend on |
49-
| `sourcekit-lsp` is Xcode-toolchain specific | `LanguageServerRegistry.sourceKitLSPPath` probes known locations and returns `nil` rather than failing to launch |
50-
| URL equality treats `/tmp/x` and `/tmp/x/` as distinct | `FileSystemManager` keys its cache on `standardizedFileURL.path` |
51-
| Terminal uses pipes, not a PTY | Documented in `TerminalSession`; no job control or terminal echo |
52-
53-
## Quality gates
54-
55-
- [x] Builds with no warnings
56-
- [x] `swift test` passes
57-
- [ ] Completion works for Swift
58-
- [ ] Diagnostics render
59-
- [ ] No leaks in a 30-minute session
44+
| Source editor API churn (upstream is pre-1.0) | Pinned `from: 0.15.2`; `Theme.editorTheme` in `EditorTheme+Bridge.swift` isolates the surface we touch. [MEMORY.md #8](docs/MEMORY.md) |
45+
| `sourcekit-lsp` is Xcode-toolchain specific | `LanguageServerRegistry.sourceKitLSPPath` probes known paths and returns `nil` rather than failing to launch |
46+
| URL equality treats `/tmp/x` and `/tmp/x/` as distinct | `FileSystemManager` keys its cache on `standardizedFileURL.path`. [MEMORY.md #3](docs/MEMORY.md) |
47+
| Terminal uses pipes, not a PTY | Documented in `TerminalSession`, tracked as issue #5 |
48+
| LSP is the largest module and unused | If issues 1–3 do not land, delete it rather than keep it aspirational. [CURRENT_STATE.md](docs/CURRENT_STATE.md) |

‎README.md‎

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,19 +100,39 @@ leaves that `UI` composes.
100100
| `` ⌃` `` | Toggle terminal |
101101
| `⇧⌘L` | Toggle dark/light theme |
102102

103+
## Documentation
104+
105+
| Document | What it covers |
106+
|---|---|
107+
| [docs/IDEA.md](docs/IDEA.md) | What this is for, what it deliberately is not, design principles |
108+
| [docs/CURRENT_STATE.md](docs/CURRENT_STATE.md) | What works, what does not, test coverage, next steps |
109+
| [docs/STACK.md](docs/STACK.md) | Toolchain and dependency versions, with the reasoning for each choice |
110+
| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | Module boundaries, data flow, concurrency, where coupling lives |
111+
| [docs/PROCESS.md](docs/PROCESS.md) | Local gate, branching, PRs, definition of done, releasing |
112+
| [docs/MEMORY.md](docs/MEMORY.md) | Constraints that are expensive to rediscover |
113+
| [docs/BRANCHING.md](docs/BRANCHING.md) | Branch naming and the PR flow |
114+
| [docs/COMMITTING.md](docs/COMMITTING.md) | Conventional Commits types and scopes |
115+
| [AGENTS.md](AGENTS.md) | Instructions for coding agents working here |
116+
117+
`docs/MEMORY.md` is the one to read first. It records why CI cannot build this package, why
118+
`FileSystemManager` keys on paths rather than `URL`s, and which source editor API is safe to
119+
depend on — each of which cost real time to work out.
120+
121+
If a change makes any of these documents wrong, fixing the document is part of the change.
122+
See [AGENTS.md](AGENTS.md).
123+
103124
## Roadmap
104125

105126
`CodeEditorLSP` has a working transport — real `Content-Length` framing, request/response
106127
correlating by id, notification routing — and a `sourcekit-lsp` descriptor that resolves
107-
Xcode's bundled binary. It is not connected to the editor yet. Planned, in order:
108-
109-
1. Completion popup with fuzzy filtering and keyboard navigation
110-
2. Diagnostics overlay with gutter markers
111-
3. Hover tooltips
112-
4. Go-to-definition
113-
5. Settings panel
128+
Xcode's bundled binary. It is not connected to the editor yet.
114129

115-
See [`PROJECT_PLAN.md`](PROJECT_PLAN.md) for the full roadmap.
130+
1. [Completion popup](https://github.com/Yan123-tech/code-editor/issues/1)
131+
2. [Diagnostics overlay](https://github.com/Yan123-tech/code-editor/issues/2)
132+
3. [Hover and go-to-definition](https://github.com/Yan123-tech/code-editor/issues/3)
133+
4. [External change detection](https://github.com/Yan123-tech/code-editor/issues/6)
134+
5. [PTY terminal](https://github.com/Yan123-tech/code-editor/issues/5)
135+
6. [Settings panel](https://github.com/Yan123-tech/code-editor/issues/4)
116136

117137
## Contributing
118138

@@ -122,6 +142,7 @@ See [`PROJECT_PLAN.md`](PROJECT_PLAN.md) for the full roadmap.
122142

123143
- Branching model and PR flow: [docs/BRANCHING.md](docs/BRANCHING.md)
124144
- Commit types and scopes: [docs/COMMITTING.md](docs/COMMITTING.md)
145+
- Full workflow: [docs/PROCESS.md](docs/PROCESS.md)
125146

126147
Before pushing, run `swift build && swift test` locally — CI checks formatting and syntax
127148
only, for the toolchain reason described above.

0 commit comments

Comments
 (0)