jolink-runtime 0.1.0a1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. jolink_runtime-0.1.0a1/LICENSE +22 -0
  2. jolink_runtime-0.1.0a1/PKG-INFO +419 -0
  3. jolink_runtime-0.1.0a1/README.md +402 -0
  4. jolink_runtime-0.1.0a1/pyproject.toml +36 -0
  5. jolink_runtime-0.1.0a1/setup.cfg +4 -0
  6. jolink_runtime-0.1.0a1/src/jolink_runtime/__init__.py +6 -0
  7. jolink_runtime-0.1.0a1/src/jolink_runtime/adapters/__init__.py +1 -0
  8. jolink_runtime-0.1.0a1/src/jolink_runtime/adapters/base.py +112 -0
  9. jolink_runtime-0.1.0a1/src/jolink_runtime/adapters/java/__init__.py +5 -0
  10. jolink_runtime-0.1.0a1/src/jolink_runtime/adapters/java/jdwp_adapter.py +4802 -0
  11. jolink_runtime-0.1.0a1/src/jolink_runtime/adapters/java/jdwp_client.py +621 -0
  12. jolink_runtime-0.1.0a1/src/jolink_runtime/adapters/java/log_manager.py +74 -0
  13. jolink_runtime-0.1.0a1/src/jolink_runtime/adapters/java/process_discovery.py +253 -0
  14. jolink_runtime-0.1.0a1/src/jolink_runtime/adapters/java/process_manager.py +521 -0
  15. jolink_runtime-0.1.0a1/src/jolink_runtime/adapters/java/tool_schema.py +419 -0
  16. jolink_runtime-0.1.0a1/src/jolink_runtime/core/__init__.py +1 -0
  17. jolink_runtime-0.1.0a1/src/jolink_runtime/core/dispatcher.py +254 -0
  18. jolink_runtime-0.1.0a1/src/jolink_runtime/core/models.py +116 -0
  19. jolink_runtime-0.1.0a1/src/jolink_runtime/core/session_manager.py +192 -0
  20. jolink_runtime-0.1.0a1/src/jolink_runtime/core/wait_state.py +166 -0
  21. jolink_runtime-0.1.0a1/src/jolink_runtime/server/__init__.py +5 -0
  22. jolink_runtime-0.1.0a1/src/jolink_runtime/server/mcp_server.py +1106 -0
  23. jolink_runtime-0.1.0a1/src/jolink_runtime/server/tool_schema.py +284 -0
  24. jolink_runtime-0.1.0a1/src/jolink_runtime/transport/__init__.py +1 -0
  25. jolink_runtime-0.1.0a1/src/jolink_runtime/transport/stdio.py +50 -0
  26. jolink_runtime-0.1.0a1/src/jolink_runtime.egg-info/PKG-INFO +419 -0
  27. jolink_runtime-0.1.0a1/src/jolink_runtime.egg-info/SOURCES.txt +30 -0
  28. jolink_runtime-0.1.0a1/src/jolink_runtime.egg-info/dependency_links.txt +1 -0
  29. jolink_runtime-0.1.0a1/src/jolink_runtime.egg-info/entry_points.txt +2 -0
  30. jolink_runtime-0.1.0a1/src/jolink_runtime.egg-info/requires.txt +7 -0
  31. jolink_runtime-0.1.0a1/src/jolink_runtime.egg-info/top_level.txt +1 -0
  32. jolink_runtime-0.1.0a1/tests/test_java_runtime.py +3146 -0
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Nous Research
4
+ Copyright (c) 2026 joLink contributors
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1,419 @@
1
+ Metadata-Version: 2.4
2
+ Name: jolink-runtime
3
+ Version: 0.1.0a1
4
+ Summary: Local runtime evidence and debugging for coding agents
5
+ Author: joLink contributors
6
+ License-Expression: MIT
7
+ Requires-Python: <3.14,>=3.11
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: anyio==4.14.2
11
+ Requires-Dist: jsonschema==4.26.0
12
+ Requires-Dist: mcp==1.28.1
13
+ Requires-Dist: psutil==7.2.2
14
+ Provides-Extra: dev
15
+ Requires-Dist: pytest==9.0.2; extra == "dev"
16
+ Dynamic: license-file
17
+
18
+ # joLink Runtime
19
+
20
+ Run, observe, and debug local Java applications with coding agents.
21
+
22
+ > **Design principle:** Everything exists to reduce uncertainty for the LLM.
23
+
24
+ joLink gives coding agents access to real Java runtime behavior instead of
25
+ forcing them to rely only on source code, naming conventions, and assumptions.
26
+
27
+ It can start or restart a local Java application, inspect its status and logs,
28
+ and provide runtime evidence for verifying code changes. When surface-level
29
+ evidence is not enough, the agent can continue with breakpoints, exception
30
+ events, stack frames, and variables.
31
+
32
+ Free and local. It does not require a joLink account, model API key, inference
33
+ provider, or separate agent application.
34
+
35
+ ## Why joLink
36
+
37
+ Coding agents are good at reading and changing code, but they can become stuck
38
+ in a loop of static assumptions:
39
+
40
+ ```text
41
+ analyze
42
+ -> patch
43
+ -> assume the patch works
44
+ -> patch again
45
+ ```
46
+
47
+ joLink adds the missing runtime feedback loop:
48
+
49
+ ```text
50
+ analyze
51
+ -> change
52
+ -> run
53
+ -> observe
54
+ -> update the hypothesis
55
+ -> change again if necessary
56
+ ```
57
+
58
+ This is useful when:
59
+
60
+ - the Java application is not running yet;
61
+ - a code change needs to be verified against real behavior;
62
+ - repeated patches have not solved the problem;
63
+ - endpoint results do not match the source-code interpretation;
64
+ - logs or tests are insufficient to explain the executed path;
65
+ - business naming is inconsistent and static search cannot find the relevant
66
+ code;
67
+ - deeper runtime evidence such as breakpoints, stacks, or variables is needed.
68
+
69
+ The goal is not to use a debugger for every problem.
70
+
71
+ Start with the cheapest useful evidence:
72
+
73
+ ```text
74
+ application status
75
+ -> logs and actual outputs
76
+ -> exception events
77
+ -> executed path
78
+ -> breakpoints, stack frames, and variables
79
+ ```
80
+
81
+ Debug deeper only when necessary.
82
+
83
+ ## What it can do
84
+
85
+ joLink currently exposes two MCP tools:
86
+
87
+ - `java_runtime` — run, operate, observe, and debug one local Java application;
88
+ - `java_processes` — discover an already-running local JVM when attach is
89
+ needed.
90
+
91
+ The Java Runtime currently provides 15 public actions:
92
+
93
+ ```text
94
+ run
95
+ stop
96
+ restart
97
+ attach
98
+ detach
99
+ status
100
+ logs
101
+ breakpoint
102
+ exception
103
+ wait_event
104
+ threads
105
+ stack
106
+ variables
107
+ resume
108
+ cleanup_debug_state
109
+ ```
110
+
111
+ These actions support:
112
+
113
+ - launching a Java application as an owned JVM process;
114
+ - stopping or restarting an application after code changes;
115
+ - inspecting application status and logs;
116
+ - attaching to an already-running local JVM;
117
+ - setting semantic breakpoints and exception watches;
118
+ - waiting for runtime events;
119
+ - inspecting threads, stack frames, and variables;
120
+ - resuming suspended execution;
121
+ - cleaning up debug state safely.
122
+
123
+ ## Current status
124
+
125
+ Current package version:
126
+
127
+ ```text
128
+ 0.1.0a1
129
+ ```
130
+
131
+ Status:
132
+
133
+ ```text
134
+ Alpha / controlled dogfood
135
+ ```
136
+
137
+ The first adapter targets local Java applications through JDWP.
138
+
139
+ The current MCP implementation includes:
140
+
141
+ - stdio transport;
142
+ - stdout reserved exclusively for MCP protocol messages;
143
+ - JSON `TextContent` with matching `structuredContent`;
144
+ - Runtime `ok=false` mapped to MCP `isError=true`;
145
+ - cancellable `wait_event`;
146
+ - optional two-phase waiting with `arm` and `await`;
147
+ - wait-scoped JDWP requests;
148
+ - ownership-aware shutdown;
149
+ - automatic cleanup and resume paths;
150
+ - persistent JDWP packet framing across short polling timeouts.
151
+
152
+ The current two-phase implementation is intended for controlled dogfood.
153
+ Known cancellation, cleanup-preemption, handle-publication, and response
154
+ delivery limitations are tracked in:
155
+
156
+ [`docs/stage-2.1.2-lifecycle-backlog.md`](docs/stage-2.1.2-lifecycle-backlog.md)
157
+
158
+ Do not use this alpha release for unattended production JVM debugging.
159
+
160
+ ## Requirements
161
+
162
+ - JDK 8 or newer
163
+ - [uv](https://docs.astral.sh/uv/)
164
+
165
+ `uv` manages the Python environment automatically. A separate Python
166
+ installation is normally not required.
167
+
168
+ Confirm the requirements with:
169
+
170
+ ```bash
171
+ java -version
172
+ uv --version
173
+ ```
174
+
175
+ ## Install
176
+
177
+ ### 1. Install uv
178
+
179
+ Install `uv` once if it is not already available.
180
+
181
+ Windows PowerShell:
182
+
183
+ ```powershell
184
+ powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
185
+ ```
186
+
187
+ macOS or Linux:
188
+
189
+ ```bash
190
+ curl -LsSf https://astral.sh/uv/install.sh | sh
191
+ ```
192
+
193
+ ### 2. Add joLink to the MCP client
194
+
195
+ Many MCP clients support a stdio server configuration similar to the following:
196
+
197
+ ```json
198
+ {
199
+ "mcpServers": {
200
+ "jolink-runtime": {
201
+ "command": "uvx",
202
+ "args": ["jolink-runtime@0.1.0a1"]
203
+ }
204
+ }
205
+ }
206
+ ```
207
+
208
+ `uvx` downloads the package into an isolated environment and caches it
209
+ automatically. No repository clone, virtual environment, or source checkout is
210
+ required.
211
+
212
+ The exact configuration file varies by MCP client.
213
+
214
+ Restart the MCP client after changing its configuration.
215
+
216
+ ## Quick start
217
+
218
+ After the MCP server is connected, confirm that these tools are available:
219
+
220
+ ```text
221
+ java_runtime
222
+ java_processes
223
+ ```
224
+
225
+ Open a local Java project and ask the coding agent:
226
+
227
+ ```text
228
+ Use joLink to start this Java application, inspect its status and logs,
229
+ and verify the latest code changes against real runtime behavior.
230
+ ```
231
+
232
+ For a problem that has already survived multiple attempted fixes:
233
+
234
+ ```text
235
+ Do not apply another speculative patch yet.
236
+
237
+ Use joLink to run the current Java application and collect actual runtime
238
+ evidence. Start with status, logs, tests, and actual outputs. Re-evaluate the
239
+ root-cause hypothesis before changing the code again.
240
+ ```
241
+
242
+ For deeper investigation:
243
+
244
+ ```text
245
+ Use joLink to reproduce this issue.
246
+
247
+ Start with actual outputs and logs. If that evidence is insufficient, use a
248
+ breakpoint or exception watch, inspect the relevant stack frames and variables,
249
+ then resume or clean up the suspended JVM.
250
+ ```
251
+
252
+ joLink starts and observes the Java application. The coding agent may use its
253
+ normal HTTP, terminal, browser, or testing tools to trigger the scenario.
254
+
255
+ ## Typical workflow
256
+
257
+ A normal verification flow looks like this:
258
+
259
+ ```text
260
+ read the code
261
+ -> change the code
262
+ -> java_runtime(run or restart)
263
+ -> java_runtime(status)
264
+ -> java_runtime(logs)
265
+ -> trigger a test or endpoint
266
+ -> inspect the actual result
267
+ -> update the diagnosis
268
+ ```
269
+
270
+ A deeper debugging flow looks like this:
271
+
272
+ ```text
273
+ run or attach
274
+ -> configure a breakpoint or exception watch
275
+ -> wait_event(wait_mode=arm)
276
+ -> trigger the scenario after status=armed
277
+ -> wait_event(wait_mode=await, wait_handle=...)
278
+ -> inspect stack frames and variables
279
+ -> resume or cleanup_debug_state
280
+ ```
281
+
282
+ Blocking `wait_event` mode remains available, but two-phase waiting is useful
283
+ when an external action must occur only after JDWP requests are installed.
284
+
285
+ ## Runtime safety
286
+
287
+ joLink `0.1.0a1` is designed for local, trusted development environments.
288
+
289
+ Current safety boundaries:
290
+
291
+ - MCP transport is stdio;
292
+ - JDWP access is limited to local JVMs;
293
+ - one joLink server controls one Java target at a time;
294
+ - a JVM launched by joLink is treated as an owned process;
295
+ - an owned JVM may be stopped by joLink;
296
+ - an externally started JVM is attached, resumed, and detached;
297
+ - an attached JVM is never intentionally terminated;
298
+ - raw JDWP requests are armed only while a waiter owns them; logical
299
+ breakpoint and exception definitions persist until removed or cleaned up;
300
+ - after receiving a `suspension_id`, the agent must call `resume` or
301
+ `cleanup_debug_state`.
302
+
303
+ Do not expose the JDWP port to an untrusted network.
304
+
305
+ Do not use the current alpha release for remote or production debugging.
306
+
307
+ ## Client notes
308
+
309
+ ### CodeBuddy
310
+
311
+ Some current CodeBuddy environments may initially display:
312
+
313
+ ```text
314
+ Description: No description
315
+ ```
316
+
317
+ The full joLink tool description and action schema remain available after the
318
+ tool definition is loaded. This is a client-side discovery limitation rather
319
+ than a joLink runtime failure.
320
+
321
+ A project-level agent rule can improve discovery:
322
+
323
+ ```markdown
324
+ ## joLink Java Runtime
325
+
326
+ For local Java application tasks, use the `jolink-runtime` MCP to start or
327
+ restart the application, inspect status and logs, and verify code changes
328
+ against real runtime behavior.
329
+
330
+ When actual outputs and logs are insufficient, use its breakpoints, exception
331
+ events, stack frames, and variables for deeper investigation.
332
+
333
+ After inspecting a suspended JVM, always call `resume` or
334
+ `cleanup_debug_state`.
335
+ ```
336
+
337
+ ## Development
338
+
339
+ Clone the repository and install development dependencies:
340
+
341
+ ```bash
342
+ uv sync --extra dev --locked
343
+ ```
344
+
345
+ Run the default test suite:
346
+
347
+ ```bash
348
+ uv run pytest
349
+ ```
350
+
351
+ Run the stdio server from the source checkout:
352
+
353
+ ```bash
354
+ uv run jolink-runtime
355
+ ```
356
+
357
+ Equivalent module entry point:
358
+
359
+ ```bash
360
+ uv run python -m jolink_runtime.transport.stdio
361
+ ```
362
+
363
+ A generic MCP client configuration can launch it directly from a checkout:
364
+
365
+ ```json
366
+ {
367
+ "mcpServers": {
368
+ "jolink-runtime": {
369
+ "command": "uv",
370
+ "args": [
371
+ "--directory",
372
+ "/absolute/path/to/jolink-runtime",
373
+ "run",
374
+ "jolink-runtime"
375
+ ]
376
+ }
377
+ }
378
+ }
379
+ ```
380
+
381
+ ## Tests
382
+
383
+ The real subprocess acceptance test exercises the MCP stdio boundary:
384
+
385
+ ```bash
386
+ uv run pytest -q tests/e2e/test_stdio_mcp.py
387
+ ```
388
+
389
+ It performs:
390
+
391
+ ```text
392
+ initialize
393
+ -> tools/list
394
+ -> java_runtime(status)
395
+ -> close the stdio client
396
+ -> wait for the server process to exit
397
+ ```
398
+
399
+ The heavier real MCP/JVM suite is opt-in locally:
400
+
401
+ ```bash
402
+ JOLINK_RUN_MCP_JAVA_E2E=1 \
403
+ uv run pytest -q -m mcp_java_e2e tests/e2e/test_stdio_mcp_java.py
404
+ ```
405
+
406
+ The canonical CI environment for the heavier suite is:
407
+
408
+ ```text
409
+ Linux
410
+ Python 3.11
411
+ JDK 17
412
+ ```
413
+
414
+ ## Contracts
415
+
416
+ - MCP v0.1:
417
+ [`docs/mcp-contract-v0.1.md`](docs/mcp-contract-v0.1.md)
418
+ - Runtime lineage 2.4.0:
419
+ [`docs/runtime-lineage-contract-2.4.0.md`](docs/runtime-lineage-contract-2.4.0.md)