6.6 KiB
cloudcli-taskwork — workspace
Meta-repository for the Task Work plugin for CloudCLI UI (siteboon/claudecodeui).
It holds the specification, the developer scripts and two submodules. It contains
no code of its own — no package.json, no dependencies.
Specification: spec/SPEC-v3.md (current), design input:
spec/DESIGN-DOC.md.
Repository map
| Path | Repository | Role |
|---|---|---|
| (this repo) | gitea:ai-first/cloudcli-taskwork |
Workspace: spec, scripts, submodule pins |
plugin-taskwork/ |
gitea:ai-first/cloudcli-plugin-taskwork |
The product, developed here; manifest.json lives in its root |
| — | github:bvn13/cloudcli-plugin-taskwork |
Where users install the plugin from — public, anonymous HTTPS clone |
cloudcli/ |
github:bvn13/claudecodeui |
Fork of the host; source of the three upstream PRs |
| — | github:siteboon/claudecodeui |
Upstream: source of updates, target of the PRs |
| — | gitea:ai-first/cloudcli |
Pull mirror of the fork, read-only |
The plugin lives in two places on purpose: development and the submodule pin stay
on Gitea, while the host installs it over anonymous HTTPS, which a private Gitea
repository cannot serve. The GitHub copy is a push mirror — pushing to Gitea
is enough, it syncs on its own. Do not add a GitHub remote to plugin-taskwork/
and do not push there by hand.
⚠️ Never push to
gitea:ai-first/cloudcli. It is a pull mirror — anything pushed there is silently overwritten on the next sync. Thecloudcli/submodule points at the GitHub fork, and the mirror is deliberately not wired up as a remote.
Getting started
git clone --recurse-submodules ssh://git@gitea.bvn13.me:2221/ai-first/cloudcli-taskwork.git
cd cloudcli-taskwork
./scripts/bootstrap.sh
Then:
./scripts/dev-host.sh start # installs the built plugin and starts the host
It prints the URL — http://localhost:5183 by default. stop, restart,
status and logs do what they say; SERVER_PORT/VITE_PORT override the
ports.
The host runs against your real environment: the same ~/.claude projects,
the same ~/.cloudcli/auth.db, the same ~/.claude-code-ui/plugins. Nothing is
sandboxed, so you see what a user would see. Ports default to 3010/5183 rather
than 3001/5173 so an already installed CloudCLI keeps running — but note that
both instances then share one database. Set DATABASE_PATH to separate them.
After changing the plugin:
cd plugin-taskwork && npm run build
cd .. && ./scripts/link-plugin.sh # the host reads a copy, not a symlink
Client changes need only the plugin surface reopened; server changes need the host
restarted (./scripts/dev-host.sh restart), because the plugin's backend process
is spawned at host startup.
The plugin stores its data outside its own directory, in
~/.claude-code-ui/taskwork/tasks.json — the plugin directory is wiped on Update.
Access
All submodule URLs are SSH, so both submodules are writable with the same key
setup: ssh://git@gitea.bvn13.me:2221/… for the plugin (the Gitea repositories
are private) and git@github.com:bvn13/claudecodeui.git for the fork. The
upstream remote stays on HTTPS — it is fetch-only and public.
Cloning therefore needs an SSH key registered with both hosts; check with
ssh -T git@github.com and ssh -T -p 2221 git@gitea.bvn13.me.
Distribution goes through the public GitHub copy
(github:bvn13/cloudcli-plugin-taskwork), because the host clones a plugin
anonymously over HTTPS and the Gitea repository is private. The submodule keeps
pointing at Gitea: that is where the plugin is developed and pushed first.
Scripts
| Script | Purpose |
|---|---|
scripts/bootstrap.sh |
Init submodules, wire the upstream remote, install deps, build the host's native modules and the plugin |
scripts/dev-host.sh |
Run the patched host locally: start, stop, restart, status, logs |
scripts/export-patches.sh |
Regenerate plugin-taskwork/patches/*.patch from the fork's feature branches (§12.0) |
scripts/link-plugin.sh |
Symlink the local plugin into the host's plugin directory (--unlink to remove) |
scripts/check-submodule-pins.sh |
Verify every pinned submodule commit is reachable from its origin |
Branches in cloudcli/
Each feature branch is cut from the upstream tag v1.37.2, never from another
feature branch — that is what keeps the three pull requests independent.
| Branch | Base | Purpose |
|---|---|---|
main |
tracks upstream/main |
Upstream sync. Carries no commits of ours |
feat/resizable-sidebar |
v1.37.2 |
PR-1 — resizable sidebar |
feat/plugin-host-api |
v1.37.2 |
PR-2 — authenticated host API for plugins |
feat/plugin-sidebar-surface |
v1.37.2 |
PR-3 — sidebar surface for plugins |
dev/taskwork |
merge of the three | Local run and debugging; the submodule is pinned here |
dev/taskwork never takes part in a pull request and may be recreated at any time.
Working with the submodules
- Commit code inside the submodule, push it, and only then record the new pin
here with a separate commit
chore: bump <submodule> to <sha>. - Update with
git submodule update --remote --merge. - Run
./scripts/check-submodule-pins.shbefore pushing a pin bump.
Status
| Piece | State |
|---|---|
| Plugin | v1.0.0, pushed to Gitea; installs, builds and runs (npm install --ignore-scripts + npm run build in ~3 s) |
feat/resizable-sidebar |
Pushed to the fork. PR-1 not opened yet; no issue needed |
feat/plugin-host-api |
Pushed to the fork. Issue text in spec/upstream/issue-1-plugin-host-api.md, PR text in plugin-taskwork/docs/upstream-pr-2.md |
feat/plugin-sidebar-surface |
Pushed to the fork. Issue text in spec/upstream/issue-2-plugin-sidebar-surface.md, PR text in plugin-taskwork/docs/upstream-pr-3.md |
dev/taskwork |
Merge of the three plus one integration commit (host API in the sidebar surface) that never goes upstream; the cloudcli pin points here |
Remaining before upstream contact (§19 of the spec): open issue #1, then PR-2; issue #2, then PR-3; PR-1 can go on its own. Also outstanding: the manual acceptance checklist (§15.4), which needs a running host in a browser.
Release
See §13.2 of the spec. In short: export patches → bump the plugin version in
package.json and manifest.json → build, typecheck, test → commit build/,
patches/, CHANGELOG.md → tag vX.Y.Z in the plugin repo → bump the pins here.
Licence
The plugin and the fork are AGPL-3.0-or-later, following the upstream host.