You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: tracing dashboard redesign and robust project-memory tooling (#127)
* feat: MCP skill bridge, agent guardrails, and session UX fixes
ReadSkill now resolves a connected MCP server name (including plugin-style
aliases like designer-skill:designer-skill) to a bridge listing that server's
tools instead of "Skill not found", and ships a designer-skill stub that routes
frontend work to the MCP tools.
best_practices_always config option folds the full /best-practices engineering
guidance into the root session's system prompt at startup (default off), so the
guardrails apply to every new session without running the command.
StrReplaceFile returns a precise, actionable error when a multi-edit batch fails
schema validation (e.g. entries collapsed by a streaming glitch), naming the bad
entries and steering toward single-edit calls; valid edits are never partially
applied.
The default system prompt now requires absence claims ("no em-dashes", "no
leftover debug", "matches the source") to be backed by an actual zero-hit scan,
and to re-ask rather than act on a self-authored reading of a non-responsive
clarifying answer.
Also: /recap on|off toggle with grey autosuggest; recaps strip <system-reminder>
blocks; configured /login providers get distinct state styling; braille
background spinner and hanging-indent working tips; scratch files are cleaned up
on exception-path session exit. Removes leftover debug instrumentation from the
skill tool.
* fix(tui): render diff context lines in normal text color
Unchanged context lines in file-edit diff snippets (Write, StrReplaceFile, and
all diff cards) used a muted grey (tool_diff_context), which read as dimmed
against the normal body text. Match the normal `text` token instead — terminal
default foreground in dark, #213853 in light — so edited-file previews are easy
to read. Added/removed lines keep their green/red styling, so changes still
stand out.
* Redesign tracing dashboard with Usage page and polish
Refresh the Statistics and Sessions surfaces of the agent tracing
visualizer and add a new Usage page, keeping the existing neutral/zinc
identity (no new brand accent) and the dependency-free SVG charts.
- Add shared shadcn-style Card primitives (12px radius, subtle shadow)
- Statistics: icon-tile metric cards with helper lines, titled chart/
tool/table cards, rounded bars, bordered hover-row project table,
width-contained layout, and an empty state
- Sessions: focus rings and a search hint in the toolbar, softer card
radius with hover lift, folder-tile project group headers
- New Usage page: summary cards, a GitHub-style activity heatmap keyed
on daily turns (monochrome intensity ramp), and a turn-trend chart
- Header: app icon tile, subtitle, accessible theme toggle; add the
Usage tab as polished pills
- Add a prefers-reduced-motion safety block to global CSS
Behavior, data flow, and DOM/event contracts are unchanged.
* Rank command-name matches above alias matches in slash completer
Typing /report surfaced /report_error first because its "report" alias
was an exact match, ranked above /reports (a command-name prefix match).
Rank by match tier (name exact, name prefix, alias exact, alias prefix)
then by command-name length, so the closest command name wins. /report
now lists /reports first.
Drop the now-unused _command_lookup and add regression tests.
* Polish dashboard with blue accent and richer Usage page
Apply a soft-enterprise analytics treatment across the tracing
visualizer and make the Usage visualizations feel intentional.
- Introduce a single restrained blue accent (primary/ring tokens) for
light and dark; charts and the heatmap now carry visual hierarchy
- Shared premium MetricCard (rounded-2xl, icon tile, hover lift); used
by Statistics and Usage
- Usage: heatmap and a new Usage Insights panel sit side by side to use
the available width; larger blue GitHub-style heatmap with a
Turns/Sessions toggle and Less/More legend
- New area trend chart with gradient fill, gridlines, axis labels, and a
hover tooltip (dependency-free SVG)
- Statistics: single accent tool bars with a neutral error badge instead
of red segments; blue daily-usage series
- Soft muted page background and consistent rounded-2xl cards
Charts remain hand-rolled SVG (no recharts). Behavior and data flow are
unchanged.
* chore(deps): bump react to 19.2.7 in vis and web
Align the web and vis frontends on the latest stable React (19.2.7,
@types/react 19.2.17) on top of vite 8, and refresh both lockfiles.
Both frontends type-check and build cleanly under vite 8 + react 19.2.7.
* Make Daily Usage chart fill the card width
The chart used a fixed 600x140 viewBox with maxHeight, so
preserveAspectRatio letterboxed it: the plot rendered ~600px wide and
floated centered in a much wider card. Measure the container width with
a ResizeObserver and render the SVG full width (taller, with gridlines
and a sessions Y axis), matching the Usage trend chart.
* fix(memory): legible capacity errors, list action, and full-store education
The project-memory budget check silently added a 3-char entry delimiter that
the rejection message never disclosed, so a near-full store reported e.g.
"2085/2200, entry (113) exceeds" — math that reads as satisfiable (2085+113<2200)
but isn't. With no visibility into the true ceiling or what was stored, the agent
could only blind-shrink the entry and loop until interrupted.
- project_memory: delimiter-aware accounting; rejections now report exact free
chars, the entry's real cost (content + separator), used/limit, and a compact
inventory (index, size, preview) so the next remove/replace is guided. Add
status() and capacity(); flag capacity failures via MemoryOpResult.full.
- Memory tool: new read-only `list` action for mid-session introspection; on a
full-store rejection, append a plain-language explanation (nothing lost, task
continues, how to free space) to the user-facing tool card.
- Raise limits MEMORY 2200->5000, USER 1375->2500 (within the 8 KB injection budget).
- /memory: show per-store capacity and a "nearly full" guidance panel at >=85%.
- memory.md: best-effort housekeeping guidance — don't loop on rejection.
* feat(memory): routing-guard advisory and index-based entry locator
Add a structural detector that nudges the agent toward editing the
authoritative project file when a memory write looks like a rule or
value-assignment that belongs in a file (a recurring failure mode: a
correction rephrased as a "preference" and stored in memory while the
governing file stays stale). The guard never blocks — it only appends a
one-line advisory on add/replace — so false positives cost a sentence.
Also let replace/remove identify an entry by 0-based `index` (from
`list`) as a deterministic alternative to `old_text` substring matching;
out-of-range indices report the inventory so the retry is guided.
Slash completer now surfaces the matched alias as the menu label
(`/res` -> `/resume`) while keeping name matches ranked above alias-only
matches.
memory.md guidance updated for authoritative-files-first and the new
index-based locator.
* test: green CI for new module, recap usage string, and designer-skill
Regenerate the inline snapshots that pin auto-discovered state so they
match the new code:
- pyinstaller `hiddenimports` now includes the new
`pythinker_code.tools.memory.routing_guard` module.
- wire-handshake slash-command list: `/recap` usage gained `on|off` and
the `skill:designer-skill` command was added.
Make the recap slash-command test await type-safe: the registry types
commands as `None | Awaitable[None]`, so guard with `isinstance(ret,
Awaitable)` before awaiting (matching the existing shell-slash test
helper) instead of awaiting the union directly, which pyright rejects.
* fix(deps): regenerate web and vis lockfiles so npm ci succeeds in build
The react 19.2.7 / vite 8.0.16 bump left both lockfiles inconsistent:
they were missing the platform-specific optional @emnapi/* wasm-binding
deps (oxc-parser, oxc-resolver, rolldown). Because those are optional
per-OS deps, a partial `--package-lock-only` regen on one platform does
not capture the set CI's Linux runner needs, so `npm ci` kept failing
with EUSAGE ("package.json and package-lock.json are not in sync") and
broke `make build-web` / build-vis in the PyInstaller onefile jobs.
Regenerate both lockfiles from a clean install so they carry the full
cross-platform optional-dep tree. Direct deps are unchanged (react
19.2.7, vite 8.0.16, typescript 5.9.3); the churn is transitive/optional
ordering. Verified `npm ci` succeeds and `build-web`/`build-vis` produce
assets in both web/ and vis/.
* fix: address PR review feedback
- cli: replace silent contextlib.suppress(Exception) in the exception-path
session cleanup with explicit try/except that logs at debug, so import or
runtime failures during best-effort cleanup are traceable (CodeRabbit).
- slash (/recap): revert the in-memory turn_recaps toggle when persistence
fails, so runtime state matches the reported failure instead of silently
diverging (CodeRabbit, major).
- test_slash_recap: await the recap command via a type-honest cast instead of
a bare `await ret` (clears the "statement has no effect" code-scanning flag).
- test_session: silence ARG001 on the three exception-cleanup tests with
@pytest.mark.usefixtures (renaming the param to _isolated_share_dir would
break pytest fixture injection).
- test_settings_recaps_slash: assert save_config is actually called in the
singular `/recap on` alias test (CodeRabbit).
* feat(memory): confirm before remembering routing-flagged writes
When an add/replace looks like a rule, a value/limit, or names a project file
(the existing routing_guard signals), gate it behind user confirmation before
writing — so the agent can't silently fill memory with corrections that belong
in an authoritative file. Plain durable facts (no signals) still write directly.
Uses the shared approval flow (Runtime.approval), so yolo/auto-approve and
"allow for session" are honored automatically:
- approved -> the entry is written;
- declined by the user -> not written; the agent is told to edit the governing
file instead, with the user's feedback;
- no user available (headless) -> skipped cleanly, reported as skipped (not an
error), so unattended runs never accumulate flagged memory.
This replaces the weaker post-write advisory nudge with a real gate. Also makes
the full-store guidance target-specific ("Project memory" vs "User memory")
instead of always saying "Project memory" (CodeRabbit).
* fix(web): pin ultracite to 7.1.1 so biome resolves ultracite/core
Regenerating web/package-lock.json bumped ultracite within `^7.1.1` to 7.8.3,
which restructured its package exports and dropped `ultracite/core` —
web/biome.json extends `ultracite/core`, so `make check-web` (biome) failed
with "Could not resolve ultracite/core". Pin ultracite to exactly 7.1.1 (the
version main uses) until biome.json is migrated to newer ultracite. The
cross-platform @emnapi lockfile fix is preserved; `npm ci`, biome, and the web
build all pass.
* fix: address CodeRabbit review on latest commits
- memory gate: stop logging the raw content preview (content[:60]) in the
routing-flagged debug log — a declined/blocked write could otherwise leak
secrets/PII; log only target + signals (CodeRabbit, major).
- cli: drop the redundant local `logger` import in the exception-path cleanup;
the enclosing function already binds `logger` in scope (CodeRabbit).
- docs/build: the react bump moved web/vis to Vite 8, but build_vis.py, web/
AGENTS.md, and architecture.md still said "Vite 7". Update the labels (the
Node engine constraint ^20.19.0 || >=22.12.0 is unchanged in Vite 8).
Copy file name to clipboardExpand all lines: CHANGELOG.md
+10Lines changed: 10 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,6 +15,16 @@ GitHub Releases page; `0.8.0` is the new starting line.
15
15
16
16
## Unreleased
17
17
18
+
-**designer-skill MCP bridge.** Bundled a `designer-skill` stub skill that routes frontend work to the connected designer-skill MCP tools instead of failing ReadSkill; plugin-style names like `designer-skill:designer-skill` resolve correctly, and ReadSkill falls back to a generic MCP bridge (any user-configured server name) when only the MCP server is connected.
19
+
-**Always-on best practices.** New `best_practices_always` config option folds the full `/best-practices` engineering guidance into the root session's system prompt at startup, so the guardrails apply to every new session without running the command. Default off.
20
+
-**Smarter multi-edit errors.** A `StrReplaceFile` batch that fails schema validation (e.g. edit entries collapsed by a streaming glitch) now returns a precise, actionable error naming the bad entries and steering toward single-edit calls, instead of a wall of validation errors. Valid edits are never partially applied.
21
+
-**Agent guardrails.** The default system prompt now requires absence claims ("no em-dashes", "no leftover debug", "matches the source") to be backed by an actual zero-hit scan, and to re-ask rather than act on a self-authored reading of a non-responsive clarifying answer.
22
+
-**`/recap on|off`.** Toggle turn recaps from the recap command (mirrors `/settings recap(s)`), with a grey inline autosuggest reflecting the current state.
23
+
-**Recap hygiene.** Session recaps strip `<system-reminder>` blocks so injected harness context no longer leaks into one-line recaps.
24
+
-**Login selector polish.** Configured `/login` providers render with distinct success/state styling; the background working indicator uses the braille spinner, and working tips wrap with a hanging indent under the verb.
25
+
-**Scratch cleanup on exit.** Sessions that end via an exception now clean up their scratch files instead of orphaning them.
26
+
-**Readable diff context.** Unchanged context lines in file-edit diff snippets now render in the normal body-text color instead of muted grey, so edited-file previews are easier to read; added/removed lines are unchanged.
27
+
18
28
## 0.42.0 (2026-06-12)
19
29
20
30
-**Adversarial branch review hardening.** A multi-agent review pass confirmed and fixed: committed-but-clean isolation worktrees are now retained (commits ahead of the creation base count as changes — they were previously orphaned on cleanup); foreground shell commands and relative-path file edits now resolve against the agent's work dir, so worktree isolation actually binds them (host exec gained a `cwd` argument); safe mode now also disables the read-only-command prompt elision; locally parallel-safe MCP/tools run in parallel in the same-step gate; worktree add/remove serializes per repo. Behavior notes: same-step tool calls without `supports_parallel` now serialize deterministically (previously fully concurrent), and text-mode error diagnostics moved to stderr — capture `2>&1` or use `--output-format stream-json` if you scraped stdout.
Copy file name to clipboardExpand all lines: src/pythinker_code/agents/default/system.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,7 +23,7 @@ Eight rules that override convenience, speed, and every other instruction in thi
23
23
24
24
1.**Read before write.** Never edit a file you have not read this session; confirm the exact lines you are about to modify still match what you read.
25
25
2.**Complete code only.** Never write placeholders, stubs, `TODO: implement`, elided bodies, or "rest of the file unchanged" markers into files. If a change is too large for one step, split the work — never abridge the code. (Genuine `TODO:` notes for real technical debt are fine.)
26
-
3.**Evidence before claims.** Every "done", "fixed", or "works" names the command you ran and the result you observed. Verification means a passing test, a working repro, or a deterministic command that confirms the intended behavior — compiling or type-checking alone is not verification. This definition is canonical: it is what "verify" means everywhere in this prompt.
26
+
3.**Evidence before claims.** Every "done", "fixed", or "works" names the command you ran and the result you observed. Verification means a passing test, a working repro, or a deterministic command that confirms the intended behavior — compiling or type-checking alone is not verification. This definition is canonical: it is what "verify" means everywhere in this prompt. A claim that something is *absent* — no banned strings, no em-dashes, no leftover debug instrumentation, no TODOs, output matches the source — is only true after a scan that returned zero hits; never assert absence from memory.
27
27
4.**Re-verify after every edit.** An edit invalidates all prior verification; re-run the smallest check that proves the change is sound before building on top of it.
28
28
5.**Honest failure.** When verification fails, report the failing output verbatim under **BLOCKERS**. Never weaken an assertion, skip a test, widen a tolerance, swallow an error, or silently narrow scope to get to green.
29
29
6.**Match the codebase.** Existing style, granularity, naming, and idioms beat your preferences. A correct change that fights the codebase's conventions is not done.
@@ -57,7 +57,7 @@ State multi-step plans inline as `Step → verify: check`; substantial tasks kee
57
57
58
58
**Report** with `path:line` references over pasted blocks, concise findings, and explicit residual risk — unverified assumptions, untested paths, recommended follow-ups, and unrelated issues noticed but not touched.
59
59
60
-
**Ask vs. act.** Act without asking when intent is clear, the change is reversible, and it is in scope. Ask one focused question — before implementation, never after mistakes — when interpretations genuinely diverge, an action is irreversible or destructive, credentials are needed, requirements conflict, or scope grows beyond the request. Never ask what a tool call can answer.
60
+
**Ask vs. act.** Act without asking when intent is clear, the change is reversible, and it is in scope. Ask one focused question — before implementation, never after mistakes — when interpretations genuinely diverge, an action is irreversible or destructive, credentials are needed, requirements conflict, or scope grows beyond the request. Never ask what a tool call can answer. If an answer to a clarifying question does not actually resolve the ambiguity, say so and re-ask with your default stated — never act on a self-authored interpretation of a non-answer.
61
61
62
62
**Steering.** If the user interjects or redirects mid-task, stop, reconcile the new instruction with the current plan, update the todos, then continue.
0 commit comments