@cryptiklemur/lattice 1.25.1 → 1.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,123 +1,136 @@
1
- # Lattice
1
+ <p align="center">
2
+ <img src="docs/screenshots/dashboard.png" alt="Lattice Dashboard" width="720" />
3
+ </p>
2
4
 
3
- Multi-machine agentic dashboard for Claude Code. Monitor sessions, manage projects, track costs, and orchestrate across mesh-networked nodes.
5
+ <h1 align="center">Lattice</h1>
6
+
7
+ <p align="center">
8
+ Multi-machine agentic dashboard for Claude Code.<br/>
9
+ Monitor sessions, manage projects, track costs, and orchestrate across mesh-networked nodes.
10
+ </p>
11
+
12
+ <p align="center">
13
+ <a href="https://www.npmjs.com/package/@cryptiklemur/lattice"><img src="https://img.shields.io/npm/v/@cryptiklemur/lattice?style=flat-square&color=blue" alt="npm version" /></a>
14
+ <a href="https://github.com/cryptiklemur/lattice/actions"><img src="https://img.shields.io/github/actions/workflow/status/cryptiklemur/lattice/ci.yml?style=flat-square&label=CI" alt="CI" /></a>
15
+ <a href="https://github.com/cryptiklemur/lattice/blob/main/LICENSE"><img src="https://img.shields.io/github/license/cryptiklemur/lattice?style=flat-square" alt="License" /></a>
16
+ <a href="https://github.com/cryptiklemur/lattice"><img src="https://img.shields.io/github/stars/cryptiklemur/lattice?style=flat-square" alt="Stars" /></a>
17
+ </p>
4
18
 
5
19
  > **Alpha** — Lattice is under active development. APIs and features may change.
6
20
 
7
- ![Dashboard](docs/screenshots/dashboard.png)
21
+ ---
8
22
 
9
- ## What is Lattice?
23
+ ## Quick Start
10
24
 
11
- Lattice is a web dashboard that sits alongside your Claude Code sessions. It gives you a unified view across projects, machines, and sessions — with real-time monitoring, cost tracking, and configuration management.
25
+ ```bash
26
+ npm install -g @cryptiklemur/lattice
27
+ lattice
28
+ ```
12
29
 
13
- ### Core Features
30
+ Opens at `http://localhost:7654`. Add projects through the UI or point it at a directory with a `CLAUDE.md` file.
14
31
 
15
- - **Multi-project dashboard** — Fleet overview with node status, session counts, cost stats, and recent activity across all projects
16
- - **Real-time chat** — Send messages, approve tool use, monitor context window usage and costs with per-message token counts
17
- - **Session management** — Browse, rename, delete, search, and resume sessions with date range filtering and hover previews
18
- - **Analytics** — Cost over time, token flow, cache efficiency, session complexity, activity calendar, and 15+ chart types
19
- - **Cost budget** — Daily spend tracking with configurable enforcement (warning, confirm, or hard block)
20
- - **Theme system** — 23 base16 themes (12 dark, 11 light) with OKLCH color space for perceptual consistency
32
+ <details>
33
+ <summary>Install with Bun</summary>
21
34
 
22
- ![Chat View](docs/screenshots/chat-view.png)
35
+ ```bash
36
+ bun install -g @cryptiklemur/lattice
37
+ lattice
38
+ ```
23
39
 
24
- ### Productivity
40
+ </details>
25
41
 
26
- - **Session tabs** — Open multiple sessions as tabs, switch between them, split-pane via right-click
27
- - **Message bookmarks** — Pin important messages, jump between bookmarks, global bookmarks view across all sessions
28
- - **Keyboard shortcuts** — Press `?` to see all shortcuts, `Ctrl+K` for command palette
29
- - **Message actions** — Copy messages (raw markdown or plain text), start new sessions from any message
30
- - **Auto-titling** — Sessions automatically get descriptive titles from the first exchange
31
- - **Session hover previews** — Hover any session to see cost, duration, message count, model, and last message
42
+ <details>
43
+ <summary>Development setup</summary>
32
44
 
33
- ![Analytics](docs/screenshots/analytics.png)
45
+ ```bash
46
+ git clone https://github.com/cryptiklemur/lattice.git
47
+ cd lattice
48
+ bun install
49
+ bun run dev
50
+ ```
34
51
 
35
- ### Infrastructure
52
+ Hot-reloads both server and client automatically.
36
53
 
37
- - **MCP server management** — Add, edit, and remove MCP servers at global or project level
38
- - **Skill marketplace** — Search and install skills from [skills.sh](https://skills.sh)
39
- - **Mesh networking** — Connect multiple machines, proxy sessions across nodes with automatic discovery
40
- - **Configuration editor** — Edit CLAUDE.md, environment variables, rules, and permissions through the UI
41
- - **Memory management** — View and edit Claude's project memories with frontmatter metadata
54
+ </details>
42
55
 
43
- ![Settings](docs/screenshots/settings.png)
56
+ ---
44
57
 
45
- ### Mobile Support
58
+ ## Features
46
59
 
47
- Responsive design with touch targets, swipe-to-open sidebar, and optimized layouts for mobile devices.
60
+ ### Chat & Sessions
48
61
 
49
- <img src="docs/screenshots/mobile-chat.png" width="300" alt="Mobile chat view" />
62
+ Send messages, approve tool use, and monitor context window usage with per-message token counts. Browse, rename, delete, and search sessions with date range filtering and hover previews. Sessions automatically get descriptive titles from the first exchange.
50
63
 
51
- ## Quick Start
64
+ ![Chat View](docs/screenshots/chat-view.png)
52
65
 
53
- ### Install
66
+ ### Analytics & Cost Tracking
54
67
 
55
- ```bash
56
- # With npm
57
- npm install -g lattice-ai
68
+ Track spending, token usage, cache efficiency, and session patterns with 15+ chart types. Set daily cost budgets with configurable enforcement (warning, confirm, or hard block).
58
69
 
59
- # With bun
60
- bun install -g lattice-ai
61
- ```
70
+ ![Analytics](docs/screenshots/analytics.png)
62
71
 
63
- ### Run
72
+ ### Workspace
64
73
 
65
- ```bash
66
- lattice
67
- ```
74
+ Open multiple sessions as tabs and switch between them. Split-pane via right-click context menu. Pin important messages with bookmarks — jump between them per-session or browse the global bookmarks view. Per-project tab state persists across navigation.
68
75
 
69
- Opens the dashboard at `http://localhost:7654`. Add projects through the UI or by navigating to a directory with a `CLAUDE.md` file.
76
+ Press `?` for keyboard shortcuts, `Ctrl+K` for the command palette.
70
77
 
71
- ### Development
78
+ ![Keyboard Shortcuts](docs/screenshots/keyboard-shortcuts.png)
72
79
 
73
- ```bash
74
- git clone https://github.com/cryptiklemur/lattice.git
75
- cd lattice
76
- bun install
77
- bun run dev
78
- ```
80
+ ### Themes & Settings
81
+
82
+ 23 base16 themes (12 dark, 11 light) with OKLCH color space. Configure MCP servers, environment variables, rules, permissions, and Claude settings through the UI.
83
+
84
+ ![Settings](docs/screenshots/settings.png)
85
+
86
+ ### Infrastructure
79
87
 
80
- The dev server hot-reloads both the Bun server and the Vite client automatically.
88
+ - **Mesh networking** Connect multiple machines with automatic discovery and session proxying
89
+ - **MCP servers** — Add, edit, and remove at global or project level
90
+ - **Skill marketplace** — Search and install from [skills.sh](https://skills.sh)
91
+ - **Memory management** — View and edit Claude's project memories
92
+
93
+ ### Mobile
94
+
95
+ Responsive design with touch targets, swipe-to-open sidebar, and optimized layouts.
96
+
97
+ <img src="docs/screenshots/mobile-chat.png" width="300" alt="Mobile chat view" />
98
+
99
+ ---
81
100
 
82
101
  ## Architecture
83
102
 
84
- Lattice is a Bun monorepo with three packages:
103
+ Bun monorepo with three packages:
85
104
 
86
- | Package | Description |
87
- |---------|------------|
88
- | `shared/` | TypeScript types, message protocol definitions, constants |
89
- | `server/` | Bun WebSocket server — session management, analytics engine, mesh networking, structured logging |
90
- | `client/` | React 19 + Vite + Tailwind + daisyUI — UI components, state management, 23 themes |
105
+ | Package | Stack |
106
+ |---------|-------|
107
+ | `shared/` | TypeScript types, message protocol, constants |
108
+ | `server/` | Bun WebSocket server, analytics engine, mesh networking |
109
+ | `client/` | React 19, Vite, Tailwind, daisyUI, 23 themes |
91
110
 
92
- The server communicates with clients via WebSocket using a typed message protocol defined in `shared/`. Sessions are managed through the [Claude Agent SDK](https://github.com/anthropics/claude-agent-sdk). The client uses Tanstack Store for state and Tanstack Router for routing.
111
+ Communication via typed WebSocket messages. Sessions managed through the [Claude Agent SDK](https://github.com/anthropics/claude-agent-sdk). Client state via Tanstack Store + Router.
93
112
 
94
113
  ### Security
95
114
 
96
- - Authentication via passphrase with scrypt hashing and 24-hour token expiration
97
- - Per-client WebSocket rate limiting (100 messages per 10-second window)
98
- - Attachment upload size limits (10MB max)
99
- - Bash `cd` commands boundary-checked against project directory
100
- - Mesh pairing tokens expire after 5 minutes
101
- - Graceful server shutdown with active stream draining
115
+ | Feature | Detail |
116
+ |---------|--------|
117
+ | Authentication | Passphrase with scrypt hashing, 24-hour token expiration |
118
+ | Rate limiting | 100 messages per 10-second window per client |
119
+ | Attachments | 10MB upload limit |
120
+ | Bash commands | `cd` boundary-checked against project directory |
121
+ | Mesh pairing | Tokens expire after 5 minutes |
122
+ | Shutdown | Graceful drain of active streams |
102
123
 
103
124
  ### Testing
104
125
 
105
- Playwright test suite covering onboarding, session flow, keyboard shortcuts, accessibility, message actions, and session previews.
106
-
107
126
  ```bash
108
- # Start the server first
109
- bun run dev
110
-
111
- # Run tests
112
- bunx playwright test
113
-
114
- # Single test file
115
- bunx playwright test tests/session-flow.spec.ts
127
+ bun run dev # start server
128
+ bunx playwright test # run tests
116
129
  ```
117
130
 
118
- ## Configuration
131
+ Playwright suite covers onboarding, session flow, keyboard shortcuts, accessibility, message actions, and session previews.
119
132
 
120
- Lattice stores its config at `~/.lattice/config.json`. Global Claude settings are read from `~/.claude/` and `~/.claude.json`.
133
+ ## Configuration
121
134
 
122
135
  | Path | Purpose |
123
136
  |------|---------|
@@ -125,15 +138,12 @@ Lattice stores its config at `~/.lattice/config.json`. Global Claude settings ar
125
138
  | `~/.lattice/bookmarks.json` | Message bookmarks across all sessions |
126
139
  | `~/.claude/CLAUDE.md` | Global Claude instructions |
127
140
  | `~/.claude.json` | Global MCP server configuration |
128
- | `~/.claude/skills/` | Global skills directory |
129
-
130
- Project-level settings are stored in each project's `.claude/` directory and `.mcp.json`.
131
141
 
132
- ### Environment
142
+ **Environment variables:**
133
143
 
134
- - `ANTHROPIC_API_KEY` — Optional. Server uses the token from `claude setup-token` if not set.
135
- - `DEBUG=lattice:*` — Enable structured debug logging (namespaces: server, ws, chat, session, mesh, auth, fs, analytics)
136
- - Server binds to `0.0.0.0:7654` by default. Override with `lattice --port <port>`.
144
+ - `ANTHROPIC_API_KEY` — Optional. Uses `claude setup-token` if not set.
145
+ - `DEBUG=lattice:*` — Structured debug logging.
146
+ - Server binds to `0.0.0.0:7654`. Override with `lattice --port <port>`.
137
147
 
138
148
  ## Contributing
139
149
 
@@ -0,0 +1,117 @@
1
+ import { useState, useEffect } from "react";
2
+ import { Blocks, Loader2 } from "lucide-react";
3
+ import { useWebSocket } from "../../hooks/useWebSocket";
4
+ import type { ProjectSettings, ServerMessage, PluginInfo } from "@lattice/shared";
5
+
6
+ interface ProjectPluginsProps {
7
+ settings: ProjectSettings;
8
+ updateSection: (section: string, data: Record<string, unknown>) => void;
9
+ }
10
+
11
+ export function ProjectPlugins({ settings, updateSection }: ProjectPluginsProps) {
12
+ var { send, subscribe, unsubscribe } = useWebSocket();
13
+ var [plugins, setPlugins] = useState<PluginInfo[]>([]);
14
+ var [loaded, setLoaded] = useState(false);
15
+ var [disabledPlugins, setDisabledPlugins] = useState<string[]>(settings.disabledPlugins ?? []);
16
+ var [saving, setSaving] = useState(false);
17
+
18
+ useEffect(function () {
19
+ function handleListResult(msg: ServerMessage) {
20
+ if (msg.type !== "plugin:list_result") return;
21
+ var data = msg as { type: "plugin:list_result"; plugins: PluginInfo[] };
22
+ setPlugins(data.plugins);
23
+ setLoaded(true);
24
+ }
25
+
26
+ subscribe("plugin:list_result", handleListResult);
27
+ send({ type: "plugin:list" } as any);
28
+
29
+ return function () {
30
+ unsubscribe("plugin:list_result", handleListResult);
31
+ };
32
+ }, []);
33
+
34
+ useEffect(function () {
35
+ setDisabledPlugins(settings.disabledPlugins ?? []);
36
+ }, [settings.disabledPlugins]);
37
+
38
+ function handleToggle(pluginKey: string) {
39
+ var next: string[];
40
+ if (disabledPlugins.indexOf(pluginKey) !== -1) {
41
+ next = disabledPlugins.filter(function (k) { return k !== pluginKey; });
42
+ } else {
43
+ next = disabledPlugins.concat(pluginKey);
44
+ }
45
+ setDisabledPlugins(next);
46
+ setSaving(true);
47
+ updateSection("plugins", { disabledPlugins: next });
48
+ setTimeout(function () { setSaving(false); }, 500);
49
+ }
50
+
51
+ if (!loaded) {
52
+ return <div className="text-[13px] text-base-content/40 py-4">Loading...</div>;
53
+ }
54
+
55
+ if (plugins.length === 0) {
56
+ return (
57
+ <div className="py-6 text-center text-[13px] text-base-content/30">
58
+ No plugins installed. Install plugins from Global Settings to use them in projects.
59
+ </div>
60
+ );
61
+ }
62
+
63
+ var enabledCount = plugins.length - disabledPlugins.length;
64
+
65
+ return (
66
+ <div className="py-2 space-y-4">
67
+ <div className="flex items-center justify-between">
68
+ <p className="text-[12px] text-base-content/40">
69
+ Toggle plugins on/off for this project. Disabled plugins won't load in new sessions.
70
+ </p>
71
+ {saving && <Loader2 size={12} className="text-primary animate-spin" />}
72
+ </div>
73
+
74
+ <div className="text-[11px] text-base-content/30 mb-1">
75
+ {enabledCount} of {plugins.length} enabled
76
+ </div>
77
+
78
+ <div className="space-y-1.5">
79
+ {plugins.map(function (plugin) {
80
+ var isDisabled = disabledPlugins.indexOf(plugin.key) !== -1;
81
+ return (
82
+ <div
83
+ key={plugin.key}
84
+ className={
85
+ "flex items-center gap-3 px-3 py-2.5 rounded-xl border transition-colors duration-[120ms] " +
86
+ (isDisabled
87
+ ? "bg-base-300/30 border-base-content/8 opacity-50"
88
+ : "bg-base-300 border-base-content/15")
89
+ }
90
+ >
91
+ <Blocks size={14} className="text-base-content/25 flex-shrink-0" />
92
+ <div className="flex-1 min-w-0">
93
+ <div className="flex items-center gap-2">
94
+ <span className="text-[13px] font-bold text-base-content truncate">{plugin.name}</span>
95
+ <span className="text-[10px] font-mono px-1.5 py-0.5 rounded-md bg-base-content/8 text-base-content/40">
96
+ v{plugin.version}
97
+ </span>
98
+ </div>
99
+ <div className="text-[11px] text-base-content/30 mt-0.5">
100
+ {plugin.marketplace}
101
+ {plugin.skillCount > 0 ? " \u00B7 " + plugin.skillCount + " skill" + (plugin.skillCount !== 1 ? "s" : "") : ""}
102
+ </div>
103
+ </div>
104
+ <input
105
+ type="checkbox"
106
+ checked={!isDisabled}
107
+ onChange={function () { handleToggle(plugin.key); }}
108
+ className="toggle toggle-sm toggle-primary"
109
+ aria-label={(isDisabled ? "Enable" : "Disable") + " " + plugin.name}
110
+ />
111
+ </div>
112
+ );
113
+ })}
114
+ </div>
115
+ </div>
116
+ );
117
+ }
@@ -12,6 +12,7 @@ import { ProjectRules } from "./ProjectRules";
12
12
  import { ProjectMcp } from "./ProjectMcp";
13
13
  import { ProjectMemory } from "./ProjectMemory";
14
14
  import { ProjectNotifications } from "./ProjectNotifications";
15
+ import { ProjectPlugins } from "./ProjectPlugins";
15
16
 
16
17
  var SECTION_CONFIG: Record<string, { title: string }> = {
17
18
  general: { title: "General" },
@@ -20,6 +21,7 @@ var SECTION_CONFIG: Record<string, { title: string }> = {
20
21
  environment: { title: "Environment" },
21
22
  mcp: { title: "MCP Servers" },
22
23
  skills: { title: "Skills" },
24
+ plugins: { title: "Plugins" },
23
25
  rules: { title: "Rules" },
24
26
  permissions: { title: "Permissions" },
25
27
  memory: { title: "Memory" },
@@ -51,6 +53,10 @@ function renderSection(
51
53
  return <ProjectSkills settings={settings} projectSlug={projectSlug} />;
52
54
  }
53
55
 
56
+ if (section === "plugins") {
57
+ return <ProjectPlugins settings={settings} updateSection={updateSection} />;
58
+ }
59
+
54
60
  if (section === "rules") {
55
61
  return <ProjectRules settings={settings} updateSection={updateSection} />;
56
62
  }