@chrisai/base 2.3.0

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.
Files changed (48) hide show
  1. package/README.md +157 -0
  2. package/bin/install.js +340 -0
  3. package/package.json +40 -0
  4. package/src/commands/audit-claude-md.md +31 -0
  5. package/src/commands/audit.md +33 -0
  6. package/src/commands/carl-hygiene.md +33 -0
  7. package/src/commands/groom.md +35 -0
  8. package/src/commands/history.md +27 -0
  9. package/src/commands/pulse.md +33 -0
  10. package/src/commands/scaffold.md +33 -0
  11. package/src/commands/status.md +28 -0
  12. package/src/commands/surface-convert.md +35 -0
  13. package/src/commands/surface-create.md +34 -0
  14. package/src/commands/surface-list.md +27 -0
  15. package/src/framework/context/base-principles.md +71 -0
  16. package/src/framework/frameworks/audit-strategies.md +53 -0
  17. package/src/framework/frameworks/satellite-registration.md +44 -0
  18. package/src/framework/tasks/audit-claude-md.md +68 -0
  19. package/src/framework/tasks/audit.md +64 -0
  20. package/src/framework/tasks/carl-hygiene.md +160 -0
  21. package/src/framework/tasks/groom.md +164 -0
  22. package/src/framework/tasks/history.md +34 -0
  23. package/src/framework/tasks/pulse.md +83 -0
  24. package/src/framework/tasks/scaffold.md +167 -0
  25. package/src/framework/tasks/status.md +35 -0
  26. package/src/framework/tasks/surface-convert.md +143 -0
  27. package/src/framework/tasks/surface-create.md +184 -0
  28. package/src/framework/tasks/surface-list.md +42 -0
  29. package/src/framework/templates/active-md.md +112 -0
  30. package/src/framework/templates/backlog-md.md +100 -0
  31. package/src/framework/templates/state-md.md +48 -0
  32. package/src/framework/templates/workspace-json.md +50 -0
  33. package/src/hooks/_template.py +129 -0
  34. package/src/hooks/active-hook.py +115 -0
  35. package/src/hooks/backlog-hook.py +107 -0
  36. package/src/hooks/base-pulse-check.py +206 -0
  37. package/src/hooks/psmm-injector.py +67 -0
  38. package/src/hooks/satellite-detection.py +131 -0
  39. package/src/packages/base-mcp/index.js +108 -0
  40. package/src/packages/base-mcp/package.json +10 -0
  41. package/src/packages/base-mcp/tools/surfaces.js +404 -0
  42. package/src/packages/carl-mcp/index.js +115 -0
  43. package/src/packages/carl-mcp/package.json +10 -0
  44. package/src/packages/carl-mcp/tools/decisions.js +269 -0
  45. package/src/packages/carl-mcp/tools/domains.js +361 -0
  46. package/src/packages/carl-mcp/tools/psmm.js +204 -0
  47. package/src/packages/carl-mcp/tools/staging.js +245 -0
  48. package/src/skill/base.md +111 -0
package/README.md ADDED
@@ -0,0 +1,157 @@
1
+ <div align="center">
2
+ <img src="terminal.svg" alt="BASE terminal" width="740"/>
3
+ </div>
4
+
5
+ <div align="center">
6
+
7
+ [![npm](https://img.shields.io/npm/v/@chrisai/base?color=00d8ff&label=npm&style=flat-square)](https://www.npmjs.com/package/@chrisai/base)
8
+ [![Node](https://img.shields.io/badge/node-%3E%3D16.7.0-brightgreen?style=flat-square)](https://nodejs.org)
9
+ [![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](LICENSE)
10
+ [![Claude Code](https://img.shields.io/badge/Claude%20Code-compatible-8b5cf6?style=flat-square)](https://claude.ai/code)
11
+
12
+ </div>
13
+
14
+ ---
15
+
16
+ ## What is BASE?
17
+
18
+ BASE keeps your Claude Code workspace from becoming a mess. It scaffolds structure, tracks workspace health, surfaces the right context automatically, and tells you when things go stale — so you spend time building, not maintaining.
19
+
20
+ **The core pattern:** structured JSON files (data surfaces) + lightweight Python hooks that inject them into Claude's context every session. Claude always knows what's active, what's queued, and where satellites stand — without you having to say it.
21
+
22
+ ---
23
+
24
+ ## Install
25
+
26
+ ```bash
27
+ npx @chrisai/base --global --workspace
28
+ ```
29
+
30
+ | Flag | What it does |
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 |
37
+
38
+ **Common flows:**
39
+
40
+ ```bash
41
+ # Full install — global commands + current workspace
42
+ npx @chrisai/base --global --workspace
43
+
44
+ # Already have global? Just wire a new workspace
45
+ npx @chrisai/base --workspace
46
+
47
+ # Global only — set up each workspace later with /base:scaffold
48
+ npx @chrisai/base --global
49
+ ```
50
+
51
+ ---
52
+
53
+ ## What Gets Installed
54
+
55
+ ```
56
+ ~/.claude/ ← --global
57
+ ├── commands/base/ 11 slash commands
58
+ ├── skills/base/ Entry point (base.md)
59
+ └── base-framework/
60
+ ├── tasks/ pulse, groom, audit, scaffold...
61
+ ├── templates/ workspace.json, STATE.md, surfaces
62
+ ├── context/ base-principles.md
63
+ ├── frameworks/ audit-strategies.md
64
+ └── hooks/ Session hooks (scaffold source)
65
+
66
+ ./.base/ ← --workspace
67
+ ├── workspace.json Manifest: surfaces, satellites, groom config
68
+ ├── data/
69
+ │ ├── active.json Active projects surface
70
+ │ └── backlog.json Backlog surface
71
+ ├── hooks/ Surface injection hooks
72
+ ├── base-mcp/ BASE MCP server
73
+ └── carl-mcp/ CARL MCP server
74
+
75
+ ./.claude/
76
+ ├── hooks/
77
+ │ ├── base-pulse-check.py Drift detection (every session)
78
+ │ ├── psmm-injector.py Per-session meta memory
79
+ │ └── satellite-detection.py PAUL project auto-registration
80
+ └── settings.json Hook registrations (merged)
81
+ ```
82
+
83
+ ---
84
+
85
+ ## Commands
86
+
87
+ After install, open Claude Code and run `/base:scaffold` to complete setup.
88
+
89
+ | Command | Description |
90
+ |---------|------------|
91
+ | `/base:scaffold` | Set up BASE in a new or existing workspace |
92
+ | `/base:pulse` | Daily workspace health briefing |
93
+ | `/base:groom` | Weekly maintenance cycle |
94
+ | `/base:audit` | Deep workspace optimization |
95
+ | `/base:status` | Quick health check |
96
+ | `/base:history` | Workspace evolution timeline |
97
+ | `/base:audit-claude-md` | Audit CLAUDE.md, generate recommended version |
98
+ | `/base:carl-hygiene` | CARL domain maintenance |
99
+ | `/base:surface create` | Create a new data surface (guided) |
100
+ | `/base:surface convert` | Convert a markdown file to a data surface |
101
+ | `/base:surface list` | Show all registered data surfaces |
102
+
103
+ ---
104
+
105
+ ## Data Surfaces
106
+
107
+ The core primitive. A data surface is a structured JSON file + a Python hook that injects it into Claude's context every session. Any persistent data you want Claude to passively know about becomes a surface.
108
+
109
+ ```
110
+ workspace.json registers it → hook reads it → Claude knows it
111
+ ```
112
+
113
+ **Built-in surfaces:**
114
+ - `active.json` — Current projects, status, blockers, deadlines
115
+ - `backlog.json` — Future work queue, ideas, deferred items
116
+
117
+ **Create your own:**
118
+ ```
119
+ /base:surface create
120
+ ```
121
+ Guided schema builder. Point it at any data you want surfaced — contacts, clients, API keys, anything. BASE generates the JSON schema, the hook, and wires it automatically.
122
+
123
+ ---
124
+
125
+ ## PAUL Satellite Integration
126
+
127
+ BASE auto-detects [PAUL](https://github.com/ChristopherKahler/paul) projects in your workspace. Every session, `satellite-detection.py` scans for `.paul/paul.json` files and registers any new projects in `workspace.json`. Weekly groom cycles check satellite health: stale loops, abandoned phases, overdue milestones.
128
+
129
+ No manual registration. It just works.
130
+
131
+ ---
132
+
133
+ ## Ecosystem
134
+
135
+ BASE is part of a three-layer workspace system:
136
+
137
+ | System | Role |
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 |
142
+
143
+ Each is independent. Use one, some, or all.
144
+
145
+ ---
146
+
147
+ ## Requirements
148
+
149
+ - Node.js ≥ 16.7.0
150
+ - [Claude Code](https://claude.ai/code)
151
+ - Python 3 (for hooks)
152
+
153
+ ---
154
+
155
+ ## License
156
+
157
+ MIT — [Chris Kahler](https://github.com/ChristopherKahler)
package/bin/install.js ADDED
@@ -0,0 +1,340 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const os = require('os');
6
+ const readline = require('readline');
7
+ const { execSync } = require('child_process');
8
+
9
+ // Colors
10
+ const cyan = '\x1b[36m';
11
+ const green = '\x1b[32m';
12
+ const yellow = '\x1b[33m';
13
+ const dim = '\x1b[2m';
14
+ const reset = '\x1b[0m';
15
+
16
+ // Get version from package.json
17
+ const pkg = require('../package.json');
18
+
19
+ const banner = `
20
+ ${cyan} ██████╗ █████╗ ███████╗███████╗
21
+ ██╔══██╗██╔══██╗██╔════╝██╔════╝
22
+ ██████╔╝███████║███████╗█████╗
23
+ ██╔══██╗██╔══██║╚════██║██╔══╝
24
+ ██████╔╝██║ ██║███████║███████╗
25
+ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝${reset}
26
+
27
+ BASE Framework ${dim}v${pkg.version}${reset}
28
+ Builder's Automated State Engine for Claude Code
29
+ `;
30
+
31
+ // Parse args
32
+ const args = process.argv.slice(2);
33
+ const hasGlobal = args.includes('--global') || args.includes('-g');
34
+ const hasLocal = args.includes('--local') || args.includes('-l');
35
+ const hasWorkspace = args.includes('--workspace') || args.includes('-w');
36
+
37
+ // Parse --config-dir argument
38
+ function parseConfigDirArg() {
39
+ const configDirIndex = args.findIndex(arg => arg === '--config-dir' || arg === '-c');
40
+ if (configDirIndex !== -1) {
41
+ const nextArg = args[configDirIndex + 1];
42
+ if (!nextArg || nextArg.startsWith('-')) {
43
+ console.error(` ${yellow}--config-dir requires a path argument${reset}`);
44
+ process.exit(1);
45
+ }
46
+ return nextArg;
47
+ }
48
+ const configDirArg = args.find(arg => arg.startsWith('--config-dir=') || arg.startsWith('-c='));
49
+ if (configDirArg) {
50
+ return configDirArg.split('=')[1];
51
+ }
52
+ return null;
53
+ }
54
+ const explicitConfigDir = parseConfigDirArg();
55
+
56
+ // Parse --workspace-dir argument
57
+ function parseWorkspaceDirArg() {
58
+ const idx = args.findIndex(arg => arg === '--workspace-dir');
59
+ if (idx !== -1) {
60
+ const nextArg = args[idx + 1];
61
+ if (!nextArg || nextArg.startsWith('-')) {
62
+ console.error(` ${yellow}--workspace-dir requires a path argument${reset}`);
63
+ process.exit(1);
64
+ }
65
+ return nextArg;
66
+ }
67
+ return null;
68
+ }
69
+ const explicitWorkspaceDir = parseWorkspaceDirArg();
70
+ const hasHelp = args.includes('--help') || args.includes('-h');
71
+
72
+ console.log(banner);
73
+
74
+ // Show help if requested
75
+ if (hasHelp) {
76
+ console.log(` ${yellow}Usage:${reset} npx base-framework [options]
77
+
78
+ ${yellow}Options:${reset}
79
+ ${cyan}-g, --global${reset} Install commands globally (to ~/.claude)
80
+ ${cyan}-l, --local${reset} Install commands locally (to ./.claude)
81
+ ${cyan}-w, --workspace${reset} Install workspace layer (.base/ in current directory)
82
+ ${cyan}-c, --config-dir <path>${reset} Specify custom Claude config directory
83
+ ${cyan}--workspace-dir <path>${reset} Specify workspace root (default: cwd)
84
+ ${cyan}-h, --help${reset} Show this help message
85
+
86
+ ${yellow}Examples:${reset}
87
+ ${dim}# Full install: global commands + workspace layer${reset}
88
+ npx base-framework --global --workspace
89
+
90
+ ${dim}# Global commands only (no workspace data)${reset}
91
+ npx base-framework --global
92
+
93
+ ${dim}# Workspace layer only (assumes commands already installed)${reset}
94
+ npx base-framework --workspace
95
+
96
+ ${dim}# Install to current project only${reset}
97
+ npx base-framework --local --workspace
98
+
99
+ ${yellow}What gets installed:${reset}
100
+ ${cyan}Commands (--global or --local):${reset}
101
+ commands/base/ - Slash commands (/base:surface-create, etc.)
102
+ skills/base/ - Skill framework (tasks, templates, context)
103
+
104
+ ${cyan}Workspace (--workspace):${reset}
105
+ .base/data/ - Data surface directory
106
+ .base/hooks/ - Surface injection hooks
107
+ .base/base-mcp/ - BASE MCP server (npm install auto-runs)
108
+ .base/carl-mcp/ - CARL MCP server (npm install auto-runs)
109
+ .mcp.json - MCP server registration (merged)
110
+ `);
111
+ process.exit(0);
112
+ }
113
+
114
+ /**
115
+ * Expand ~ to home directory
116
+ */
117
+ function expandTilde(filePath) {
118
+ if (filePath && filePath.startsWith('~/')) {
119
+ return path.join(os.homedir(), filePath.slice(2));
120
+ }
121
+ return filePath;
122
+ }
123
+
124
+ /**
125
+ * Recursively copy directory
126
+ */
127
+ function copyDir(srcDir, destDir) {
128
+ fs.mkdirSync(destDir, { recursive: true });
129
+ const entries = fs.readdirSync(srcDir, { withFileTypes: true });
130
+ for (const entry of entries) {
131
+ const srcPath = path.join(srcDir, entry.name);
132
+ const destPath = path.join(destDir, entry.name);
133
+ if (entry.isDirectory()) {
134
+ copyDir(srcPath, destPath);
135
+ } else {
136
+ fs.copyFileSync(srcPath, destPath);
137
+ }
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Install commands and skill framework
143
+ */
144
+ function installCommands(isGlobal) {
145
+ const src = path.join(__dirname, '..');
146
+ const configDir = expandTilde(explicitConfigDir) || expandTilde(process.env.CLAUDE_CONFIG_DIR);
147
+ const defaultGlobalDir = configDir || path.join(os.homedir(), '.claude');
148
+ const claudeDir = isGlobal ? defaultGlobalDir : path.join(process.cwd(), '.claude');
149
+
150
+ const locationLabel = isGlobal
151
+ ? claudeDir.replace(os.homedir(), '~')
152
+ : claudeDir.replace(process.cwd(), '.');
153
+
154
+ console.log(` Installing commands to ${cyan}${locationLabel}${reset}\n`);
155
+
156
+ // Copy commands
157
+ const commandsSrc = path.join(src, 'src', 'commands');
158
+ const commandsDest = path.join(claudeDir, 'commands', 'base');
159
+ copyDir(commandsSrc, commandsDest);
160
+ console.log(` ${green}+${reset} commands/base/ (3 slash commands)`);
161
+
162
+ // Copy skill entry point
163
+ const skillSrc = path.join(src, 'src', 'skill');
164
+ const skillDest = path.join(claudeDir, 'skills', 'base');
165
+ copyDir(skillSrc, skillDest);
166
+ console.log(` ${green}+${reset} skills/base/ (entry point + MCP package sources)`);
167
+
168
+ // Copy MCP package sources into skill (for scaffold reference)
169
+ const packagesSrc = path.join(src, 'src', 'packages');
170
+ const packagesDest = path.join(claudeDir, 'skills', 'base', 'packages');
171
+ copyDir(packagesSrc, packagesDest);
172
+
173
+ // Copy BASE framework (tasks, templates, context, frameworks)
174
+ const frameworkSrc = path.join(src, 'src', 'framework');
175
+ const frameworkDest = path.join(claudeDir, 'base-framework');
176
+ copyDir(frameworkSrc, frameworkDest);
177
+ console.log(` ${green}+${reset} base-framework/ (tasks, templates, context, frameworks)`);
178
+
179
+ // Copy session hooks to global base-framework/hooks/ (source for scaffold)
180
+ const sessionHookNames = ['base-pulse-check.py', 'psmm-injector.py', 'satellite-detection.py'];
181
+ const hooksFrameworkDest = path.join(claudeDir, 'base-framework', 'hooks');
182
+ fs.mkdirSync(hooksFrameworkDest, { recursive: true });
183
+ const hooksSrcDir = path.join(src, 'src', 'hooks');
184
+ for (const hookFile of sessionHookNames) {
185
+ const hookSrcPath = path.join(hooksSrcDir, hookFile);
186
+ if (fs.existsSync(hookSrcPath)) {
187
+ fs.copyFileSync(hookSrcPath, path.join(hooksFrameworkDest, hookFile));
188
+ }
189
+ }
190
+ console.log(` ${green}+${reset} base-framework/hooks/ (session hooks for scaffold)`);
191
+
192
+ console.log(`\n ${green}Commands installed.${reset}\n`);
193
+ }
194
+
195
+ /**
196
+ * Install workspace layer (.base/)
197
+ */
198
+ function installWorkspace() {
199
+ const src = path.join(__dirname, '..');
200
+ const workspaceDir = expandTilde(explicitWorkspaceDir) || process.cwd();
201
+ const baseDir = path.join(workspaceDir, '.base');
202
+
203
+ console.log(` Installing workspace layer to ${cyan}${baseDir.replace(os.homedir(), '~')}${reset}\n`);
204
+
205
+ // Create .base directories
206
+ fs.mkdirSync(path.join(baseDir, 'data'), { recursive: true });
207
+ fs.mkdirSync(path.join(baseDir, 'hooks'), { recursive: true });
208
+ console.log(` ${green}+${reset} .base/data/`);
209
+ console.log(` ${green}+${reset} .base/hooks/`);
210
+
211
+ // Copy MCP servers
212
+ const baseMcpSrc = path.join(src, 'src', 'packages', 'base-mcp');
213
+ const baseMcpDest = path.join(baseDir, 'base-mcp');
214
+ copyDir(baseMcpSrc, baseMcpDest);
215
+ console.log(` ${green}+${reset} .base/base-mcp/`);
216
+
217
+ const carlMcpSrc = path.join(src, 'src', 'packages', 'carl-mcp');
218
+ const carlMcpDest = path.join(baseDir, 'carl-mcp');
219
+ copyDir(carlMcpSrc, carlMcpDest);
220
+ console.log(` ${green}+${reset} .base/carl-mcp/`);
221
+
222
+ // Copy all hooks from single src/hooks/ directory
223
+ // Surface hooks (_template, active-hook, backlog-hook) → .base/hooks/
224
+ // Session hooks (base-pulse-check, psmm-injector) → .claude/hooks/
225
+ const allHooksSrc = path.join(src, 'src', 'hooks');
226
+ const surfaceHooks = ['_template.py', 'active-hook.py', 'backlog-hook.py'];
227
+ const sessionHooks = ['base-pulse-check.py', 'psmm-injector.py', 'satellite-detection.py'];
228
+
229
+ const entries = fs.readdirSync(allHooksSrc);
230
+ for (const file of entries) {
231
+ const srcPath = path.join(allHooksSrc, file);
232
+ if (surfaceHooks.includes(file)) {
233
+ fs.copyFileSync(srcPath, path.join(baseDir, 'hooks', file));
234
+ } else if (sessionHooks.includes(file)) {
235
+ const claudeHooksDir = path.join(workspaceDir, '.claude', 'hooks');
236
+ fs.mkdirSync(claudeHooksDir, { recursive: true });
237
+ fs.copyFileSync(srcPath, path.join(claudeHooksDir, file));
238
+ } else {
239
+ // Unknown hooks default to .base/hooks/
240
+ fs.copyFileSync(srcPath, path.join(baseDir, 'hooks', file));
241
+ }
242
+ }
243
+ console.log(` ${green}+${reset} .base/hooks/ (${surfaceHooks.length} surface hooks)`);
244
+ console.log(` ${green}+${reset} .claude/hooks/ (${sessionHooks.length} session hooks: pulse, PSMM, satellite)`);
245
+
246
+ // npm install for MCP servers
247
+ console.log(`\n Installing MCP dependencies...`);
248
+ try {
249
+ execSync('npm install', { cwd: baseMcpDest, stdio: 'pipe' });
250
+ console.log(` ${green}+${reset} base-mcp dependencies installed`);
251
+ } catch (e) {
252
+ console.log(` ${yellow}!${reset} base-mcp npm install failed — run manually in .base/base-mcp/`);
253
+ }
254
+ try {
255
+ execSync('npm install', { cwd: carlMcpDest, stdio: 'pipe' });
256
+ console.log(` ${green}+${reset} carl-mcp dependencies installed`);
257
+ } catch (e) {
258
+ console.log(` ${yellow}!${reset} carl-mcp npm install failed — run manually in .base/carl-mcp/`);
259
+ }
260
+
261
+ // Merge MCP registrations into .mcp.json
262
+ const mcpJsonPath = path.join(workspaceDir, '.mcp.json');
263
+ let mcpConfig = { mcpServers: {} };
264
+ if (fs.existsSync(mcpJsonPath)) {
265
+ try {
266
+ mcpConfig = JSON.parse(fs.readFileSync(mcpJsonPath, 'utf-8'));
267
+ } catch (e) { /* start fresh */ }
268
+ }
269
+ mcpConfig.mcpServers['carl-mcp'] = {
270
+ type: 'stdio',
271
+ command: 'node',
272
+ args: ['./.base/carl-mcp/index.js']
273
+ };
274
+ mcpConfig.mcpServers['base-mcp'] = {
275
+ type: 'stdio',
276
+ command: 'node',
277
+ args: ['./.base/base-mcp/index.js']
278
+ };
279
+ fs.writeFileSync(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
280
+ console.log(` ${green}+${reset} .mcp.json (carl-mcp + base-mcp registered)`);
281
+
282
+ console.log(`\n ${green}Workspace layer installed.${reset}`);
283
+ console.log(` Run ${cyan}/base:scaffold${reset} to complete workspace setup.\n`);
284
+ }
285
+
286
+ /**
287
+ * Prompt for install location
288
+ */
289
+ function promptLocation() {
290
+ const rl = readline.createInterface({
291
+ input: process.stdin,
292
+ output: process.stdout
293
+ });
294
+
295
+ const configDir = expandTilde(explicitConfigDir) || expandTilde(process.env.CLAUDE_CONFIG_DIR);
296
+ const globalPath = configDir || path.join(os.homedir(), '.claude');
297
+ const globalLabel = globalPath.replace(os.homedir(), '~');
298
+
299
+ console.log(` ${yellow}What would you like to install?${reset}
300
+
301
+ ${cyan}1${reset}) Full install ${dim}(commands to ${globalLabel} + workspace layer to .base/)${reset}
302
+ ${cyan}2${reset}) Commands only ${dim}(${globalLabel})${reset}
303
+ ${cyan}3${reset}) Workspace only ${dim}(.base/ in current directory)${reset}
304
+ `);
305
+
306
+ rl.question(` Choice ${dim}[1]${reset}: `, (answer) => {
307
+ rl.close();
308
+ const choice = answer.trim() || '1';
309
+ if (choice === '1' || choice === '2') {
310
+ installCommands(true);
311
+ }
312
+ if (choice === '1' || choice === '3') {
313
+ installWorkspace();
314
+ }
315
+ if (choice !== '1' && choice !== '2' && choice !== '3') {
316
+ installCommands(true);
317
+ installWorkspace();
318
+ }
319
+ console.log(` ${green}Done!${reset} Launch Claude Code and run ${cyan}/base:surface-list${reset}.\n`);
320
+ });
321
+ }
322
+
323
+ // Main
324
+ if (hasHelp) {
325
+ // Already handled above
326
+ } else if (hasGlobal || hasLocal || hasWorkspace) {
327
+ if (hasGlobal && hasLocal) {
328
+ console.error(` ${yellow}Cannot specify both --global and --local${reset}`);
329
+ process.exit(1);
330
+ }
331
+ if (hasGlobal || hasLocal) {
332
+ installCommands(hasGlobal);
333
+ }
334
+ if (hasWorkspace) {
335
+ installWorkspace();
336
+ }
337
+ console.log(` ${green}Done!${reset} Launch Claude Code and run ${cyan}/base:surface-list${reset}.\n`);
338
+ } else {
339
+ promptLocation();
340
+ }
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@chrisai/base",
3
+ "version": "2.3.0",
4
+ "description": "Builder's Automated State Engine — workspace orchestration framework for Claude Code",
5
+ "bin": {
6
+ "base-framework": "bin/install.js"
7
+ },
8
+ "files": [
9
+ "bin",
10
+ "src/commands",
11
+ "src/skill",
12
+ "src/framework",
13
+ "src/packages",
14
+ "src/hooks",
15
+ "README.md"
16
+ ],
17
+ "keywords": [
18
+ "claude",
19
+ "claude-code",
20
+ "ai",
21
+ "workspace",
22
+ "orchestration",
23
+ "base",
24
+ "data-surfaces",
25
+ "mcp"
26
+ ],
27
+ "author": "Chris Kahler",
28
+ "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/ChristopherKahler/base.git"
32
+ },
33
+ "bugs": {
34
+ "url": "https://github.com/ChristopherKahler/base/issues"
35
+ },
36
+ "homepage": "https://github.com/ChristopherKahler/base#readme",
37
+ "engines": {
38
+ "node": ">=16.7.0"
39
+ }
40
+ }
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: base:audit-claude-md
3
+ description: Audit CLAUDE.md and generate recommended version
4
+ allowed-tools: [Read, Write, Edit, Glob, Grep, Bash]
5
+ ---
6
+
7
+ <objective>
8
+ Audit the project's CLAUDE.md for completeness, accuracy, and alignment with workspace state. Generate a recommended version.
9
+
10
+ **When to use:** "audit claude md", "check my claude.md", after major workspace changes.
11
+ </objective>
12
+
13
+ <execution_context>
14
+ @.claude/skills/base/tasks/audit-claude-md.md
15
+ </execution_context>
16
+
17
+ <context>
18
+ $ARGUMENTS
19
+
20
+ @CLAUDE.md
21
+ </context>
22
+
23
+ <process>
24
+ Follow task: @.claude/skills/base/tasks/audit-claude-md.md
25
+ </process>
26
+
27
+ <success_criteria>
28
+ - [ ] Current CLAUDE.md analyzed
29
+ - [ ] Gaps and outdated sections identified
30
+ - [ ] Recommended version generated or changes suggested
31
+ </success_criteria>
@@ -0,0 +1,33 @@
1
+ ---
2
+ name: base:audit
3
+ description: Deep workspace optimization
4
+ allowed-tools: [Read, Write, Edit, Glob, Grep, Bash, Agent, AskUserQuestion]
5
+ ---
6
+
7
+ <objective>
8
+ Deep workspace audit — comprehensive optimization across all areas with actionable recommendations.
9
+
10
+ **When to use:** "audit my workspace", "deep clean", monthly optimization.
11
+ </objective>
12
+
13
+ <execution_context>
14
+ @.claude/skills/base/tasks/audit.md
15
+ @.claude/skills/base/context/base-principles.md
16
+ @.claude/skills/base/frameworks/audit-strategies.md
17
+ </execution_context>
18
+
19
+ <context>
20
+ $ARGUMENTS
21
+
22
+ @.base/workspace.json
23
+ </context>
24
+
25
+ <process>
26
+ Follow task: @.claude/skills/base/tasks/audit.md
27
+ </process>
28
+
29
+ <success_criteria>
30
+ - [ ] All areas audited with strategy-specific checks
31
+ - [ ] Findings categorized and prioritized
32
+ - [ ] Actionable recommendations presented
33
+ </success_criteria>
@@ -0,0 +1,33 @@
1
+ ---
2
+ name: base:carl-hygiene
3
+ description: CARL domain maintenance and rule review
4
+ allowed-tools: [Read, Write, Edit, Glob, Grep, Bash, AskUserQuestion]
5
+ ---
6
+
7
+ <objective>
8
+ CARL rule lifecycle management — review staleness, dedup, staging pipeline, domain health.
9
+
10
+ **When to use:** "carl hygiene", "review carl rules", "clean up carl".
11
+ </objective>
12
+
13
+ <execution_context>
14
+ @.claude/skills/base/tasks/carl-hygiene.md
15
+ </execution_context>
16
+
17
+ <context>
18
+ $ARGUMENTS
19
+
20
+ @.carl/manifest
21
+ @.base/workspace.json
22
+ </context>
23
+
24
+ <process>
25
+ Follow task: @.claude/skills/base/tasks/carl-hygiene.md
26
+ </process>
27
+
28
+ <success_criteria>
29
+ - [ ] All domains reviewed for staleness
30
+ - [ ] Duplicate/conflicting rules identified
31
+ - [ ] Staging pipeline processed
32
+ - [ ] carl_hygiene.last_run updated in workspace.json
33
+ </success_criteria>
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: base:groom
3
+ description: Weekly workspace maintenance cycle
4
+ allowed-tools: [Read, Write, Edit, Glob, Grep, Bash, AskUserQuestion]
5
+ ---
6
+
7
+ <objective>
8
+ Structured weekly maintenance — review each workspace area, update statuses, archive stale items, reduce drift.
9
+
10
+ **When to use:** Weekly maintenance, "groom my workspace", "run grooming".
11
+ </objective>
12
+
13
+ <execution_context>
14
+ @.claude/skills/base/tasks/groom.md
15
+ @.claude/skills/base/context/base-principles.md
16
+ @.claude/skills/base/frameworks/audit-strategies.md
17
+ </execution_context>
18
+
19
+ <context>
20
+ $ARGUMENTS
21
+
22
+ @.base/workspace.json
23
+ @.base/STATE.md
24
+ </context>
25
+
26
+ <process>
27
+ Follow task: @.claude/skills/base/tasks/groom.md
28
+ </process>
29
+
30
+ <success_criteria>
31
+ - [ ] All workspace areas reviewed
32
+ - [ ] Stale items addressed
33
+ - [ ] STATE.md updated with groom results
34
+ - [ ] Drift score recalculated
35
+ </success_criteria>