Skip to content

Navigation Menu

Sign in
Sign up

Improve concurrency handling, fix part of CI pipeline and more #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Aksem wants to merge 45 commits into main
base: main
Choose a base branch
Loading
from fix/lsp-request-concurrency-cap
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
30898f6
Fix ER lifecycle: force-kill orphans, concurrent shutdown, bound ER s...
Aksem Jul 21, 2026
20e48d1
Add OTLP endpoint validation, reachability probe, and export-log sile...
Aksem Jul 21, 2026
a599b21
Add automated release sweep across workspace packages (PRD-0006)
Aksem Jul 22, 2026
df006e1
Add list_envs/remove_envs actions and throttle run fan-out at depth 0...
Aksem Jul 23, 2026
91d8717
Split package release from workspace orchestration (ADR-0065)
Aksem Jul 23, 2026
c054de2
Sync python interpreters
Aksem Jul 23, 2026
a8cff6f
Add service config env-var overrides addressed by derived name (ADR-0...
Aksem Aug 1, 2026
0510524
Bridge check_toolchains drift into audit_code and fix precommit merge
Aksem Aug 1, 2026
29e58d6
Split file read from modify and add version-checked saves (ADR-0071)
Aksem Aug 3, 2026
e882c5b
Bound LSP request concurrency per backend (opt-in, unbounded by default)
Aksem Aug 4, 2026
983f26f
Apply formatter across the codebase
Aksem Aug 4, 2026
2c16b58
Make import sorting independent of the runner's working directory
Aksem Aug 4, 2026
224e648
Apply formatter to the remaining files
Aksem Aug 4, 2026
f5d6e13
Fix WM server layered-architecture violations found by audit_code
Aksem Aug 5, 2026
42f3330
Derive Python tool target-version from requires-python
Aksem Aug 6, 2026
fbdf049
Add in-session recovery from stale state (PRD-0008)
Aksem Aug 8, 2026
1deb3f3
Add code action resolve/apply and lint fix apply actions
Aksem Aug 8, 2026
889c0e9
Complete ADR-0080 cancellable in-flight runs, catch up recovery docs
Aksem Aug 8, 2026
9603bb9
Fix ruff position offsets and lint fixability, scope file listing to ...
Aksem Aug 9, 2026
7334b82
Lint codebase and fix part of problems
Aksem Aug 9, 2026
d616913
Extract finecode_knowledge as a standalone schema-free package
Aksem Aug 9, 2026
329e087
Add node.js 22 to devcontainer
Aksem Aug 10, 2026
e5705ea
Absolutize resource URIs in CLI payloads before they reach ERs
Aksem Aug 10, 2026
7bfeed8
Lint fixes
Aksem Aug 12, 2026
f937d87
Name the unknown project when ER dispatch fans out to a bad path
Aksem Aug 12, 2026
8e315cb
Lint fixes
Aksem Aug 13, 2026
f81aab6
Stream subprocess output line by line and fix a semaphore leak
Aksem Aug 13, 2026
587603a
Add a keep-alive shared WM server for the devcontainer
Aksem Aug 15, 2026
9f2b4ab
Add run_agent_task action with pi.dev and Claude Code backends
Aksem Aug 15, 2026
54fd453
Add get_git_status, get_git_diff and restore_git_files actions
Aksem Aug 15, 2026
50a01e0
Add , , to icommandrunner
Aksem Aug 16, 2026
d39179b
Add --results-file to run for per-run, unmerged results
Aksem Aug 16, 2026
3439ae8
Lint fixes in finecode_extension_runner
Aksem Aug 16, 2026
4962590
Let a handler ask the run's client a question (ADR-0082)
Aksem Aug 17, 2026
b3fdd60
Replace elicitation origin ContextVar with an explicit parameter
Aksem Aug 17, 2026
eab535f
Add create/rename/delete file operations to code actions (ADR-0083)
Aksem Aug 21, 2026
d8cc237
Validate CLI payload field names and types against action schemas
Aksem Aug 22, 2026
0dbb9e2
Catch up action reference docs and fix converter edge cases
Aksem Aug 23, 2026
c0f9fc4
Replace layered concurrency caps with a single process budget (ADR-0090)
Aksem Sep 3, 2026
3ba945a
Add the WM-side knowledge service and a lookup-literal lint rule (ADR...
Aksem Sep 5, 2026
1334b61
Capture stderr from the dedicated WM server startup
Aksem Sep 5, 2026
10a13ec
Make the dev_workspace venv validity check actually exercise imports
Aksem Sep 5, 2026
f1e8a1b
Revert "Make the dev_workspace venv validity check actually exercise ...
Aksem Sep 5, 2026
a7e490e
Add a real `finecode version` command; use it for venv validation
Aksem Sep 5, 2026
86e6b39
Wire root pyproject.toml up to already-landed extensions and contracts
Aksem Sep 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
29 changes: 29 additions & 0 deletions .devcontainer/README.md
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ This directory contains the DevContainer configuration for developing FineCode i
- `devcontainer.json`: Main configuration file for VS Code DevContainers.
- `docker-compose.devcontainer.yml`: Compose service definition for the main workspace container.

## Node.js

Node.js 22 is a runtime dependency of `setup_system` handlers that install
npm-distributed tools (e.g. pi coding agent, which rejects Node older than
22.19.0). The base image already ships `nvm` itself (no Node version installed), so
`setup-node.sh` installs Node 22 through that pre-existing `nvm` in
`postCreateCommand`. Because Node is installed via nvm under
the `vscode` user, `npm install -g` works without sudo.

## Local observability stack (opt-in)

The devcontainer includes the repository-level `docker-compose.otel.yml`, but all of
Expand All @@ -24,6 +33,26 @@ WAL events are recorded on disk regardless of whether the stack is running, so y
bring it up later and ingest the history retroactively. See
[ADR-0052](../../finecode_internal_docs/adr/0052-observability-stack-opt-in-via-compose-profile.md).

## Persistent WM server

`FINECODE_WM_AUTOSTART=1` is set in `.env.example`, so `postStartCommand` runs
`start-wm-server --detach --keep-alive` on every container start, via
`start-wm-server.sh`. The workspace stays warm across commands instead of rebuilding
its config and runners each time. Comment the variable out to go back to a server
per client; the script is also a no-op when the `dev_workspace` venv does not exist
yet.

Changing the variable needs the container **recreated**, not reopened — Compose
resolves `.env` into a container's environment only when that container is created
(the same caveat as `FINECODE_OTLP_ENDPOINT` above; see [Developing
FineCode](../docs/guides/developing-finecode.md#local-observability-stack) for the
rebuild commands).

What comes with a keep-alive server — resident extension runners, a fixed log level,
and why a server started lazily after a crash is not one — is described under
[`start-wm-server`](../docs/cli.md#start-wm-server). Re-run
`sh .devcontainer/start-wm-server.sh` to get the persistent one back.

## Optional private internal docs mount

The workspace service supports an optional bind mount for private internal docs.
Expand Down
23 changes: 22 additions & 1 deletion .devcontainer/devcontainer.json
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,28 @@
],
"service": "workspace",
"shutdownAction": "stopCompose",
"postCreateCommand": "sh .devcontainer/post-create-dev-workspace.sh && sh .devcontainer/setup-shell.sh",
// Node.js is required by the pi coding agent, which setup_system installs via
// npm. Pi's preflight rejects anything older than 22.19.0, so Debian's own
// nodejs package is not an option, and so is the node devcontainer feature: the
// base image already ships nvm itself, and running the feature on top of that
// hits a BuildKit bug writing into nvm's cache dir. setup-node.sh installs Node
// via that pre-existing nvm instead, at container-create time. See
// setup-node.sh for the full explanation.
// remoteEnv (not containerEnv): containerEnv is baked into the compose
// service's own environment, including its `sleep infinity` entrypoint process —
// and "${containerEnv:PATH}" does not self-resolve there, so it overwrote PATH
// with the literal unexpanded string and broke everything, including `sleep`.
// remoteEnv only applies to devcontainer-managed processes (postCreateCommand,
// terminals), where the substitution does work.
"remoteEnv": {
"NVM_DIR": "/usr/local/share/nvm",
"PATH": "/usr/local/share/nvm/current/bin:${containerEnv:PATH}"
},
"postCreateCommand": "sh .devcontainer/setup-node.sh && sh .devcontainer/post-create-dev-workspace.sh && sh .devcontainer/setup-shell.sh",
// postStart, not postCreate: a stopped container loses its WM server, so this
// has to run again on every start. The venv it needs may not exist yet on the
// first create; the script exits cleanly in that case.
"postStartCommand": "sh .devcontainer/start-wm-server.sh",
"customizations": {
"vscode": {
"extensions": [
Expand Down
3 changes: 3 additions & 0 deletions .devcontainer/docker-compose.devcontainer.yml
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ services:
# both COMPOSE_PROFILES=otel and FINECODE_OTLP_ENDPOINT in .env — the ready
# collector URL is provided there, so developers never compose it themselves.
- FINECODE_OTLP_ENDPOINT=${FINECODE_OTLP_ENDPOINT:-}
# Read only by .devcontainer/start-wm-server.sh; passed through here so the
# value set in .env is visible to processes inside the container.
- FINECODE_WM_AUTOSTART=${FINECODE_WM_AUTOSTART:-}
# uv's default cache (~/.cache/uv) lives on the container's overlay
# filesystem, a different device than this bind-mounted workspace. uv
# dedupes installs by hardlinking from its cache into each venv, but
Expand Down
24 changes: 24 additions & 0 deletions .devcontainer/setup-node.sh
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/sh
# Installs Node via the nvm already baked into the base image.
#
# We do NOT use the ghcr.io/devcontainers/features/node feature for this:
# the base image already ships nvm itself (no Node version installed yet)
# at /usr/local/share/nvm, owned by vscode:nvm. Running the node feature on
# top of that hits its "NVM already installed" code path, which skips the
# ownership fixup it only does for a freshly created nvm dir and calls
# `nvm install` directly. That specific command works fine under a normal
# `docker run`, but fails with "Permission denied" writing into
# /usr/local/share/nvm/.cache when run inside a BuildKit RUN layer, which
# does not reproduce ownership from the base image's read-only layer
# correctly on copy-up. Running nvm install here, in postCreateCommand
# (a normal container process, not a build layer) sidesteps the bug.
set -eu

export NVM_DIR="/usr/local/share/nvm"
export NVM_SYMLINK_CURRENT=true
# shellcheck source=/dev/null
. "$NVM_DIR/nvm.sh"

umask 0002
nvm install 22
nvm alias default 22
29 changes: 29 additions & 0 deletions .devcontainer/start-wm-server.sh
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/sh
# Start a persistent shared FineCode WM server at container start, so the
# workspace stays warm for the life of the container. What that costs is
# documented in docs/cli.md, "Autostarting a persistent server".
#
# FineCode itself never reads FINECODE_WM_AUTOSTART — this script is its only
# consumer, and it turns it into an explicit `--keep-alive` on the server it
# starts, because keep-alive must never be ambient.
set -eu

if [ -z "${FINECODE_WM_AUTOSTART:-}" ] || [ "${FINECODE_WM_AUTOSTART}" = "0" ]; then
exit 0
fi

VENV_PYTHON=".venvs/dev_workspace/bin/python"
if [ ! -x "$VENV_PYTHON" ]; then
echo "FineCode WM autostart: $VENV_PYTHON not found, skipping." >&2
exit 0
fi

# Never fatal: the workspace is fully usable without it, because every client
# starts a server on demand anyway. Failing container start over a warm cache
# would be a worse outcome than the cold start it is trying to avoid.
if "$VENV_PYTHON" -m finecode start-wm-server --detach --keep-alive; then
echo "FineCode WM autostart: shared server running."
else
echo "FineCode WM autostart: no shared server reachable yet; it may still be" \
"starting, and clients attach to it when it is." >&2
fi
6 changes: 6 additions & 0 deletions .env.example
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,9 @@ DEVCONTAINER_INTERNAL_DOCS_PATH=
# use it to start/stop the collector while the endpoint stays armed.
# COMPOSE_PROFILES=otel
# FINECODE_OTLP_ENDPOINT=http://otel-lgtm:4317

# Start a persistent shared WM server when the devcontainer starts, so config and
# extension runners survive between commands. Comment out to get a server per
# client instead. What comes with it: docs/cli.md, "Autostarting a persistent
# server".
FINECODE_WM_AUTOSTART=1
5 changes: 2 additions & 3 deletions .github/workflows/ci-cd.yml
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,13 @@ jobs:
if: ${{ !cancelled() && steps.install.outcome == 'success' }}
run: |
source .venvs/dev_workspace/${{ matrix.venv_bin }}/activate
# TODO: test with all supported python versions
python -m finecode run --log-level="$FINECODE_LOG_LEVEL" run_tests
shell: bash

- name: Publish to TestPyPI and verify
if: runner.os == 'Linux' && github.event_name == 'workflow_dispatch' && inputs.publish_testpypi
env:
FINECODE_CONFIG_PUBLISH_AND_VERIFY_ARTIFACT__INIT_REPOSITORY_PROVIDER__REPOSITORIES: '[{"name": "testpypi", "url": "https://test.pypi.org/"}]'
FINECODE_CONFIG_PUBLISH_AND_VERIFY_ARTIFACT__INIT_REPOSITORY_PROVIDER__REPOSITORIES: '[{"name": "testpypi", "index_url": "https://test.pypi.org/simple/", "upload_url": "https://test.pypi.org/legacy/"}]'
FINECODE_CONFIG_PUBLISH_AND_VERIFY_ARTIFACT__INIT_REPOSITORY_PROVIDER__CREDENTIALS_BY_REPOSITORY: '{"testpypi": {"username": "${{ secrets.TESTPYPI_USERNAME }}", "password": "${{ secrets.TESTPYPI_PASSWORD }}"}}'
run: |
source .venvs/dev_workspace/${{ matrix.venv_bin }}/activate
Expand All @@ -154,7 +153,7 @@ jobs:
- name: Publish to PyPI and verify
if: runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/')
env:
FINECODE_CONFIG_PUBLISH_AND_VERIFY_ARTIFACT__INIT_REPOSITORY_PROVIDER__REPOSITORIES: '[{"name": "pypi", "url": "https://pypi.org/"}]'
FINECODE_CONFIG_PUBLISH_AND_VERIFY_ARTIFACT__INIT_REPOSITORY_PROVIDER__REPOSITORIES: '[{"name": "pypi", "index_url": "https://pypi.org/simple/", "upload_url": "https://upload.pypi.org/legacy/"}]'
FINECODE_CONFIG_PUBLISH_AND_VERIFY_ARTIFACT__INIT_REPOSITORY_PROVIDER__CREDENTIALS_BY_REPOSITORY: '{"pypi": {"username": "${{ secrets.PYPI_USERNAME }}", "password": "${{ secrets.PYPI_PASSWORD }}"}}'
run: |
# TODO: make sure git tag exists (for manual trigger)
Expand Down
Loading
Loading

AltStyle によって変換されたページ (->オリジナル) /