Commit Graph
754 Commits
Author SHA1 Message Date
Shen Hao bebc3ba9e8 fix(tui-v2): add missing keysym.py — tuiapp_v2 ImportError on fresh clone
`tuiapp_v2.py:27` imports `fmt_key`, `fmt_keys` from `keysym`, but the
module file was never tracked. PR #513 (tui v2/v3 fixes) is unusable on a
fresh checkout without this. Adds the cross-platform shortcut formatter
that turns binding strings into mac/Win-Linux key labels (e.g.
`"ctrl+b"` → `"⌃B"` / `"Ctrl+B"`), honoring `GA_KEYSYM_STYLE`.
2026-05-28 10:13:21 +08:00
Shen Hao 5f92cd1b80 fix(tui-v3): keep shell └ output rows on bare terminal bg
Last commit wrapped both the `! cmd` echo AND the `└ output` rows in
the charcoal tile.  User wants only the echo line carry the band —
output rows stay on the terminal's native bg so the eye reads "this
is the command, that's its output" instead of one fused block.
2026-05-28 04:16:17 +08:00
Shen Hao 8804218d28 fix(tui-v3): keep └ output fg colors — shell tile becomes bg-only
Previous commit's _TILE_SHELL forced a light fg across both the `└`
gutter and the command output, erasing the dim styling on the gutter
and overwriting any ANSI the shell command emitted into stdout.

Make the tile bg-only (`\x1b[48;2;65;60;65m`).  Re-add `_DIM` around the
`└ ` gutter and leave `ln` un-styled so the terminal's default fg /
the shell's own colours come through.  The band itself stays full-row
because `_tile` re-asserts the bg after every embedded `_RST`.
2026-05-28 04:13:49 +08:00
Shen Hao 14186e50f3 fix(tui-v3): render shell-mode echo + output as full-width charcoal tile
Per user screenshot 040748, the committed `! echo hi` line and the
`└ output` rows used to sit on bare black while normal user bubbles
got the 55,55,55 charcoal band — visually inconsistent and broke the
cc-style "this is a discrete block" affordance.

New `_TILE_SHELL` (65,60,65 bg, light fg) wraps both halves via
`_tile()`, so the pink `!` prompt and dim `└` glyph inherit the band
across the full row width.  Slightly warmer shade than `_TILE_U` so
the user-bubble and shell-output bands stay distinguishable when
interleaved.  Black-terminal only — matches user spec.
2026-05-28 04:11:24 +08:00
Shen Hao ebb29c57ba fix(tui): v2+v3 bug fixes, pending input queue, ! shell magic, /resume
v2 Ctrl+S freeze: defer reset() + cleanup via call_after_refresh so the
keystroke handler returns immediately even when streaming has the
reactive queue saturated. Added _skip_change_next flag to short-circuit
on_input_area_changed during the deferred clear.

v3 terminal title: route _set_term_title via os.write(1,...) — sys.stdout
gets redirected to sb_agent.log during PTK app run, so OSC 0 escapes
were silently ending up in the log file. Default _session_name = 'session'
for v2 parity, and repaint title on running→idle transition.

v3 input row bg fill: _tile() now pads explicit bg-active spaces to
width — PTK's cell renderer doesn't honour \x1b[K (erase-to-EOL), so
the user bubble's charcoal band used to stop at text length.

v3 /emoji picker: arrow-key menu (mirrors /llm). Pet styles cleaned to
bear (default) + cat + dot + unicode. Bear calm tier restored to ʕ•ᴥ•ʔ.
• used for the calm tier, o for focused — matches user-requested mood
progression. Pet frame rate decoupled from spinner via self._spin // 5.

v3 ask_user "coderun freeze" fix: _tool_status no longer marks an
in-flight ask_user chip as ✓ ok when the stream contains the
"Waiting for your answer ..." marker. Bumped DoneEvent grace from 2 s
to 10 s when the marker is in the stream so a slow ask_user_queue.put
doesn't cause the picker to fall through to _finalize.

v3 /scheduler picker: added pre_checked kwarg to _show_menu so the
running set lands atomically. slash_cmds._match_service relaxed to
path-only matching so directly-launched (`python reflect/foo.py`)
reflect tasks are detected. Running rows highlighted in functional
green. Confirm card accepts ← as cancel (parity with Esc) — same on
v2 ChoiceList.

v3 keybindings: Esc Esc (within 800 ms) → /rewind (handled in
_handle_key so PTK's Esc interception path actually fires).

v3 pending input queue: agent.task_dir wired so ga.turn_end_callback
can consume `<task_dir>/_intervene`. New AgentBridge.inject_intervene
appends to the file (atomic vs read-modify-write), and _drain_pending
routes the combined message either through that hook (mid-turn) or via
put_task (idle). Cooldown 5 s, resets per new pending. ↑ recalls the
last queued message, Esc clears the queue. v2 has equivalent shape:
AgentSession.pending + per-session agent.task_dir + _inject_intervene
+ _poll_pending timer.

! shell magic: prefix `!` enters shell mode — pink border, prompt mark
swaps `❯` → `!`, body strips the leading `!` so the glyph appears
once. Enter runs the rest as `subprocess.run(shell=True, timeout=30)`,
echoes `! cmd` + `└ output` into scrollback, and appends to LLM
history (via _intervene when agent is running, direct backend.history
append when idle — sidesteps the iterator race).

/resume: forwarded as a literal to the agent so GA's _handle_slash_cmd
(agentmain.py:124) can expand it. Added to v3 _cmds() + v2 COMMANDS +
slash_cmds.COMMANDS + i18n + /help + Tips.

Turn marker regex fix: agent_loop.py:52 switches `**LLM Running
(Turn N) ...**` to the short `**Turn N ...**` when task_dir is set.
Extended all v3/v2 turn-marker regexes to match either form.

Cherry-picked upstream fixes:
- PR #466 (8ae3645): _collapse_choice early-return when the
  on_select callback (e.g. /rewind) detaches the anchor widget.
- PR #461 (08f21e8): SelectableStatic.has_valid_selection_parent +
  app-level _is_stale_selectable_mouse_event filter that swallows
  mouse events on detached widgets.
2026-05-28 04:06:28 +08:00
Shen Hao 156802b694 Enhance GETTING_STARTED with installation and config details
Added installation instructions for Windows and Linux, including one-click install options and manual clone instructions. Updated configuration examples and GUI launch commands.
2026-05-27 23:16:36 +08:00
Shen Hao 44b0e0d80d Update roadmap and community GUI links in README 2026-05-27 23:16:09 +08:00
Shen HaoandShen Hao 7ccb90d0fa fix(tui): polish tui_v3 Windows UX — 6 issues (#510)
1. _TILE_U: switch tile bg/fg to truecolor (48;2;55;55;55 / 38;2;230;230;230)
   so the file-tree tiles render legibly on Win Terminal dark themes
   instead of a muddy 8-color block.
2. _ticker: tighten the redraw cadence 0.4s -> 0.1s so the spinner and
   status line feel responsive on Windows.
3. terminal title: add _set_term_title() helper and emit OSC 0 on init /
   session new / rename / quit so the tab title tracks the active session.
4. _drain: stream-aware grace window — when the pending stream carries a
   pending ask_user ("Waiting for your answer"), extend the post-done poll
   so the question card is not swallowed before the prompt appears.
5. /emoji command: split _PETS into _PETS_UNICODE / _PETS_ASCII behind a
   module-level _pet_style toggle; add the /emoji dispatch + _cmd_emoji
   handler so users on fonts without emoji can fall back to ASCII pets.

Local-only edits, no cross-module API change; AST parses clean.

Co-authored-by: Shen Hao <shenhao-stu@users.noreply.github.com>
2026-05-27 22:36:38 +08:00
Shen HaoandShen Hao 3621d96224 feat(tui): add /conductor command + tips/i18n polish (#509)
- slash_cmds: register /conductor bundle + prompt_for builder (frontends/conductor.py)
- tui_v3: bind /conductor with en/zh i18n + palette entry + inject route
- tuiapp_v2: bind /conductor with COMMANDS row + route map + Tip easter-egg
- 5 new Tips bilingual surfacing Ctrl+O / /update / /scheduler / Ctrl+S / /conductor

Co-authored-by: Shen Hao <shenhao-stu@users.noreply.github.com>
2026-05-27 22:24:34 +08:00
nianyucatfish 7d001ca8a7 fix(tui_v2): /continue resumes unfinished plan + /stop refills input (#508)
/continue previously pushed plan_scan_baseline past every restored
message, so plan_state.is_active() saw an empty slice and hid the card —
even when the prior session's plan.md still had `[ ]` items the user
wanted to keep working on. `working['in_plan_mode']` isn't replayed by
the log restore either, so the card never came back.

Make the baseline conditional: default to 0 so the scanner walks the
full restored history; only push past it when the restored plan.md is
already all-done, suppressing the stale ✓ card. Resolved-path missing
or empty items naturally fall back to "no card".

/stop now also refills the input box with the just-sent user message,
so an interrupted send is one keystroke from edit-and-resend. Only
when the box is empty (don't clobber a half-typed follow-up). Agent
history is untouched — a resend duplicates the turn in LLM context;
/rewind 1 is the manual escape.

Behaviour matrix (/continue):
  unfinished plan  → baseline=0, scanner finds path, card resumes
  completed plan   → baseline=len(msgs), card stays hidden
  plan.md deleted  → resolve_path None, card stays hidden
  fresh enter_plan_mode after continue → working flag re-arms, normal
2026-05-27 22:05:00 +08:00
Shen HaoandShen Hao 91fcdf51b4 fix(tui): slash-cmd polish, bundle i18n sync & settle spinner on abort (#507)
* fix(tui): slash-cmd polish — /scheduler perf, v2 i18n typo, v3 bundle i18n

- slash_cmds: cache `running_services` list (≥1s TTL) and use a single
  service-name preload + lru-cached lookup. /scheduler picker cold path
  ~2.1s → ~1.0s, warm path ~0ms. Cache is invalidated whenever
  `start_service` succeeds so the picker reflects the new state on the
  next open.
- tuiapp_v2: drop the stray space inside `/reload-keys` zh description
  ("重新加载 mykey.py" → "重新加载mykey.py").
- tui_v3: route the remaining slash_cmds-bundle rows (/autorun,
  /morphling, /goal, /hive, /scheduler) through _t() the same way
  /update already was, with matching en/zh entries in _I18N. Keeps the
  v3 command palette fully bilingual.

* tui: settle spinner on abort + DRY-extract annotation helpers

Aborting a turn (Ctrl+C / /stop) left the live spinner ticking elapsed
until the LLM stream unwound in the background. Now we freeze a
`_stop_summary` snapshot the instant the user aborts and flip the line to
a settled "Stopping…", then "Stopped after Xm Ys" once done.

- ChatMessage._stop_summary: abort-time (elapsed, in, out) snapshot
- _mark_stopping(): freeze + repaint every in-flight assistant on /stop
- _stopping_annotation() / _done_annotation() stopped-state branch
- DRY: _fmt_tokens() single source for `↑ N · ↓ M`, _freeze_summary()
  single source for the snapshot tuple (de-dups spinner/done/stopping
  and the two capture paths)
- carries the branch's existing ask_user multi-choice "; ".join collapse

---------

Co-authored-by: Shen Hao <shenhao-stu@users.noreply.github.com>
2026-05-27 21:28:12 +08:00
Liang Jiaqing 49970b539d ljqCtrl: GrabWindow支持str标题+找不到窗口assert报错 2026-05-27 19:29:52 +08:00
Liang Jiaqing 73c0ccc9d9 ljqCtrl: add Activate/GetForeground/Click check; SOP精简39行; ui_detect物理坐标提醒 2026-05-27 19:02:10 +08:00
LJQ a3173b8981 Merge PR #504: fix(tui): /scheduler UX polish — hide cron advisory, ask_user-style confirm, running-state + untick-to-stop
Merged pull request #504 from shenhao-stu:fix/tui-scheduler-ux
2026-05-27 18:47:06 +08:00
LJQ 37c7c528c9 Merge PR #503: feat(slash/update): rework /update into a dual-branch upstream sync
Merged pull request #503 from shenhao-stu:feat/update-prompt-dual-branch
2026-05-27 18:46:59 +08:00
Liang Jiaqing 01f46b75bb refactor: fix_messages rewrite, Click check, ui_detect batch OCR 2026-05-27 16:49:07 +08:00
Shen Hao 8b9fb8ff13 feat(slash/update): rework /update into a dual-branch upstream sync
The previous /update prompt always did `git pull` + auto-merge and kept
local edits without committing, which left users with upstream changes
sitting as staged-only changes and an unintended divergent local branch.

Rework the /update prompt (both zh/en) into two explicit paths:
- If local commits exist: merge upstream into the current branch,
  auto-resolving conflicts in favor of upstream, keeping local commits.
- Otherwise: `git reset --mixed upstream/main` so local main aligns
  exactly with upstream/main, leaving no local-only commit while
  uncommitted working-tree changes are preserved.

Never push; never create a commit in the no-local-commit path. Also adds
a concise preview + summary step. Prompt kept short per user request.
2026-05-27 16:47:02 +08:00
Shen Hao fa49f487f5 fix(tui): /scheduler reflects running state and supports stop via untick (bug4)
Before: /scheduler picker always showed an empty selection, so reflect/*.py
and frontends/*app*.py services that were already running could neither be
identified nor stopped from the TUI.  Re-running /scheduler started another
instance instead of toggling the existing one.

This change keeps discovery in the shared slash_cmds module and wires both
TUIs through the same helpers (parity rule from tui_frontend_sop):

* frontends/slash_cmds.py
  - running_service_ids(): inspect hub.pyw subprocess registry and return the
    set of currently-running service ids (reflect/* and frontends/*app*).
  - stop_service(sid): graceful terminate via the same registry, idempotent.
  - list_launchable_services() result is unchanged; callers read running set
    separately so the picker can decorate labels without leaking state into
    discovery.

* frontends/tuiapp_v2.py, frontends/tui_v3.py
  - Picker now pre-checks the running set and appends an i18n " · running"
    tag to those labels so the user can SEE what is up and untick to stop.
  - On submit we diff picked vs running -> (starts, stops); empty diff is a
    no-op with a clear breadcrumb.  Confirm card lists both sides.
  - MultiChoiceList (v2) no longer early-returns on empty labels for picker
    callbacks, so unticking the last running service still fires on_select
    (single-select dialogs retain the legacy guard).
  - Full bilingual i18n: scheduler.running_tag / no_change / diff.start /
    diff.stop added to both en/zh tables.

Smoke: py_compile clean on all three files; manual /scheduler round-trip
(start A, reopen picker -> A pre-checked, untick A -> stop A) verified on
both v2 and v3.
2026-05-27 16:38:57 +08:00
Shen Hao c122ee6f73 fix(tui): v3 /scheduler confirm card -> ask_user-style (no checkmarks, Esc rolls back to picker preserving selection, full i18n) 2026-05-27 15:43:47 +08:00
Shen Hao 6126389aa1 fix(tui): v2 /scheduler confirm card -> ask_user-style (no ✅, Esc rolls back to picker via msg.on_cancel) 2026-05-27 15:41:21 +08:00
Shen Hao 34a14d0a60 fix(tui): hide cron advisory from v2 scheduler picker 2026-05-27 15:12:59 +08:00
Liang Jiaqing 9f653fdf45 feat(ui_detect): support PIL.Image direct input alongside file path 2026-05-27 15:10:01 +08:00
Liang Jiaqing 30e331a224 fix(llmcore): robust _fix_messages — defensive .get, dedup tool_results, clean orphan results from first user msg 2026-05-27 13:46:29 +08:00
Liang Jiaqing 9d03baf0e0 llmcore: bump claude-cli UA to 2.1.152, add context-mgmt/effort betas, Stainless headers, refine fake_cc system injection 2026-05-27 13:32:43 +08:00
LJQ 67d1850219 Merge pull request #496 from shenhao-stu:fix/tui-frontend-polish
fix(tui): polish continue picker and prevent stash freeze
2026-05-27 10:36:20 +08:00
LJQ d4ca2ce0b7 Merge pull request #495 from shenhao-stu:feat/slash-command-bundle
feat(tui): add shared slash-command bundle with hub-aligned /scheduler launcher
2026-05-27 10:36:13 +08:00
LJQ 5dad98a0ed Merge pull request #493 from shenhao-stu:main
fix(llmcore): add Cloudflare 520-527 to _stream_with_retry _RETRYABLE set
2026-05-27 10:36:03 +08:00
Liang Jiaqing db68ddf804 Fix desktop bridge startup loading flow 2026-05-27 09:37:03 +08:00
Shen Hao 9c463e19b5 fix(tui): support cross-platform stash shortcut 2026-05-27 06:51:54 +08:00
Shen Hao 16fae59a49 Fix TUI v2 picker rendering and stash latency 2026-05-27 06:07:42 +08:00
Shen Hao 96fd00381c Polish TUI v3 scheduler and command handling 2026-05-27 06:07:42 +08:00
Shen Hao 1a39221a59 Harden continue session listing and restore parsing 2026-05-27 06:07:42 +08:00
Shen Hao 465708bb0e Add shared frontend slash command helpers 2026-05-27 06:07:41 +08:00
Shen Hao 032a9ad33e fix(scheduler): align /scheduler picker with hub.pyw + add commit-answer confirm
The /scheduler picker previously listed only reflect/*.py (skipping just
underscore-prefixed files), so it leaked goal_mode/agent_persona and missed
the frontend apps that hub.pyw's launcher shows. It also started tasks via
`python reflect/X.py` instead of the canonical `agentmain.py --reflect`.

- slash_cmds.py: add list_launchable_services() + start_service() that mirror
  hub.pyw discover_services() exactly (EXCLUDES goal_mode/chatapp_common/tuiapp,
  reflect tasks via agentmain.py --reflect, frontend *app*.py incl. streamlit).
- tuiapp_v2.py / tui_v3.py: /scheduler now shows the full hub.pyw service set
  (reflect + frontend) and, after the multi-select Enter, requires a second
  commit-answer confirmation before anything is actually launched.

Parity verified at runtime: list_launchable_services() == discover_services().
2026-05-27 05:46:53 +08:00
Shen Hao fc74f2a7f4 feat(tui-v3): wire slash bundle + multi-select scheduler menu
Hook the slash_cmds bundle into tui_v3: register the commands in the
palette, add the prompt-injection dispatch and the /scheduler launcher.
Extend the in-house _show_menu with an opt-in multi_select mode
(Space toggles, Enter submits) so /scheduler can start several reflect
tasks at once, plus the matching command tips.
2026-05-27 05:30:46 +08:00
Shen Hao 7c00108053 feat(tui-v2): wire slash command bundle into the Textual TUI
Hook the slash_cmds bundle into tuiapp_v2: register the commands in the
COMMANDS palette and dispatch table, add the prompt-injection handlers
(/update /autorun /morphling /goal /hive) and the /scheduler picker
(multi-select reflect tasks via the existing multi_choice picker), plus
the matching command tips.
2026-05-27 05:30:46 +08:00
Shen Hao 63c61560b2 feat(tui): add slash_cmds bundle (prompt-injection + scheduler helpers)
Introduce frontends/slash_cmds.py, a shared bundle backing the new
slash commands for both Textual (v2) and curses (v3) frontends.

Provides prompt builders for /update /autorun /morphling /goal /hive
(each injects a concise, imperative directive into the agent prompt)
and the reflect-task discovery/launch helpers used by /scheduler.
2026-05-27 05:30:46 +08:00
Shen Hao 874c5ea234 fix(llmcore): add Cloudflare 520-527 to _stream_with_retry _RETRYABLE set 2026-05-26 23:28:01 +08:00
AspasZhang 17ba44fed9 chore: update WeChat group 19 QR code image (#492) 2026-05-26 17:29:16 +08:00
Jiaqing Liang 0d4705e633 Add salient mining SOP to L4 memory 2026-05-26 12:32:54 +08:00
Jiaqing Liang fce7238391 fix: force UTF-8 output for PowerShell code_run 2026-05-26 12:16:30 +08:00
YooooEX f758d1a200 fix: support review command in Telegram frontend
Wire the existing /review handler into tgapp so Telegram users can invoke in-session code review, including help responses and streamed agent execution.
2026-05-26 12:09:04 +08:00
slowlyo a9b1dcce98 fix: ga scripts prefer project .venv over system python
Prefer project virtualenv Python in ga launchers to avoid PEP 668/system Python issues, falling back to PATH python when no venv exists.
2026-05-26 12:03:14 +08:00
hao yang 2f2905dfee feat: prefer pwsh over powershell in code_run on Windows
Use pwsh when available for better UTF-8 and modern PowerShell behavior, with fallback to legacy powershell.
2026-05-26 11:52:25 +08:00
Kailigithub efb91b930c fix: correct subagent_sop.md references to subagent.md
Align .gitignore and plan_sop.md with the actual memory/subagent.md file. Closes #482.
2026-05-26 11:49:39 +08:00
w286554018 73e555c1ec fix: wrap _turn_end_hooks iteration with list()
Prevent RuntimeError when a turn-end hook mutates _turn_end_hooks during callback iteration.
2026-05-26 11:47:04 +08:00
Liang Jiaqing 9e72234222 refactor: hive_sop restructure, GrabWindowBg, ui_detect unified API, worker rule9, incubator_sop 2026-05-26 10:02:51 +08:00
Jiaqing Liang ab0919cfa7 fix mykey path, add inject-prompt button, harden reload_mykeys 2026-05-25 13:29:12 +08:00
LJQ 552c5c07e6 Merge pull request #475 from skydog221/main
fix(qqapp):Change message type to Markdown message(msg_type-2))
2026-05-25 09:28:24 +08:00
skydog221 bb656b189e fix(qqapp):Change message type to Markdown message(msg_type-2)) 2026-05-24 21:16:05 +08:00