@chrisai/base 2.3.0 → 2.3.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 +418 -75
- package/package.json +1 -1
- package/src/framework/tasks/scaffold.md +12 -5
- package/src/hooks/satellite-detection.py +3 -3
package/README.md
CHANGED
|
@@ -9,15 +9,113 @@
|
|
|
9
9
|
[](LICENSE)
|
|
10
10
|
[](https://claude.ai/code)
|
|
11
11
|
|
|
12
|
+
**Your AI builder operating system.**<br/>
|
|
13
|
+
Turn Claude Code from a per-session tool into a workspace that remembers, maintains itself, and never goes stale.
|
|
14
|
+
|
|
12
15
|
</div>
|
|
13
16
|
|
|
14
17
|
---
|
|
15
18
|
|
|
16
|
-
##
|
|
19
|
+
## The Problem Every Claude Code User Hits
|
|
20
|
+
|
|
21
|
+
You start a Claude Code session. Claude doesn't know:
|
|
22
|
+
|
|
23
|
+
- What you're working on
|
|
24
|
+
- What's blocked
|
|
25
|
+
- What you worked on yesterday
|
|
26
|
+
- What's overdue
|
|
27
|
+
- Which projects need attention
|
|
28
|
+
|
|
29
|
+
So you repeat yourself. Every. Single. Session.
|
|
30
|
+
|
|
31
|
+
Maybe you've tried fixing this with a massive `CLAUDE.md` file, `@`-mentions pointing at markdown docs, or manual context dumps at session start. It works... until it doesn't. Files go stale. Your CLAUDE.md becomes a junk drawer. You forget to update things. Claude starts making decisions based on outdated information. And the bigger your workspace gets, the worse it breaks.
|
|
32
|
+
|
|
33
|
+
**This is the duct tape phase.** Everyone goes through it. BASE is what comes after.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## What BASE Actually Does
|
|
17
38
|
|
|
18
|
-
BASE
|
|
39
|
+
BASE turns your Claude Code workspace into a managed operating system. Instead of scattered markdown files and manual context loading, you get:
|
|
19
40
|
|
|
20
|
-
**
|
|
41
|
+
**Structured data that Claude reads automatically.** Your active projects, backlog items, client lists — anything you want Claude to passively know about — lives in structured JSON files. Lightweight hooks inject compact summaries into every session automatically. You never type "here's what I'm working on" again.
|
|
42
|
+
|
|
43
|
+
**Health monitoring that catches drift before it hurts.** A drift score tracks how far your workspace state has drifted from reality. When things go stale, BASE tells you. When grooming is overdue, BASE tells you. You fix it with a guided maintenance cycle, not a weekend of cleanup.
|
|
44
|
+
|
|
45
|
+
**A manifest that drives everything.** One config file (`workspace.json`) declares what your workspace contains, how each area should be maintained, and what projects are in play. Every command reads from it. Your workspace is self-describing.
|
|
46
|
+
|
|
47
|
+
### What This Looks Like in Practice
|
|
48
|
+
|
|
49
|
+
You open Claude Code. Before you type anything, Claude already knows:
|
|
50
|
+
|
|
51
|
+
```xml
|
|
52
|
+
<active-awareness items="5">
|
|
53
|
+
[URGENT]
|
|
54
|
+
- [ACT-001] Client Portal Launch (Blocked: API auth)
|
|
55
|
+
DUE: 2026-03-20
|
|
56
|
+
[HIGH]
|
|
57
|
+
- [ACT-002] Course Module 3 (In Progress)
|
|
58
|
+
- [ACT-003] MCP Server Refactor (In Review)
|
|
59
|
+
|
|
60
|
+
BEHAVIOR: PASSIVE AWARENESS ONLY.
|
|
61
|
+
Do NOT proactively mention unless user asks or deadline < 24h.
|
|
62
|
+
</active-awareness>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Claude doesn't nag. It doesn't start the session with "here are your tasks." But the moment you ask "what should I work on?" — the answer is instant and accurate. No file reading. No context window wasted. No stale data.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## How It Works
|
|
70
|
+
|
|
71
|
+
### Data Surfaces — The Core Concept
|
|
72
|
+
|
|
73
|
+
A "data surface" is just a structured JSON file paired with a hook that injects it into Claude's context. That's it.
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
JSON file (your data) → Hook (reads + summarizes) → Claude knows it
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
BASE ships with two built-in surfaces:
|
|
80
|
+
|
|
81
|
+
| Surface | What It Tracks |
|
|
82
|
+
|---------|---------------|
|
|
83
|
+
| **Active** | Current projects, tasks, blockers, deadlines, status |
|
|
84
|
+
| **Backlog** | Future work, ideas, deferred items with review deadlines |
|
|
85
|
+
|
|
86
|
+
But you can create surfaces for anything — clients, contacts, content pipelines, API keys, whatever persistent data you want Claude to passively know about. The `/base:surface create` command walks you through it: define a schema, pick an injection format, and BASE generates the JSON file, the hook, and the wiring automatically.
|
|
87
|
+
|
|
88
|
+
### The Manifest — One File Rules Everything
|
|
89
|
+
|
|
90
|
+
`workspace.json` is the brain. It registers:
|
|
91
|
+
|
|
92
|
+
- Every data surface and its schema
|
|
93
|
+
- Every tracked area in your workspace (projects, tools, content, clients...)
|
|
94
|
+
- Grooming schedules per area
|
|
95
|
+
- Audit strategies per area type
|
|
96
|
+
- Connected projects and their health status
|
|
97
|
+
|
|
98
|
+
Every BASE command reads from this manifest. You configure it once during setup, and the system maintains itself from there.
|
|
99
|
+
|
|
100
|
+
### Hooks — The Glue
|
|
101
|
+
|
|
102
|
+
BASE uses Claude Code's [hook system](https://docs.anthropic.com/en/docs/claude-code/hooks) to inject context automatically. There are two types:
|
|
103
|
+
|
|
104
|
+
**Every prompt** (`UserPromptSubmit`) — Fire on every message you send, keeping Claude's awareness current throughout the session:
|
|
105
|
+
|
|
106
|
+
| Hook | What It Does |
|
|
107
|
+
|------|-------------|
|
|
108
|
+
| **Pulse check** | Calculates workspace drift score, warns if grooming is overdue |
|
|
109
|
+
| **PSMM injector** | Re-injects important session moments (decisions, corrections, insights) into Claude's context so they don't get buried in a long session. [Details below.](#per-session-meta-memory-psmm) |
|
|
110
|
+
| **Surface hooks** | One per data surface (active, backlog, or custom). Reads the JSON, outputs a compact summary so Claude passively knows the current state |
|
|
111
|
+
|
|
112
|
+
**Session start** (`SessionStart`) — Runs once when a Claude Code session begins:
|
|
113
|
+
|
|
114
|
+
| Hook | What It Does |
|
|
115
|
+
|------|-------------|
|
|
116
|
+
| **PAUL project detection** | Scans your workspace for [PAUL](https://github.com/ChristopherKahler/paul) project files (`.paul/paul.json`) and auto-registers new ones into `workspace.json`. Only needs to run once — your project list doesn't change mid-session. (More on PAUL below.) |
|
|
117
|
+
|
|
118
|
+
All hooks are lightweight Python — they read JSON files and output compact XML summaries. No network calls, no heavy dependencies, no noticeable latency. A hook that has nothing to report outputs nothing and exits silently.
|
|
21
119
|
|
|
22
120
|
---
|
|
23
121
|
|
|
@@ -27,128 +125,373 @@ BASE keeps your Claude Code workspace from becoming a mess. It scaffolds structu
|
|
|
27
125
|
npx @chrisai/base --global --workspace
|
|
28
126
|
```
|
|
29
127
|
|
|
30
|
-
|
|
31
|
-
|------|-------------|
|
|
32
|
-
| `--global` | Install commands + framework to `~/.claude` |
|
|
33
|
-
| `--workspace` | Install workspace layer (`.base/`) in current directory |
|
|
34
|
-
| `--local` | Install commands to `./.claude` instead of global |
|
|
35
|
-
| `--config-dir <path>` | Custom Claude config directory |
|
|
36
|
-
| `--workspace-dir <path>` | Target a specific workspace path |
|
|
128
|
+
One command. Two layers:
|
|
37
129
|
|
|
38
|
-
|
|
130
|
+
- `--global` installs commands and the framework to `~/.claude` (shared across all your workspaces)
|
|
131
|
+
- `--workspace` installs the data layer to `.base/` in your current directory
|
|
132
|
+
|
|
133
|
+
Then open Claude Code and run `/base:scaffold` to configure your workspace with a guided setup.
|
|
39
134
|
|
|
40
135
|
```bash
|
|
41
|
-
# Full install —
|
|
136
|
+
# Full install — most users start here
|
|
42
137
|
npx @chrisai/base --global --workspace
|
|
43
138
|
|
|
44
|
-
# Already
|
|
139
|
+
# Already installed globally? Wire up a new workspace
|
|
45
140
|
npx @chrisai/base --workspace
|
|
46
141
|
|
|
47
|
-
# Global only — set up
|
|
142
|
+
# Global only — set up workspaces later with /base:scaffold
|
|
48
143
|
npx @chrisai/base --global
|
|
49
144
|
```
|
|
50
145
|
|
|
146
|
+
| Flag | What It Does |
|
|
147
|
+
|------|-------------|
|
|
148
|
+
| `--global` | Commands + framework to `~/.claude` (shared) |
|
|
149
|
+
| `--workspace` | Data layer to `.base/` in current directory |
|
|
150
|
+
| `--local` | Commands to `./.claude` instead of global |
|
|
151
|
+
| `--config-dir <path>` | Custom Claude config directory |
|
|
152
|
+
| `--workspace-dir <path>` | Target a specific workspace path |
|
|
153
|
+
|
|
51
154
|
---
|
|
52
155
|
|
|
53
156
|
## What Gets Installed
|
|
54
157
|
|
|
55
158
|
```
|
|
56
|
-
~/.claude/
|
|
57
|
-
├── commands/base/
|
|
58
|
-
├── skills/base/
|
|
159
|
+
~/.claude/ Shared across all workspaces
|
|
160
|
+
├── commands/base/ 11 slash commands
|
|
161
|
+
├── skills/base/ Skill entry point + package sources
|
|
59
162
|
└── base-framework/
|
|
60
|
-
├── tasks/
|
|
61
|
-
├── templates/
|
|
62
|
-
├── context/
|
|
63
|
-
├── frameworks/
|
|
64
|
-
└── hooks/
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
├── workspace.json
|
|
163
|
+
├── tasks/ How each command works (pulse, groom, audit...)
|
|
164
|
+
├── templates/ Schemas for workspace.json, STATE.md, surfaces
|
|
165
|
+
├── context/ Core principles
|
|
166
|
+
├── frameworks/ Audit strategies, project registration
|
|
167
|
+
└── hooks/ Session hook sources
|
|
168
|
+
|
|
169
|
+
.base/ Per-workspace
|
|
170
|
+
├── workspace.json The manifest — everything is registered here
|
|
68
171
|
├── data/
|
|
69
|
-
│ ├── active.json
|
|
70
|
-
│ └── backlog.json
|
|
71
|
-
├── hooks/ Surface injection hooks
|
|
72
|
-
├── base-mcp/ BASE MCP server
|
|
73
|
-
└── carl-mcp/ CARL MCP server
|
|
74
|
-
|
|
75
|
-
./.claude/
|
|
172
|
+
│ ├── active.json Active work surface
|
|
173
|
+
│ └── backlog.json Backlog surface
|
|
76
174
|
├── hooks/
|
|
77
|
-
│ ├──
|
|
78
|
-
│ ├──
|
|
79
|
-
│ └──
|
|
80
|
-
|
|
175
|
+
│ ├── _template.py Hook template for creating new surfaces
|
|
176
|
+
│ ├── active-hook.py Injects active work into Claude's context
|
|
177
|
+
│ └── backlog-hook.py Injects backlog into Claude's context
|
|
178
|
+
├── base-mcp/ MCP server for surface operations (CRUD)
|
|
179
|
+
└── carl-mcp/ MCP server for rules engine operations
|
|
180
|
+
|
|
181
|
+
.claude/hooks/ Registered in settings.json
|
|
182
|
+
├── base-pulse-check.py [UserPromptSubmit] Drift + groom reminders
|
|
183
|
+
├── psmm-injector.py [UserPromptSubmit] Session meta memory
|
|
184
|
+
└── satellite-detection.py [SessionStart] PAUL project discovery
|
|
81
185
|
```
|
|
82
186
|
|
|
83
187
|
---
|
|
84
188
|
|
|
85
|
-
##
|
|
189
|
+
## The Maintenance Cycle
|
|
190
|
+
|
|
191
|
+
Most workspace management tools are set-and-forget. BASE is designed around the reality that workspaces are living things that drift.
|
|
192
|
+
|
|
193
|
+
### Pulse — Session Start Health Check
|
|
86
194
|
|
|
87
|
-
|
|
195
|
+
`/base:pulse` runs automatically via hook. It reads your manifest, checks filesystem timestamps, and calculates a drift score:
|
|
88
196
|
|
|
89
|
-
|
|
|
90
|
-
|
|
91
|
-
|
|
|
92
|
-
|
|
|
93
|
-
|
|
|
94
|
-
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
197
|
+
| Drift Score | What It Means | What to Do |
|
|
198
|
+
|-------------|--------------|------------|
|
|
199
|
+
| **0** | Everything is current | Work normally |
|
|
200
|
+
| **1-7** | Minor drift | Fix at next groom |
|
|
201
|
+
| **8-14** | Moderate — Claude may be acting on stale info | Groom soon |
|
|
202
|
+
| **15+** | Critical — workspace context is unreliable | Groom now |
|
|
203
|
+
|
|
204
|
+
No stop hooks. No unreliable session-end tracking. Pulse always starts from filesystem ground truth.
|
|
205
|
+
|
|
206
|
+
### Groom — Weekly Maintenance
|
|
207
|
+
|
|
208
|
+
`/base:groom` is a guided, voice-friendly walkthrough of your entire workspace. It reviews one area at a time, oldest-first:
|
|
209
|
+
|
|
210
|
+
1. **Active work** — "Still active? Status changed? Anything done?" — walks through each project and task
|
|
211
|
+
2. **Backlog** — Enforces time-based rules:
|
|
212
|
+
- High priority items get 7 days before they demand a decision
|
|
213
|
+
- Medium gets 14 days. Low gets 30 days.
|
|
214
|
+
- Items that sit past 2x their review window get auto-archived.
|
|
215
|
+
- "Decide or kill" — nothing sits in limbo forever.
|
|
216
|
+
3. **Graduation** — "Ready to work on any backlog items?" Items move to active work. Always explicit, never automatic.
|
|
217
|
+
4. **Directories** — Scans tracked directories (projects, clients, tools) for orphaned or new items
|
|
218
|
+
5. **Connected projects** — Checks project health across your workspace (more on this below)
|
|
219
|
+
6. **System layer** — Quick scan for dead hooks, unused commands, stale rules
|
|
220
|
+
|
|
221
|
+
Result: drift score resets to 0, summary gets logged, next groom date is set.
|
|
222
|
+
|
|
223
|
+
### Audit — Deep Optimization
|
|
224
|
+
|
|
225
|
+
`/base:audit` goes deeper than grooming. Each tracked area maps to a configurable audit strategy:
|
|
226
|
+
|
|
227
|
+
| Strategy | Applies To | What It Does |
|
|
228
|
+
|----------|-----------|-------------|
|
|
229
|
+
| `staleness` | Working memory files | Checks file age against thresholds |
|
|
230
|
+
| `classify` | Directories (projects/, clients/) | Lists items for triage: active, archive, or delete |
|
|
231
|
+
| `cross-reference` | Tools with config files | Finds orphaned tools and broken config references |
|
|
232
|
+
| `dead-code` | System directories | Finds unused hooks, commands, skills |
|
|
233
|
+
| `pipeline-status` | Content or task workflows | Flags stuck items and bottlenecks |
|
|
234
|
+
|
|
235
|
+
The number of audit phases is dynamic — generated from your manifest, not hardcoded. A small workspace gets 3 phases. A large one gets 12. Same command, adapted to your reality.
|
|
102
236
|
|
|
103
237
|
---
|
|
104
238
|
|
|
105
|
-
## Data
|
|
239
|
+
## MCP Servers — Claude Operates on Your Data
|
|
106
240
|
|
|
107
|
-
|
|
241
|
+
BASE ships two MCP servers so Claude can read and write your workspace data through structured tool calls instead of raw file edits.
|
|
108
242
|
|
|
243
|
+
### BASE MCP — Works With Any Surface
|
|
244
|
+
|
|
245
|
+
A generic CRUD interface for all registered surfaces. Claude can add items, update status, archive old work, and search across everything:
|
|
246
|
+
|
|
247
|
+
| Tool | What It Does |
|
|
248
|
+
|------|-------------|
|
|
249
|
+
| `base_list_surfaces` | List all surfaces with item counts |
|
|
250
|
+
| `base_get_surface` | Read all items from a surface |
|
|
251
|
+
| `base_get_item` | Get one item by ID |
|
|
252
|
+
| `base_add_item` | Add item (auto-generates ID, validates against schema) |
|
|
253
|
+
| `base_update_item` | Update specific fields (preserves everything else) |
|
|
254
|
+
| `base_archive_item` | Move item to archive with timestamp |
|
|
255
|
+
| `base_search` | Search across one or all surfaces by keyword |
|
|
256
|
+
|
|
257
|
+
When you create a new surface, the MCP server auto-discovers it from `workspace.json`. No code changes needed.
|
|
258
|
+
|
|
259
|
+
### CARL MCP — Rules Engine + Decision Memory + Session Intelligence
|
|
260
|
+
|
|
261
|
+
[CARL](https://github.com/ChristopherKahler/carl) (Context Augmentation & Reinforcement Layer) is a dynamic rules engine for Claude Code. On its own, CARL stores behavioral rules in domain files — groups of rules that load automatically based on what you're doing. Say "check Skool" and CARL loads your Skool community rules. Start coding and it loads your development standards. The rules are just config files in `.carl/`.
|
|
262
|
+
|
|
263
|
+
**CARL is fully independent — it works without BASE, and BASE works without CARL.** But BASE bundles CARL's MCP server as an optional capability. If you use CARL, BASE gives it MCP superpowers (programmatic rule management, decision logging, session memory). If you don't use CARL, this MCP server sits idle and everything else in BASE works normally.
|
|
264
|
+
|
|
265
|
+
When both are active, Claude gets programmatic access to three powerful systems:
|
|
266
|
+
|
|
267
|
+
#### Dynamic Rules
|
|
268
|
+
|
|
269
|
+
Claude can read, search, and manage your rule domains through tool calls instead of file edits:
|
|
270
|
+
|
|
271
|
+
| Tool | What It Does |
|
|
272
|
+
|------|-------------|
|
|
273
|
+
| `carl_list_domains` | List all rule domains and their status |
|
|
274
|
+
| `carl_get_domain_rules` | Read rules for a specific domain |
|
|
275
|
+
| `carl_stage_proposal` | Stage a new rule proposal for review (more on this below) |
|
|
276
|
+
|
|
277
|
+
#### Decision Logger
|
|
278
|
+
|
|
279
|
+
Decisions get lost. You make a call in one session — "we're using OAuth, not API keys" — and three sessions later Claude asks you the same question. Or worse, it makes the opposite choice because it has no memory of what you decided.
|
|
280
|
+
|
|
281
|
+
CARL's decision logger fixes this. Decisions are stored per domain (e.g., `decisions/development.json`, `decisions/global.json`) and **load automatically alongside domain rules**. When CARL loads the "development" domain because you're coding, every decision you've ever logged in that domain loads with it as lightweight metadata. Claude reads your decisions before acting on the prompt itself. It never misses a key decision again — not because it searches for it, but because the decision is already in context the moment the domain is relevant.
|
|
282
|
+
|
|
283
|
+
| Tool | What It Does |
|
|
284
|
+
|------|-------------|
|
|
285
|
+
| `carl_log_decision` | Record a decision with domain, rationale, and recall keywords |
|
|
286
|
+
| `carl_search_decisions` | Search across all domains when you need to find something specific |
|
|
287
|
+
|
|
288
|
+
#### Per-Session Meta Memory (PSMM)
|
|
289
|
+
|
|
290
|
+
Here's the problem with long Claude Code sessions: Claude's context window is huge (up to 1M tokens), but important moments — a design decision you made at minute 5, a correction at minute 20, a key insight at minute 45 — get buried under thousands of lines of tool output and code. By the time you're deep into the session, Claude has technically "seen" these moments but they've drifted so far back in context that they stop influencing behavior.
|
|
291
|
+
|
|
292
|
+
PSMM fixes this. When something significant happens during a session — a decision, a correction, a context shift, a key insight — Claude logs it:
|
|
293
|
+
|
|
294
|
+
| Tool | What It Does |
|
|
295
|
+
|------|-------------|
|
|
296
|
+
| `carl_psmm_log` | Log a session meta-memory entry (type: DECISION, CORRECTION, SHIFT, INSIGHT, COMMITMENT) |
|
|
297
|
+
|
|
298
|
+
The PSMM hook re-injects these entries into Claude's context on every prompt. Important moments stay hot for the entire session, no matter how long it runs.
|
|
299
|
+
|
|
300
|
+
#### The Rule Staging Pipeline
|
|
301
|
+
|
|
302
|
+
This is where PSMM, decisions, and rules connect into a learning loop:
|
|
303
|
+
|
|
304
|
+
1. **During a session** — Claude notices a pattern worth codifying (a correction you gave, a decision that should become policy, an insight about how you work)
|
|
305
|
+
2. **Stage it** — `carl_stage_proposal` creates a draft rule in staging, not in your live rules
|
|
306
|
+
3. **Review during hygiene** — BASE's `/base:carl-hygiene` command walks you through staged proposals: approve, edit, or kill each one
|
|
307
|
+
4. **Approved rules go live** — They become part of your CARL domains, loaded automatically in future sessions
|
|
308
|
+
|
|
309
|
+
This means your AI assistant gets smarter over time — not by accumulating a massive prompt, but by distilling session learnings into clean, targeted rules. And because staging exists, nothing goes live without your review. The hygiene cycle (part of BASE's groom flow) prevents staged proposals from going stale — they get reviewed or they get killed.
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## Multi-Project Workspaces — BASE + PAUL
|
|
314
|
+
|
|
315
|
+
Here's where BASE really separates from "just another CLAUDE.md helper."
|
|
316
|
+
|
|
317
|
+
Most Claude Code users work on one project at a time. But real workspaces have multiple projects — apps, client work, tools, content pipelines — each in their own directory, sometimes their own git repo. Without something managing the workspace level, you lose track. Projects stall silently. Work gets abandoned. Nobody notices until it's a problem.
|
|
318
|
+
|
|
319
|
+
### What Is PAUL?
|
|
320
|
+
|
|
321
|
+
[PAUL](https://github.com/ChristopherKahler/paul) is a project orchestration framework for Claude Code. It manages individual project builds through a structured **Plan → Apply → Unify** loop:
|
|
322
|
+
|
|
323
|
+
- **Plan** — Define what you're building, break it into phases, get alignment before writing code
|
|
324
|
+
- **Apply** — Execute the plan phase by phase with built-in progress tracking
|
|
325
|
+
- **Unify** — Reconcile what was planned vs what was built, close the loop, start the next milestone
|
|
326
|
+
|
|
327
|
+
Each PAUL project lives in its own directory with a `.paul/` config folder that tracks the project's state, milestones, and phase history. PAUL is excellent at managing a single project's lifecycle. But it doesn't know about your other projects, your backlog, or your workspace health.
|
|
328
|
+
|
|
329
|
+
### Where BASE Comes In
|
|
330
|
+
|
|
331
|
+
BASE is designed to work alongside PAUL as the workspace layer that ties everything together. Think of it as the difference between **project management** and **portfolio management:**
|
|
332
|
+
|
|
333
|
+
- **PAUL** manages each project: "What phase am I in? What's the plan? What's left to build?"
|
|
334
|
+
- **BASE** manages your workspace: "Which of my 6 projects needs attention? Which ones are stalling? What should I work on today?"
|
|
335
|
+
|
|
336
|
+
### How They Connect
|
|
337
|
+
|
|
338
|
+
BASE automatically detects and registers PAUL projects across your workspace:
|
|
339
|
+
|
|
340
|
+
- On session start, a hook scans your workspace for `.paul/paul.json` files and registers any new PAUL projects in `workspace.json` automatically
|
|
341
|
+
- If you started using PAUL before BASE, update PAUL to the latest version and run `/paul:register` in any PAUL project directory to generate the `paul.json` manifest. The next time you start a session in your BASE workspace, it picks it up automatically.
|
|
342
|
+
- Activity timestamps from each project flow into the workspace manifest so BASE always knows when each project was last touched
|
|
343
|
+
- During weekly groom, BASE checks each registered project's health:
|
|
344
|
+
- **Stuck?** — Planning done but implementation stalled for 7+ days
|
|
345
|
+
- **Abandoned?** — No activity for 14+ days with work still incomplete
|
|
346
|
+
- **Drifting?** — Milestone marked complete but no new work started
|
|
347
|
+
- You can configure health checks per project — enable or disable them in the manifest
|
|
348
|
+
|
|
349
|
+
BASE never modifies your projects. It only reads and reports. Each project manages itself through PAUL. BASE manages the workspace those projects live in.
|
|
350
|
+
|
|
351
|
+
```json
|
|
352
|
+
{
|
|
353
|
+
"satellites": {
|
|
354
|
+
"my-saas-app": {
|
|
355
|
+
"path": "apps/my-saas-app",
|
|
356
|
+
"engine": "paul",
|
|
357
|
+
"state": "apps/my-saas-app/.paul/STATE.md",
|
|
358
|
+
"registered": "2026-03-15",
|
|
359
|
+
"groom_check": true,
|
|
360
|
+
"last_activity": "2026-03-17T14:30:00-05:00"
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
109
364
|
```
|
|
110
|
-
workspace.json registers it → hook reads it → Claude knows it
|
|
111
|
-
```
|
|
112
365
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
366
|
+
### Without PAUL
|
|
367
|
+
|
|
368
|
+
Don't use PAUL? BASE still works as a standalone workspace framework. You still get:
|
|
369
|
+
|
|
370
|
+
- Data surfaces for tracking any structured information
|
|
371
|
+
- Drift detection and grooming for all workspace areas
|
|
372
|
+
- Audit strategies for directories, tools, and system files
|
|
373
|
+
- The full MCP server for surface CRUD
|
|
374
|
+
- Custom surface creation for anything you need
|
|
375
|
+
|
|
376
|
+
The project detection hook simply has nothing to find. Everything else operates independently.
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
## Creating Custom Surfaces
|
|
381
|
+
|
|
382
|
+
The built-in `active` and `backlog` surfaces are starting points. The real power is creating surfaces for your specific needs.
|
|
383
|
+
|
|
384
|
+
### `/base:surface create`
|
|
385
|
+
|
|
386
|
+
A guided workflow that generates everything:
|
|
116
387
|
|
|
117
|
-
**Create your own:**
|
|
118
388
|
```
|
|
119
|
-
/base:surface create
|
|
389
|
+
> /base:surface create
|
|
390
|
+
|
|
391
|
+
What does this surface track? → "Client projects and their current phase"
|
|
392
|
+
|
|
393
|
+
What fields does each item need?
|
|
394
|
+
- name (string, required)
|
|
395
|
+
- company (string, required)
|
|
396
|
+
- phase (enum: discovery, proposal, active, maintenance)
|
|
397
|
+
- monthly_value (number)
|
|
398
|
+
- next_action (string)
|
|
399
|
+
|
|
400
|
+
How should this appear in Claude's context?
|
|
401
|
+
- Group by: phase
|
|
402
|
+
- Summary format: "[ID] name — company (phase)"
|
|
403
|
+
- Behavior: passive (silent unless asked)
|
|
404
|
+
|
|
405
|
+
Generating...
|
|
406
|
+
+ .base/data/clients.json
|
|
407
|
+
+ .base/hooks/clients-hook.py
|
|
408
|
+
+ workspace.json updated
|
|
409
|
+
+ Hook registered in settings.json
|
|
120
410
|
```
|
|
121
|
-
|
|
411
|
+
|
|
412
|
+
Next session, Claude passively knows your client roster without you doing anything.
|
|
413
|
+
|
|
414
|
+
### `/base:surface convert`
|
|
415
|
+
|
|
416
|
+
Already have a markdown file with structured data? This command reads it, detects the structure, proposes a JSON schema, migrates the content, and generates everything. Your old `@CLIENTS.md` file becomes a proper data surface with full MCP support.
|
|
122
417
|
|
|
123
418
|
---
|
|
124
419
|
|
|
125
|
-
##
|
|
420
|
+
## The Ecosystem
|
|
421
|
+
|
|
422
|
+
BASE is one layer of a three-part system. Each tool is fully independent — use one, some, or all.
|
|
126
423
|
|
|
127
|
-
|
|
424
|
+
| Tool | What It Manages | Core Question It Answers |
|
|
425
|
+
|------|----------------|------------------------|
|
|
426
|
+
| **BASE** | Your workspace as a whole | "What am I working on? What's stale? What needs attention?" |
|
|
427
|
+
| **[CARL](https://github.com/ChristopherKahler/carl)** | Session-level behavioral rules | "What rules and context should Claude load for what I'm doing right now?" |
|
|
428
|
+
| **[PAUL](https://github.com/ChristopherKahler/paul)** | Individual project builds | "What's the plan? What phase am I in? What's left?" |
|
|
128
429
|
|
|
129
|
-
No
|
|
430
|
+
**All three are fully independent.** No dependencies between them. Use one, two, or all three.
|
|
431
|
+
|
|
432
|
+
**How they enhance each other when combined:**
|
|
433
|
+
- **BASE + PAUL** — PAUL projects auto-register with BASE on session start, giving you workspace-level visibility across all your builds. BASE groom checks project health. PAUL handles the project. BASE handles the portfolio.
|
|
434
|
+
- **BASE + CARL** — BASE bundles CARL's MCP server, upgrading CARL from config files to programmatic rule management, decision logging, and session memory. BASE groom can optionally check CARL rule health and surface staged proposals for review.
|
|
435
|
+
- **CARL + PAUL** — Independent. Each operates in its own scope (session rules vs project builds).
|
|
436
|
+
- **All three** — The full stack. BASE manages the workspace, CARL manages session behavior, PAUL manages project builds. Each layer does its job without stepping on the others.
|
|
437
|
+
|
|
438
|
+
Think of it as layers:
|
|
439
|
+
|
|
440
|
+
```
|
|
441
|
+
┌─────────────────────────────────┐
|
|
442
|
+
│ PAUL (per-project lifecycle) │ Plan → Apply → Unify
|
|
443
|
+
├─────────────────────────────────┤
|
|
444
|
+
│ CARL (per-session rules) │ Load rules based on intent
|
|
445
|
+
├─────────────────────────────────┤
|
|
446
|
+
│ BASE (workspace layer) │ Surfaces, health, grooming
|
|
447
|
+
└─────────────────────────────────┘
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
BASE works alone. CARL works alone. PAUL works alone. But together, they turn Claude Code from a per-session coding tool into a managed operating system for AI builders.
|
|
130
451
|
|
|
131
452
|
---
|
|
132
453
|
|
|
133
|
-
##
|
|
454
|
+
## Design Principles
|
|
455
|
+
|
|
456
|
+
1. **If it's not current, it's harmful.** Stale context feeds Claude bad information. Maintenance isn't optional — it's the whole point.
|
|
457
|
+
2. **Every file earns its place.** Can't explain why it's here in 5 seconds? It moves or dies.
|
|
458
|
+
3. **Archive over delete.** When in doubt, archive. You can always delete later. You can't un-delete.
|
|
459
|
+
4. **The workspace is the product.** Treat it like production code, not a scratch pad.
|
|
460
|
+
5. **One manifest drives everything.** `workspace.json` is the single source of truth. No manual bookkeeping.
|
|
461
|
+
6. **Tools register themselves.** Projects auto-register. Surfaces auto-discover. Zero human memory required.
|
|
462
|
+
7. **Passive by default.** Claude has awareness. Claude does not nag.
|
|
134
463
|
|
|
135
|
-
|
|
464
|
+
---
|
|
136
465
|
|
|
137
|
-
|
|
138
|
-
|--------|------|
|
|
139
|
-
| **BASE** | Workspace lifecycle — surfaces, grooming, drift detection |
|
|
140
|
-
| **CARL** | Dynamic rules engine — just-in-time rule injection |
|
|
141
|
-
| **PAUL** | Project orchestration — Plan → Apply → Unify loop |
|
|
466
|
+
## Quick Start
|
|
142
467
|
|
|
143
|
-
|
|
468
|
+
```bash
|
|
469
|
+
# 1. Install globally + wire current workspace
|
|
470
|
+
npx @chrisai/base --global --workspace
|
|
471
|
+
|
|
472
|
+
# 2. Open Claude Code
|
|
473
|
+
claude
|
|
474
|
+
|
|
475
|
+
# 3. Run guided workspace setup
|
|
476
|
+
/base:scaffold
|
|
477
|
+
|
|
478
|
+
# 4. Check workspace health anytime
|
|
479
|
+
/base:pulse
|
|
480
|
+
|
|
481
|
+
# 5. Weekly maintenance
|
|
482
|
+
/base:groom
|
|
483
|
+
|
|
484
|
+
# 6. Create a custom surface for anything you want Claude to know about
|
|
485
|
+
/base:surface create
|
|
486
|
+
```
|
|
144
487
|
|
|
145
488
|
---
|
|
146
489
|
|
|
147
490
|
## Requirements
|
|
148
491
|
|
|
149
|
-
- Node.js
|
|
150
|
-
-
|
|
151
|
-
-
|
|
492
|
+
- **Node.js** >= 16.7.0
|
|
493
|
+
- **Python 3** (for hooks)
|
|
494
|
+
- **[Claude Code](https://claude.ai/code)**
|
|
152
495
|
|
|
153
496
|
---
|
|
154
497
|
|
package/package.json
CHANGED
|
@@ -125,17 +125,24 @@ Symlinks are ONLY offered when scaffold detects existing files at workspace root
|
|
|
125
125
|
<step name="install_hooks">
|
|
126
126
|
Install and register BASE session hooks.
|
|
127
127
|
|
|
128
|
-
|
|
128
|
+
**UserPromptSubmit hooks** (fire every prompt):
|
|
129
|
+
- base-pulse-check.py — drift detection + groom reminders
|
|
130
|
+
- psmm-injector.py — per-session meta memory injection
|
|
129
131
|
|
|
130
|
-
|
|
132
|
+
**SessionStart hooks** (fire once when session begins):
|
|
133
|
+
- satellite-detection.py — PAUL project auto-registration
|
|
134
|
+
|
|
135
|
+
For each hook:
|
|
131
136
|
1. Check if `.claude/hooks/{hook}` exists in workspace
|
|
132
137
|
2. If not: copy from `~/.claude/base-framework/hooks/{hook}` (global install source)
|
|
133
138
|
- If `~/.claude/base-framework/hooks/{hook}` doesn't exist either, warn:
|
|
134
139
|
"BASE framework not globally installed. Run `npx base-framework --global` first, then re-run scaffold."
|
|
135
|
-
3. Check project `.claude/settings.json` for hook registration
|
|
136
|
-
|
|
140
|
+
3. Check project `.claude/settings.json` for hook registration:
|
|
141
|
+
- base-pulse-check.py and psmm-injector.py → register in `UserPromptSubmit` array
|
|
142
|
+
- satellite-detection.py → register in `SessionStart` array
|
|
143
|
+
4. If not registered: add the hook path to the correct event array in settings.json
|
|
137
144
|
|
|
138
|
-
Report: "
|
|
145
|
+
Report: "Hooks installed (pulse + PSMM on every prompt, satellite detection on session start)."
|
|
139
146
|
</step>
|
|
140
147
|
|
|
141
148
|
<step name="first_groom">
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""
|
|
3
3
|
Hook: satellite-detection.py
|
|
4
|
-
Purpose:
|
|
5
|
-
|
|
4
|
+
Purpose: Scans the workspace recursively for .paul/paul.json files,
|
|
5
|
+
cross-references registered satellites in workspace.json, and
|
|
6
6
|
auto-registers any unregistered projects it finds.
|
|
7
|
-
Triggers:
|
|
7
|
+
Triggers: SessionStart — runs once when Claude Code starts a session.
|
|
8
8
|
Output: <base-satellites> block if new satellites registered, silent otherwise.
|
|
9
9
|
"""
|
|
10
10
|
|