feat: Claude Code Monitor — lanes, pipelines and a merged workspace

Internal SmartGift build of a Claude Code monitoring dashboard.

Lanes: a durable unit of parallel agent work, one per working directory,
tracked across session restarts. Managed lanes are git worktrees the
dashboard provisions and can reset or remove behind a three-check destroy
guard and a counted preflight; adopted lanes are directories you already
own and are never destroyable.

Pipelines: a lane moves through pipeline stages. A stage the agent declares
with evidence renders green; a stage inferred from the tool-event stream
renders dashed amber and never counts as done. Detection is forward-only
within a 30-minute window, and never writes the declared stage.

Workspace: one page at /run with a lane grid, the selected lane's pipeline,
and a full Claude console behind a disclosure.
This commit is contained in:
2026-07-29 17:07:45 +07:00
commit 62425b2f58
781 changed files with 220565 additions and 0 deletions
+167
View File
@@ -0,0 +1,167 @@
# electron-builder configuration for Claude Code Agent Monitor (macOS + Windows).
#
# Defaults to ad-hoc signing so the project can build distributable DMGs
# without a paid Apple Developer account. When the following environment
# variables are set in CI (typically as repository secrets), the same
# config produces a Developer IDsigned and Apple-notarized DMG:
#
# APPLE_ID Apple ID email
# APPLE_TEAM_ID Developer team identifier
# APPLE_APP_SPECIFIC_PASSWORD App-specific password for notarytool
# CSC_LINK Base64-encoded .p12 cert (optional)
# CSC_KEY_PASSWORD Password for the .p12 (optional)
#
# No code changes are required to enable notarization later.
appId: com.vn.smartgift.ccam.desktop
productName: Claude Code Monitor
copyright: Copyright (c) 2026 SmartGift. All rights reserved.
directories:
output: release
buildResources: assets
# We pre-build with tsc into out/, and we ship the existing server/ and
# client/dist/ from the parent repo as extraResources. Keeping the bundle
# small: no source maps, no parent node_modules tree.
files:
- "out/**/*"
- "package.json"
extraResources:
- from: "../server"
to: "app/server"
filter:
- "**/*"
- "!__tests__/**"
- "!**/*.test.js"
- from: "../client/dist"
to: "app/client/dist"
filter: ["**/*"]
- from: "../scripts"
to: "app/scripts"
filter:
- "**/*"
- "!**/*.test.js"
- from: "../package.json"
to: "app/package.json"
- from: "../node_modules"
to: "app/node_modules"
filter:
- "**/*"
- "!**/*.md"
- "!**/test/**"
- "!**/tests/**"
- "!**/*.d.ts"
# better-sqlite3 ships from desktop/node_modules (per-arch rebuilt by
# install-app-deps). The root copy is built for the system Node and
# would trip @electron/universal's identical-file detector.
- "!**/better-sqlite3/**"
# Tray icon images need to live OUTSIDE the asar archive: `nativeImage` can't
# always read them from an asar path, and `files` here (out/**, package.json)
# would otherwise leave them out of the bundle entirely. Ship them as plain
# files at `Resources/assets/`; `trayImagePath()` reads them via
# `process.resourcesPath` in production. macOS uses the template PNGs; Windows
# uses the colored `icon.ico` (a template/black glyph would vanish on the
# dark Windows taskbar).
- from: "assets"
to: "assets"
filter:
- "tray-icon-Template*.png"
- "icon.ico"
asar: true
asarUnpack:
# better-sqlite3 native bindings cannot live inside asar.
- "**/node_modules/better-sqlite3/**"
mac:
category: public.app-category.developer-tools
icon: assets/icon.icns
hardenedRuntime: true
gatekeeperAssess: false
# Ad-hoc signed by default: the `package` npm script sets
# CSC_IDENTITY_AUTO_DISCOVERY=false so a code-signing cert already in the
# contributor's keychain is never picked up (it would fail distribution
# signing). Real Developer ID signing activates only when CSC_LINK (an
# explicit .p12) is provided — that path is unaffected by the flag.
# No `arch:` here on purpose. Pinning the arch list in the config makes
# electron-builder build *every* listed architecture regardless of the CLI
# flag, so `electron-builder --mac --arm64` would still emit an x64 DMG too.
# With arch left unspecified, the `--arm64` / `--x64` / `--universal` flags
# the `dmg:*` npm scripts pass are what decide which single DMG is produced.
target:
- dmg
extendInfo:
LSUIElement: false
NSHighResolutionCapable: true
NSRequiresAquaSystemAppearance: false
dmg:
artifactName: "ClaudeCodeMonitor-${version}-${arch}.dmg"
# The mounted-volume title carries the architecture so that, when a release/
# directory holds more than one DMG, the Finder windows are distinguishable
# and nobody drags an x64 build onto Apple Silicon (which triggers a Rosetta
# prompt). The arch label is NOT set here: the `${arch}` macro expands
# inconsistently inside `title` — it yields `-arm64` / an empty string rather
# than `arm64` / `x64`. The per-arch `dmg:*` scripts in package.json override
# `dmg.title` with an explicit, clean label instead.
title: "Claude Code Monitor"
icon: assets/icon.icns
contents:
# Left slot: the .app bundle. Do NOT set `type: file` here — electron-builder
# auto-fills the app at this slot when type/path are omitted. With an
# explicit `type: file` and no `path`, recent electron-builder resolves
# `path: ""` against the project dir and stat's `<repo>/desktop`, then
# bombs with `<repo>/desktop not a file`. Omitting both is the canonical
# form documented in the electron-builder DMG layout examples.
- x: 130
y: 220
- x: 410
y: 220
type: link
path: /Applications
window:
width: 540
height: 380
win:
# Multi-size BMP icon generated by `scripts/build-win-icon.ps1` from the same
# `icon.png` the macOS pipeline renders — see that script's header. Embedded
# in the .exe and reused for the installer + taskbar.
icon: assets/icon.ico
# Emit both an NSIS installer (.exe) and a no-install portable .exe. The
# `win` / `win:portable` npm scripts pass an explicit target so each produces
# exactly one artifact; a bare `electron-builder --win` builds both. No
# `arch:` is pinned here for the same reason as macOS above — the per-arch
# CLI flag (`--x64`) is what decides the architecture.
target:
- nsis
- portable
# Unsigned by default. Unlike macOS there is no keychain identity to suppress:
# Windows signing activates only when an explicit certificate is provided via
# CSC_LINK + CSC_KEY_PASSWORD (or win.certificateFile). Unsigned builds run
# fine; SmartScreen may show a "more info" prompt on first launch.
nsis:
# A two-step installer (not oneClick) so the user can pick the install dir.
# Per-user install (perMachine: false) writes to %LOCALAPPDATA%\Programs and
# needs no administrator elevation.
oneClick: false
perMachine: false
allowToChangeInstallationDirectory: true
createDesktopShortcut: true
createStartMenuShortcut: true
shortcutName: "Claude Code Monitor"
uninstallDisplayName: "Claude Code Monitor ${version}"
artifactName: "ClaudeCodeMonitor-Setup-${version}-${arch}.${ext}"
# Keep the per-user SQLite database + settings (under userData) on uninstall,
# mirroring macOS where dragging the .app to Trash never touches user data.
deleteAppDataOnUninstall: false
portable:
artifactName: "ClaudeCodeMonitor-${version}-${arch}-portable.${ext}"
# Notarization runs only when the Apple credentials are present (macOS only;
# the hook is a no-op on Windows).
afterSign: scripts/notarize.js