Commit Graph

1901 Commits

Author SHA1 Message Date
程序员阿江(Relakkes) 633320e9f2 fix(release): allow explicitly skipping Windows signing v0.6.0 2026-09-06 11:46:22 +08:00
程序员阿江(Relakkes) 783eed6be6 fix(release): reuse the prepared macOS signing keychain 2026-09-06 04:17:06 +08:00
程序员阿江(Relakkes) a3b5f603af release: v0.6.0 2026-09-06 04:10:35 +08:00
程序员阿江(Relakkes) 817ced2061 test(skills): cover Computer Use settings transitions in slash commands 2026-09-06 04:10:29 +08:00
程序员阿江(Relakkes) 7af6c53ff8 fix(desktop): restore macOS background computer use and app shutdown
Keep occluded renderers live with display-filtered window streams, refresh
capture regions after geometry changes, and preserve the paste read window.
Allow application shutdown to finish even when resource cleanup throws.

Validated with check:native and an isolated desktop MCP workflow covering
background search, playback, lyrics, and repeated text entry.
2026-09-06 03:50:49 +08:00
程序员阿江(Relakkes) fe7ea03b86 chore(sponsors): retire expired placements while preserving saved providers 2026-09-06 00:10:51 +08:00
程序员阿江(Relakkes) 814c02a786 feat(im): add scan-to-create Feishu bots plus WeCom, QQ and Slack adapters
Connecting Feishu meant creating a bot by hand on the open platform and
pasting an App ID and App Secret back. Feishu also exposes an RFC 8628
device-authorization flow, so the desktop can now render a QR code, and
confirming it in the app creates the bot and stores its credentials
directly. `adapters/feishu/registration.ts` implements that protocol
rather than importing `registerApp` from `@larksuiteoapi/node-sdk@1.73`:
the repository pins 1.60 for the chat client, and the SDK runs the whole
poll inside one un-cancellable promise where the desktop needs the
stateless begin/poll pair the DingTalk registration already uses. The
scan is create-only, so it can never rewrite the configuration of a bot
the user already runs, and it pre-fills exactly the scopes, events and
callbacks this adapter calls. International tenants finish on Lark's
domain, which is now persisted and honoured by the client.

WeCom, QQ and Slack join the same session model. WeCom and QQ bind by
scanning; Slack has no scan flow, so it uses an app manifest that
pre-fills the scopes and Socket Mode. All three run over long
connections, so no public callback URL is needed, and all three accept
private chats only — pairing authorizes one person, and answering in a
group would extend that authorization to everyone else in the room.

They are built on a new `adapters/common/chat-runtime.ts` instead of a
fourth copy of the loop the five existing adapters each carry. A platform
supplies a `ChatPort` — how to say something, how to open a streaming
reply, optionally how to send an image — and the runtime owns pairing,
command routing, session restore, permission bookkeeping and the
translation of the server's stream. The existing five are deliberately
left on their own copies; migrating them is a separate change with its
own regression surface.

Attachments are downloaded through a deferred loader that runs after the
pairing gate and inside the per-chat queue. Resolving them eagerly would
let an unpaired stranger make the adapter fetch bytes and write them
under ~/.claude/im-downloads — on Slack with the bot token attached —
and would let a slow attachment overtake a text message sent after it.

The sidecar launcher's per-adapter branches become one table. It is
declared above the mode dispatch on purpose: `runAdapters` is hoisted and
runs at module top level, so a table declared below it is still in its
temporal dead zone when the adapters mode reads it — which type checks,
lints and unit tests all miss, and only the compiled binary reveals.

Verified with the checks `check:impact` selects: adapters, server,
desktop, electron, policy, chat-contract, agent-flow, docs, native
(sidecar compile, packaging and an adapters-mode smoke against the real
binary) and coverage. The scan flows themselves are not verified against
live platforms — that needs real WeCom, QQ and Slack accounts and would
create real bots.

Claude-Session: https://claude.ai/code/session_01CCGoP316AK7wdQG3Ms6Uwq
2026-09-05 23:46:50 +08:00
Relakkes Yang 90a4a11d28 fix(computer-use): remove per-app approval prompts 2026-09-05 03:09:15 +08:00
Relakkes Yang d93d8248c9 fix(computer-use): align Windows virtual cursor with macOS 2026-09-04 23:35:10 +08:00
程序员阿江(Relakkes) e28d0a6534 fix(computer-use): resolve duplicate AX groups 2026-09-02 11:27:51 +08:00
程序员阿江(Relakkes) 5520c62b35 fix(computer-use): keep labeled controls actionable 2026-09-02 11:15:15 +08:00
程序员阿江(Relakkes) 19e88db8ea fix(computer-use): keep startup enumeration out of turns 2026-09-02 10:43:12 +08:00
程序员阿江(Relakkes) 3e3ae6510a fix(desktop): await sidecar cleanup before quit 2026-09-02 10:18:27 +08:00
程序员阿江(Relakkes) 7dd09a4964 fix(computer-use): retire daemon on client shutdown 2026-09-02 09:53:45 +08:00
程序员阿江(Relakkes) e1616ddfc7 fix(computer-use): deminiaturize offscreen macOS targets 2026-09-02 09:26:12 +08:00
程序员阿江(Relakkes) 79f15a08a4 fix(trace): preserve semantics for truncated requests 2026-09-02 09:05:52 +08:00
程序员阿江(Relakkes) f3d23631cf fix(rewind): scope checkpoints to replacement turns 2026-09-02 09:04:36 +08:00
程序员阿江(Relakkes) 4926a00232 fix(desktop): clarify cached token usage 2026-09-02 09:00:42 +08:00
程序员阿江(Relakkes) a7fe10581b test(desktop): stabilize macOS build install check 2026-09-02 08:55:53 +08:00
程序员阿江(Relakkes) df0a566ed2 fix(computer-use): restore offscreen macOS targets 2026-09-02 08:51:02 +08:00
程序员阿江(Relakkes) 1440f0acd8 fix(computer-use): resolve exact app bundle paths 2026-09-02 08:47:33 +08:00
程序员阿江(Relakkes) e1f7cc9d81 fix(desktop): count unique edited files in activity summary 2026-09-02 08:44:48 +08:00
程序员阿江(Relakkes) 08929e88ee fix(desktop): preserve project cwd after session creation 2026-09-02 08:44:48 +08:00
程序员阿江(Relakkes) d354840c3b fix(desktop): install adapter dependencies for macOS builds 2026-09-02 08:44:48 +08:00
程序员阿江(Relakkes) 5ec0947bf8 docs: record post-v0.5.5 issue triage 2026-09-01 21:57:23 +08:00
程序员阿江(Relakkes) 8d8169ea70 fix(models): add GLM 5.3 reasoning capabilities (#1283) 2026-09-01 21:56:49 +08:00
程序员阿江(Relakkes) cf9d6c41ab fix(proxy): preserve Computer Use tool images (#1277) 2026-09-01 21:35:15 +08:00
程序员阿江(Relakkes) aa237f2c22 feat(desktop): expose conversation-only rewind (#1273) 2026-09-01 21:33:55 +08:00
程序员阿江(Relakkes) ece7c54c45 fix(proxy): preserve DeepSeek reasoning content by model (#1269) 2026-09-01 21:33:18 +08:00
程序员阿江(Relakkes) 5eecf5cbc5 fix(api): tolerate progressing tool input streams (#1271) 2026-09-01 21:32:42 +08:00
程序员阿江(Relakkes) c0f3318d9f fix(telegram): preserve complete streamed replies (#1264) 2026-09-01 21:29:09 +08:00
程序员阿江(Relakkes) b1ecce7812 fix(desktop): preserve inline image placement (#1240) 2026-09-01 21:21:24 +08:00
程序员阿江(Relakkes) ee1efaff04 fix(desktop): clarify long rate-limit retries (#1266) 2026-09-01 21:13:25 +08:00
程序员阿江(Relakkes) 0fd6904a95 merge: integrate Computer Use into local main 2026-09-01 20:14:24 +08:00
程序员阿江(Relakkes) 8a37865536 fix(computer-use): harden native macOS automation runtime 2026-09-01 20:06:25 +08:00
程序员阿江(Relakkes) ad7321f7cc fix(computer-use): align long-running macOS automation with Codex 2026-09-01 17:31:17 +08:00
程序员阿江(Relakkes) 8751e558e5 fix(computer-use): preserve background input across focus changes
Track real and synthetic focus with process-bound monitor receipts.
Bind keyboard activation to the snapshot window and align targeted
pointer and keyboard bursts with the reference event sequence.
Wait for pasteboard data delivery before restoring the clipboard,
and add focus/stream diagnostics with transition regression coverage.

Validated with check:native and six covered NetEase focus cycles.
2026-08-31 23:03:54 +08:00
程序员阿江(Relakkes) 217867fff1 fix(computer-use): capture fresh aligned frames for covered windows 2026-08-31 12:30:58 +08:00
程序员阿江(Relakkes) 42d7cb1c93 fix(computer-use): maintain long-lived window capture streams 2026-08-31 11:25:38 +08:00
程序员阿江(Relakkes) 6ace7f865b fix(computer-use): restore background macOS automation 2026-08-26 20:38:47 +08:00
程序员阿江(Relakkes) 66206cd8a3 feat(desktop): surface the system prompt and injected context in trace
A traced session already recorded everything needed to explain a model
request, but the presentation kept it out of reach. The system prompt lived
inside each individual call, so reading it meant picking a call first. The
context the harness assembles — CLAUDE.md, system-reminder blocks,
deferred-tool rosters — was indistinguishable from what the person typed,
because the provider receives all of it as user-role text.

- The session overview names the system prompt and tool catalog, read once
  from the first model call rather than hunted down per request. This is the
  opening header, not a session-wide invariant: late tool registration and a
  mid-session model change rewrite it for later requests, which keep their own
  header on their own detail.
- A model call's detail separates injected context from the exchange, one row
  per injection labelled by its own content instead of its wrapper tag.
- Tool rows carry their input summary and model rows their token counts, so
  scanning the tree distinguishes one call from the next.
- An assistant turn that only reasoned says so, including when the provider
  withheld the reasoning, instead of rendering as a bare label.

Recognition of injected context is by wrapper tag against a closed list.
Position cannot stand in for it: hoistToolResults moves every tool result to
the front of a merged user message, so an attachment the harness appended and
an instruction typed after interrupting a tool arrive in the same shape. The
ambiguity is resolved toward the conversation — unrecognized text stays the
person's message, because looking for what you said and not finding it is the
worse failure.

requestParse also learns the OpenAI Responses wire format, which about a
quarter of traced sessions use and which previously yielded an empty message
list and no system prompt. Responses splits a tool round trip into sibling
function_call / function_call_output entries; across 150 real trace files
those outnumber plain messages 1199 to 878, so they are mapped onto the
tool_use / tool_result vocabulary rather than skipped. Its flat tool
`parameters` and `instructions` spellings are read too, the latter with `||`
so an empty `system` array cannot shadow it.

All new surfaces use design tokens, so the six themes need no per-theme work.

Claude-Session: https://claude.ai/code/session_0119s8U5VzUvVpNgWA7B3pSg
2026-08-26 19:17:24 +08:00
程序员阿江(Relakkes) a834434284 feat(desktop): add a sidebar task view grouped by run state and day
The sidebar could only group sessions by workspace. With many workspaces
open that is orthogonal to the question people actually ask — "which of
the tasks I just started are done?" — so a finished session had to be
hunted for across a dozen collapsed project groups.

A bell in the sidebar header now switches the list to a flat task view:
running sessions first, then sessions bucketed by calendar day (today,
yesterday, previous 7/30 days, earlier). Each row carries its title and
its owning directory, which is exactly the pairing the project grouping
folds away.

The bell shares one state with the existing "organize sidebar -> by
time" menu item, which promised this and still grouped by workspace.
That reuses the `projectOrganization` preference already persisted to
localStorage and to the desktop UI preferences service, so no new
storage key and no migration.

A session stopped on a permission prompt shows a warning dot rather than
the running spinner: it counts as unfinished, but it is waiting on the
user, not working.

Buckets use calendar-day boundaries, not elapsed hours — a task finished
at 23:50 belongs to "yesterday" when read at 00:10, and a mutation to
elapsed-hours arithmetic turns the guard test red.

Verified: check:desktop green (318 files, 4617 tests, lint + tsc +
build); the flat view, bell round trip and preference flip exercised in
a real browser against a sandboxed server with seeded sessions;
group/title/workspace contrast measured >= 4.83:1 across all six themes;
no horizontal overflow at the 240px minimum sidebar width.

Claude-Session: https://claude.ai/code/session_018mbioW3EEr7KbrWVgBvUvJ
2026-08-26 19:17:24 +08:00
程序员阿江(Relakkes) 7858c46bd2 fix(models): preserve GPT relay reasoning effort (#1238) 2026-08-26 19:17:24 +08:00
Relakkes Yang e5d385dac2 fix(computer-use): harden Windows desktop automation 2026-08-24 02:32:23 +08:00
程序员阿江-Relakkes a78b4e73ce feat(release): sign Windows artifacts with SignPath (#1265)
feat(release): sign Windows artifacts with SignPath
2026-08-23 19:57:27 +08:00
Relakkes Yang a8cb0c509d test(policy): budget the full dead-import sweep 2026-08-23 19:55:11 +08:00
Relakkes Yang 5fafabfca1 fix(release): isolate draft validation from published assets 2026-08-23 19:36:21 +08:00
Relakkes Yang 417cfdfd69 fix(release): preserve Windows updater config before signing 2026-08-23 19:17:29 +08:00
Relakkes Yang c7a90f2cd1 fix(release): separate SignPath test and release policies 2026-08-23 18:55:10 +08:00
程序员阿江(Relakkes) dd4edc0efe merge: bring main into the computer-use worktree
main is 87 commits ahead and carries a large amount of fixed behaviour this
branch should not be re-deciding. The rule applied throughout: this worktree
owns Computer Use, main owns everything else.

Only 12 files were touched on both sides, and Git merged all of them without
reporting a conflict — but two of those silent merges were wrong, and neither
was visible until the checks ran.

`desktop/src/api/client.ts` ended up with two `apiGetBlob` implementations.
Both sides had independently hit the same problem (an `<img src>` pointed at an
API endpoint is a cross-origin subresource, so it carries no Authorization
header and the server's fetch-metadata policy refuses it) and both had written
the same fix. Git saw two additions in different places and kept both, which
does not even compile. main's version survives: it builds its headers through
the shared `buildHeaders()` rather than assembling them inline, so it inherits
whatever main adds there later.

`src/server/api/computer-use.ts` still imported `runtime/mac_helper.py` and
`runtime/requirements.txt` as compile-time text, both deleted on this branch.
Nothing at runtime referenced them, which is why the deletion looked clean; the
bundler resolves those imports when the server module is loaded, so the failure
surfaced only when the tests actually imported it. That path is now Windows-only
in the same sense the rest of the Python bridge is, and it also ships
`win_cursor_badge.py`, which the badge needs because it runs as its own process.

`computer-use-requirements.test.ts` drops its darwin half for the same reason —
the pins it guards still matter, but only one requirements file is left.

Verified: server 3869 tests / 331 files, desktop 4612 tests / 319 files
(lint + tsc + build), Swift 272 XCTest + 14 Swift Testing, Python 25.

Claude-Session: https://claude.ai/code/session_015j1yxxaoonyAS2iZ7qGnTS
2026-08-23 18:39:47 +08:00