Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
702 commits
Select commit Hold shift + click to select a range
3079954
no message
elecvoid243 Jun 29, 2026
8215aa4
Merge branch 'all' of https://github.com/elecvoid243/AstrBot into all
elecvoid243 Jun 29, 2026
73a59a8
Revert "no message"
elecvoid243 Jun 29, 2026
3486707
fix(git-diff): preserve files_changed when diff payload is empty/null
elecvoid243 Jun 30, 2026
770ddf6
docs(specs): add diff fullscreen mode design spec
elecvoid243 Jun 30, 2026
7985826
feat(diff): add fullscreen i18n keys for DiffPreview
elecvoid243 Jun 30, 2026
8bbf644
feat(diff): add fullscreen overlay to DiffPreview
elecvoid243 Jun 30, 2026
00ccd8a
docs(plans): add implementation plan for diff fullscreen mode
elecvoid243 Jun 30, 2026
962e520
Merge branch 'fix/git-diff-empty-data-loss' into all: add diff fullsc…
elecvoid243 Jun 30, 2026
358a3f9
fix(chatui): fix in-line comment button in diff preview
elecvoid243 Jun 30, 2026
fd6ba31
Merge remote-tracking branch 'upstream/master' into all
elecvoid243 Jun 30, 2026
4488d96
fix(chatui):调整reasoningsidebar和gitdiffsidebar的初始大小
elecvoid243 Jul 1, 2026
57da278
fix(file-preview): surface clipboard failure on insecure context
elecvoid243 Jul 1, 2026
7e35d13
fix(git-diff): clear bulk-stage selection after success
elecvoid243 Jul 1, 2026
13c75d3
feat(diff-preview): hunk folding in split mode
elecvoid243 Jul 1, 2026
4ade614
feat(shiki): add MATLAB syntax highlighting
elecvoid243 Jul 1, 2026
fb47a75
fix(computer): suppress nested console window in local python tool
elecvoid243 Jul 1, 2026
639a1bf
feat(spcode): add result card for code_format tool
elecvoid243 Jul 1, 2026
f92ac7b
fix(git-history): invalidate ETag on Reset to avoid 304-replay of fil…
elecvoid243 Jul 1, 2026
fd0eda4
feat: widen file-comment LLM context to ±3 with derived merge threshold
elecvoid243 Jul 2, 2026
7a63b66
feat: collapsible code context in comments preview dialog
elecvoid243 Jul 2, 2026
5707627
docs: add sidebar search feature design spec
elecvoid243 Jul 2, 2026
377282b
docs: add sidebar search implementation plan
elecvoid243 Jul 2, 2026
f7936a4
feat(dashboard): add useSpcodeFileSearch composable
elecvoid243 Jul 2, 2026
61ecc63
feat(dashboard): add SearchPanel component
elecvoid243 Jul 2, 2026
766d24c
feat(dashboard): mount SearchPanel in FileBrowserView
elecvoid243 Jul 2, 2026
4883844
feat(dashboard): wire search button + Cmd-F + open-file in sidebar
elecvoid243 Jul 2, 2026
8749b63
feat(dashboard): i18n keys for sidebar search
elecvoid243 Jul 2, 2026
4646ce5
docs: refactor sidebar search spec to use python_ripgrep library
elecvoid243 Jul 2, 2026
fc16ca6
feat(dashboard): drop obsolete backend field from sidebar search
elecvoid243 Jul 2, 2026
50191ce
docs: add file-name-search endpoint to sidebar search spec
elecvoid243 Jul 2, 2026
691affd
docs: add mode toggle (Filename/Content) to sidebar search spec
elecvoid243 Jul 2, 2026
54d2672
feat(dashboard): add Filename/Content mode toggle to SearchPanel
elecvoid243 Jul 2, 2026
fdb137e
docs: update file-name-search spec to use python_ripgrep.files
elecvoid243 Jul 2, 2026
c4617c3
refactor(dashboard): move search input from panel to toolbar
elecvoid243 Jul 2, 2026
59c7158
feat(dashboard): scroll search result click to file preview + center …
elecvoid243 Jul 2, 2026
ec80b3b
fix(dashboard): keep breadcrumb visible while search panel is open
elecvoid243 Jul 2, 2026
3f56cbf
fix(dashboard): case-insensitive breadcrumb root + basename fallback
elecvoid243 Jul 2, 2026
0121b9b
fix(dashboard): re-anchor breadcrumb path against worktree root
elecvoid243 Jul 2, 2026
b32e945
style(dashboard): give breadcrumb a primary-tint background (light + …
elecvoid243 Jul 2, 2026
8557d53
style(dashboard): lift breadcrumb background alpha to be actually vis…
elecvoid243 Jul 2, 2026
d73408e
docs: deprecate v0.3 dynamic-choice-box spec in favor of v1.0 blockin…
elecvoid243 Jul 2, 2026
4352cf3
refactor(frontend): rewrite parseInteractiveChoice for v1.0, add requ…
elecvoid243 Jul 2, 2026
c7c0d60
feat(frontend): add interactiveChoice Pinia store
elecvoid243 Jul 2, 2026
3386e6f
test(dashboard): add submitChoice + reconcile tests for interactiveCh…
elecvoid243 Jul 2, 2026
ff16a84
refactor(frontend): change InteractiveChoiceBox emit to (requestId, p…
elecvoid243 Jul 2, 2026
57798c2
feat(frontend): wire SSE events + Pinia store to ChatMessageList
elecvoid243 Jul 2, 2026
98b2f24
fix(dashboard): resolve currentUmo null-vs-undefined type mismatch
elecvoid243 Jul 2, 2026
6f199b2
feat(dashboard): widen file-browser encoding type and surface encodin…
elecvoid243 Jul 3, 2026
e1a1308
Merge branch 'feature/dashboard-ansi-preview'
elecvoid243 Jul 3, 2026
ec4b035
fix(dashboard): keep unified-mode gutter column on del lines
elecvoid243 Jul 3, 2026
023f683
Merge branch 'feat/dynamic-choice-box' into all: v1.0 blocking intera…
elecvoid243 Jul 3, 2026
7be5aee
feat(frontend): wire SSE interactive_choice event to Pinia store (spe…
elecvoid243 Jul 3, 2026
8f1bb42
Merge branch 'feat/dynamic-choice-box' into all: wire SSE interactive…
elecvoid243 Jul 3, 2026
2296bc4
fix(frontend): write SSE interactive_choice part into botRecord.conte…
elecvoid243 Jul 3, 2026
cfc9a04
Merge branch 'feat/dynamic-choice-box' into all: write SSE interactiv…
elecvoid243 Jul 3, 2026
24e59e8
fix(dashboard): persist ignored-state and scope interactive choice pe…
elecvoid243 Jul 4, 2026
b271e5b
fix(dashboard): mark pending ask_user_choice as ignored on chat-input…
elecvoid243 Jul 4, 2026
898fb49
fix(dashboard): persist interactive_choice parts in chat history
Jul 5, 2026
a5f11b4
fix(chat): recover interactive_choice parts from pre-fix plain-text h…
elecvoid243 Jul 5, 2026
8029ca6
fix(dashboard): drop ask_user_choice tool_call parts to avoid duplica…
elecvoid243 Jul 5, 2026
a38eafb
fix(dashboard): scrub stale ask_user_choice tool_call parts on histor…
elecvoid243 Jul 5, 2026
549aaf6
fix(dashboard): drop orphan ask_user_choice result when interactive_c…
elecvoid243 Jul 5, 2026
ef6a73d
Merge remote-tracking branch 'upstream/master' into all
elecvoid243 Jul 6, 2026
9fda6b5
fix(dashboard): fix sidebar resize width when toolbar exists
elecvoid243 Jul 7, 2026
2dca7e9
docs: add design spec for hunk-level discard in gitdiff sidebar
Jul 7, 2026
2d1b8aa
docs: add implementation plan for hunk-level discard feature
Jul 7, 2026
4ccfb51
docs: extend plan to also cover split-mode hunk discard buttons
Jul 7, 2026
08ef0b8
feat(dashboard): add parseSpcodeFileDiscardHunk response parser
Jul 7, 2026
9aa978e
feat(dashboard): add useSpcodeFileDiscardHunk composable
Jul 7, 2026
d13775c
refactor(dashboard): add hunkIndex to DiffHunk for cross-truncation l…
Jul 7, 2026
362f4c0
refactor(dashboard): refactor hunk header from button to div role=button
Jul 7, 2026
6591fdb
feat(dashboard): add hunk discard props, state, handler, and patch bu…
Jul 7, 2026
506344c
feat(dashboard): render hunk discard button in hunk headers (unified …
Jul 7, 2026
f3f9a6d
feat(dashboard): thread hunk discard props through GitDiffFileItem
Jul 7, 2026
373c0e6
docs: refine plan with 4-hunk-header scope and no-emit design
Jul 7, 2026
702ed4c
feat(dashboard): thread hunk discard props through GitDiffBodyContent
Jul 7, 2026
7e60a48
feat(dashboard): wire hunk discard handler in GitDiffSidebar
Jul 7, 2026
9a75e11
feat(dashboard): add hunk discard i18n keys (en/zh-CN/ru-RU)
Jul 7, 2026
1c3e327
fix(dashboard): resolve hunk discard "corrupt patch at line N"
Jul 7, 2026
c301a38
fix(dashboard): persist interactive_choice extra_content into chat hi…
elecvoid243 Jul 8, 2026
4b3918b
feat(dashboard): render extra_content from ask_user_choice (v1.1)
elecvoid243 Jul 8, 2026
2262496
Merge remote-tracking branch 'upstream/master' into all
elecvoid243 Jul 9, 2026
aa3e210
fix(chat_service): normalize history timestamps after sanitization
elecvoid243 Jul 9, 2026
bd11d85
feat(chat): polish file browser workspace
elecvoid243 Jul 9, 2026
acede45
feat(chat): add file-level history shortcut in file preview pane
elecvoid243 Jul 9, 2026
cc79c8f
fix(chat): route non-empty_repository backend errors to error state
elecvoid243 Jul 9, 2026
9133ff8
docs(spec): design — beautify chat-input status chips by role
elecvoid243 Jul 9, 2026
769ca3f
docs(plan): implementation plan — beautify chat-input status chips
elecvoid243 Jul 9, 2026
e3dc50c
chore(ui): add --sp-* design tokens + dashboard vitest setup
elecvoid243 Jul 9, 2026
d35a3ad
test(ui): add SpSegmentedControl unit tests (TDD red)
elecvoid243 Jul 9, 2026
f8bcc7f
feat(ui): introduce SpSegmentedControl generic component
elecvoid243 Jul 9, 2026
216c23f
refactor(chat): rewrite SpcodeProjectIndicator as status badge
elecvoid243 Jul 9, 2026
cacb206
refactor(chat): rewrite SpcodeCodegraphChip as status badge
elecvoid243 Jul 9, 2026
9c06149
refactor(chat): rewrite SpcodePlanModeChip as segmented control
elecvoid243 Jul 9, 2026
34b01ee
refactor(chat): rewrite GitDiffChip as ghost button
elecvoid243 Jul 9, 2026
42d70f7
style(chat): adjust ChatInput status row layout (column to row, gap 6px)
elecvoid243 Jul 9, 2026
f17d590
chore(i18n): refresh planModeChip tooltips + add segment aria-labels …
elecvoid243 Jul 9, 2026
2901099
feat(chat): add opaque resting background to status badges and ghost …
elecvoid243 Jul 9, 2026
3159a83
feat(chat): apply opaque chip backgrounds, stack status row verticall…
Jul 11, 2026
927a7d7
feat(gitdiff): bulk restore selected files via diff sidebar toolbar
Jul 11, 2026
f595386
Merge branch 'feat/gitdiff-bulk-restore' into all
elecvoid243 Jul 11, 2026
69e3539
feat(gitdiff): expose bulk restore in 'all (with HEAD)' scope
Jul 11, 2026
2512a7c
Merge branch 'feat/gitdiff-bulk-restore' into all
elecvoid243 Jul 11, 2026
104ea4e
docs(specs): add Document Manager sub-tab design (Spec A — frontend)
Jul 11, 2026
76915bd
fix(dashboard): prevent v-toolbar from covering TodoSidebar top
elecvoid243 Jul 11, 2026
0234e79
feat(chat): interactive choice v1.2 — 放宽 title/label 截断上限 + :title to…
elecvoid243 Jul 11, 2026
f796d37
feat(chat): interactive choice — ignored header 补全 title 渲染
elecvoid243 Jul 11, 2026
2699bc8
feat(chat): add drag-resize handle to TodoSidebar (mirrors GitDiffSid…
elecvoid243 Jul 12, 2026
1790b95
chore(dashboard): regenerate mdi font subset
elecvoid243 Jul 12, 2026
dcf640b
docs(plans): add Document Manager frontend implementation plan (17 ta…
elecvoid243 Jul 12, 2026
7defbad
Merge branch 'AstrBotDevs:master' into all
elecvoid243 Jul 13, 2026
bd5fe60
Merge branch 'all' of https://github.com/elecvoid243/AstrBot into all
elecvoid243 Jul 13, 2026
d6db9fa
Merge branch 'AstrbotDevs:master' into all
elecvoid243 Jul 14, 2026
f77ed15
Merge branch 'all' of https://github.com/elecvoid243/AstrBot into all
elecvoid243 Jul 14, 2026
a2269de
Merge branch 'AstrbotDevs/master' into all
elecvoid243 Jul 14, 2026
3d67bf2
feat(dashboard): make es_search "+N more" footer expandable/collapsible
elecvoid243 Jul 15, 2026
b7eef6c
fix(dashboard): anchor todo-summary-bar drag start to rendered rect
elecvoid243 Jul 15, 2026
27eeb92
fix(dashboard): polish file-restore dialog (untracked wording, refres…
elecvoid243 Jul 15, 2026
0753eb6
fix(dashboard): polish document manager history UX
elecvoid243 Jul 15, 2026
a284f50
docs: design workspace fullscreen mode
elecvoid243 Jul 15, 2026
768d021
docs: plan workspace fullscreen implementation
elecvoid243 Jul 15, 2026
256b284
feat(dashboard): add workspace fullscreen mode
elecvoid243 Jul 15, 2026
1214f21
feat(dashboard): split workspace fullscreen into global and inner
elecvoid243 Jul 15, 2026
7046b63
docs: design workspace history sidebar
elecvoid243 Jul 15, 2026
1b005e3
docs: plan workspace history sidebar implementation
elecvoid243 Jul 15, 2026
a4d5ab3
Merge branch 'AstrBotDevs:master' into all
elecvoid243 Jul 15, 2026
8e735a4
feat(dashboard): add workspace history sidebar i18n keys
elecvoid243 Jul 15, 2026
49933d8
Merge branch 'all' of https://github.com/elecvoid243/AstrBot into all
elecvoid243 Jul 15, 2026
ae037dd
feat(dashboard): implement workspace history sidebar
elecvoid243 Jul 15, 2026
9ee117a
feat(dashboard): make per-file history SHAs deep-link to global log
elecvoid243 Jul 15, 2026
7ef41ae
fix(dashboard): restore file preview when docsRoot is "."
elecvoid243 Jul 15, 2026
a4d7544
Merge remote-tracking branch 'upstream/master' into all
elecvoid243 Jul 16, 2026
6bad23b
docs: design git repo init prompt in GitDiffSidebar
elecvoid243 Jul 16, 2026
6491cb9
docs: plan git repo init prompt in GitDiffSidebar
elecvoid243 Jul 16, 2026
73e1999
feat(dashboard): parse git-repo-probe response
elecvoid243 Jul 16, 2026
e2a8ba6
feat(dashboard): add git-repo-probe composable with ETag cache
elecvoid243 Jul 16, 2026
79e2856
feat(dashboard): add GitRepoInitPrompt component
elecvoid243 Jul 16, 2026
ff1f9b1
feat(dashboard): wire git-repo-probe composable into GitDiffSidebar
elecvoid243 Jul 16, 2026
bed1156
feat(dashboard): add repo-init prompt slot in GitDiffSidebar
elecvoid243 Jul 16, 2026
f8ed4d2
feat(dashboard): add repo-init i18n keys for 3 locales
elecvoid243 Jul 16, 2026
fd742bc
fix(dashboard): align git-repo-probe parser with actual backend envelope
elecvoid243 Jul 16, 2026
c1eb0cb
fix(dashboard): make git-repo-probe polling refresh immediately on start
elecvoid243 Jul 16, 2026
987d59c
fix(dashboard): unwrap OpenAPI envelope in git-repo-probe
elecvoid243 Jul 16, 2026
f20a34e
refactor(dashboard): drop git-repo-probe polling, check once on sideb…
elecvoid243 Jul 16, 2026
bcc3675
perf(dashboard): gate all git composable polling on isGitRepo
elecvoid243 Jul 16, 2026
9497ff7
feat(dashboard): send force=true on git-init for loaded projects
elecvoid243 Jul 16, 2026
4e8d992
feat: show prunable worktree tabs with warning badge and migrate to g…
elecvoid243 Jul 16, 2026
ffb409f
fix: correct worktree selection, dirty count field, and stale scroll …
elecvoid243 Jul 16, 2026
f96544b
docs: add design spec for AI-generated commit message in GitCommitDialog
elecvoid243 Jul 17, 2026
2284c72
docs: add implementation plan for AI-generated commit message
elecvoid243 Jul 17, 2026
0715eb4
feat: add bilingual commit message prompt builder
elecvoid243 Jul 17, 2026
f7898e4
feat: add useSpcodeBtw composable for /spcode/btw endpoint
elecvoid243 Jul 17, 2026
e394959
feat: add i18n keys for AI commit message generation
elecvoid243 Jul 17, 2026
982262f
feat: add AI generate button with language toggle to GitCommitDialog
elecvoid243 Jul 17, 2026
9b218a2
feat: pass umo and worktree props to GitCommitDialog
elecvoid243 Jul 17, 2026
93e2210
feat(dashboard): 提交信息 AI 生成改用结构化 JSON 回复
elecvoid243 Jul 17, 2026
753d1f6
fix(git): 仅允许在已暂存页签提交,防止漏提未暂存改动
elecvoid243 Jul 17, 2026
5aa923e
feat(dashboard): 文件浏览器预览支持编辑并保存工作区文件
elecvoid243 Jul 17, 2026
a111847
feat(dashboard): 文档管理器新增文档搜索功能
elecvoid243 Jul 17, 2026
16b9d83
docs: add selection comment design spec
elecvoid243 Jul 17, 2026
2cda37b
docs: add selection comment implementation plan
elecvoid243 Jul 17, 2026
f9a6d14
feat(comments): pure range helpers + renderWindow range branch + File…
elecvoid243 Jul 17, 2026
b687511
feat(comments): addSelectionComment API
elecvoid243 Jul 17, 2026
4129019
feat(comments): add SelectionActionMenu component
elecvoid243 Jul 17, 2026
3a88e46
feat(comments): FileBrowserCodeView selection-comment support
elecvoid243 Jul 17, 2026
bde3b1d
feat(dashboard): 预览面板 Markdown 渲染视图、文档管理预设目录与面包屑根导航修复
elecvoid243 Jul 17, 2026
767ef37
feat(comments): i18n rangeLabel key for three locales
elecvoid243 Jul 17, 2026
0b8ba0c
feat(comments): FileCommentEditor range mode
elecvoid243 Jul 17, 2026
d660324
feat(comments): preview dialog renders range comments
elecvoid243 Jul 17, 2026
8175310
feat(comments): workspace selection-comment wiring
elecvoid243 Jul 17, 2026
0eecf75
feat(comments): document-manager selection-comment wiring
elecvoid243 Jul 17, 2026
023a7a8
fix(comments): copy menu invisible in rendered markdown view
elecvoid243 Jul 17, 2026
b9b28ec
feat(dashboard): unify document-manager toolbar with workspace style,…
elecvoid243 Jul 17, 2026
b1ac21b
feat(dashboard): document-manager meta header row (name/size/mtime)
elecvoid243 Jul 17, 2026
6d9adfe
fix(dashboard): workspace tree collapse button always visible
elecvoid243 Jul 17, 2026
2351c54
feat(dashboard): revert commit action in git history view
elecvoid243 Jul 17, 2026
9c7f000
docs: gitignore editor design spec
elecvoid243 Jul 17, 2026
92edb4f
docs: gitignore editor implementation plan
elecvoid243 Jul 17, 2026
a7b589c
feat(dashboard): GitIgnoreEditor overlay component
elecvoid243 Jul 17, 2026
976ca45
feat(dashboard): wire gitignore editor into git diff view
elecvoid243 Jul 17, 2026
e07964e
perf(dashboard): uncontrolled ShikiEditor with idle-scheduled highlight
elecvoid243 Jul 17, 2026
b26d532
perf(dashboard): sink gitignore editing state out of the sidebar
elecvoid243 Jul 17, 2026
28d1308
perf(dashboard): sink workspace editor state out of the preview pane
elecvoid243 Jul 17, 2026
d46a32e
feat(dashboard): add rename and delete actions to the workspace file …
elecvoid243 Jul 17, 2026
b64bdbc
docs: add CodeMirror file editor design spec
elecvoid243 Jul 18, 2026
e103784
docs: add CodeMirror file editor implementation plan
elecvoid243 Jul 18, 2026
91bd610
feat(dashboard): add CodeMirror 6 language packs for the file editor
elecvoid243 Jul 18, 2026
99b89c1
feat(dashboard): add lazy CodeMirror language mapping for file editing
elecvoid243 Jul 18, 2026
635c25e
feat(dashboard): add CodeMirrorEditor file editing component
elecvoid243 Jul 18, 2026
363337c
feat(dashboard): switch gitignore editor to CodeMirrorEditor
elecvoid243 Jul 18, 2026
81a9a11
feat(dashboard): switch workspace file editor to CodeMirrorEditor
elecvoid243 Jul 18, 2026
293b6cd
refactor(dashboard): remove the superseded ShikiEditor overlay component
elecvoid243 Jul 18, 2026
4bf3e94
feat(dashboard): switch document editor to CodeMirrorEditor with mark…
elecvoid243 Jul 18, 2026
19b7097
feat(dashboard): move gitignore edit entry into the commit bar
elecvoid243 Jul 18, 2026
bf263d7
fix(dashboard): correct gitignore button i18n key and add missing en/…
elecvoid243 Jul 18, 2026
15f0d68
docs: add git-stats heatmap panel design spec
elecvoid243 Jul 18, 2026
032be35
docs: add git-stats heatmap implementation plan
elecvoid243 Jul 18, 2026
d2392cd
feat(dashboard): add git-stats response parser
elecvoid243 Jul 18, 2026
ee4f8b1
feat(dashboard): add useSpcodeGitStats composable
elecvoid243 Jul 18, 2026
0f46c75
feat(dashboard): add GitStatsPanel component
elecvoid243 Jul 18, 2026
760726f
feat(dashboard): embed GitStatsPanel in GitLogView with filter linkage
elecvoid243 Jul 18, 2026
655e586
feat(dashboard): wire git-stats panel into GitDiffSidebar with persis…
elecvoid243 Jul 18, 2026
60aafce
feat(dashboard): add git-stats panel i18n (en/zh/ru)
elecvoid243 Jul 18, 2026
9127080
feat(dashboard): colorize git stats +/- and redesign log filter grid
elecvoid243 Jul 18, 2026
a1f5137
feat(chat): support drag-to-chat from sidebar file browser
elecvoid243 Jul 18, 2026
6e12927
docs(spec): add git-stats heatmap range adjustability design
Jul 18, 2026
9878611
docs(plan): add git-stats heatmap range implementation plan
Jul 18, 2026
395e99d
feat(dashboard): add GitStatsRange types and preset helper
Jul 18, 2026
def765e
feat(dashboard): support since/until in useSpcodeGitStats
Jul 18, 2026
2e6314d
feat(dashboard): i18n for git-stats heatmap range UI
Jul 18, 2026
7a0de2d
feat(dashboard): add heatmap range popover to GitStatsPanel
Jul 18, 2026
1e02d25
feat(dashboard): drive heatmap grid width from range prop
Jul 18, 2026
a30cc1f
refactor(dashboard): pass range prop through GitLogView
Jul 18, 2026
44303ac
feat(dashboard): own + persist heatmap range in sidebar
Jul 18, 2026
28cbb89
fix(dashboard): shrink heatmap cells and right-size range popover font
Jul 18, 2026
e6314ea
fix(dashboard): keep 6mo heatmap cells large, only compact beyond 26 …
Jul 18, 2026
73accef
fix(dashboard): forward range since/until to git-stats so hot files u…
Jul 18, 2026
f8f0249
Merge branch 'feat/git-log-filter-redesign' into all
Jul 18, 2026
ee35264
fix(dashboard): pin ≤6mo heatmap cells to the 6mo size, leave shorter…
elecvoid243 Jul 18, 2026
4af5701
fix(dashboard): show 7 actual cells for 1w on Sunday
elecvoid243 Jul 18, 2026
efa1fd7
Merge remote-tracking branch 'upstream/master' into all
elecvoid243 Jul 19, 2026
a0585de
update readme
elecvoid243 Jul 19, 2026
2efbbf8
no message
elecvoid243 Jul 19, 2026
22704c3
no message
elecvoid243 Jul 19, 2026
b2b2581
feat(chat): enhance git diff sidebar with stats heatmap and fullscree…
elecvoid243 Jul 19, 2026
bdfcd28
feat(dashboard): add interactiveChoice.cancelled i18n key (zh-CN/en-U…
elecvoid243 Jul 19, 2026
ad091c9
feat(dashboard): add cancelledStates bucket + reconcile orphan detection
elecvoid243 Jul 19, 2026
b0cb40a
feat(dashboard): dispatch + route interactive_choice_resolved SSE events
elecvoid243 Jul 19, 2026
91eb0c4
fix(dashboard): filter applyInteractiveChoiceResolved on reason='canc…
elecvoid243 Jul 19, 2026
d736185
feat(dashboard): add cancelled state to InteractiveChoiceBox
elecvoid243 Jul 19, 2026
ec78200
docs(dashboard): update InteractiveChoiceBox header for 5-state v1.2
elecvoid243 Jul 19, 2026
112e556
Merge branch 'feature/v1.2-cancelled-state-dashboard' into all
elecvoid243 Jul 20, 2026
3b3aac6
fix(dashboard): fix interactive box display when timeout
elecvoid243 Jul 20, 2026
339e628
fix(dashboard): sync stagedFiles from the authoritative git-status sn…
elecvoid243 Jul 20, 2026
21b30fe
Merge remote-tracking branch 'upstream/master' into all
elecvoid243 Jul 20, 2026
b84c6b6
style(chat): widen git diff sidebar resizer hit area to 6px
elecvoid243 Jul 20, 2026
13f1ec6
feat(chat): add path input to file browser breadcrumb
elecvoid243 Jul 20, 2026
95b193f
feat(chat): add fake search bar trigger with shortcut hint
elecvoid243 Jul 20, 2026
611b33c
docs: add recent files design spec
elecvoid243 Jul 20, 2026
2272648
docs: add recent files implementation plan
elecvoid243 Jul 20, 2026
cba99f4
feat(dashboard): add useRecentFiles composable skeleton with types an…
elecvoid243 Jul 20, 2026
0bfc54c
feat(dashboard): useRecentFiles.recordOpen - dedupe, LIFO, trim, path…
elecvoid243 Jul 20, 2026
ddcf872
feat(dashboard): useRecentFiles.remove and clear - single-row + full-…
elecvoid243 Jul 20, 2026
0c72e0e
feat(dashboard): useRecentFiles reactive worktree switching
elecvoid243 Jul 20, 2026
ed82f3f
feat(dashboard): add RecentFilesBlock component (default collapsed + …
elecvoid243 Jul 20, 2026
19f5037
feat(dashboard): add i18n keys for RecentFilesBlock (en-US + zh-CN)
elecvoid243 Jul 20, 2026
50f6257
feat(dashboard): GitDiffSidebar records file openings into useRecentF…
elecvoid243 Jul 20, 2026
0501e2c
feat(dashboard): FileBrowserView embeds RecentFilesBlock above FileTr…
elecvoid243 Jul 20, 2026
db94049
fix(dashboard): move recent-files watcher after currentRoot declarati…
elecvoid243 Jul 20, 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
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ __pycache__
.conda/
uv.lock
.coverage
.codegraph/

# IDE and editors
.vscode
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
> This Branch is for *spzx*, use it with the plugins following
>
> **SPCODE TOOLKIT** (https://github.com/elecvoid243/astrbot_plugin_spcode_toolkit)
>
> **NEO CARGO MANAGER** (https://github.com/elecvoid243/astrbot_plugin_neo_cargo)
>
> **ASK USER CHOICE** (https://github.com/elecvoid243/astrbot_plugin_ask_user_choice)
>
> **LIGHTRAG ADAPDATOR** (https://github.com/elecvoid243/astrbot_plugin_lightrag)
>
>

![AstrBot-Logo-Simplified](https://github.com/user-attachments/assets/36fb04e4-cc75-4454-bd8b-049d11aa86f9)


Expand Down
6 changes: 6 additions & 0 deletions README_zh.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
> 本分支基于Astrbot原始项目,用以支持spzx。请与以下插件配套使用
> **SPCODE TOOLKIT** (https://github.com/elecvoid243/astrbot_plugin_spcode_toolkit)
> **NEO CARGO MANAGER** (https://github.com/elecvoid243/astrbot_plugin_neo_cargo)
> **ASK USER CHOICE** (https://github.com/elecvoid243/astrbot_plugin_ask_user_choice)
> **LIGHTRAG ADAPDATOR** (https://github.com/elecvoid243/astrbot_plugin_lightrag)

![AstrBot-Logo-Simplified](https://github.com/user-attachments/assets/36fb04e4-cc75-4454-bd8b-049d11aa86f9)

<div align="center">
Expand Down
4 changes: 2 additions & 2 deletions astrbot/builtin_stars/builtin_commands/commands/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ def __init__(self, context: star.Context) -> None:

async def update_dashboard(self, event: AstrMessageEvent) -> None:
"""更新管理面板"""
await event.send(MessageChain().message("⏳ Updating dashboard..."))
await event.send(MessageChain().message("⏳ 正在更新管理面板..."))
await download_dashboard(version=f"v{VERSION}", latest=False)
await event.send(MessageChain().message("✅ Dashboard updated successfully."))
await event.send(MessageChain().message("✅ 管理面板更新成功。"))
152 changes: 124 additions & 28 deletions astrbot/builtin_stars/builtin_commands/commands/conversation.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import json

from sqlalchemy import case, func, select
from sqlmodel import col

from astrbot.api import sp, star
from astrbot.api.event import AstrMessageEvent, MessageEventResult
from astrbot.core import logger
from astrbot.core.agent.context.token_counter import EstimateTokenCounter
from astrbot.core.agent.message import Message
from astrbot.core.agent.runners.deerflow.constants import (
DEERFLOW_AGENT_RUNNER_PROVIDER_ID_KEY,
DEERFLOW_PROVIDER_TYPE,
Expand All @@ -12,6 +16,7 @@
from astrbot.core.agent.runners.deerflow.deerflow_api_client import DeerFlowAPIClient
from astrbot.core.db.po import ProviderStat
from astrbot.core.utils.active_event_registry import active_event_registry
from astrbot.core.utils.llm_metadata import LLM_METADATAS

from .utils.rst_scene import RstScene

Expand Down Expand Up @@ -142,8 +147,8 @@ async def reset(self, message: AstrMessageEvent) -> None:
if required_perm == "admin" and message.role != "admin":
message.set_result(
MessageEventResult().message(
f"Reset command requires admin permission in {scene.name} scenario, "
f"you (ID {message.get_sender_id()}) are not admin, cannot perform this action.",
f"{scene.name}场景下,重置命令需要管理员权限,"
f" (ID {message.get_sender_id()}) 不是管理员,无法执行此操作。",
),
)
return
Expand All @@ -156,16 +161,12 @@ async def reset(self, message: AstrMessageEvent) -> None:
umo,
agent_runner_type,
)
message.set_result(
MessageEventResult().message("✅ Conversation reset successfully.")
)
message.set_result(MessageEventResult().message("✅ 会话重置成功。"))
return

if not self.context.get_using_provider(umo):
message.set_result(
MessageEventResult().message(
"😕 Cannot find any LLM provider. Configure one first."
),
MessageEventResult().message("😕 未找到任何 LLM Provider,请先配置。"),
)
return

Expand All @@ -174,7 +175,7 @@ async def reset(self, message: AstrMessageEvent) -> None:
if not cid:
message.set_result(
MessageEventResult().message(
"😕 You are not in a conversation. Use /new to create one.",
"😕 您当前不在任何会话中,请使用 /new 创建一个。",
),
)
return
Expand All @@ -187,7 +188,31 @@ async def reset(self, message: AstrMessageEvent) -> None:
[],
)

ret = "✅ Conversation reset successfully."
ret = "✅ 会话重置成功。"

# 清理该会话下的所有 subagent
try:
from astrbot.core.subagent_manager import SubAgentManager

cleanup_result = await SubAgentManager.cleanup_session(umo)
if cleanup_result["status"] == "cleaned":
cleaned_count = len(cleanup_result["cleaned_agents"])
if cleaned_count > 0:
ret += f" 🧹 同时清理了 {cleaned_count} 个子智能体: {', '.join(cleanup_result['cleaned_agents'])}。"
except Exception as e:
logger.warning(f"[SubAgent] Failed to cleanup subagents on /reset: {e}")

# 清理该会话下的所有 subagent
try:
from astrbot.core.subagent_manager import SubAgentManager

cleanup_result = await SubAgentManager.cleanup_session(umo)
if cleanup_result["status"] == "cleaned":
cleaned_count = len(cleanup_result["cleaned_agents"])
if cleaned_count > 0:
ret += f" 🧹 Also cleaned {cleaned_count} subagent(s): {', '.join(cleanup_result['cleaned_agents'])}."
except Exception as e:
logger.warning(f"[SubAgent] Failed to cleanup subagents on /reset: {e}")

Comment on lines +205 to 216

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This block of code to clean up subagents is a duplicate of the one above (lines 193-203). This causes SubAgentManager.cleanup_session(umo) to be called twice and appends a second cleanup message to the result string, one in Chinese and one in English.

This is likely a copy-paste error and should be removed to avoid redundant operations and confusing output.

message.set_extra("_clean_group_context_session", True)

Expand All @@ -210,13 +235,13 @@ async def stop(self, message: AstrMessageEvent) -> None:
if stopped_count > 0:
message.set_result(
MessageEventResult().message(
f"✅ Requested to stop {stopped_count} running tasks."
f"✅ 已请求停止 {stopped_count} 个运行中的任务。"
)
)
return

message.set_result(
MessageEventResult().message("✅ No running tasks in the current session.")
MessageEventResult().message("✅ 当前会话中没有运行中的任务。")
)

async def new_conv(self, message: AstrMessageEvent) -> None:
Expand All @@ -230,9 +255,7 @@ async def new_conv(self, message: AstrMessageEvent) -> None:
message.unified_msg_origin,
agent_runner_type,
)
message.set_result(
MessageEventResult().message("✅ New conversation created.")
)
message.set_result(MessageEventResult().message("✅ 新对话已创建。"))
return

active_event_registry.stop_all(message.unified_msg_origin, exclude=message)
Expand All @@ -246,20 +269,95 @@ async def new_conv(self, message: AstrMessageEvent) -> None:
message.set_extra("_clean_group_context_session", True)

message.set_result(
MessageEventResult().message(
f"✅ Switched to new conversation: {cid[:4]}。"
),
MessageEventResult().message(f"✅ 已切换到新对话: {cid[:4]}。"),
)

async def cmd_context(self, message: AstrMessageEvent) -> None:
"""显示当前会话上下文窗口的 token 占用情况"""
umo = message.unified_msg_origin
cid = await self.context.conversation_manager.get_curr_conversation_id(umo)

if not cid:
message.set_result(
MessageEventResult().message(
"\u274c 当前不在任何会话中。使用 /new 创建一个。"
),
)
return

conv = await self.context.conversation_manager.get_conversation(umo, cid)
if not conv:
message.set_result(
MessageEventResult().message("\u274c 无法获取会话信息。")
)
return

# 获取当前 provider 及 max_context_tokens
provider = self.context.get_using_provider(umo)
if not provider:
message.set_result(
MessageEventResult().message("\u274c 未配置 LLM Provider。")
)
return

model_name = provider.get_model() or "unknown"
max_tokens = provider.provider_config.get("max_context_tokens", 0)
if max_tokens <= 0:
model_info = LLM_METADATAS.get(model_name)
if model_info:
max_tokens = model_info["limit"]["context"]
else:
max_tokens = 128000

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The value 128000 is a magic number used as a fallback for max_context_tokens. To improve maintainability and readability, it's best to define this as a named constant at the top of the file or in a relevant constants module.

For example:

# At the top of the file
DEFAULT_MAX_CONTEXT_TOKENS = 128_000

# In this function
...
max_tokens = DEFAULT_MAX_CONTEXT_TOKENS


# 解析 history 为 Message 列表并估算 token
raw_history = json.loads(conv.history) if conv.history else []
messages = [Message(**msg) for msg in raw_history]

counter = EstimateTokenCounter()
trusted = conv.token_usage if messages else 0
estimated = counter.count_tokens(messages, trusted_token_usage=trusted)

# 计算使用率 + 进度条
usage_pct = (estimated / max_tokens * 100) if max_tokens > 0 else 0
bar_width = 20
filled = int(bar_width * min(usage_pct, 100) / 100)
bar = "\u2588" * filled + "\u2591" * (bar_width - filled)

if usage_pct < 50:
level = "\U0001f7e2 充裕"
hint = ""
elif usage_pct < 75:
level = "\U0001f7e1 适中"
hint = ""
else:
level = "\U0001f534 紧张"
hint = "\U0001f4a1 上下文即将用尽,建议发送 /reset 重置或 /new 新建会话。如果继续会话,将在用量超过 82% 时进行自动压缩。"

ret = [
f"\U0001f4ca 上下文占用 (会话: {cid[:8]}...)",
f"模型: {model_name}",
f"占用: {estimated:,} / {max_tokens:,} tokens",
f"使用率: {usage_pct:.1f}% [{bar}]",
f"状态: {level}",
]
if hint:
ret.append(hint)
if trusted > 0:
ret.append("\U0001f4a1 精度: 基于 LLM 返回的精确值")
elif messages:
ret.append("\U0001f4a1 精度: 本地字符估算 (仅供参考)")

message.set_result(MessageEventResult().message("\n".join(ret)))

async def stats(self, message: AstrMessageEvent) -> None:
"""Show token usage statistics for the current conversation."""
"""显示当前会话的 Token 用量统计。"""
umo = message.unified_msg_origin
cid = await self.context.conversation_manager.get_curr_conversation_id(umo)

if not cid:
message.set_result(
MessageEventResult().message(
"❌ You are not in a conversation. Use /new to create one."
"❌ 您当前不在任何会话中,请使用 /new 创建一个。"
),
)
return
Expand Down Expand Up @@ -289,9 +387,7 @@ async def stats(self, message: AstrMessageEvent) -> None:

if stats.record_count == 0:
message.set_result(
MessageEventResult().message(
"📊 No stats available for this conversation yet."
),
MessageEventResult().message("📊 该会话暂无统计数据。"),
)
return

Expand All @@ -301,11 +397,11 @@ async def stats(self, message: AstrMessageEvent) -> None:
total_tokens = total_input_other + total_input_cached + total_output

ret = (
f"📊 Conversation Token usage (ID: {cid[:8]}...)\n"
f"Total: {total_tokens:,}\n"
f"Input (cached): {total_input_cached:,}\n"
f"Input (other): {total_input_other:,}\n"
f"Output: {total_output:,}\n"
f"📊 会话 Token 用量 (ID: {cid[:8]}...)\n"
f"总计: {total_tokens:,}\n"
f"输入 (缓存命中): {total_input_cached:,}\n"
f"输入 (其他): {total_input_other:,}\n"
f"输出: {total_output:,}\n"
)

message.set_result(MessageEventResult().message(ret))
4 changes: 1 addition & 3 deletions astrbot/builtin_stars/builtin_commands/commands/help.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,7 @@ async def help(self, event: AstrMessageEvent) -> None:
dashboard_version = await get_dashboard_version()
command_lines = await self._build_reserved_command_lines()
commands_section = (
"\n".join(command_lines)
if command_lines
else "No enabled built-in commands."
"\n".join(command_lines) if command_lines else "没有已启用的内置指令。"
)

msg_parts = [
Expand Down
36 changes: 13 additions & 23 deletions astrbot/builtin_stars/builtin_commands/commands/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ async def provider(

if reachability_check_enabled and (llms or ttss or stts):
await event.send(
MessageEventResult().message("👀 Testing provider reachability...")
MessageEventResult().message("👀 正在测试 Provider 可达性...")
)

llm_data, tts_data, stt_data = await asyncio.gather(
Expand Down Expand Up @@ -177,24 +177,22 @@ async def provider(
line += " 👈"
parts.append(line + "\n")

parts.append("\nUse /provider <idx> to switch LLM providers.")
parts.append("\n使用 /provider <idx> 切换 LLM Provider。")
ret = "".join(parts)

if ttss:
ret += "\nUse /provider tts <idx> to switch TTS providers."
ret += "\n使用 /provider tts <idx> 切换 TTS Provider。"
if stts:
ret += "\nUse /provider stt <idx> to switch STT providers."
ret += "\n使用 /provider stt <idx> 切换 STT Provider。"

event.set_result(MessageEventResult().message(ret))
elif idx == "tts":
if idx2 is None:
event.set_result(
MessageEventResult().message("Please enter the index.")
)
event.set_result(MessageEventResult().message("请输入序号。"))
return
if idx2 > len(self.context.get_all_tts_providers()) or idx2 < 1:
event.set_result(
MessageEventResult().message("❌ Invalid provider index.")
MessageEventResult().message("❌ 无效的 Provider 序号。")
)
return
provider = self.context.get_all_tts_providers()[idx2 - 1]
Expand All @@ -204,18 +202,14 @@ async def provider(
provider_type=ProviderType.TEXT_TO_SPEECH,
umo=umo,
)
event.set_result(
MessageEventResult().message(f"✅ Successfully switched to {id_}.")
)
event.set_result(MessageEventResult().message(f"✅ 已成功切换到 {id_}."))
elif idx == "stt":
if idx2 is None:
event.set_result(
MessageEventResult().message("Please enter the index.")
)
event.set_result(MessageEventResult().message("请输入序号。"))
return
if idx2 > len(self.context.get_all_stt_providers()) or idx2 < 1:
event.set_result(
MessageEventResult().message("❌ Invalid provider index.")
MessageEventResult().message("❌ 无效的 Provider 序号。")
)
return
provider = self.context.get_all_stt_providers()[idx2 - 1]
Expand All @@ -225,13 +219,11 @@ async def provider(
provider_type=ProviderType.SPEECH_TO_TEXT,
umo=umo,
)
event.set_result(
MessageEventResult().message(f"✅ Successfully switched to {id_}.")
)
event.set_result(MessageEventResult().message(f"✅ 已成功切换到 {id_}."))
elif isinstance(idx, int):
if idx > len(self.context.get_all_providers()) or idx < 1:
event.set_result(
MessageEventResult().message("❌ Invalid provider index.")
MessageEventResult().message("❌ 无效的 Provider 序号。")
)
return
provider = self.context.get_all_providers()[idx - 1]
Expand All @@ -241,8 +233,6 @@ async def provider(
provider_type=ProviderType.CHAT_COMPLETION,
umo=umo,
)
event.set_result(
MessageEventResult().message(f"✅ Successfully switched to {id_}.")
)
event.set_result(MessageEventResult().message(f"✅ 已成功切换到 {id_}."))
else:
event.set_result(MessageEventResult().message("❌ Invalid parameter."))
event.set_result(MessageEventResult().message("❌ 无效的参数。"))
Loading
Loading