Commit Graph

2211 Commits

Author SHA1 Message Date
程序员阿江(Relakkes) 02a4a66a11 fix: filter external sources from ClawHub search results 2026-09-21 22:14:36 +08:00
程序员阿江(Relakkes) 9bf6e76896 feat: support AGENTS.md project instructions 2026-09-21 20:45:58 +08:00
程序员阿江(Relakkes) 0e07a4e44f Merge commit 'e4d85a6d6' 2026-09-21 20:22:04 +08:00
程序员阿江(Relakkes) e4d85a6d66 fix: stabilize chat history scrolling and subagent history loading 2026-09-21 20:21:59 +08:00
程序员阿江(Relakkes) 366fe72792 fix(desktop): resolve home-relative HTML preview paths 2026-09-21 18:05:50 +08:00
程序员阿江(Relakkes) 3dbf7493a2 fix(desktop): query session suggestions directly from SQLite 2026-09-21 12:04:19 +08:00
程序员阿江(Relakkes) 7c7ce7d6b9 feat(desktop): add independent session collaboration 2026-09-21 01:16:27 +08:00
程序员阿江(Relakkes) 0f2c2b2c6e fix: stream background task completion while the model is working
Publish root task terminal notifications when queued, preserving model follow-ups and lifecycle ordering without duplicate delivery.

Refs #1352, #1345 (background task status only; other reported issues remain outside this fix).
2026-09-20 22:16:46 +08:00
程序员阿江(Relakkes) 83b0242558 fix: resolve reproduced issue regressions and add Zed support
- Restore file-tree Add to chat and keyboard menu behavior (#1322).
- Preserve nested OpenAI cache hits beside zero-valued cache fields (#1327).
- Allow exact development renderer CORS preflights while retaining auth (#1335).
- Prevent stale transcripts from restoring explicitly cleared goals (#1339).
- Recover interrupted auto-dream attempts while preserving legacy stamps (#1349).
- Add Zed to the existing editor discovery and launch menu (#1346).

Refs #1322, #1327, #1335, #1339, #1349, #1346

Validation: local before/after reproductions, browser smoke, server 5537
and desktop 6086 tests passed; provider/chat/agent-flow/persistence checks
passed. Changed-line coverage is 98.23%. The full coverage gate remains
blocked by the unchanged IM slow-drip test; native signing/package
validation is incomplete.
2026-09-20 20:29:40 +08:00
程序员阿江(Relakkes) 42915081ca fix(desktop): preserve message order when returning to latest history 2026-09-20 18:35:20 +08:00
程序员阿江(Relakkes) b8c7a11507 fix: complete AruHub model mappings and limit sponsor star 2026-09-20 17:15:18 +08:00
程序员阿江(Relakkes) a16d9847fb feat: add AruHub sponsor and provider preset 2026-09-20 16:50:45 +08:00
程序员阿江(Relakkes) 239ecda192 release: v0.6.5 v0.6.5 2026-09-20 15:21:48 +08:00
程序员阿江(Relakkes) e14ce97725 merge: integrate model selection race fix 2026-09-20 03:57:43 +08:00
程序员阿江(Relakkes) a800fe0063 fix(desktop): preserve model selection across stale session refreshes 2026-09-20 03:57:36 +08:00
程序员阿江(Relakkes) 6c75668334 fix(desktop): streamline provider setup and OpenCode signup 2026-09-20 03:50:15 +08:00
程序员阿江(Relakkes) e36538f670 fix(server): restore inspection of large records and partial transcripts 2026-09-20 03:16:49 +08:00
程序员阿江(Relakkes) d16aabcf74 fix(perf): restore continuous history scrolling and bound search indexing 2026-09-20 03:02:30 +08:00
程序员阿江(Relakkes) 22e050f463 fix(desktop): restore slash capability lists and localize computer use
Show frequent commands, skills and plugins in matching visual and keyboard order.
Update discovery hints and computer-use labels across all five locales.
2026-09-20 02:24:38 +08:00
程序员阿江(Relakkes) 2d4f48765f feat(desktop): streamline composer capability discovery
Unify skill, plugin and file search across the plus and mention menus.
Prioritize common slash commands and hide withdrawn managed skill packs.
Refresh capability candidates when reopening the composer menu.
2026-09-20 01:25:45 +08:00
程序员阿江(Relakkes) 8ad8a011f4 fix(models): add Opus 5 catalog and runtime support 2026-09-19 22:25:23 +08:00
程序员阿江(Relakkes) 27f660fe5c fix(perf): bound large session history and tracing resource usage
Page transcript and trace reads, bound UI caches and retained task records,
and replace full-file background polling with incremental projections.
Preserve recovery and ownership semantics across pages and cancel stale work.
2026-09-19 20:29:20 +08:00
程序员阿江(Relakkes) 6bfed2b774 fix(desktop): open native folder dialog when creating projects 2026-09-19 18:36:48 +08:00
程序员阿江(Relakkes) 30855c77d4 feat(desktop): allow switching execution model on plan approval 2026-09-19 13:13:18 +08:00
程序员阿江(Relakkes) 2981c29b49 feat(desktop): allow switching execution model on plan approval
Add an execution-model picker row to the plan approval bar so users can
approve a plan and switch to a different model for implementation in one
step. Same-provider switches use the CLI's in-process set_model control
request (no restart); cross-provider switches approve → interrupt →
restart the CLI with the new env → auto-continue execution.
2026-09-19 13:10:50 +08:00
程序员阿江(Relakkes) 40dfc81e9a feat(desktop): surface chat capabilities in a searchable composer menu
The "+" composer menu used to offer only file attachments and slash
commands, so skills, connectors, agents, agent teams, Computer Use and
workflows had no discoverable entry point beyond natural language. The
menu now opens a searchable panel — shared verbatim by both composers —
with drill-in sub-lists backed by the existing APIs: skills and
connected connectors insert mention badges, agents and workflows insert
their slash text, teams offer a create-via-chat prompt seed plus
workbench shortcuts, and Computer Use gets an inline global switch.

Slash commands that duplicate a permanent GUI surface (status, cost,
context, config, doctor, memory, plugin, help) no longer crowd the
empty-query listing; typing their names still matches and runs them.
2026-09-19 11:26:29 +08:00
程序员阿江(Relakkes) ce87bb1712 feat(desktop): redesign context usage popover around remaining window
The old panel led with a per-category breakdown (Messages / Skills /
System prompt) that answers a diagnostic question, not the ones users
actually watch: how much window is left, how fast the session is, and
how well the cache is doing.

Reorder the panel to match: the headline is now the remaining window,
a single segmented bar compresses the composition into one strip with
the per-category list behind a collapsed toggle, and the session stats
promote speed / cache hit / cost to a three-stat row.
2026-09-19 10:20:00 +08:00
程序员阿江(Relakkes) 0f924d35f7 fix(connectors): stop stale enabledPlugins tombstones from failing skill installs
A first-install failure wrote enabled=false into settings for a plugin
that was never published to a marketplace. Every later plugin load then
reported plugin-not-found for that inert entry, and the session reload
at the end of any connector prepare treated those foreign errors as a
failure, so all skill connectors died in the installing-plugin phase.

Align with upstream semantics (verified against codex-rs and the ChatGPT
desktop app): never write a disabled tombstone for an unpublished plugin,
treat an explicitly disabled missing entry as inert instead of a load
error, and stop letting unrelated plugin errors veto a connector reload.
2026-09-19 10:03:57 +08:00
程序员阿江(Relakkes) 4aca1d98c0 feat(desktop): search and create projects from the composer picker
The composer directory picker only showed ten recent projects with no
search and no way to name one. Load the full project list with a deep
session-history scan, filter it client-side with a fuzzy scorer, and
offer a "new project" entry that names a folder through the existing
ProjectEditorModal and selects it as the working directory.

Also key the recent-projects response cache by scan depth so a shallow
request can no longer truncate a deeper one.
2026-09-19 09:27:16 +08:00
程序员阿江(Relakkes) 451621a58a fix(desktop): serve trace views from the index instead of rereading JSONL
Opening or polling a trace used to read and parse the whole session JSONL
on every request, so a live multi-hundred-MB trace stalled the shared
server for seconds at a time and the trace list could trigger full
rebuilds for every file on the page.

The trace detail now serves the SQLite projection: summaries and call
locators come from the index, calls ship as body-less shells, and the
detail pane keeps fetching one full call at a time through the existing
byte-range endpoint. The list answers from stored summaries and defers
projection of missing or stale sources to a serialized background queue,
so no request path performs a full file read. A schema v5 migration adds
the body facts the tree header shows (request/response bytes, response
status, event title/message) and marks old projections for rebuild,
since shells built from them would look permanently pending.

Also fixes the model-count bookkeeping that violated the call_count
CHECK constraint when a rewritten call dropped a model to zero, which
used to degrade the projection and force a full-rescan fallback.
2026-09-19 01:13:25 +08:00
程序员阿江(Relakkes) 491f4492f1 fix(cli): make control-channel task stops idempotent for evicted tasks
Shell tasks are evicted from the CLI registry the turn after they terminate
(and a process restart clears it outright), but the desktop Activity panel
learns about termination only through forwarded events. When one is missed,
the panel keeps showing the task as running and Stop answers with
'No task found with ID' — and for Agent tasks the failure was latched and
replayed on every WS reconnect, flooding the chat with the same error.

Stopping a task that is already gone is not an error: the goal state (not
running) already holds. stopTaskFromControlRequest now answers not_found
with an idempotent success carrying a structured reason, and the server
converges on it: it untracks the task and synthesizes the terminal
task_notification so clients drop the stale running entry instead of
reporting background_task_stop_failed. The LLM-facing TaskStop tool keeps
erroring so the model learns its handle is stale, and a CLI without the
structured response keeps the explicit failure path.
2026-09-18 22:35:44 +08:00
程序员阿江(Relakkes) fdfc8c0782 fix(desktop): seed new sessions from the project root instead of a stale worktree
The sidebar New Session button seeded the new session's directory with
currentSession.workDir first. Isolated-worktree sessions keep their workDir
pointing at .claude/worktrees/<slug> forever, so every follow-up session was
created inside the stale worktree: the branch panel then ran git there, main
showed as checked out elsewhere, and launching failed with 'Branch "main" is
already checked out in another worktree'.

Add getSessionSeedWorkDir() (projectRoot for worktree sessions, own workDir
otherwise, preserving intentional repo subdirectories) and use it at all
three seeding sites: the sidebar New Session button, the launch draft seed
for empty sessions, and the scheduled-task default folder.
2026-09-18 22:35:22 +08:00
程序员阿江(Relakkes) b463710b35 fix(desktop): keep unbreakable composer runs from widening past the panel 2026-09-18 15:57:19 +08:00
程序员阿江(Relakkes) af2872a50f fix(desktop): stop inlining subagent transcripts in the session timeline
A session with 44 linked subagent transcripts returned a 541,817,705-byte /
539,323,608-character /messages body — past V8's 536,870,888-character string
limit, where Chromium hands the renderer an empty string. The session opened to
"Unexpected end of JSON input" instead of its history.

HTTP now serves the root transcript only; an Agent card fetches its run's tool
stream from /subagents/by-tool when expanded, reusing the truncation the server
already applies to oversized runs. Rewind checkpoints, team task anchors and
workspace change attribution keep the merged view they depend on.

Measured on the session that failed: /messages 542 MB -> 40 MB; one run payload
45.8 MB -> 22.9 MB (the Activity projection is no longer sent twice when it is
the same array).
2026-09-17 22:34:18 +08:00
程序员阿江(Relakkes) fe10efb65f feat(desktop): add the OpenCode Go subscription provider
OpenCode Go binds the wire format to the URL path and translates nothing
between formats, so one provider record serves /chat/completions, /messages
and /responses depending on the model, each accepting a different credential
header. A record carries only one apiFormat, so presets can now declare
ordered per-model prefix rules (modelApiFormats) and the proxy resolves the
effective format from the request body. Only the exceptions are listed;
anything unmatched keeps the provider's format, which is the endpoint with the
broadest compatibility. A preset with rules is authoritative for apiFormat,
because a value written by a cc-switch import or the edit form would otherwise
silently disable every rule and point the CLI straight at the upstream.

The gateway also rejects any request without a stable per-conversation
x-opencode-session, so presets can declare upstreamHeaders with $SESSION_ID
and $VERSION placeholders. The id is the one the CLI already sends; it is
redacted in traces the same way the credential is, since it also names the
local transcript files.

Title generation builds its own upstream request and bypassed all of the
above, which left AI titles failing for every provider that needs local
request handling; it now goes through the same proxy the CLI uses.

Verified against the live gateway: glm/kimi reach /chat/completions,
minimax/qwen/union-alpha reach /messages, grok/gpt reach /responses, each
with the credential that endpoint accepts.
2026-09-17 22:00:02 +08:00
程序员阿江(Relakkes) 404422487b fix(desktop): keep AskUserQuestion answers, and lock the composer while it waits
The card renders from the transcript, but it can only be answered through the
live permission request. Two ways that mismatch bit users:

An unanswered question whose request is gone — the renderer was away when it
arrived, and the bounded 30-minute pending-permission window then reclaimed the
CLI — rendered as a fully editable form whose Submit and "chat about this"
buttons were silently dead, with nothing saying why. The card now reports the
question as expired and delivers the answers as an ordinary message instead,
which is the only channel left once nothing is waiting.

Answers also lived only in component state, so switching tabs (ContentRouter
mounts only the active tab) or scrolling the card out of the virtualized window
threw them away. They now live in a store slice keyed by session and toolUseId,
along with the two terminal states only this renderer knows about, so a remount
cannot resurrect an answerable form and deliver the same answer twice.

While a question is pending the composer no longer takes a message at all: the
model is blocked inside the tool call, so a queued message cannot reach it until
the question resolves, and reading it as "I already replied" is how questions
got abandoned. The round button stays Stop, which aborts the question and
unlocks the composer.

Tested: cd desktop && bunx vitest run (5889 passed; the one failure is the
pre-existing computerUseWorker case that needs adapters/node_modules)
Tested: cd desktop && bun run lint && bun run build
2026-09-17 21:37:51 +08:00
程序员阿江(Relakkes) c421907195 fix(desktop): count session tokens as new input+output, not cache hits
The context panel treated every cache read as spend and measured tok/s
against decode time without TTFT, so a 270k-window DeepSeek session
read as 40M tokens at 512 tok/s.
2026-09-17 17:15:20 +08:00
程序员阿江(Relakkes) f2bfaab50f docs(readme): make English the default README
README.md carried the Chinese version while README.en.md held the English one,
so the GitHub landing page opened in Chinese. Swap them: README.md is now
English and the Chinese version lives in README.zh-CN.md, with both language
switchers pointing at the new paths.
2026-09-17 16:51:56 +08:00
程序员阿江(Relakkes) 02d7228b44 release: v0.6.4 v0.6.4 2026-09-17 12:08:14 +08:00
程序员阿江(Relakkes) 9f47bbcd8a fix(agent-teams): inherit the lead model instead of hardcoded Opus
Unconfigured teammates were spawned as claude-opus-4-8, so mapped
third-party providers such as cc-switch DeepSeek billed the expensive
fallback. Agent page aliases now resolve through the provider mapping.
2026-09-17 11:40:56 +08:00
程序员阿江(Relakkes) a4bb7c5284 fix(desktop): stop cold session lists from scanning every JSONL
A building or empty local index used to fall through to a full transcript scan, so opening the sidebar or traces page could sit on GET /api/sessions until the 120s client timeout. Serve partial SQLite rows instead, look up trace titles by session id, and treat client disconnects as 499.
2026-09-17 02:08:53 +08:00
程序员阿江(Relakkes) 35736f3f3a fix(desktop): route teammate permission prompts to the lead session
Print-mode team leads were treating mailbox permission asks as ordinary chat, so desktop members hung forever with no approval UI. Forward those requests through the existing can_use_tool host prompt and label them with the teammate name.
2026-09-16 22:27:15 +08:00
程序员阿江(Relakkes) 88ea66f86e fix(desktop): stop the test-connection button from collapsing on long errors
The test-connection row is a flex row where the result text kept its default
`min-width: auto`, so a long upstream error forced every pixel of overflow onto
the button. Because `size="sm"` pins the height at h-6, the label wrapped and
the button rendered as a squashed two-line block.

Pin the button with `shrink-0 whitespace-nowrap` and let the error text take the
remaining width (`min-w-0 flex-1 break-words`) so long messages, including
unbreakable URLs, wrap inside the row.
2026-09-16 22:21:06 +08:00
程序员阿江(Relakkes) 0676c194e8 fix(desktop): restore window dragging on the sidebar and workspace headers
The sidebar shell's permanent compositing layer dropped macOS app-region
hits around the traffic lights. The workspace header slot also marked its
leftover titlebar space as no-drag, so the empty strip could not move the
window on either platform.
2026-09-15 20:50:06 +08:00
程序员阿江(Relakkes) 8a9e3800a7 fix(desktop): hide short-project fold control and shrink context meter
The fold button was shown whenever a project was marked expanded, including
short lists auto-expanded by history paging. Keep it only above the 6-session
threshold. Replace the composer percentage chip with a compact ring.
2026-09-15 20:21:49 +08:00
程序员阿江(Relakkes) 3e160f7e7a release: v0.6.3 v0.6.3 2026-09-15 18:06:59 +08:00
程序员阿江(Relakkes) a4cd0306fa fix(desktop): keep ngrok start consent validation in sync with the shared version
PUBLIC_ACCESS_CONSENT_VERSION moved to 2 when remote provider management
landed, but the Electron IPC validator still accepted only the literal 1.
The renderer sends the constant, so publicAccessStart was rejected as an
invalid payload in the preload guard and again in the main-process handler,
before PublicAccessManager saw the request at all. That rejection bypasses
the manager's error classification, so the settings page could only show the
generic "operation failed" line while the state stayed disabled: public
access could not be enabled, and autoStart could never become eligible
because consent v2 was never persisted.

Validate against the shared constant instead of a copy of its value, and
stop pinning the stale literal in the tests that let this drift through:
capabilities.test.ts and electronHost.test.ts now send the constant and
reject the previous, next and non-numeric versions.
2026-09-15 17:54:59 +08:00
程序员阿江(Relakkes) 7eb466228c feat(settings): restore authoritative Agent Teams control in General 2026-09-15 17:24:29 +08:00
程序员阿江(Relakkes) 79f6e58b40 revert(desktop): drop the curated skill packages from the skills market
The skills tab mounted the connector catalog as a featured row above the
skill market, and that row was the only place the five curated packages
(frontend design, canvas design, generative art, webapp testing, MCP
builder) were offered. Stop mounting it, so the tab renders the market
alone and those packages have no entry point left in the UI.

The featured slot on Market and MarketHome stays in place, and the
catalog, bundle lock and installer under src/services/connectors are
untouched: restoring the row is a change to one branch of ExtensionMarket,
packages already installed keep working, and their mentions still resolve.
The ExtensionMarket test now asserts the tab does not mount the catalog
again.
2026-09-15 17:24:29 +08:00
程序员阿江(Relakkes) 16e58b92c0 feat(usage): show session token totals and generation speed in the context panel
The context panel could say what was in the window but nothing about what the
session had spent: no total token count, no cache hit rate, no generation speed.
The numbers were already on the wire — translateCliUsage picked four token
buckets out of the CLI's result message and dropped duration_ms, duration_api_ms
and num_turns with them — and nothing anywhere accumulated how long the model
spent emitting tokens rather than waiting on prefill.

Measure that span where it happens: a decode span opens at the first generated
delta and closes at message_stop, rides the stream_event up to QueryEngine, and
accumulates in cost-tracker beside totalAPIDuration, including the project
config restore path so it survives a CLI restart. Tokens/sec is output over that
span, never over wall clock, which would divide by tool execution time.

The totals needed fixing before they were worth showing. Claude Code persists one
JSONL line per content block of a reply and repeats the whole usage object on
every one, so summing lines overstated real transcripts by 2.2x — and
chooseRicherUsage prefers the larger of two snapshots, so the inspector actively
selected the inflated one. The transcript readers and the renderer's history
summary now deduplicate on usageAccounting's key, the rule stats.ts and the
activity index already use.

The panel polls a usageOnly inspection mode while it is open and stops when it
closes: one get_session_usage control, no skills-directory scan, no transcript
re-read, and no request stacked behind one that has not answered.
2026-09-15 17:24:29 +08:00