@tonycasey/lisa 0.5.13

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 +42 -0
  2. package/dist/cli.js +390 -0
  3. package/dist/lib/interfaces/IDockerClient.js +2 -0
  4. package/dist/lib/interfaces/IMcpClient.js +2 -0
  5. package/dist/lib/interfaces/IServices.js +2 -0
  6. package/dist/lib/interfaces/ITemplateCopier.js +2 -0
  7. package/dist/lib/mcp.js +35 -0
  8. package/dist/lib/services.js +57 -0
  9. package/dist/package.json +36 -0
  10. package/dist/templates/agents/.sample.env +12 -0
  11. package/dist/templates/agents/docs/STORAGE_SETUP.md +161 -0
  12. package/dist/templates/agents/skills/common/group-id.js +193 -0
  13. package/dist/templates/agents/skills/init-review/SKILL.md +119 -0
  14. package/dist/templates/agents/skills/init-review/scripts/ai-enrich.js +258 -0
  15. package/dist/templates/agents/skills/init-review/scripts/init-review.js +769 -0
  16. package/dist/templates/agents/skills/lisa/SKILL.md +92 -0
  17. package/dist/templates/agents/skills/lisa/cache/.gitkeep +0 -0
  18. package/dist/templates/agents/skills/lisa/scripts/storage.js +374 -0
  19. package/dist/templates/agents/skills/memory/SKILL.md +31 -0
  20. package/dist/templates/agents/skills/memory/scripts/memory.js +533 -0
  21. package/dist/templates/agents/skills/prompt/SKILL.md +19 -0
  22. package/dist/templates/agents/skills/prompt/scripts/prompt.js +184 -0
  23. package/dist/templates/agents/skills/tasks/SKILL.md +31 -0
  24. package/dist/templates/agents/skills/tasks/scripts/tasks.js +489 -0
  25. package/dist/templates/claude/config.js +40 -0
  26. package/dist/templates/claude/hooks/README.md +158 -0
  27. package/dist/templates/claude/hooks/common/complexity-rater.js +290 -0
  28. package/dist/templates/claude/hooks/common/context.js +263 -0
  29. package/dist/templates/claude/hooks/common/group-id.js +188 -0
  30. package/dist/templates/claude/hooks/common/mcp-client.js +131 -0
  31. package/dist/templates/claude/hooks/common/transcript-parser.js +256 -0
  32. package/dist/templates/claude/hooks/common/zep-client.js +175 -0
  33. package/dist/templates/claude/hooks/session-start.js +401 -0
  34. package/dist/templates/claude/hooks/session-stop-worker.js +341 -0
  35. package/dist/templates/claude/hooks/session-stop.js +122 -0
  36. package/dist/templates/claude/hooks/user-prompt-submit.js +256 -0
  37. package/dist/templates/claude/settings.json +46 -0
  38. package/dist/templates/docker/.env.lisa.example +17 -0
  39. package/dist/templates/docker/docker-compose.graphiti.yml +45 -0
  40. package/dist/templates/rules/shared/clean-architecture.md +333 -0
  41. package/dist/templates/rules/shared/code-quality-rules.md +469 -0
  42. package/dist/templates/rules/shared/git-rules.md +64 -0
  43. package/dist/templates/rules/shared/testing-principles.md +469 -0
  44. package/dist/templates/rules/typescript/coding-standards.md +751 -0
  45. package/dist/templates/rules/typescript/testing.md +629 -0
  46. package/dist/templates/rules/typescript/typescript-config-guide.md +465 -0
  47. package/package.json +64 -0
  48. package/scripts/postinstall.js +710 -0
@@ -0,0 +1,161 @@
1
+ # Storage Setup Guide
2
+
3
+ ## Overview
4
+
5
+ Lisa uses a graph database (Neo4j) to store persistent memory. This enables Lisa to remember context across sessions, track project history, and provide intelligent assistance based on past interactions.
6
+
7
+ There are three storage options available:
8
+
9
+ | Option | Best For | Requirements |
10
+ |--------|----------|--------------|
11
+ | **Local Docker** | Development, testing | Docker Desktop |
12
+ | **Zep Cloud** | Managed service, easiest setup | Zep Cloud account |
13
+
14
+ ---
15
+
16
+ ## Option 1: Local Docker (Recommended for Development)
17
+
18
+ Run Neo4j and the Zep (Graphiti) MCP server locally using Docker.
19
+
20
+ ### Prerequisites
21
+ - Docker Desktop installed and running
22
+ - At least 4GB RAM available for containers
23
+
24
+ ### Setup Steps
25
+
26
+ 1. **Initialize with local mode:**
27
+ ```bash
28
+ lisa init --mode local
29
+ ```
30
+
31
+ 2. **Start the services:**
32
+ ```bash
33
+ lisa up
34
+ ```
35
+
36
+ 3. **Verify the connection:**
37
+ ```bash
38
+ lisa doctor
39
+ ```
40
+
41
+ ### What Gets Started
42
+ - **Neo4j** - Graph database on port 7474 (browser) and 7687 (bolt)
43
+ - **MCP Server** - Memory API on port 8010
44
+
45
+ ### Stopping Services
46
+ ```bash
47
+ lisa down
48
+ ```
49
+ ---
50
+
51
+ ## Option 2: Zep Cloud (Fully Managed)
52
+
53
+ Use Zep's managed service for production.
54
+
55
+ ### Prerequisites
56
+ - Zep Cloud account (sign up at [getzep.com](https://getzep.com))
57
+
58
+ ### Setup Steps
59
+
60
+ 1. **Create a Zep project:**
61
+ - Go to [cloud.getzep.com](https://cloud.getzep.com)
62
+ - Create a new project
63
+ - Copy your API key (starts with `z_`)
64
+
65
+ 2. **Initialize with zep-cloud mode:**
66
+ ```bash
67
+ lisa init --mode zep-cloud
68
+ ```
69
+
70
+ 3. **Enter Zep API key when prompted**
71
+
72
+ 4. **Verify the connection:**
73
+ ```bash
74
+ lisa doctor
75
+ ```
76
+
77
+ ### How It Works
78
+ - **No Docker required** - Lisa connects directly to Zep's REST API
79
+ - **No MCP server** - Uses Zep's native `/api/v2` endpoints
80
+ - **Free tier** - 1,000 episodes/month, unlimited storage
81
+
82
+ ---
83
+
84
+ ## Manual Configuration
85
+
86
+ If you chose "Set up later" during initialization, follow these steps:
87
+
88
+ 1. **Edit the environment file:**
89
+ ```bash
90
+ nano .agents/.env
91
+ ```
92
+
93
+ 2. **Uncomment and configure your chosen option:**
94
+
95
+ **For Local Docker:**
96
+ ```env
97
+ STORAGE_MODE=local
98
+ GRAPHITI_ENDPOINT=http://localhost:8010/mcp/
99
+ GRAPHITI_GROUP_ID=your-project-name
100
+ ```
101
+
102
+ **For Zep Cloud:**
103
+ ```env
104
+ STORAGE_MODE=zep-cloud
105
+ GRAPHITI_GROUP_ID=your-project-name
106
+ ZEP_API_KEY=z_xxxxx
107
+ ```
108
+ Note: No endpoint needed - Lisa uses Zep's native REST API directly.
109
+
110
+ 3. **Start a new terminal session** (to load new environment variables)
111
+
112
+ 4. **Run `lisa doctor`** to verify the connection
113
+
114
+ ---
115
+
116
+ ## Environment Variables Reference
117
+
118
+ | Variable | Mode | Description |
119
+ |----------|------|-------------|
120
+ | `STORAGE_MODE` | all | Storage mode: `local`, `zep-cloud`, or `skip` |
121
+ | `GRAPHITI_ENDPOINT` | local | MCP server endpoint URL (not needed for zep-cloud) |
122
+ | `GRAPHITI_GROUP_ID` | all | Memory group identifier (usually project name) |
123
+ | `ZEP_API_KEY` | zep-cloud | Zep Cloud API key (starts with `z_`) |
124
+
125
+ ---
126
+
127
+ ## Commands Reference
128
+
129
+ | Command | Description |
130
+ |---------|-------------|
131
+ | `lisa init` | Initialize Lisa in a project |
132
+ | `lisa up` | Start local Docker services |
133
+ | `lisa down` | Stop local Docker services |
134
+ | `lisa doctor` | Check storage connection status |
135
+
136
+ ---
137
+
138
+ ## Troubleshooting
139
+
140
+ ### `lisa doctor` shows "Docker missing or not running"
141
+ - Ensure Docker Desktop is installed and running
142
+ - On macOS: Check the Docker icon in the menu bar
143
+ - On Linux: Run `sudo systemctl start docker`
144
+
145
+ ### "MCP check failed" error
146
+ - Verify the endpoint URL is correct
147
+ - For local mode: Ensure `lisa up` has been run
148
+ - Check that port 8010 is not blocked by firewall
149
+
150
+ ### "Invalid API key" (Zep Cloud)
151
+ - Verify the API key is correct
152
+ - Check the project ID matches your Zep project
153
+ - Ensure your Zep account is active
154
+
155
+ ---
156
+
157
+ ## Getting Help
158
+
159
+ - Run `lisa --help` for command options
160
+ - Check [github.com/TonyCasey/lisa](https://github.com/TonyCasey/lisa) for updates
161
+ - Report issues at the GitHub repository
@@ -0,0 +1,193 @@
1
+ "use strict";
2
+ /**
3
+ * Group ID Utilities
4
+ *
5
+ * Shared functions for normalizing paths to Graphiti group IDs.
6
+ * Used by memory, tasks, prompt, and other skills.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.PREFIX_MAP = exports.TYPE_MAP = exports.MAX_GROUP_ID_LENGTH = void 0;
43
+ exports.normalizePathToGroupId = normalizePathToGroupId;
44
+ exports.getCurrentGroupId = getCurrentGroupId;
45
+ exports.isWindows = isWindows;
46
+ exports.getRootBoundary = getRootBoundary;
47
+ exports.getHierarchicalGroupIds = getHierarchicalGroupIds;
48
+ exports.detectPrefixTag = detectPrefixTag;
49
+ const path = __importStar(require("path"));
50
+ const os = __importStar(require("os"));
51
+ exports.MAX_GROUP_ID_LENGTH = 128;
52
+ /**
53
+ * Normalize a path to a valid group ID string.
54
+ * Works cross-platform (Windows and Unix).
55
+ *
56
+ * @example
57
+ * normalizePathToGroupId('/Users/tony.casey/Repos/api') // 'users-tony_casey-repos-api'
58
+ * normalizePathToGroupId('C:\\dev\\lisa') // 'c-dev-lisa'
59
+ */
60
+ function normalizePathToGroupId(absolutePath) {
61
+ let normalized = absolutePath
62
+ .toLowerCase()
63
+ .replace(/^[a-z]:/i, (match) => match.charAt(0)) // C: -> c
64
+ .replace(/^\//, '') // Remove leading slash (Unix)
65
+ .replace(/\\/g, '-') // Backslash to dash (Windows)
66
+ .replace(/\//g, '-') // Forward slash to dash (Unix)
67
+ .replace(/\./g, '_') // Dots to underscores
68
+ .replace(/^-+/, '') // Remove leading dashes
69
+ .replace(/-+/g, '-'); // Collapse multiple dashes
70
+ if (normalized.length > exports.MAX_GROUP_ID_LENGTH) {
71
+ normalized = normalized.slice(-exports.MAX_GROUP_ID_LENGTH);
72
+ }
73
+ return normalized;
74
+ }
75
+ /**
76
+ * Get the current folder's group ID.
77
+ */
78
+ function getCurrentGroupId(cwd = process.cwd()) {
79
+ return normalizePathToGroupId(cwd);
80
+ }
81
+ /**
82
+ * Check if we're on Windows
83
+ */
84
+ function isWindows() {
85
+ return os.platform() === 'win32';
86
+ }
87
+ /**
88
+ * Get the root boundary for hierarchical traversal.
89
+ * - Windows: drive root (e.g., C:\) or home directory, whichever is deeper
90
+ * - Unix: home directory or /
91
+ */
92
+ function getRootBoundary(cwd = process.cwd()) {
93
+ const homeDir = os.homedir();
94
+ if (isWindows()) {
95
+ // On Windows, check if cwd is under home directory
96
+ const cwdLower = cwd.toLowerCase();
97
+ const homeLower = homeDir.toLowerCase();
98
+ if (cwdLower.startsWith(homeLower)) {
99
+ return homeDir; // Under home, use home as boundary
100
+ }
101
+ // Not under home (e.g., C:\dev\), use drive root as boundary
102
+ const driveRoot = path.parse(cwd).root; // e.g., "C:\"
103
+ return driveRoot;
104
+ }
105
+ // Unix: use home directory if under it, otherwise use /
106
+ if (cwd.startsWith(homeDir)) {
107
+ return homeDir;
108
+ }
109
+ return '/';
110
+ }
111
+ /**
112
+ * Get hierarchical group IDs from current folder up to root boundary.
113
+ * Returns array ordered from most specific (current) to least specific (root).
114
+ * Works cross-platform (Windows and Unix).
115
+ */
116
+ function getHierarchicalGroupIds(cwd = process.cwd()) {
117
+ const rootBoundary = getRootBoundary(cwd);
118
+ const groups = [];
119
+ let currentPath = path.resolve(cwd);
120
+ const maxDepth = 10; // Safety limit
121
+ let depth = 0;
122
+ while (depth < maxDepth) {
123
+ groups.push(normalizePathToGroupId(currentPath));
124
+ // Stop if we've reached the root boundary
125
+ if (currentPath.toLowerCase() === rootBoundary.toLowerCase()) {
126
+ break;
127
+ }
128
+ const parentPath = path.dirname(currentPath);
129
+ // Stop if we can't go up anymore (reached filesystem root)
130
+ if (parentPath === currentPath) {
131
+ break;
132
+ }
133
+ currentPath = parentPath;
134
+ depth++;
135
+ }
136
+ return groups;
137
+ }
138
+ /**
139
+ * Entity type to tag mapping for memory classification.
140
+ */
141
+ exports.TYPE_MAP = {
142
+ // Code & Architecture
143
+ 'decision': 'code:decision',
144
+ 'pattern': 'code:pattern',
145
+ 'dependency': 'code:dependency',
146
+ 'tech-debt': 'code:tech-debt',
147
+ // Context & History
148
+ 'bug': 'context:bug',
149
+ 'rationale': 'context:rationale',
150
+ 'failed': 'context:failed',
151
+ 'quirk': 'context:quirk',
152
+ // External
153
+ 'feedback': 'external:feedback',
154
+ 'incident': 'external:incident',
155
+ 'contract': 'external:contract',
156
+ // People & Process
157
+ 'contributor': 'people:contributor',
158
+ 'review': 'people:review',
159
+ 'blocker': 'people:blocker',
160
+ 'estimate': 'people:estimate',
161
+ // Project
162
+ 'scope-in': 'project:scope-in',
163
+ 'scope-out': 'project:scope-out',
164
+ 'milestone': 'project:milestone',
165
+ 'init-review': 'type:init-review',
166
+ };
167
+ /**
168
+ * Auto-detect prefixes in text for automatic tagging.
169
+ */
170
+ exports.PREFIX_MAP = {
171
+ 'DECISION:': 'code:decision',
172
+ 'PATTERN:': 'code:pattern',
173
+ 'TECH-DEBT:': 'code:tech-debt',
174
+ 'BUG:': 'context:bug',
175
+ 'RATIONALE:': 'context:rationale',
176
+ 'FAILED:': 'context:failed',
177
+ 'INCIDENT:': 'external:incident',
178
+ 'BLOCKER:': 'people:blocker',
179
+ 'SCOPE-IN:': 'project:scope-in',
180
+ 'SCOPE-OUT:': 'project:scope-out',
181
+ 'INIT-REVIEW:': 'type:init-review',
182
+ };
183
+ /**
184
+ * Detect tag from text prefix.
185
+ */
186
+ function detectPrefixTag(text) {
187
+ for (const [prefix, tag] of Object.entries(exports.PREFIX_MAP)) {
188
+ if (text.toUpperCase().startsWith(prefix)) {
189
+ return tag;
190
+ }
191
+ }
192
+ return null;
193
+ }
@@ -0,0 +1,119 @@
1
+ # Init Review Skill
2
+
3
+ ## Purpose
4
+ Automatically analyzes a codebase when Lisa is installed, creating a foundational memory of the project structure, technologies, and patterns. This init review serves as context for all future Claude sessions.
5
+
6
+ ## Triggers
7
+ Use when the user says things like:
8
+ - "run init review"
9
+ - "analyze this codebase"
10
+ - "scan the project"
11
+ - "what is this project about"
12
+ - "refresh codebase summary"
13
+
14
+ ## How to use
15
+
16
+ ### Automatic (during npm install)
17
+ The init review runs automatically when Lisa is installed via `npm install @tonycasey/lisa`. It:
18
+ 1. Detects if the folder is a codebase
19
+ 2. Runs static analysis (language, framework, structure)
20
+ 3. Stores result as first memory
21
+ 4. Queues background AI enrichment
22
+
23
+ ### Manual commands
24
+ ```bash
25
+ # Run init review (or re-run with --force)
26
+ node scripts/init-review.js run [--force]
27
+
28
+ # Show current init review
29
+ node scripts/init-review.js show
30
+
31
+ # Check status (done, enriched, etc.)
32
+ node scripts/init-review.js status
33
+ ```
34
+
35
+ ## I/O contract
36
+
37
+ ### Static analysis output
38
+ ```json
39
+ {
40
+ "status": "ok",
41
+ "action": "run",
42
+ "result": {
43
+ "version": "1.0",
44
+ "project": { "name": "lisa", "path": "/dev/lisa", "groupId": "dev-lisa" },
45
+ "codebase": {
46
+ "language": "TypeScript",
47
+ "languages": ["TypeScript", "JavaScript"],
48
+ "framework": null,
49
+ "buildTools": ["npm", "tsc"]
50
+ },
51
+ "structure": {
52
+ "entryPoints": ["src/cli.ts", "src/index.ts"],
53
+ "mainModules": ["src/domain/", "src/infrastructure/"],
54
+ "testDirs": ["tests/"]
55
+ },
56
+ "dependencies": {
57
+ "count": 12,
58
+ "noteworthy": ["commander", "fs-extra", "@anthropic-ai/claude-code"]
59
+ },
60
+ "patterns": {
61
+ "architecture": "clean-architecture",
62
+ "testing": "node-test"
63
+ },
64
+ "metrics": {
65
+ "fileCount": 45,
66
+ "hasTests": true,
67
+ "hasDocumentation": true
68
+ }
69
+ },
70
+ "summary": "TypeScript CLI project with clean-architecture pattern..."
71
+ }
72
+ ```
73
+
74
+ ### Show output
75
+ ```json
76
+ {
77
+ "status": "ok",
78
+ "action": "show",
79
+ "review": "TypeScript CLI project with clean-architecture pattern...",
80
+ "enriched": true,
81
+ "timestamp": "2026-01-11T15:30:00Z"
82
+ }
83
+ ```
84
+
85
+ ### Status output
86
+ ```json
87
+ {
88
+ "status": "ok",
89
+ "action": "status",
90
+ "done": true,
91
+ "enriched": true,
92
+ "timestamp": "2026-01-11T15:30:00Z",
93
+ "groupId": "dev-lisa"
94
+ }
95
+ ```
96
+
97
+ ## Memory storage
98
+
99
+ Init reviews are stored with these tags:
100
+ - `type:init-review` - Identifies as init review memory
101
+ - `scope:codebase` - Full codebase analysis
102
+ - `ai:enriched` - Present if AI enrichment completed
103
+
104
+ ## Marker file
105
+
106
+ Location: `.agents/.init-review-done`
107
+
108
+ Prevents re-running on subsequent installs. Delete to force re-run, or use `--force` flag.
109
+
110
+ ## Cross-model checklist
111
+ - Codex: Use explicit script paths; verify triggers match
112
+ - Claude: Keep output concise; shown in session-start context
113
+ - Gemini: Explicit commands; avoid model-specific tokens
114
+
115
+ ## Notes
116
+ - Static analysis targets <2 seconds execution
117
+ - AI enrichment runs in background (30-60 seconds)
118
+ - Logs written to `.agents/.init-review.log`
119
+ - Never blocks npm install - errors are caught and logged