Skip to content

Commit 34938ed

Browse files
committed
docs: add runtime selection guide
1 parent f3fb85a commit 34938ed

7 files changed

Lines changed: 203 additions & 16 deletions

File tree

README.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,9 @@ The bootstrap and first vertical slice are in place:
2121
- the Gradle build, convention plugins, and module structure exist
2222
- the HTTP server, descriptor file workflow, and edit-application path work
2323
- the IntelliJ backend provides PSI-backed symbol resolution, references,
24-
rename planning, and parser-level diagnostics
25-
- the standalone backend is scaffolded and currently advertises `APPLY_EDITS`
26-
only
24+
rename planning, and Kotlin semantic diagnostics for Kotlin files
25+
- the standalone backend provides symbol resolution, references, diagnostics,
26+
rename planning, and edit application through the shared HTTP contract
2727

28-
The next work is to replace the standalone scaffolding with a full Kotlin
29-
Analysis API implementation and to bring `callHierarchy` online behind
30-
capability gating.
28+
The main remaining work is to bring `callHierarchy` online and harden the
29+
standalone dependency path so it does not depend on the IntelliJ build cache.

docs/api-reference.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ truth.
4848
| `RESOLVE_SYMBOL` | Yes | Yes | IntelliJ resolves against PSI and indices; standalone resolves against the Kotlin Analysis API. |
4949
| `FIND_REFERENCES` | Yes | Yes | Both hosts return locations and optional declarations. |
5050
| `CALL_HIERARCHY` | No | No | The route exists, but production support is not implemented. |
51-
| `DIAGNOSTICS` | Yes | Yes | IntelliJ diagnostics are parser-level today; standalone reports Kotlin Analysis API diagnostics. |
51+
| `DIAGNOSTICS` | Yes | Yes | IntelliJ reports Kotlin semantic diagnostics for Kotlin files and falls back to PSI parse errors for other PSI; standalone reports Kotlin Analysis API diagnostics. |
5252
| `RENAME` | Yes | Yes | The response is a text edit plan in both hosts. |
5353
| `APPLY_EDITS` | Yes | Yes | This is the shared mutation primitive across both hosts. |
5454

@@ -97,6 +97,7 @@ the edit set before touching the workspace.
9797

9898
## Next steps
9999

100-
Use [Get started](get-started.md) if you still need a running instance. Keep
101-
[Operator guide](operator-guide.md) nearby when you need the descriptor fields,
102-
CLI flags, or runtime defaults.
100+
Use [Choose a runtime](choose-a-runtime.md) if you need to decide which host to
101+
start. Use [Get started](get-started.md) if you still need a running instance.
102+
Keep [Operator guide](operator-guide.md) nearby when you need the descriptor
103+
fields, CLI flags, or runtime defaults.

docs/choose-a-runtime.md

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
---
2+
title: Choose a runtime
3+
description: Decide when to use the IntelliJ host, the standalone host, or
4+
both.
5+
---
6+
7+
Kast exposes the same HTTP/JSON contract through two runtime hosts. This page
8+
helps you decide which host to start, what each one needs from your workspace,
9+
and how to keep one client flow across both.
10+
11+
<div class="grid cards" markdown>
12+
13+
- **Use the IntelliJ host**
14+
15+
Start Kast from a plugin-enabled IDE when you want analysis to run against
16+
the workspace currently loaded in IntelliJ.
17+
18+
[Go to IntelliJ startup](#use-the-intellij-host)
19+
20+
- **Use the standalone host**
21+
22+
Start Kast as a headless JVM process when you need CI, scripts, or another
23+
environment without a running IDE.
24+
25+
[Go to standalone startup](#use-the-standalone-host)
26+
27+
- **Use both with one client**
28+
29+
Keep discovery and request handling identical, then select the runtime from
30+
the descriptor file at connection time.
31+
32+
[Go to shared client flow](#use-both-with-one-client-flow)
33+
34+
</div>
35+
36+
## Compare the hosts
37+
38+
Both hosts write the same descriptor shape and serve the same route map. The
39+
main difference is where analysis runs and how the workspace gets loaded.
40+
41+
| Question | IntelliJ host | Standalone host |
42+
| --- | --- | --- |
43+
| Where it runs | Inside the IntelliJ process for one open project | In its own JVM process |
44+
| How it starts | Open a project in the plugin-enabled IDE | Launch the wrapper script or fat JAR |
45+
| Workspace source | The project already opened in IntelliJ | `--workspace-root` or `KAST_WORKSPACE_ROOT` |
46+
| Source discovery | Uses the IDE project model, PSI, and indices | Scans conventional source roots and auto-discovers Gradle modules when available |
47+
| Default bind | `127.0.0.1` on an ephemeral port | `127.0.0.1` on an ephemeral port |
48+
| Descriptor field | `backendName = "intellij"` | `backendName = "standalone"` |
49+
| Current production capabilities | `RESOLVE_SYMBOL`, `FIND_REFERENCES`, `DIAGNOSTICS`, `RENAME`, `APPLY_EDITS` | `RESOLVE_SYMBOL`, `FIND_REFERENCES`, `DIAGNOSTICS`, `RENAME`, `APPLY_EDITS` |
50+
| Common use case | Local development with a live IDE project | CI, automation, and headless workflows |
51+
52+
## Use the IntelliJ host
53+
54+
Use the IntelliJ host when your workspace is already open in IntelliJ and you
55+
want Kast to start from that project context.
56+
57+
1. Build the plugin from the repo root.
58+
59+
```bash
60+
./gradlew :backend-intellij:buildPlugin
61+
```
62+
63+
2. Start the sandbox IDE.
64+
65+
```bash
66+
./gradlew :backend-intellij:runIde
67+
```
68+
69+
3. Open the workspace you want Kast to serve.
70+
71+
4. Wait for the project-scoped service to start and write a descriptor under
72+
`~/.kast/instances/`, or under `KAST_INSTANCE_DIR` if you set that
73+
environment variable first.
74+
75+
5. Read the descriptor and connect to the advertised `host` and `port`.
76+
77+
> **Note:** The IntelliJ host starts one Kast server per open workspace. It
78+
> binds to `127.0.0.1`, picks an ephemeral port, and uses fixed startup limits
79+
> of `maxResults = 500`, `requestTimeoutMillis = 30000`, and
80+
> `maxConcurrentRequests = 4`.
81+
82+
## Use the standalone host
83+
84+
Use the standalone host when you need Kast outside IntelliJ, or when you want
85+
to wire it into CI and scripts.
86+
87+
1. Build the standalone distribution from the repo root.
88+
89+
```bash
90+
./gradlew :backend-standalone:fatJar \
91+
:backend-standalone:writeWrapperScript
92+
```
93+
94+
2. Start the wrapper script with an absolute workspace path.
95+
96+
```bash
97+
./backend-standalone/build/scripts/backend-standalone \
98+
--workspace-root=/absolute/path/to/workspace
99+
```
100+
101+
3. Add overrides only when the default discovery path is not enough.
102+
103+
- Use `--source-roots` to replace automatic source-root discovery.
104+
- Use `--classpath` to add absolute classpath entries.
105+
- Use `--module-name` when you supply manual source roots.
106+
- Use `--token` or `KAST_TOKEN` when you want protected routes.
107+
108+
4. Read the descriptor file and connect to the advertised `host` and `port`.
109+
110+
> **Warning:** If you bind the standalone host to a non-loopback address, you
111+
> must also set a non-empty token. Kast rejects non-local binding without a
112+
> token.
113+
114+
## Use both with one client flow
115+
116+
Kast is easier to integrate when your client treats the runtime host as a
117+
discovery result instead of a hardcoded mode.
118+
119+
```mermaid
120+
graph LR
121+
Client["Client or agent"] --> Descriptor["Descriptor directory"]
122+
Descriptor --> IntelliJ["IntelliJ host"]
123+
Descriptor --> Standalone["Standalone host"]
124+
Client --> Api["/api/v1/health and /api/v1/capabilities"]
125+
```
126+
127+
Use this flow when you want the same client to work in local development and
128+
headless environments.
129+
130+
1. Read descriptor files from `~/.kast/instances/`, or from `KAST_INSTANCE_DIR`
131+
when you override the location.
132+
2. Select the descriptor that matches the target `workspaceRoot`, or filter by
133+
`backendName` if you need one specific host.
134+
3. Call `/api/v1/health` to confirm the runtime identity.
135+
4. Call `/api/v1/capabilities` and gate optional routes against the returned
136+
capabilities.
137+
5. Send the same request shapes regardless of which host answered.
138+
139+
## Enable standalone usage in CI or scripts
140+
141+
The standalone host fits automated environments because it does not depend on a
142+
running IDE. A minimal bootstrap looks like this.
143+
144+
```bash
145+
./gradlew :backend-standalone:fatJar \
146+
:backend-standalone:writeWrapperScript
147+
148+
export KAST_INSTANCE_DIR="$PWD/.kast-instances"
149+
export KAST_TOKEN="ci-shared-secret"
150+
151+
./backend-standalone/build/scripts/backend-standalone \
152+
--workspace-root="$PWD" \
153+
--token="$KAST_TOKEN"
154+
```
155+
156+
If your automation already knows the workspace root, you can set
157+
`KAST_WORKSPACE_ROOT` instead of passing `--workspace-root`.
158+
159+
## Verify the runtime you started
160+
161+
The startup path is complete when discovery and capability checks agree with
162+
the host you intended to use.
163+
164+
- A descriptor file exists in the expected instance directory.
165+
- The descriptor reports the expected `workspaceRoot` and `backendName`.
166+
- `/api/v1/health` returns `status: "ok"`.
167+
- `/api/v1/capabilities` advertises the routes your client plans to call.
168+
169+
## Next steps
170+
171+
Read [Get started](get-started.md) for the first-request walkthrough. Use
172+
[Operator guide](operator-guide.md) when you need CLI flags, descriptor
173+
lifecycle details, or runtime defaults. Keep [HTTP API](api-reference.md)
174+
open when you are wiring a client against the contract.

docs/get-started.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ Kast lets you point the same client workflow at either an IntelliJ-backed
99
server or a standalone JVM process. This guide gets you from a clean checkout
1010
to a running instance and a first HTTP request.
1111

12+
Use [Choose a runtime](choose-a-runtime.md) first if you are still deciding
13+
whether to start Kast inside IntelliJ or as a standalone process.
14+
1215
> **Note:** The Gradle build uses Java 21.
1316
1417
## Prerequisites
@@ -138,5 +141,6 @@ You know the bootstrap worked when all three of these conditions are true.
138141
## Next steps
139142

140143
Read [HTTP API](api-reference.md) to wire a client against the contract. Use
141-
[Operator guide](operator-guide.md) when you need runtime defaults, CLI flags,
142-
or descriptor lifecycle details.
144+
[Choose a runtime](choose-a-runtime.md) when you need the host-selection guide.
145+
Keep [Operator guide](operator-guide.md) nearby for runtime defaults, CLI
146+
flags, or descriptor lifecycle details.

docs/index.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ text edit application.
1313

1414
<div class="grid cards" markdown>
1515

16+
- **Choose a runtime**
17+
18+
Compare the IntelliJ and standalone hosts before you wire one into your
19+
workflow.
20+
21+
[Decide which host to start](choose-a-runtime.md)
22+
1623
- **Get started**
1724

1825
Build a runtime, discover its descriptor file, and make your first
@@ -71,7 +78,8 @@ important distinction is what each host advertises right now.
7178
7279
## Next steps
7380

74-
Start with [Get started](get-started.md) if you want a running instance. Use
75-
[HTTP API](api-reference.md) when you are wiring a client or agent, and keep
81+
Start with [Choose a runtime](choose-a-runtime.md) if you need to decide
82+
between the IntelliJ and standalone hosts. Use
83+
[Get started](get-started.md) once you are ready to start one, then keep
7684
[Operator guide](operator-guide.md) open when you need the runtime defaults and
7785
descriptor details.

docs/operator-guide.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ These constraints affect clients regardless of which host you run.
141141

142142
## Next steps
143143

144-
Use [Get started](get-started.md) if you need the bootstrap flow. Read
144+
Use [Choose a runtime](choose-a-runtime.md) if you are deciding which host to
145+
start. Use [Get started](get-started.md) for the bootstrap flow, and read
145146
[HTTP API](api-reference.md) when you are implementing a client against the
146147
contract.

zensical.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Copyright &copy; 2026 amichne
1616
"""
1717
nav = [
1818
{ "Overview" = "index.md" },
19-
{ "Guide" = [{ "Get started" = "get-started.md" }, { "Operator guide" = "operator-guide.md" }] },
19+
{ "Guide" = [{ "Choose a runtime" = "choose-a-runtime.md" }, { "Get started" = "get-started.md" }, { "Operator guide" = "operator-guide.md" }] },
2020
{ "Reference" = [{ "HTTP API" = "api-reference.md" }] },
2121
{ "Architecture" = [{ "Implementation plan" = "impl-001.md" }, { "Remaining work" = "remaining-work.md" }, { "ADR 001" = "adr-001.md" }, { "ADR 002" = "adr-002.md" }, { "ADR 003" = "adr-003.md" }, { "ADR 004" = "adr-004.md" }] },
2222
]

0 commit comments

Comments
 (0)