@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tonycasey/lisa",
3
- "version": "1.0.5",
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
  "remember": "cli.js",
@@ -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 create a milestone memory summarizing what was committed.
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
- ### How to Create Commit Memory
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
- node .agents/skills/memory/scripts/memory.js add "FEATURE: Added user authentication with JWT tokens and session management" --cache --type milestone
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
- - Helps future sessions understand what was accomplished
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.5",
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",
@@ -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