@tonycasey/lisa 1.0.5 → 1.1.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.
- package/dist/package.json +1 -1
- package/dist/templates/agents/docs/EXTENDING-rules.md +57 -0
- package/dist/templates/rules/shared/git-rules.local.md +20 -0
- package/dist/templates/rules/shared/git-rules.md +24 -5
- package/package.json +2 -3
- package/scripts/postinstall.js +68 -0
- package/assets/claude-i-remember.png +0 -0
- package/assets/lisa-what-i-can-do.png +0 -0
package/dist/package.json
CHANGED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Local Extensions
|
|
2
|
+
|
|
3
|
+
This project supports local rule and skill extensions that persist across package updates.
|
|
4
|
+
|
|
5
|
+
## How Local Extensions Work
|
|
6
|
+
|
|
7
|
+
When loading any rule file (e.g., `git-rules.md`), **always check if a corresponding `.local.md` file exists** (e.g., `git-rules.local.md`). If it exists, apply both files with the local file taking precedence.
|
|
8
|
+
|
|
9
|
+
## Extension Pattern
|
|
10
|
+
|
|
11
|
+
Local files use inheritance semantics:
|
|
12
|
+
|
|
13
|
+
- **Inherits**: All sections from the base file apply unless overridden
|
|
14
|
+
- **Override**: A section with the same name in the local file replaces the base section
|
|
15
|
+
- **Extend**: New sections in the local file add to the base rules
|
|
16
|
+
|
|
17
|
+
## File Naming Convention
|
|
18
|
+
|
|
19
|
+
| Base File | Local Extension |
|
|
20
|
+
|-----------|-----------------|
|
|
21
|
+
| `git-rules.md` | `git-rules.local.md` |
|
|
22
|
+
| `coding-standards.md` | `coding-standards.local.md` |
|
|
23
|
+
| `testing-principles.md` | `testing-principles.local.md` |
|
|
24
|
+
|
|
25
|
+
## Local File Format
|
|
26
|
+
|
|
27
|
+
Local extension files should include:
|
|
28
|
+
|
|
29
|
+
1. A title indicating it's a local extension
|
|
30
|
+
2. An `> Extends:` directive referencing the base file
|
|
31
|
+
3. Sections that override or extend the base
|
|
32
|
+
|
|
33
|
+
### Example: `git-rules.local.md`
|
|
34
|
+
|
|
35
|
+
```markdown
|
|
36
|
+
# Git Rules (Local Extensions)
|
|
37
|
+
|
|
38
|
+
> Extends: git-rules.md
|
|
39
|
+
|
|
40
|
+
## Commit Messages (Override)
|
|
41
|
+
- Use format: `[JIRA-123] type: description`
|
|
42
|
+
- All commits MUST reference a Jira ticket
|
|
43
|
+
|
|
44
|
+
## Branch Naming (New Section)
|
|
45
|
+
- Feature branches: `feature/JIRA-123-description`
|
|
46
|
+
- Bugfix branches: `bugfix/JIRA-123-description`
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## For Skills
|
|
50
|
+
|
|
51
|
+
Custom skills use a `.local.md` file name suffix too:
|
|
52
|
+
|
|
53
|
+
## Important
|
|
54
|
+
|
|
55
|
+
- Local files are **preserved** during package updates
|
|
56
|
+
- Local files are **not** created automatically - users create them manually when needed
|
|
57
|
+
- Always apply local extensions when they exist
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Git Rules (Local Extensions)
|
|
2
|
+
|
|
3
|
+
> Extends: git-rules.md
|
|
4
|
+
|
|
5
|
+
<!--
|
|
6
|
+
This file extends the base git-rules.md with project-specific rules.
|
|
7
|
+
|
|
8
|
+
Add your custom git workflow rules here. They will be preserved
|
|
9
|
+
across package updates.
|
|
10
|
+
|
|
11
|
+
Example overrides:
|
|
12
|
+
|
|
13
|
+
## Commit Messages (Override)
|
|
14
|
+
- Use format: `[JIRA-123] type: description`
|
|
15
|
+
- All commits MUST reference a ticket
|
|
16
|
+
|
|
17
|
+
## Branch Naming (New Section)
|
|
18
|
+
- Feature: `feature/JIRA-123-description`
|
|
19
|
+
- Bugfix: `bugfix/JIRA-123-description`
|
|
20
|
+
-->
|
|
@@ -2,15 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
## Commit Memory Rule
|
|
4
4
|
|
|
5
|
-
**IMPORTANT:** After every successful git commit, you MUST
|
|
5
|
+
**IMPORTANT:** After every successful git commit, you MUST do TWO things:
|
|
6
|
+
1. Create a milestone memory summarizing what was committed
|
|
7
|
+
2. Update the task status if completing a Jira ticket
|
|
6
8
|
|
|
7
|
-
###
|
|
9
|
+
### Step 1: Create Commit Memory
|
|
8
10
|
|
|
9
11
|
After a commit succeeds, run:
|
|
10
12
|
```bash
|
|
11
13
|
node .agents/skills/memory/scripts/memory.js add "<summary>" --cache --type milestone
|
|
12
14
|
```
|
|
13
15
|
|
|
16
|
+
### Step 2: Update Task Status (for tickets)
|
|
17
|
+
|
|
18
|
+
If the commit completes ticket (JIRA-1234), also run:
|
|
19
|
+
```bash
|
|
20
|
+
node .agents/skills/tasks/scripts/tasks.js add "JIRA-1234: COMPLETED - <description>" --cache --status done
|
|
21
|
+
```
|
|
22
|
+
|
|
14
23
|
### Summary Format
|
|
15
24
|
|
|
16
25
|
The summary should be concise and describe:
|
|
@@ -20,9 +29,13 @@ The summary should be concise and describe:
|
|
|
20
29
|
|
|
21
30
|
### Examples
|
|
22
31
|
|
|
23
|
-
**Feature commit:**
|
|
32
|
+
**Feature commit (with Jira ticket):**
|
|
24
33
|
```bash
|
|
25
|
-
|
|
34
|
+
# Step 1: Save milestone
|
|
35
|
+
node .agents/skills/memory/scripts/memory.js add "FEATURE: [JIRA-1234] Added Excel brandlist parser with unit tests" --cache --type milestone
|
|
36
|
+
|
|
37
|
+
# Step 2: Update task status
|
|
38
|
+
node .agents/skills/tasks/scripts/tasks.js add "JIRA-1234: COMPLETED - Excel brandlist parser utility created, PR #XXXX" --cache --status done
|
|
26
39
|
```
|
|
27
40
|
|
|
28
41
|
**Bug fix:**
|
|
@@ -38,7 +51,8 @@ node .agents/skills/memory/scripts/memory.js add "REFACTOR: Migrated API handler
|
|
|
38
51
|
### Why This Matters
|
|
39
52
|
|
|
40
53
|
- Creates a searchable history of development progress
|
|
41
|
-
-
|
|
54
|
+
- Keeps task status accurate across sessions
|
|
55
|
+
- Helps future sessions understand what was achieved
|
|
42
56
|
- Builds project context for AI assistants
|
|
43
57
|
- Tracks milestones and features over time
|
|
44
58
|
|
|
@@ -62,3 +76,8 @@ node .agents/skills/memory/scripts/memory.js add "REFACTOR: Migrated API handler
|
|
|
62
76
|
- Keep commits focused and atomic
|
|
63
77
|
- Don't mix unrelated changes in one commit
|
|
64
78
|
- Write meaningful commit messages
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
## Pull Requests
|
|
82
|
+
|
|
83
|
+
Follow generic guidelines for pull requests, ensuring all required information is provided in the description.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tonycasey/lisa",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Long-term memory for Claude Code. Automatic context persistence, task tracking, and knowledge capture across coding sessions.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"lisa": "dist/cli.js",
|
|
@@ -13,8 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
"files": [
|
|
15
15
|
"dist",
|
|
16
|
-
"scripts/postinstall.js"
|
|
17
|
-
"assets"
|
|
16
|
+
"scripts/postinstall.js"
|
|
18
17
|
],
|
|
19
18
|
"scripts": {
|
|
20
19
|
"build": "tsc -p tsconfig.json",
|
package/scripts/postinstall.js
CHANGED
|
@@ -12,6 +12,7 @@ const fs = require('fs-extra');
|
|
|
12
12
|
const { execSync, spawn } = require('child_process');
|
|
13
13
|
const readline = require('readline');
|
|
14
14
|
const net = require('net');
|
|
15
|
+
const { glob } = require('glob');
|
|
15
16
|
|
|
16
17
|
// When installed as a dependency, the project root is four levels up from node_modules/@tonycasey/lisa/scripts
|
|
17
18
|
// When running locally (development), use the current working directory
|
|
@@ -326,6 +327,67 @@ async function copyTemplates(src, dest, force = false) {
|
|
|
326
327
|
return true;
|
|
327
328
|
}
|
|
328
329
|
|
|
330
|
+
/**
|
|
331
|
+
* Preserve local extensions (.local.md files and .local/ directories) before deployment.
|
|
332
|
+
* These are user-created files that should survive package updates.
|
|
333
|
+
*/
|
|
334
|
+
async function preserveLocalExtensions(targetDir) {
|
|
335
|
+
const preserved = { files: [], dirs: [] };
|
|
336
|
+
|
|
337
|
+
if (!(await fs.pathExists(targetDir))) {
|
|
338
|
+
return preserved;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Find all .local.md files (rules extensions)
|
|
342
|
+
const localFiles = await glob('**/*.local.md', { cwd: targetDir, nodir: true });
|
|
343
|
+
for (const file of localFiles) {
|
|
344
|
+
const fullPath = path.join(targetDir, file);
|
|
345
|
+
const content = await fs.readFile(fullPath, 'utf8');
|
|
346
|
+
preserved.files.push({ path: file, content });
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Find all .local directories (skill extensions)
|
|
350
|
+
const localDirs = await glob('**/*.local', { cwd: targetDir, onlyDirectories: true });
|
|
351
|
+
for (const dir of localDirs) {
|
|
352
|
+
const fullPath = path.join(targetDir, dir);
|
|
353
|
+
const files = [];
|
|
354
|
+
const dirFiles = await glob('**/*', { cwd: fullPath, nodir: true });
|
|
355
|
+
for (const file of dirFiles) {
|
|
356
|
+
const filePath = path.join(fullPath, file);
|
|
357
|
+
const content = await fs.readFile(filePath, 'utf8');
|
|
358
|
+
files.push({ path: file, content });
|
|
359
|
+
}
|
|
360
|
+
preserved.dirs.push({ path: dir, files });
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (preserved.files.length > 0 || preserved.dirs.length > 0) {
|
|
364
|
+
console.log(` Preserving ${preserved.files.length} local file(s) and ${preserved.dirs.length} local dir(s)`);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return preserved;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Restore preserved local extensions after deployment.
|
|
372
|
+
*/
|
|
373
|
+
async function restoreLocalExtensions(targetDir, preserved) {
|
|
374
|
+
for (const { path: filePath, content } of preserved.files) {
|
|
375
|
+
const fullPath = path.join(targetDir, filePath);
|
|
376
|
+
await fs.ensureDir(path.dirname(fullPath));
|
|
377
|
+
await fs.writeFile(fullPath, content, 'utf8');
|
|
378
|
+
console.log(` ✓ Restored: ${filePath}`);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
for (const { path: dirPath, files } of preserved.dirs) {
|
|
382
|
+
for (const { path: filePath, content } of files) {
|
|
383
|
+
const fullPath = path.join(targetDir, dirPath, filePath);
|
|
384
|
+
await fs.ensureDir(path.dirname(fullPath));
|
|
385
|
+
await fs.writeFile(fullPath, content, 'utf8');
|
|
386
|
+
}
|
|
387
|
+
console.log(` ✓ Restored: ${dirPath}/`);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
329
391
|
async function createSymlink(target, linkPath) {
|
|
330
392
|
try {
|
|
331
393
|
if (await fs.pathExists(linkPath)) {
|
|
@@ -641,6 +703,9 @@ async function main() {
|
|
|
641
703
|
const agentsDir = path.join(projectRoot, '.agents');
|
|
642
704
|
const claudeDir = path.join(projectRoot, '.claude');
|
|
643
705
|
|
|
706
|
+
// Preserve local extensions before copying (user-created .local.md files and .local/ directories)
|
|
707
|
+
const preservedExtensions = await preserveLocalExtensions(agentsDir);
|
|
708
|
+
|
|
644
709
|
// Copy .agents templates
|
|
645
710
|
const agentsSrc = path.join(templateRoot, 'agents');
|
|
646
711
|
const rulesSrc = path.join(templateRoot, 'rules');
|
|
@@ -658,6 +723,9 @@ async function main() {
|
|
|
658
723
|
console.log(' ✓ Copied .agents/rules/');
|
|
659
724
|
}
|
|
660
725
|
|
|
726
|
+
// Restore local extensions after copying
|
|
727
|
+
await restoreLocalExtensions(agentsDir, preservedExtensions);
|
|
728
|
+
|
|
661
729
|
// Copy .claude templates
|
|
662
730
|
const claudeSrc = path.join(templateRoot, 'claude');
|
|
663
731
|
if (await fs.pathExists(claudeSrc)) {
|
|
Binary file
|
|
Binary file
|