# DSH Buddy Suite

> **This project is no longer maintained and has been archived; `0.1.3-final` is the final version.**
>
> **End of life**: real-device testing showed that accessing WorkBuddy models through
> an unofficial client is **no longer viable** under the restrictions WorkBuddy
> introduced on **2026-10-20**. The project has therefore reached the end of its
> life and closes as the archived version `0.1.3-final`. **This plugin does not claim
> to be usable, and continued use of this approach is not recommended**; if you need
> WorkBuddy model access, use the official WorkBuddy client.
>
> **Background and boundary**: since **2026-10-20**, WorkBuddy restricts requests from
> non-official clients. The upstream dependency
> [dsh-workbuddy-connect](https://github.com/corrinehu/dsh-workbuddy-connect) has
> stopped maintenance and is planned to go offline on **2026-10-22** (refer to its
> announcement). This project respects that boundary and will no longer adapt to
> WorkBuddy's private protocol; new feature requests and PRs are closed, and no
> updates, compatibility fixes, or support will be provided.
>
> **Historical record (not a capability promise)**: before upstream stopped, this
> project had already picked up several capabilities and fixes recorded in upstream
> issues — error diagnostics (#199), context / reasoning-level control (#186 / #96),
> visibility toggles (#181 / #168), credits display (#183), tests 172 → 360 (#165),
> four-channel distribution (#180 / #176 / #175 / #160 / #158), credential
> robustness and the Windows "recycled PID" guard, plus this release's T1 graceful
> degradation / T2 health routing / T4 credential isolation. This is recorded for
> context only and does not imply the approach still works.
>
> **Thanks**: to everyone who used the project. The code and docs are kept as-is for
> reference and personal study; continued operation on any WorkBuddy / DeepSeek
> Harness version is not guaranteed, and continued use is not recommended. See
> [COMPATIBILITY.md](./COMPATIBILITY.md) for the support matrix of the final version.

English | [中文](./README.md)

**One plugin that does both WorkBuddy jobs**: it brings WorkBuddy desktop app
models into DeepSeek Harness *and* runs the WorkBuddy daily check-in
automatically at DSH startup. Model access covers **both** the China app
(WorkBuddy) and the international one (WorkBuddy AI); the check-in serves every
local China account, because the international endpoint rejects check-ins
upstream.

It is built on two same-lineage projects,
[dsh-workbuddy-connect](https://github.com/corrinehu/dsh-workbuddy-connect)
(model access) and
[dsh-buddy-checkin](https://github.com/corrinehu/dsh-buddy-checkin)
(daily check-in), and merges them into one bundle.

> **Final status: 0.1.3-final, archived.** See [KNOWN-ISSUES.md](./KNOWN-ISSUES.md)
> for what is verified, what is not, and remaining known issues. In
> short: the check-in and model halves both work on Windows against a real
> account; Linux, macOS, and the international app are untested.

## Why one bundle

Both plugins read the same thing: the sign-in the WorkBuddy desktop app keeps in
its shared `CodeBuddyExtension` directory. Since WorkBuddy 5.6 those credentials
are encrypted at rest, and the key has to be pulled from the app's own Electron
binary. Kept separate, that key-pulling, envelope-opening, and install-locating
logic exists twice, and the two copies can disagree about a WorkBuddy update.

In one bundle:

- **One credentials implementation**, so neither half can disagree about who is
  signed in or how the key is reached.
- **One dependency set**, instead of two plugins each pinning
  `@earendil-works/pi-ai`.
- **Either half can fail without the other**: a failed check-in never hides the
  model group, and a failed provider registration never takes the check-in
  panel with it.

## Features

### Model access

- **Works out of the box**: the WorkBuddy group appears in the model picker with
  no configuration.
- **Both regions side by side**: WorkBuddy (CN) and WorkBuddy AI
  (international) are separate groups with separate accounts and credits.
- **Image input**: most models accept pasted or dropped images.
- **Reasoning levels**: declared levels are listed; undeclared models can be
  probed by hand. A model whose effort parameter turns out not to be checked is
  reported as "not adjustable" and names the level it uses instead.
- **Credit badge**: the account's remaining credit sits beside the composer,
  with a ↻ to re-read.
- **Model visibility**: hidden models are remembered per signed-in account.

### Daily check-in

- **Signs in at startup** for every WorkBuddy CN account on the machine.
  Accounts already signed today — including ones signed in the app — are
  skipped, so restarts cost nothing.
- **Multi-account discovery** reads the app's shared auth directory, where each
  sign-in and account switch leaves a timestamped backup. Every CN account ever
  signed in on this machine is found, deduplicated by account.
- **Session header entry** shows the WorkBuddy mark, the account count, and a
  status dot. It stays hidden when the machine has no CN account.
- **Details panel** shows each account's outcome, credit granted, and latest
  balance; opening it re-reads every balance.
- **Retry failed accounts** re-requests exactly today's failures.

## Install

**Prerequisite**: the WorkBuddy desktop app is installed and signed in on this
machine. The plugin reuses that sign-in and starts no OAuth flow.

```sh
dsh plugin --profile web add dsh-buddy-suite
```

**The final version is `0.1.3-final`; installation stops there** — the project is
archived and no later versions will be published.

## Coexisting with dsh-workbuddy-connect

Both bundles register WorkBuddy models, so the two can be installed side by
side: every id this bundle registers is namespaced (`workbuddy-suite`,
`llm-workbuddy-suite`, …) so it cannot collide with the other plugin's.

Two consequences worth knowing:

- the model picker shows **two WorkBuddy groups**, one per plugin;
- the default-model setting that names `workbuddy/<model>` keeps pointing at
  the other plugin, which is what makes coexistence safe.

If you only want the check-in, install this bundle and remove the other one.

## Verify

```sh
# Diagnostics: credential path, on-disk format, whether the decryptor is locatable
dsh plugin --profile web exec dsh-buddy-suite doctor

# Check-in outcome (this command also runs one check-in)
dsh plugin --profile web exec dsh-buddy-suite checkin

# Sign-in state and remaining credit
dsh plugin --profile web exec dsh-buddy-suite status
```

All three accept `--json`.

## Known limitations

See [KNOWN-ISSUES.md](./KNOWN-ISSUES.md) for the full list, including:

- **The check-in is CN-only**: an international token gets a 401 from the CN
  check-in endpoint.
- **No check-in on days DSH is not opened**: there is no timer and no cron. The
  upstream only signs the current day, so a missed day cannot be recovered.
- **Restricted environments cannot run the check-in**: it needs to spawn
  subprocesses (`reg.exe`, and the app's Electron to obtain the key), which a
  sandboxed environment denies with `EPERM`. This is an environment limit, not a
  code defect.
- **Linux and macOS are untested**, and so is the international app.

## Development

**Runtime**: `engines` requires `node: ^22.19.0 || >=24.0.0` (23.x excluded — it
is not an LTS line), following the DSH `0.2.1-rc.2` kernel and the `es2024` build
target. **Node 18 / 20 are out of scope and fail at runtime**; `npm` only prints
an `EBADENGINE` warning, so do not ignore it.

**Continuous integration**: `.github/workflows/check.yml` runs `pnpm run check`
on every push to `main` and every pull request, on both Ubuntu and Windows
(Node 22, pnpm 9, `--frozen-lockfile`). Changes must be green before merging.

**Before changing anything, read both lists** (the project is archived, so no
pull requests are expected; the lists remain as historical records):

- [`NON-GOALS.md`](./NON-GOALS.md) — what this plugin deliberately does not do.
  These are not "not implemented yet" but "considered and declined"; check it
  before sending a pull request.
- [`KNOWN-ISSUES.md`](./KNOWN-ISSUES.md) — unverified items and known defects.
  This file is the source of truth for any public claim about the plugin.
- [`COMPATIBILITY.md`](./COMPATIBILITY.md) — DSH / Node / WorkBuddy support
  matrix for the final version `0.1.3-final`.

```sh
pnpm install
pnpm run check           # typecheck + test + build + verify
pnpm run check:offline   # same, but runs tests without spawning workers
```

| Path | Responsibility |
|---|---|
| `src/index.ts` | Plugin entry: assembles both providers and the check-in routes |
| `src/checkin.ts` | Check-in logic: discovery, claiming, balances, state |
| `src/checkin-routes.ts` | The check-in half's same-origin HTTP routes |
| `src/desktop-credential-protection.ts` | Envelope decryption and Electron location |
| `src/auth.ts`, `upstream.ts`, `adapter.ts`, … | Model provider half |
| `src/client/` | Browser half: settings cards, reasoning control, check-in panel |

## Acknowledgements

- [corrinehu/dsh-workbuddy-connect](https://github.com/corrinehu/dsh-workbuddy-connect) (MIT)
- [corrinehu/dsh-buddy-checkin](https://github.com/corrinehu/dsh-buddy-checkin) (MIT)
- `Sliverkiss/workbuddy2api` (MIT, Go) — the reference implementation for the
  upstream wire protocol. The repository is gone (404), so no link; the
  attribution lives on in dsh-workbuddy-connect's README and in this project's
  code comments.

## Disclaimer

For personal study and research only. Use it with your own WorkBuddy account on
your own machine, and comply with WorkBuddy's terms of service. Not affiliated
with Tencent, WorkBuddy, or DeepSeek.

## License

MIT
