Skip to content

feat: install + vault + probe slice + CLI companion + CalVer release - #8

Closed
johnnyhuy wants to merge 10 commits into
mainfrom
feat/install-vault-probe-slice
Closed

feat: install + vault + probe slice + CLI companion + CalVer release#8
johnnyhuy wants to merge 10 commits into
mainfrom
feat/install-vault-probe-slice

Conversation

@johnnyhuy

Copy link
Copy Markdown
Contributor

Summary

End-to-end first useful slice of the hoist app, plus a terminal companion CLI and CalVer release automation. Built on top of #7 (now merged into main).

Electron app (first vertical slice)

  • safeStorage vault (src/main/secrets/safestorage.ts) — default ADR-0001 backend. Encrypts via Electron safeStorage, persists atomically to userData/vault.bin with chmod 0600.
  • IPC layer (src/main/ipc.ts) — vault:list|set|delete|copy (with 30s clipboard auto-clear), harness:list|discover|install, provider:list, probe:run.
  • Anthropic probe (src/main/probes/anthropic.ts) — /v1/models, 5s timeout, returns ok | invalid | quota_exceeded | error.
  • Harness installer (src/main/installer/index.ts) — which + npm-global fallback for PATH, npm install -g for install; version probe via --version.
  • Typed preload bridge (src/preload/api.ts, src/shared/channels.ts) — window.hoist exposes vault.*, harness.*, provider.*, probe.* with strict types.
  • UI rewired (src/renderer/App.tsx) — Harnesses step shows install status + disables button on success; Keys step has masked previews, Edit/Validate/Copy/Delete actions, inline probe results with timestamp.

CLI companion (cli/)

  • Bun + TypeScript, single-file executables via bun build --compile.
  • Subcommands: hoist install, hoist keys <list|set|probe|delete>, hoist gateway <show|set|clear>, hoist list.
  • macOS Keychain (security add-generic-password) on darwin; chmod-0600 JSON fallback elsewhere.
  • Shares probe logic + provider shape with the Electron app.
  • Targets: darwin-arm64, darwin-x64, linux-arm64, linux-x64, windows-x64.

Release automation

  • release-please in CalVer YYYY.MM.PATCH. Two packages: root (tag v2026.7.0) and cli (tag cli-v2026.7.0).
  • release-please.yml opens release PRs on push to main.
  • release-build.yml auto-builds on release: mac-arm64 dmg, mac-x64 dmg, windows nsis x64, linux AppImage x64, and the five CLI binaries. macOS signing is opt-in via repo secrets.
  • ci.yml runs lint + typecheck + build + bun compile on every PR.

Tooling housekeeping

Consequences

  • App and CLI now share provider/probe contracts. Both can install Claude Code, OpenCode, Codex and probe Anthropic.
  • safeStorage is the only vault backend shipped today; ADR-0001 lists keytar/bw/op/AWS SOPS as follow-ups. The SecretBackend interface is plumbed, so adding backends is additive.
  • Vault stores Anthropic key under provider:anthropic:api_key — schema is consistent across app and CLI.
  • Pre-release: version stays at 0.0.0 in the repo. release-please will bump to 2026.7.0 on the first release PR.

Verification

  • npm run typecheck
  • npm run lint
  • npm run build ✓ (29 modules, ~206 kB renderer bundle)
  • bun run cli → bun build --compile ✓ (Mach-O arm64, binary ~50 MB)
  • Live keychain round-trip on macOS (security add/find/delete-generic-password) verified end-to-end.
  • All four wizard steps render with real data (screenshot below).

johnnyhuyand others added 10 commits May 4, 2026 23:24
Electron shell with 4-step setup wizard (harnesses, SSO, gateway, done).
Shared types for tool install specs, gateway config, and SSO config.
Vite-powered renderer with dark theme. electron-builder packaging.
Rename the app across package.json, electron-builder (appId app.hoist,
productName Hoist), main window title, preload/renderer bridge
(HoistAPI exposed as window.hoist), and UI logo text.
Co-authored-by: opencode <opencode@anthropic.com>
Rewrite BRIEF.md for hoist with additive BYOK/key-vault scope alongside
the existing harness install / SSO / gateway work. Add four ADRs:
0001 secret-storage backend abstraction, 0002 provider registry
catalog, 0003 key validity and expiry probing, 0004 bundled external
binaries.
Co-authored-by: opencode <opencode@anthropic.com>
Lay down compiling type stubs for the Phase 1+ work: SecretBackend
interface and availability types (ADR-0001), ProviderEntry catalog
shape (ADR-0002), and ProbeResult/ProbeKind/BudgetProbeKind
(ADR-0003). gitignore .opencode/.
Co-authored-by: opencode <opencode@anthropic.com>
- Install eslint + @typescript-eslint plugin and parser
- Add direct dependency with @types/which
- Ignore cli/dist and cli/node_modules
- Closes the lint gap noted in PR #6
- safeStorage backend in src/main/secrets/safestorage.ts: encrypts via Electron safeStorage, persists JSON atomically to userData/vault.bin with chmod 0600
- Extended SecretBackend interface with SecretWriteOptions to carry label metadata
- Shared CHANNELS module in src/shared/channels.ts (kept preload-free of main bundle)
- IPC handlers in src/main/ipc.ts: vault:list/set/delete/copy with 30s clipboard auto-clear, harness:*, provider:list, probe:run
- Typed HoistAPI on window.hoist via preload/api.ts
- Registered IPC handlers in main entry
Implements ADR-0001 default backend.
- src/main/probes/anthropic.ts: 5s timeout, x-api-key + anthropic-version headers; returns ok/invalid/quota_exceeded/error
- src/main/probes/index.ts: dispatches by providerId; the second provider probe slots in here
- Seeded anthropic into PROVIDER_CATALOG with envKeys ANTHROPIC_API_KEY and baseUrlEnv ANTHROPIC_BASE_URL
- src/main/providers/harnesses.ts: HARNESS_CATALOG with claude-code/opencode/codex install specs
- src/main/providers/catalog.ts: seeded with anthropic (envKeys, baseUrlEnv, defaultBaseUrl)
- src/main/installer/index.ts: discover via PATH + npm global root, npm install -g executor, version probe
- src/renderer/App.tsx: Harnesses step shows install status, Code button: hidden until installed; Keys step with masked previews, Edit/Validate/Copy/Delete, on-demand probe and inline result; sidebar nav now uses Keys not SSO
The 4-step wizard (Harnesses / Keys / Gateway / Done) is now end-to-end real.
- cli/src/index.ts: commander entry with install/keys/gateway/list subcommands
- cli/src/lib/vault.ts: macOS Keychain via `security`, fallback to chmod-0600 JSON; config at $HOIST_CONFIG_DIR or platform defaults
- cli/src/lib/harnesses.ts: same discover + npm install logic as the main process
- cli/src/lib/providers.ts: anthropic first
- cli/src/lib/probes.ts: shared Anthropic probe
- cli/scripts/build-all.ts: bun build --compile for darwin-arm64/x64, linux-arm64/x64, windows-x64
- cli/bin/run.js: dev entry that imports compiled index.js
- Tools target bun build --compile for true single-file executables (~50 MB macOS arm64)
Use case: `hoist install claude-code && hoist keys set anthropic && hoist keys probe anthropic` from any terminal.
…flow
- release-please-config.json: two packages (root app, cli), both CalVer (YYYY.MM.PATCH); root tag is plain `v2026.7.0`, cli tag is `cli-v2026.7.0`
- .release-please-manifest.json: pins current versions
- .github/workflows/release-please.yml: opens release PRs on push to main
- .github/workflows/release-build.yml: on release published, detects component from tag shape (cli-v* vs v*) and builds:
- app: mac-arm64 dmg, mac-x64 dmg, windows nsis x64, linux AppImage x64 via electron-builder
- cli: bun build --compile for darwin-arm64/x64, linux-arm64/x64, windows-x64; uploads per-target binaries
- .github/workflows/ci.yml: PR CI runs app typecheck + lint + build and cli typecheck + compile sanity
macOS signing uses APPLE_ID/APPLE_APP_SPECIFIC_PASSWORD/APPLE_TEAM_ID + CSC_LINK/CSC_KEY_PASSWORD repo secrets when present; unsigned builds otherwise.
@johnnyhuy
johnnyhuy deleted the feat/install-vault-probe-slice branch July 19, 2026 03:39
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@johnnyhuy