@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.
- package/README.md +42 -0
- package/dist/cli.js +390 -0
- package/dist/lib/interfaces/IDockerClient.js +2 -0
- package/dist/lib/interfaces/IMcpClient.js +2 -0
- package/dist/lib/interfaces/IServices.js +2 -0
- package/dist/lib/interfaces/ITemplateCopier.js +2 -0
- package/dist/lib/mcp.js +35 -0
- package/dist/lib/services.js +57 -0
- package/dist/package.json +36 -0
- package/dist/templates/agents/.sample.env +12 -0
- package/dist/templates/agents/docs/STORAGE_SETUP.md +161 -0
- package/dist/templates/agents/skills/common/group-id.js +193 -0
- package/dist/templates/agents/skills/init-review/SKILL.md +119 -0
- package/dist/templates/agents/skills/init-review/scripts/ai-enrich.js +258 -0
- package/dist/templates/agents/skills/init-review/scripts/init-review.js +769 -0
- package/dist/templates/agents/skills/lisa/SKILL.md +92 -0
- package/dist/templates/agents/skills/lisa/cache/.gitkeep +0 -0
- package/dist/templates/agents/skills/lisa/scripts/storage.js +374 -0
- package/dist/templates/agents/skills/memory/SKILL.md +31 -0
- package/dist/templates/agents/skills/memory/scripts/memory.js +533 -0
- package/dist/templates/agents/skills/prompt/SKILL.md +19 -0
- package/dist/templates/agents/skills/prompt/scripts/prompt.js +184 -0
- package/dist/templates/agents/skills/tasks/SKILL.md +31 -0
- package/dist/templates/agents/skills/tasks/scripts/tasks.js +489 -0
- package/dist/templates/claude/config.js +40 -0
- package/dist/templates/claude/hooks/README.md +158 -0
- package/dist/templates/claude/hooks/common/complexity-rater.js +290 -0
- package/dist/templates/claude/hooks/common/context.js +263 -0
- package/dist/templates/claude/hooks/common/group-id.js +188 -0
- package/dist/templates/claude/hooks/common/mcp-client.js +131 -0
- package/dist/templates/claude/hooks/common/transcript-parser.js +256 -0
- package/dist/templates/claude/hooks/common/zep-client.js +175 -0
- package/dist/templates/claude/hooks/session-start.js +401 -0
- package/dist/templates/claude/hooks/session-stop-worker.js +341 -0
- package/dist/templates/claude/hooks/session-stop.js +122 -0
- package/dist/templates/claude/hooks/user-prompt-submit.js +256 -0
- package/dist/templates/claude/settings.json +46 -0
- package/dist/templates/docker/.env.lisa.example +17 -0
- package/dist/templates/docker/docker-compose.graphiti.yml +45 -0
- package/dist/templates/rules/shared/clean-architecture.md +333 -0
- package/dist/templates/rules/shared/code-quality-rules.md +469 -0
- package/dist/templates/rules/shared/git-rules.md +64 -0
- package/dist/templates/rules/shared/testing-principles.md +469 -0
- package/dist/templates/rules/typescript/coding-standards.md +751 -0
- package/dist/templates/rules/typescript/testing.md +629 -0
- package/dist/templates/rules/typescript/typescript-config-guide.md +465 -0
- package/package.json +64 -0
- 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
|