Skip to content

Commit 02b96e5

Browse files
feat(tests): update docs
Statistics: 30 files changed, 534 insertions, 86 deletions Summary: - Dirs: src=10, plugins=8, packages=3, tests=3, .nlp2dsl=2, .=2 - Exts: .py=16, .ts=6, .json=3, .less=2, .yaml=2, .md=1 - A/M/D: 1/29/0 - Added: plugins/koru-autopilot-shared/src/cursor-composer-paste.ts - Symbols: _vsix_unpack_result, result, _koru_subprocess_timeout, manual_vsix_unpack, test_antigravity_focus_open_prefers_side_panel_when_miscategorised Added files: - plugins/koru-autopilot-shared/src/cursor-composer-paste.ts (+31/-0) Modified files: - .koru/project.json (+1/-1) - .nlp2dsl/environment.doql.less (+3/-3) - .nlp2dsl/registry/environment.doql.less (+3/-3) - .planfile/sprints/current.yaml (+12/-4) - README.md (+3/-3) - packages/coru/src/coru/cli.py (+79/-12) - packages/coru/src/coru/repair/pipeline.py (+24/-1) - packages/coru/tests/test_coru_cli.py (+40/-0) - plugins/koru-autopilot-antigravity/src/extension.ts (+2/-2) - plugins/koru-autopilot-cursor/package.json (+2/-2) - plugins/koru-autopilot-cursor/src/bridge-submit-focus.test.ts (+41/-0) - plugins/koru-autopilot-shared/src/bridge-fastpath.ts (+60/-14) - plugins/koru-autopilot-shared/src/bridge-helpers.ts (+1/-0) - plugins/koru-autopilot-shared/src/bridge-paste.ts (+44/-0) - plugins/koru-autopilot-windsurf/package.json (+2/-2) - src/koru/autonomous_daemon.py (+5/-5) - src/koru/autonomous_readiness.py (+21/-14) - src/koru/autonomous_runtime.py (+1/-3) - src/koru/autopilot/install_checks.py (+28/-0) - src/koru/environment_profile.py (+6/-0) - ... and 9 more Implementation notes (heuristics): - Type inferred from file paths + diff keywords + add/delete ratio - Scope prefers 'goal' when goal/* is touched; otherwise based on top-level dirs - For <=6 files: generate short per-file notes from added lines (defs/classes/click options/headings) - A/M/D derived from git name-status; per-file +X/-X from git numstat Co-authored-by: Koru Agent <agent@coru.dev>
1 parent 82eb3ff commit 02b96e5

35 files changed

Lines changed: 564 additions & 93 deletions

‎.koru/project.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
"runtime_dir": ".planfile/.koru",
55
"schema": "koru.project/v1",
66
"source": "auto",
7-
"updated_at": "2026-06-07T09:25:06.452428+00:00"
7+
"updated_at": "2026-06-07T10:25:44.450280+00:00"
88
}

‎.nlp2dsl/environment.doql.less‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// DOQL system map — koru
22
// role: LLM-generated schema (SystemMapIR → DOQL)
33
// format: nlp2dsl.system_map.v1
4-
// generated: 2026-06-07T09:25:09.490823+00:00
4+
// generated: 2026-06-07T10:25:47.474255+00:00
55

66
environment[name="koru"] {
7-
generated_at: "2026-06-07T09:25:07.323434+00:00";
7+
generated_at: "2026-06-07T10:25:45.322998+00:00";
88
}
99

1010
data {
@@ -199,7 +199,7 @@ desktop {
199199
status: "available";
200200
compositor: "wayland";
201201
display_server: "wayland";
202-
probed_at: "2026-06-07T09:25:07.333387+00:00";
202+
probed_at: "2026-06-07T10:25:45.333099+00:00";
203203
tools_used: ide-os-injector,xdotool,xrandr;
204204
canvas_width: 8416;
205205
canvas_height: 7680;

‎.nlp2dsl/registry/environment.doql.less‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// DOQL system map — koru
22
// role: LLM-generated schema (SystemMapIR → DOQL)
33
// format: nlp2dsl.system_map.v1
4-
// generated: 2026-06-07T09:25:09.490823+00:00
4+
// generated: 2026-06-07T10:25:47.474255+00:00
55

66
environment[name="koru"] {
7-
generated_at: "2026-06-07T09:25:07.323434+00:00";
7+
generated_at: "2026-06-07T10:25:45.322998+00:00";
88
}
99

1010
data {
@@ -199,7 +199,7 @@ desktop {
199199
status: "available";
200200
compositor: "wayland";
201201
display_server: "wayland";
202-
probed_at: "2026-06-07T09:25:07.333387+00:00";
202+
probed_at: "2026-06-07T10:25:45.333099+00:00";
203203
tools_used: ide-os-injector,xdotool,xrandr;
204204
canvas_width: 8416;
205205
canvas_height: 7680;

‎.planfile/sprints/current.yaml‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26509,7 +26509,7 @@ sprint:
2650926509
id: STARTER-541
2651026510
name: '[AUTO-DIAG] wup-koru-shell needs attention in cycle 0. queue_status=wup_failure.
2651126511
Check: WUP service=koru-shell stage=...'
26512-
status: open
26512+
status: done
2651326513
priority: high
2651426514
sprint: current
2651526515
source:
@@ -26537,9 +26537,12 @@ sprint:
2653726537
mode: interactive
2653826538
execution:
2653926539
queue: default
26540-
state: ready
26540+
state: done
2654126541
attempt: 0
2654226542
max_attempts: 1
26543+
finished_at: '2026-06-07T09:48:43.873402+00:00'
26544+
last_error: null
26545+
lease_expires_at: null
2654326546
inputs:
2654426547
prompt: '[AUTO-DIAG] wup-koru-shell needs attention in cycle 0. queue_status=wup_failure.
2654526548
Check: WUP service=koru-shell stage=quick message=TestQL command failed
@@ -26552,7 +26555,8 @@ sprint:
2655226555
api_timeout_seconds: 30.0
2655326556
outputs:
2655426557
artifacts: []
26555-
notes: []
26558+
notes:
26559+
- 'Auto-resolved by Koru: WUP no longer reports wup-koru-shell as failing.'
2655626560
sync: {}
2655726561
history:
2655826562
- timestamp: '2026-06-07T09:37:57.214100+00:00'
@@ -26563,5 +26567,9 @@ sprint:
2656326567
track=/home/tom/github/semcod/koru/.wup/tracks/1780825063_koru-shell_quick.json.
2656426568
Investigate and fix regression, stale quality artifact, or broken diagnostic
2656526569
gate.'
26570+
- timestamp: '2026-06-07T09:48:43.873402+00:00'
26571+
action: auto_resolved
26572+
source: koru wup
26573+
message: 'Auto-resolved by Koru: WUP no longer reports wup-koru-shell as failing.'
2656626574
created_at: '2026-06-07T09:37:57.214100+00:00'
26567-
updated_at: '2026-06-07T09:37:57.214100+00:00'
26575+
updated_at: '2026-06-07T09:48:43.873402+00:00'

‎CHANGELOG.md‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6666
guides; top-level [`README.md`](./README.md) Documentation section links into
6767
`docs/*` by topic.
6868

69+
## [0.1.317] - 2026-06-07
70+
71+
### Docs
72+
- Update README.md
73+
74+
### Test
75+
- Update tests/test_command_picker.py
76+
- Update tests/test_environment_profile.py
77+
- Update tests/test_ide_adapters.py
78+
79+
### Other
80+
- Update .koru/project.json
81+
- Update .nlp2dsl/environment.doql.less
82+
- Update .nlp2dsl/registry/environment.doql.less
83+
- Update .planfile/sprints/current.yaml
84+
- Update packages/coru/src/coru/cli.py
85+
- Update packages/coru/src/coru/repair/pipeline.py
86+
- Update packages/coru/tests/test_coru_cli.py
87+
- Update plugins/koru-autopilot-antigravity/src/extension.ts
88+
- Update plugins/koru-autopilot-cursor/package.json
89+
- Update plugins/koru-autopilot-cursor/src/bridge-submit-focus.test.ts
90+
- ... and 6 more files
91+
6992
## [0.1.316] - 2026-06-07
7093

7194
### Docs

‎README.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77

88
## AI Cost Tracking
99

10-
![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.1.316-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
11-
![AI Cost](https://img.shields.io/badge/AI%20Cost-$33.84-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-142.5h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)
10+
![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.1.317-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
11+
![AI Cost](https://img.shields.io/badge/AI%20Cost-$32.76-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-142.5h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)
1212

13-
- 🤖 **LLM usage:** $33.8384 (421 commits)
13+
- 🤖 **LLM usage:** $32.7624 (422 commits)
1414
- 👤 **Human dev:** ~$14250 (142.5h @ $100/h, 30min dedup)
1515

1616
Generated on 2026-06-07 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)

‎VERSION‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.1.316
1+
0.1.317

‎package-lock.json‎

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "koru-autopilot-plugins-workspace",
3-
"version": "0.1.316",
3+
"version": "0.1.317",
44
"private": true,
55
"description": "Monorepo root for all koru autopilot IDE plugins. Each IDE has its own VSIX so a regression in one cannot leak into another. Shared code (protocol, socket, host-click-submit) lives in plugins/koru-autopilot-shared and is copied into per-IDE plugins at prebuild time.",
66
"workspaces": [

‎packages/coru/src/coru/cli.py‎

Lines changed: 79 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,20 @@
2222

2323
_LANE_ENV_KEYS = ("KORU_AUTOPILOT_IDE", "KORU_AUTOPILOT_INSTANCE", "KORU_AUTOPILOT_SOCKET")
2424
_ORIGINAL_SUBPROCESS_RUN = subprocess.run
25+
_LANE_ENV_PAYLOAD_TIMEOUT_S = float(os.environ.get("CORU_LANE_ENV_PAYLOAD_TIMEOUT_S", "5"))
26+
_KORU_SUBPROCESS_TIMEOUT_S = float(os.environ.get("CORU_KORU_SUBPROCESS_TIMEOUT_S", "20"))
27+
28+
29+
def _koru_subprocess_timeout(koru_args: Sequence[str]) -> float | None:
30+
"""Return timeout for koru subprocess calls; ``None`` for long-running commands."""
31+
if not koru_args:
32+
return _KORU_SUBPROCESS_TIMEOUT_S
33+
head = str(koru_args[0]).lower()
34+
if head in {"auto", "autonomous", "serve"}:
35+
return None
36+
if head == "autopilot" and len(koru_args) > 1 and str(koru_args[1]).lower() == "daemon":
37+
return None
38+
return _KORU_SUBPROCESS_TIMEOUT_S
2539

2640

2741

@@ -414,9 +428,25 @@ def _extract_global_flags(argv: Sequence[str]) -> tuple[list[str], bool, bool, s
414428
return rest, verbose, show_version, log_format, require_plugin
415429

416430

417-
def _run(command: Sequence[str], *, passthrough: bool = True) -> int:
431+
def _run(
432+
command: Sequence[str],
433+
*,
434+
passthrough: bool = True,
435+
timeout: float | None = None,
436+
) -> int:
418437
try:
419-
proc = subprocess.run(list(command), check=False)
438+
kwargs: dict[str, Any] = {"check": False}
439+
if timeout is not None:
440+
kwargs["timeout"] = timeout
441+
proc = subprocess.run(list(command), **kwargs)
442+
except subprocess.TimeoutExpired:
443+
preview = " ".join(str(part) for part in command[:4])
444+
limit = timeout if timeout is not None else 0.0
445+
print(
446+
f"[coru] command timed out after {limit:.0f}s: {preview}",
447+
file=sys.stderr,
448+
)
449+
return 124
420450
except KeyboardInterrupt:
421451
return 130
422452
if passthrough:
@@ -1224,13 +1254,19 @@ def _bind_lane_session(ide: str, instance: str):
12241254
os.environ.pop(key, None)
12251255

12261256

1227-
def _run_with_lane_environment(command: Sequence[str], *, ide: str, instance: str) -> int:
1257+
def _run_with_lane_environment(
1258+
command: Sequence[str],
1259+
*,
1260+
ide: str,
1261+
instance: str,
1262+
timeout: float | None = _KORU_SUBPROCESS_TIMEOUT_S,
1263+
) -> int:
12281264
previous = {key: os.environ[key] for key in _LANE_ENV_KEYS if key in os.environ}
12291265
try:
12301266
os.environ["KORU_AUTOPILOT_IDE"] = ide
12311267
os.environ["KORU_AUTOPILOT_INSTANCE"] = instance
12321268
os.environ.pop("KORU_AUTOPILOT_SOCKET", None)
1233-
return _run(command)
1269+
return _run(command, timeout=timeout)
12341270
finally:
12351271
for key in _LANE_ENV_KEYS:
12361272
if key in previous:
@@ -1268,9 +1304,16 @@ def _koru_autopilot_env_payload(ide: str, instance: str) -> dict[str, Any] | Non
12681304
text=True,
12691305
check=False,
12701306
env=_lane_subprocess_env(ide, instance),
1271-
timeout=5.0,
1307+
timeout=_LANE_ENV_PAYLOAD_TIMEOUT_S,
12721308
close_fds=True,
12731309
)
1310+
except subprocess.TimeoutExpired:
1311+
print(
1312+
f"[coru] koru autopilot env timed out after {_LANE_ENV_PAYLOAD_TIMEOUT_S:.0f}s "
1313+
f"(ide={ide} instance={instance})",
1314+
file=sys.stderr,
1315+
)
1316+
return None
12741317
except Exception:
12751318
return None
12761319
if proc.returncode != 0:
@@ -1284,10 +1327,18 @@ def _koru_autopilot_env_payload(ide: str, instance: str) -> dict[str, Any] | Non
12841327
return payload
12851328

12861329

1287-
def _run_with_resolved_lane_env(command: Sequence[str], *, ide: str, instance: str) -> int:
1330+
def _run_with_resolved_lane_env(
1331+
command: Sequence[str],
1332+
*,
1333+
ide: str,
1334+
instance: str,
1335+
timeout: float | None = _KORU_SUBPROCESS_TIMEOUT_S,
1336+
) -> int:
12881337
payload = _koru_autopilot_env_payload(ide, instance)
12891338
if not payload:
1290-
return _run_with_lane_environment(command, ide=ide, instance=instance)
1339+
if timeout is None:
1340+
return _run(list(command))
1341+
return _run_with_lane_environment(command, ide=ide, instance=instance, timeout=timeout)
12911342

12921343
lane_keys = ("KORU_AUTOPILOT_IDE", "KORU_AUTOPILOT_INSTANCE", "KORU_AUTOPILOT_SOCKET")
12931344
previous = {key: os.environ[key] for key in lane_keys if key in os.environ}
@@ -1299,7 +1350,7 @@ def _run_with_resolved_lane_env(command: Sequence[str], *, ide: str, instance: s
12991350
os.environ["KORU_AUTOPILOT_INSTANCE"] = str(payload["instance"])
13001351
if payload.get("ide"):
13011352
os.environ["KORU_AUTOPILOT_IDE"] = str(payload["ide"])
1302-
return _run(command)
1353+
return _run(command, timeout=timeout)
13031354
finally:
13041355
for key in lane_keys:
13051356
if key in previous:
@@ -1313,7 +1364,12 @@ def _run_koru_lane(ide: str, instance: str, koru_args: Sequence[str]) -> int:
13131364
if koru_exec is None:
13141365
print("error: koru is not available; run 'coru ensure --install'", file=sys.stderr)
13151366
return 127
1316-
return _run_with_resolved_lane_env([*koru_exec, *koru_args], ide=ide, instance=instance)
1367+
return _run_with_resolved_lane_env(
1368+
[*koru_exec, *koru_args],
1369+
ide=ide,
1370+
instance=instance,
1371+
timeout=_koru_subprocess_timeout(koru_args),
1372+
)
13171373

13181374

13191375
def _koruenv_run_fallback(ide: str, instance: str, run_payload: Sequence[str]) -> int:
@@ -1384,7 +1440,9 @@ def _lane_status_payload(
13841440
if resolved.get("socket"):
13851441
env["KORU_AUTOPILOT_SOCKET"] = str(resolved["socket"])
13861442
try:
1387-
proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True, check=False, env=env, timeout=5.0, close_fds=True)
1443+
proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True, check=False, env=env, timeout=_LANE_ENV_PAYLOAD_TIMEOUT_S, close_fds=True)
1444+
except subprocess.TimeoutExpired:
1445+
return None
13881446
except Exception:
13891447
return None
13901448
if proc.returncode != 0:
@@ -1406,7 +1464,9 @@ def _fetch_manage_report(ide: str, instance: str) -> dict[str, Any] | None:
14061464
cmd = [*koru_exec, "autopilot", "manage", "--ide", ide, "--format", "json"]
14071465
env = _lane_subprocess_env(ide, instance)
14081466
try:
1409-
proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True, check=False, env=env, timeout=5.0, close_fds=True)
1467+
proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True, check=False, env=env, timeout=_LANE_ENV_PAYLOAD_TIMEOUT_S, close_fds=True)
1468+
except subprocess.TimeoutExpired:
1469+
return None
14101470
except Exception:
14111471
return None
14121472
if proc.returncode != 0 and not proc.stdout.strip():
@@ -2660,7 +2720,14 @@ def _lane_manage_fix(ide: str, instance: str) -> int:
26602720
if koru_exec is None:
26612721
print("error: koru is not available; run 'coru ensure --install'", file=sys.stderr)
26622722
return 127
2663-
return _run_koru_lane(ide, instance, ["autopilot", "manage", "--ide", ide, "--fix"])
2723+
rc = _run_koru_lane(ide, instance, ["autopilot", "manage", "--ide", ide, "--fix"])
2724+
if rc != 0:
2725+
_run_koru_lane(
2726+
ide,
2727+
instance,
2728+
["ide", "doctor", "--ide", ide, "--fix", "--gc-sockets"],
2729+
)
2730+
return rc
26642731

26652732

26662733
def _lane_daemon_foreground(ide: str, instance: str) -> int:

0 commit comments

Comments
 (0)