mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-27 15:13:37 +08:00
* feat(desktop): seed cc-haha-builtin marketplace into Electron package
Wires the missing desktop side of the plugin-seed mechanism. The CLI
side (src/utils/plugins/{pluginDirectories,marketplaceManager}.ts) has
been on main for a while and exposes `getPluginSeedDirs()` +
`registerSeedMarketplaces()` reading `CLAUDE_CODE_PLUGIN_SEED_DIR`. But
the desktop side never set that env var or copied any seed into the
Electron package, so:
- v0.5.11 packaged users see whatever marketplaces they manually
registered (typically just `reverse-engineering` from a one-off
`plugin marketplace add ./plugins`).
- The image-gen plugin added in PR #49 was invisible after install
because no mechanism shipped it inside the Electron bundle.
What this commit adds
- `desktop/scripts/build-plugin-seed.ts` (new)
- Mirrors the repo's `plugins/` directory into
`desktop/plugin-seed/marketplaces/cc-haha-builtin/`.
- Generates `desktop/plugin-seed/known_marketplaces.json` with a
placeholder `installLocation`. registerSeedMarketplaces() recomputes
the real path at runtime via findSeedMarketplaceLocation(), so the
placeholder is intentional — handles cases like multi-stage Docker
builds where the seed lives at a different path than where it was
built.
- `desktop/package.json`
- Adds `build:plugin-seed` script.
- Prepends it to `electron:dev` and `electron:build` so the seed is
always fresh before the app starts (or is packaged).
- Adds `plugin-seed/**` to electron-builder `files` and `asarUnpack`
so the seed dir ships inside the .app/.exe but stays outside the
asar archive (CC reads files from disk, not from asar).
- `desktop/electron/services/sidecarManager.ts`
- Threads `desktopRoot` through `buildSidecarEnv(...)` and adds
`CLAUDE_CODE_PLUGIN_SEED_DIR=<desktopRoot>/plugin-seed` so the
spawned server sidecar finds the seed.
- `src/server/index.ts`
- Calls `registerSeedMarketplaces()` at server boot so the seeded
marketplace appears in `~/.claude/plugins/known_marketplaces.json`
and the desktop's Settings → Plugins page picks it up.
- Fire-and-forget (`void ...`) rather than `await`, since
`startServer` is sync and the registration takes ~ms; the seeded
marketplace appears in the UI within 1-2 seconds of server boot.
(The original drafted version used `await` inside a sync function,
which doesn't compile — fixed in this commit.)
- `.gitignore` — excludes `desktop/plugin-seed/` from version control
(regenerated on every electron build, never committed).
End-to-end flow after this lands
build time:
bun run electron:build
→ bun run build:plugin-seed
→ desktop/plugin-seed/marketplaces/cc-haha-builtin/{plugin/,...}
→ desktop/plugin-seed/known_marketplaces.json
→ bun run build:sidecars + electron-builder
→ packages plugin-seed/** into .app/.exe (asarUnpack ensures
the dir is on disk, not inside asar)
runtime (first launch):
Electron main → spawn server sidecar with
CLAUDE_CODE_PLUGIN_SEED_DIR=<resourcesDir>/plugin-seed
Server sidecar starts → registerSeedMarketplaces()
→ reads seed/known_marketplaces.json
→ calls findSeedMarketplaceLocation() to resolve real path
→ writes resolved entry into ~/.claude/plugins/known_marketplaces.json
Desktop Settings → Plugins reads ~/.claude/plugins/known_marketplaces.json
→ shows cc-haha-builtin marketplace with both reverse-engineering
and image-gen plugins available to install.
Verification
- `bun run desktop/scripts/build-plugin-seed.ts` produces the seed
with both plugins present, valid JSON, in expected dir layout.
- `bun run lint` (desktop): tsc --noEmit clean — no remaining type
errors from the await→void change or the buildSidecarEnv signature
change.
- Seed marketplace.json plugins array confirmed includes both
reverse-engineering (v0.4.6, post-#33) and image-gen (v1.0.0, from
#49).
Tested: build script runs locally; tsc clean.
Not-tested: live `bun run electron:package` end-to-end pack on this
host (no codesign, slow). The packaging-side wiring (asarUnpack +
files) is configuration-only and matches established patterns
(node_modules/node-pty/**, src-tauri/binaries/**); no behaviour change
to the existing package layout besides adding plugin-seed/.
Risk: low — additive across the board, no existing path changes
behaviour. The fire-and-forget marketplace registration cannot block
boot; if it fails, the worst case is the user sees no seeded
marketplace and can manually re-add it (existing flow).
Confidence: high
Scope-risk: narrow — desktop wiring + 1 server-side hook call.
* test(server): add seed-marketplaces-startup integration tests
Covers the registerSeedMarketplaces() integration that startServer()
now invokes at boot. Four cases:
- env var unset → returns false, no write
- valid seed → returns true, writes primary entry with resolved (non-placeholder) installLocation
- repeat call → primary entry stays intact (returns false on the no-op call but the previously-written entry survives)
- nonexistent seed dir → returns false, no crash
Resolves the change-policy 'Server product files changed without a server test file in the PR' block on PR #50.
* test(desktop): pass desktopRoot to buildSidecarEnv in sidecar test
buildSidecarEnv now requires desktopRoot to derive CLAUDE_CODE_PLUGIN_SEED_DIR. The existing 'passes portable config' test still called the old 2-arg signature, breaking both desktop-checks (vitest) and desktop-native-checks (tsc) on PR #50.
Tested:
- bunx vitest run electron/services/sidecarManager.test.ts -t 'passes portable config' — 1 passed
- tsc -p electron/tsconfig.json — clean
Confidence: high
Scope-risk: narrow
---------
Co-authored-by: 你的姓名 <you@example.com>
100 lines
1.7 KiB
Plaintext
100 lines
1.7 KiB
Plaintext
.env
|
|
.env.*
|
|
!.env.example
|
|
node_modules
|
|
openspec
|
|
.DS_Store
|
|
|
|
# Computer Use runtime (auto-generated)
|
|
.runtime/
|
|
extracted-natives/
|
|
|
|
# Adapter attachment cache (created at runtime by AttachmentStore when
|
|
# running adapter tests or the feishu/telegram adapters locally)
|
|
.lark-attachments/
|
|
.tg-attachments/
|
|
|
|
# Playwright MCP snapshots & logs
|
|
.playwright-mcp/
|
|
|
|
# OMX state/logs
|
|
.omx/
|
|
|
|
# E2E screenshots
|
|
e2e-*.png
|
|
|
|
# Local/generated artifacts
|
|
artifacts/
|
|
|
|
# Desktop build output
|
|
desktop/dist/
|
|
desktop/electron-dist/
|
|
desktop/build-artifacts/
|
|
desktop/src-tauri/binaries/
|
|
desktop/src-tauri/target/
|
|
desktop/src-tauri/gen/
|
|
desktop/package-lock.json
|
|
|
|
# Desktop brand asset candidates (keep only selected ones in public/)
|
|
desktop/brand-assets/
|
|
|
|
# Claude local config & auto-generated
|
|
.claude/*
|
|
# …but project-level agents under .claude/agents/ are part of the repo and
|
|
# should be shared with other contributors. Whitelist them explicitly.
|
|
!.claude/agents/
|
|
!.claude/agents/**
|
|
|
|
# Kiro IDE local config (steering, specs, hooks) — local only
|
|
.kiro/
|
|
|
|
# Superpowers plans & specs (local only)
|
|
docs/superpowers/
|
|
.superpowers/
|
|
|
|
# Temp server/web logs
|
|
.tmp-*.log
|
|
|
|
# Editor / IDE local config
|
|
.vscode/
|
|
|
|
# codegraph local index (generated by the codegraph tool, not a build artifact)
|
|
.codegraph/
|
|
|
|
# Debug / temp screenshots (root dir only)
|
|
/*.png
|
|
bug_attachments/
|
|
|
|
# Private keys & credentials
|
|
*.pem
|
|
*.key
|
|
*.p12
|
|
credentials*.json
|
|
|
|
# TS build cache
|
|
*.tsbuildinfo
|
|
|
|
# Temp markdown snapshots
|
|
sidebar-snapshot.md
|
|
|
|
# VitePress
|
|
docs/.vitepress/dist
|
|
docs/.vitepress/cache
|
|
runtime/__pycache__
|
|
|
|
# IDE
|
|
.idea
|
|
|
|
# Codex logs
|
|
.codex-logs/
|
|
|
|
# Local AI assistant artifacts (graph, notes)
|
|
CLAUDE.md
|
|
.mavis/
|
|
.opencode/
|
|
graphify-out/
|
|
.gitignore
|
|
|
|
# desktop/scripts/build-plugin-seed.ts output
|
|
desktop/plugin-seed/
|