Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
5c54557
fix: preserve compiler-safe agent flow
DorianDevp Jul 17, 2026
51b9a26
docs: define compiler-safe goal flow
DorianDevp Jul 17, 2026
a6b1ce5
feat: add product contracts, Flow explorer, widgets and surfaces
DorianDevp Jul 19, 2026
00db102
chore: ignore log files
DorianDevp Jul 20, 2026
f6229e5
fix: stop cursor teleport and settle render/flow/creation bugs
DorianDevp Jul 20, 2026
1849595
fix: report and select the model each turn actually uses
DorianDevp Jul 20, 2026
cf77935
feat: add marker-driven project adapters
DorianDevp Jul 20, 2026
6293e90
feat: add session skill picker
DorianDevp Jul 20, 2026
62fb3a6
docs: define project intelligence and skills
DorianDevp Jul 20, 2026
14d9b2e
feat: add OpenAI-compatible backend
DorianDevp Jul 20, 2026
52574d8
test: add project intelligence A/B benchmark
DorianDevp Jul 20, 2026
6ce16b2
docs: report real-model benchmark
DorianDevp Jul 20, 2026
8a48f3b
fix: use typed patches for local models
DorianDevp Jul 20, 2026
152f7db
docs: compare Qwen 3.6 and GPT-5.6
DorianDevp Jul 20, 2026
fcd4b65
feat: add stateful local model runtime
DorianDevp Jul 20, 2026
389effe
test: benchmark bounded local tools
DorianDevp Jul 20, 2026
a099aa7
fix: restore headless smoke coverage
DorianDevp Jul 20, 2026
c8fd654
docs: specify Angular reactivity benchmark
DorianDevp Jul 20, 2026
241a0ed
docs: define local backend runtime
DorianDevp Jul 20, 2026
561dcc7
fix: repair unparseable model output instead of erroring
DorianDevp Jul 21, 2026
bcfa38d
fix: harden the OpenAI-compatible backend failure paths
DorianDevp Jul 21, 2026
e25e44a
fix: restore skills picker cancel bindings
DorianDevp Jul 21, 2026
7dfcbba
fix: name the current phase's model in the prompt title
DorianDevp Jul 21, 2026
2533b22
fix: cap Dockerfile reads in the deno adapter
DorianDevp Jul 21, 2026
b1402fc
docs: document backend and discovery model commands
DorianDevp Jul 21, 2026
a598ea2
test: cover review navigation and details bindings
DorianDevp Jul 21, 2026
ad2d047
docs: move the VS Code client design into doc
DorianDevp Jul 21, 2026
243c2a6
chore: clear stylua and selene debt
DorianDevp Jul 21, 2026
e209662
docs: record recent fixes in the changelog
DorianDevp Jul 21, 2026
d697298
fix: settle local backend cancellation, eviction and model reporting
DorianDevp Jul 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/target
/doc/tags
*.log
loopbioticd-v*.tar.gz
loopbioticd-v*.tar.gz.sha256
.luarc.local.json
130 changes: 130 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Repository instructions for agents

## Required product contracts

Before changing this repository, read these three files in full:

1. [`doc/ui.md`](doc/ui.md) — visible surfaces, hierarchy, layout, responsive
behavior, and theming.
2. [`doc/interactions.md`](doc/interactions.md) — state transitions, focus,
navigation, actions, review safety, and recovery.
3. [`doc/feeling.md`](doc/feeling.md) — product character, voice, pacing, trust,
and the intended experience.

They are separate views of one product and are mandatory context, including for
backend or protocol work that can surface new state, progress, errors, cards, or
actions in Neovim.

## Non-negotiable UI model

Loopbiotic has exactly two user-facing product Windows:

- **PromptWindow** owns user intent, the visible turn mode, prompt text, and visible attached
context.
- **AgentWindow** owns all agent progress, responses, and Widgets.

Use the vocabulary from `doc/ui.md`: a technical Neovim float or buffer may be a
Frame; content inside a Window may be a View or Widget. Frames, Views, pickers,
progress states, file choosers, and Widgets do not create additional product
Windows.

Do not introduce a third product Window. AgentWindow does not render general
next-intent actions. Its deliberate exception is patch review: the agent comment
and `Accept` / `Reject` remain the explicit source-mutation gate. `Accept` may
continue an already authorized Goal; `Reject` pauses it and opens PromptWindow
without running the model. A Widget may change local representation or pending
prompt context, but only an explicit PromptWindow submission may introduce new
intent.

There is no automatic intent-routing mode. The mode visible in PromptWindow is
the user-selected response contract: `fix`/`propose` require Patch,
`explain`/`review` require Finding, and `investigate` requires Hypothesis. Never
infer or replace the selected mode from prompt wording. Every patch remains inert
behind `Accept` / `Reject`.

Every PromptWindow, including Reply, must visibly own one valid turn mode.
`keymaps.modes` opens the local picker; submit snapshots and transmits that exact
mode through both `session/start` and `session/reply`. Never add a mode control
to AgentWindow or contact the backend when the picker selection changes.

## Living-contract rule

The three product documents must self-heal with every change.

- At task start, compare the request and current implementation with all three
contracts. Identify which statements and invariants are affected.
- During implementation, treat explicit user direction as the intended delta and
preserve unrelated invariants. Do not redesign adjacent surfaces implicitly.
- Before finishing, reconcile all three documents against the resulting behavior,
even when only one appears directly affected.
- Update affected text in the same patch as code and tests. Rewrite current-state
sections in place; do not add design changelog entries.
- Normative sections describe the approved product. Current contradictions are
allowed only when they are explicit under `Known implementation gaps` in the
relevant contract. Update or remove those gaps as implementation moves.
- Remove obsolete descriptions. Do not present a known gap as shipped canonical
behavior and do not leave implemented behavior undocumented.
- When runtime code and a descriptive statement disagree, code is evidence of
current behavior, not automatic authority for product intent. Resolve the
conflict using the user's request, protected invariants, tests, and surrounding
design; then repair every stale side.
- A documentation-only task still requires checking cross-document consistency.
A backend-only task may leave the files unchanged only after verifying that no
user-visible state, wording, timing, action, or trust boundary changed.

## Change vocabulary

Use these scope words consistently in plans and handoffs:

- **Tune:** preserve the concept and adjust a property.
- **Rebuild:** the named surface or flow may change structure.
- **Unify:** apply an existing project pattern to another location.
- **Explore:** compare alternatives; do not silently make one the contract.
- **Local:** change only the named component or state.
- **Systemic:** change the shared rule and every affected consumer.

For product-facing changes, be able to state:

```text
Scope:
Intent:
Preserve:
UI delta:
Interaction delta:
Feeling delta:
States checked:
Acceptance condition:
```

This is a reasoning checklist, not a required user-facing form.

## Product change definition of done

A product-facing change is complete only when:

- implementation and tests match the normative contract, or every remaining
mismatch is explicitly and accurately tracked as a known implementation gap;
- loading, success, empty, error, hidden, disabled, and narrow-layout states were
considered where relevant;
- visible shortcut labels match actual bindings;
- focus, navigation, cancellation, retry, and source-mutation boundaries remain
explicit;
- every agent state reuses AgentWindow; new intent originates in PromptWindow,
while `Accept` only continues an already authorized Goal;
- AgentWindow tab ownership, visible/wrapped state, off-tab behavior, and `pr`
restoration were preserved or deliberately updated;
- Widget payloads are registered, versioned, schema-validated, provenance-aware,
and limited to allowlisted local intents;
- Widget-selected context is visible and removable before prompt submission;
- patch review keeps the agent comment, diff, and explicit `Accept` / `Reject`;
rejection performs no model turn and transfers focus through PromptWindow back
to AgentWindow when the prompt is closed;
- new-file and directory proposals are workspace-bound, collision-checked, and
reviewed through Netrw when available without treating it as a product Window;
- new runtime copy matches the voice in `doc/feeling.md`;
- documentation describes the resulting current state rather than the edit that
produced it.

Keep implementation pointers in the contracts at file/module granularity. Avoid
line-number references and duplicated internal details that cannot be maintained
reliably.
59 changes: 54 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,28 @@ The project follows [Semantic Versioning](https://semver.org/).

### Fixed

- Model output that is not parseable as a Loopbiotic op (for example JSON with
an unescaped quote inside a string value) is now repaired through the normal
retry loop: the model is asked to re-emit one strict JSON object before the
error card is shown. The error card with the raw output still appears after
three failed attempts.
- The skills picker no longer errors on open; `q`/`<Esc>` cancel it and restore
the previous selection as the footer promises.
- The PromptWindow title now names the model of the phase the current mode
runs: discovery modes show the discovery model instead of the patch model,
and an explicit model change updates the title immediately.
- The OpenAI-compatible backend now runs each turn under the shared
`LOOPBIOTIC_TURN_TIMEOUT_SECS` deadline, no longer leaks cancellation state
when a speculative turn is aborted, caps workspace file reads, and surfaces
the raw model output when a local model answers in prose.
- Empty or malformed model-preference state now supplies both patch and
discovery model maps instead of crashing backend setup.
- OpenAI-compatible local models now return the same typed patch hunks as
Codex. Rust renders and validates the unified diff, so weak models no longer
have to reproduce fragile diff syntax themselves.
- The Codex model picker now reads the authenticated app-server `model/list`
catalog and its default model. A discovery-only model is no longer presented
as the entire set of selectable patch models.
- Navigating to a card or draft no longer throws "Cursor position outside
buffer" when the target line does not exist yet — for example a patch hunk
that appends to the end of a short file, or an agent-supplied location past
Expand Down Expand Up @@ -49,10 +71,13 @@ The project follows [Semantic Versioning](https://semver.org/).

### Changed

- Auto sessions are conversational-first. Their first response and normal
replies cannot return patches or completion summaries; persistent goal
execution starts only from the explicit `Goal` action. Sending a message
pauses an active goal and answers conversationally.
- The real-model A/B runner flushes each result to JSONL immediately, preserving
completed samples when a long local benchmark is interrupted.
- Every Prompt and Reply carries a visible user-selected mode. Automatic intent
routing was removed: fix/propose require Patch, explain/review require Finding,
and investigate requires Hypothesis. Slash-prefixed text no longer overrides
that visible mode. Persistent multi-step goal execution remains explicit, and
every patch stays behind local Accept/Reject review.
- Goal work is limited to one file, one coherent hunk, and 32 changed lines
per turn. Only explicit goals may speculate on the next patch; ordinary
speculation is read-only post-accept conversation.
Expand All @@ -69,6 +94,30 @@ The project follows [Semantic Versioning](https://semver.org/).

### Added

- The LM Studio/OpenAI-compatible backend now uses streaming Responses with
provider-stored session chains, optional private reasoning, real cancellation,
and Rust-owned bounded workspace read/search/list tools. Tools are available
only for discovery and explicit Goals, never execute commands or mutate
source, and remain independent of MCP and instruction Skills.
- A controlled real-model Project Intelligence A/B runner now compares the
feature-disabled baseline, marker-derived ProjectProfile, and ProjectProfile
plus selected Skills. It includes Angular 22, TypeScript 6, React, Nx, and
Rust fixtures, deterministic rubrics, token/latency/retry telemetry, and an
OpenAI-compatible LM Studio backend for safe sequential local-model runs.
- PromptWindow now has a session-scoped Markdown Skills multiselect. Configured
files such as `AGENTS.md` autoload as locked inert instructions; optional root
Markdown files are explicitly selected, remain visible through Reply, and are
content-addressed and bounded before reaching the backend. A deterministic
ProjectProfile is built in Rust by marker-activated technology adapters and
supplies exact lockfile versions, Nx/Cargo workspace areas and dependencies,
commands, Compose infrastructure, and active Neovim LSP capabilities without
MCP or a model discovery turn. Protocol version is now 12.
- Prompts resolve a session-pinned static Flow graph through LSP call hierarchy
without opening UI or changing geometry. The explorer is an explicit `F`
toggle with lazy caller/callee expansion, exact call-site/reference
navigation and responsive split/single-pane layouts. Callstack answers carry
a structured `flow_path` and render it directly in the card UI. The bounded
normalized graph is sent to every backend without agent-side rediscovery.
- Conversation turns have a 10-second visible-response budget and work turns
a 20-second budget. Slow turns yield a focusable `Working` card, continue in
the background, and can be interrupted through the real Codex
Expand All @@ -87,7 +136,7 @@ The project follows [Semantic Versioning](https://semver.org/).
backend, the concrete model the next turn will use (configured, or resolved
from the backend — the Claude CLI announces it at process start, Ollama
always knows it), and the models the backend can enumerate (Ollama's local
tags). Protocol version is now 10.
tags).
- The prompt window title names the active agent and resolved model (never
"default"), refreshing as soon as warmup resolves it, and `Ctrl-l`
(`keymaps.models`) opens a model picker fed by the backend-enumerated
Expand Down
6 changes: 6 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading