From f4c564ea3bb42712b7c56a472aaeee6c53bb47d7 Mon Sep 17 00:00:00 2001 From: Tony Casey Date: Fri, 6 Feb 2026 09:44:47 +0000 Subject: [PATCH 1/6] refactor(skills): consolidate git into github, rename init-review to review (LISA-19) - Merge git skill content (CI triggers, version bumping, workflows) into github skill - Move bump-version.ts from skills/git/ to skills/github/ - Add customizable pr-description-template.txt for PR body generation - Rename init-review skill to review across all paths and references - Update deploy script, init command, and CLAUDE.md skill table - Add pr skill to symlink lists for claude and opencode Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 4 +- scripts/deploy-lisa.js | 4 +- src/lib/commands/init.ts | 4 +- src/lib/commands/skills.ts | 10 +- src/lib/scanner/reviewer.ts | 4 +- .../skills/{git => github}/bump-version.ts | 0 .../{init-review => review}/ai-enrich.ts | 0 .../{init-review => review}/init-review.ts | 0 src/project/.lisa/skills/git/SKILL.md | 171 ------------------ src/project/.lisa/skills/github/SKILL.md | 96 +++++++++- .../skills/github/pr-description-template.txt | 8 + src/project/.lisa/skills/pr/SKILL.md | 3 +- .../skills/{init-review => review}/SKILL.md | 18 +- 13 files changed, 124 insertions(+), 198 deletions(-) rename src/lib/skills/{git => github}/bump-version.ts (100%) rename src/lib/skills/{init-review => review}/ai-enrich.ts (100%) rename src/lib/skills/{init-review => review}/init-review.ts (100%) delete mode 100644 src/project/.lisa/skills/git/SKILL.md create mode 100644 src/project/.lisa/skills/github/pr-description-template.txt rename src/project/.lisa/skills/{init-review => review}/SKILL.md (87%) diff --git a/CLAUDE.md b/CLAUDE.md index 4951bb3..0594c47 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -114,8 +114,8 @@ Skills are invoked with `/skill-name` in Claude Code: | `/tasks` | Create, load, or summarize tasks | "tasks", "list tasks", "add task" | | `/lisa` | Intelligent assistant for memory and tasks | "lisa", "hey lisa" | | `/jira` | Create and manage Jira issues | "jira", "create ticket" | -| `/git` | GitHub and Git workflow helpers | "create pr", "pr checks" | -| `/init-review` | Initial codebase review and summary | First session in a repo | +| `/github` | GitHub/Git workflow helpers, Issues, Projects | "create pr", "github issues", "bump version" | +| `/review` | Initial codebase review and summary | First session in a repo | Skills source: `src/project/.lisa/skills/` Skills deployed to: `.lisa/skills/` diff --git a/scripts/deploy-lisa.js b/scripts/deploy-lisa.js index 4ac1f17..14ad293 100644 --- a/scripts/deploy-lisa.js +++ b/scripts/deploy-lisa.js @@ -441,7 +441,7 @@ async function main() { await fs.ensureDir(claudeSkillsDir); // Create individual symlinks for each Lisa skill (same pattern as OpenCode) - const lisaSkills = ['memory', 'tasks', 'lisa', 'git', 'jira', 'init-review', 'prompt']; + const lisaSkills = ['memory', 'tasks', 'lisa', 'jira', 'review', 'prompt', 'github', 'pr']; for (const skill of lisaSkills) { const skillLink = path.join(claudeSkillsDir, skill); const skillTarget = path.join(targetLisa, 'skills', skill); @@ -481,7 +481,7 @@ async function main() { const opencodeSkillsDir = path.join(targetOpenCode, 'skills'); await fs.ensureDir(opencodeSkillsDir); - const lisaSkills = ['memory', 'tasks', 'lisa', 'git', 'jira', 'init-review', 'prompt']; + const lisaSkills = ['memory', 'tasks', 'lisa', 'jira', 'review', 'prompt', 'github', 'pr']; for (const skill of lisaSkills) { const skillLink = path.join(opencodeSkillsDir, skill); const skillTarget = path.join(targetLisa, 'skills', skill); diff --git a/src/lib/commands/init.ts b/src/lib/commands/init.ts index d33f73a..c15006b 100644 --- a/src/lib/commands/init.ts +++ b/src/lib/commands/init.ts @@ -522,7 +522,7 @@ export async function initCommand(opts: IInitOptions, services: ICliServices): P await fs.ensureDir(claudeSkillsDir); - const lisaSkills = ['memory', 'tasks', 'lisa', 'git', 'jira', 'init-review', 'prompt', 'github']; + const lisaSkills = ['memory', 'tasks', 'lisa', 'jira', 'review', 'prompt', 'github', 'pr']; for (const skill of lisaSkills) { const skillLink = path.join(claudeSkillsDir, skill); const skillTarget = path.join(skillsDir, skill); @@ -583,7 +583,7 @@ export async function initCommand(opts: IInitOptions, services: ICliServices): P await fs.ensureDir(opencodeSkillsDir); - const lisaSkills = ['memory', 'tasks', 'lisa', 'git', 'jira', 'init-review', 'prompt']; + const lisaSkills = ['memory', 'tasks', 'lisa', 'jira', 'review', 'prompt', 'github', 'pr']; for (const skill of lisaSkills) { const skillLink = path.join(opencodeSkillsDir, skill); const skillTarget = path.join(skillsDir, skill); diff --git a/src/lib/commands/skills.ts b/src/lib/commands/skills.ts index a2f9de7..0d5657a 100644 --- a/src/lib/commands/skills.ts +++ b/src/lib/commands/skills.ts @@ -2,7 +2,7 @@ * Skill Passthrough Command Module * * Simple passthrough commands that delegate to skill scripts: - * jira, github, prompt, bump-version, init-review, compile-skills + * jira, github, prompt, bump-version, review, compile-skills */ import type {Command} from 'commander'; @@ -50,18 +50,18 @@ export function registerSkillCommands(program: Command): void { .allowUnknownOption() .action(async (_opts, cmd) => { const args = cmd.args || []; - const scriptPath = path.join(__dirname, '..', 'skills', 'git', 'bump-version.js'); + const scriptPath = path.join(__dirname, '..', 'skills', 'github', 'bump-version.js'); await spawnAndWait(scriptPath, args); }); - // Subcommand: lisa init-review + // Subcommand: lisa review program - .command('init-review') + .command('review') .description('Run initial codebase review') .allowUnknownOption() .action(async (_opts, cmd) => { const args = cmd.args || []; - const scriptPath = path.join(__dirname, '..', 'skills', 'init-review', 'init-review.js'); + const scriptPath = path.join(__dirname, '..', 'skills', 'review', 'init-review.js'); await spawnAndWait(scriptPath, args); }); diff --git a/src/lib/scanner/reviewer.ts b/src/lib/scanner/reviewer.ts index f9c812a..1f1bdfc 100644 --- a/src/lib/scanner/reviewer.ts +++ b/src/lib/scanner/reviewer.ts @@ -93,8 +93,8 @@ async function runInitReview(projectPath: string): Promise<{ // Look for init-review script in the project's .lisa folder // or in our dist/project location const possiblePaths = [ - path.join(projectPath, '.lisa', 'skills', 'init-review', 'scripts', 'init-review.js'), - path.join(__dirname, '..', '..', 'project', '.lisa', 'skills', 'init-review', 'scripts', 'init-review.js'), + path.join(projectPath, '.lisa', 'skills', 'review', 'scripts', 'init-review.js'), + path.join(__dirname, '..', '..', 'project', '.lisa', 'skills', 'review', 'scripts', 'init-review.js'), ]; let scriptPath: string | null = null; diff --git a/src/lib/skills/git/bump-version.ts b/src/lib/skills/github/bump-version.ts similarity index 100% rename from src/lib/skills/git/bump-version.ts rename to src/lib/skills/github/bump-version.ts diff --git a/src/lib/skills/init-review/ai-enrich.ts b/src/lib/skills/review/ai-enrich.ts similarity index 100% rename from src/lib/skills/init-review/ai-enrich.ts rename to src/lib/skills/review/ai-enrich.ts diff --git a/src/lib/skills/init-review/init-review.ts b/src/lib/skills/review/init-review.ts similarity index 100% rename from src/lib/skills/init-review/init-review.ts rename to src/lib/skills/review/init-review.ts diff --git a/src/project/.lisa/skills/git/SKILL.md b/src/project/.lisa/skills/git/SKILL.md deleted file mode 100644 index abf74c8..0000000 --- a/src/project/.lisa/skills/git/SKILL.md +++ /dev/null @@ -1,171 +0,0 @@ ---- -name: git -description: "GitHub and Git workflow helpers; triggers on 'create pr', 'pr checks', 'retrigger tests', 'bump version', 'push'." ---- - -## Purpose -Model-neutral helper for GitHub and Git workflows including PR management, CI triggers, version bumping, and branch operations. - -## Triggers -Use when the user says: "create a pr", "check pr status", "retrigger tests", "toggle test label", "pr checks", "bump version", "push to remote". - -## How to use - -### Check PR Status -```bash -# View PR checks -gh pr checks --repo - -# View PR details -gh pr view --repo -``` - -### Retrigger CI Tests -When a PR test fails and a fix is pushed, tests don't automatically re-run. Toggle the "TEST" label to trigger: - -```bash -# Remove and re-add TEST label to trigger CI -gh pr edit --repo --remove-label "TEST" -sleep 2 -gh pr edit --repo --add-label "TEST" -``` - -### Check CircleCI Pipeline Status -```bash -# Get latest pipeline for a branch -curl -s -H "Circle-Token: $(cat ~/.circleci/cli.yml | grep token | awk '{print $2}')" \ - "https://circleci.com/api/v2/project/gh///pipeline?branch=" \ - | jq '.items[0] | {number, state, created_at}' - -# Get workflow status for a pipeline -curl -s -H "Circle-Token: $(cat ~/.circleci/cli.yml | grep token | awk '{print $2}')" \ - "https://circleci.com/api/v2/pipeline//workflow" \ - | jq '.items[] | {name, status}' -``` - -### Poll CI Until Completion -```bash -# Poll current branch -lisa pr checks - -# Or use gh CLI directly -gh pr checks --watch -``` - -### Bump Version -Bump the semantic version in package.json before pushing: - -```bash -# Bump minor version (default): 1.2.3 → 1.3.0 -lisa bump-version - -# Bump patch version: 1.2.3 → 1.2.4 -lisa bump-version patch - -# Bump major version: 1.2.3 → 2.0.0 -lisa bump-version major -``` - -Output (JSON to stdout): -```json -{ - "status": "ok", - "bumpType": "minor", - "oldVersion": "1.2.3", - "newVersion": "1.3.0", - "file": "/path/to/package.json" -} -``` - -## Workflow: Push with Version Bump - -**When pushing changes to remote**, bump the version first: - -1. **Bump version** (default: minor): - ```bash - lisa bump-version - ``` - -2. **Commit the version bump**: - ```bash - git add package.json - git commit -m "chore: bump version to $(node -p "require('./package.json').version")" - ``` - -3. **Push to remote**: - ```bash - git push - ``` - -**One-liner for bump + commit + push**: -```bash -lisa bump-version && \ -git add package.json && \ -git commit -m "chore: bump version to $(node -p \"require('./package.json').version\")" && \ -git push -``` - -## Workflow: PR Created - -**When a Pull Request is created**, follow these steps: - -1. **Create the PR** with the TEST label: - ```bash - gh pr create --title "[TICKET-123] - Title" --body "..." --label "TEST" - ``` - -2. **Update Jira tickets** to "Code Review" status (see jira skill) - -3. **Monitor CI** - Check if tests pass: - ```bash - gh pr checks --repo - ``` - -## Workflow: PR Test Failure - -**When CI tests fail on a PR:** - -1. **Identify the failure** - Check CircleCI logs or GitHub checks -2. **Push a fix** - Commit and push the fix to the branch -3. **Retrigger tests** - Toggle the TEST label: - ```bash - gh pr edit --repo --remove-label "TEST" && \ - sleep 2 && \ - gh pr edit --repo --add-label "TEST" - ``` -4. **Monitor** - Watch for the new pipeline to complete - -## I/O Contract (examples) - -### PR Checks -``` -gh pr checks 1266 -Run linter pass 1m28s https://github.com/... -ci/circleci pass 5m12s https://circleci.com/... -``` - -### CircleCI Pipeline Status -```json -{ - "number": 6162, - "state": "created", - "created_at": "2026-01-13T17:27:10.963Z" -} -``` - -### CircleCI Workflow Status -```json -{ - "name": "test", - "status": "running" -} -``` - -## Cross-model checklist -- Claude: Use concise commands; prefer gh CLI for GitHub operations -- Gemini: Explicit commands; avoid model-specific tokens - -## Notes -- Requires `gh` CLI authenticated with GitHub -- Requires CircleCI CLI/token for pipeline status -- TEST label triggers CI workflow via GitHub Actions/CircleCI integration diff --git a/src/project/.lisa/skills/github/SKILL.md b/src/project/.lisa/skills/github/SKILL.md index 7bc0614..d20fdff 100644 --- a/src/project/.lisa/skills/github/SKILL.md +++ b/src/project/.lisa/skills/github/SKILL.md @@ -1,11 +1,11 @@ --- name: github -description: "GitHub Issues and Projects v2 management via gh CLI; triggers on 'github', 'create issue', 'list issues', 'github project', 'project board', 'sync tasks'." +description: "GitHub and Git workflow helpers, Issues and Projects v2 management via gh CLI; triggers on 'github', 'create issue', 'list issues', 'github project', 'project board', 'sync tasks', 'create pr', 'pr checks', 'retrigger tests', 'bump version', 'push'." --- ## Purpose -Model-neutral helper to interact with GitHub Issues and Projects v2 using the gh CLI. Supports creating, listing, viewing, closing, and managing issues, managing GitHub Projects v2 boards, and bidirectional sync between Lisa tasks and GitHub Issues. +Model-neutral helper for GitHub and Git workflows including Issues, Projects v2, PR management, CI triggers, and version bumping. Uses the `gh` CLI. ## Triggers @@ -16,6 +16,7 @@ Use when the user says: - "github project", "project board", "kanban" - "add to project", "update project field", "move to column" - "sync tasks with github", "import github issues", "export tasks to github" +- "create a pr", "check pr status", "retrigger tests", "toggle test label", "pr checks", "bump version", "push to remote" ## Configuration @@ -398,6 +399,93 @@ lisa github sync --repo owner/repo lisa github sync --repo owner/repo --dry-run ``` +## Git Workflows + +### Check PR Status +```bash +# View PR checks +gh pr checks --repo + +# View PR details +gh pr view --repo +``` + +### Retrigger CI Tests +When a PR test fails and a fix is pushed, tests don't automatically re-run. Toggle the "TEST" label to trigger: + +```bash +# Remove and re-add TEST label to trigger CI +gh pr edit --repo --remove-label "TEST" +sleep 2 +gh pr edit --repo --add-label "TEST" +``` + +### Check CircleCI Pipeline Status +```bash +# Get latest pipeline for a branch +curl -s -H "Circle-Token: $(cat ~/.circleci/cli.yml | grep token | awk '{print $2}')" \ + "https://circleci.com/api/v2/project/gh///pipeline?branch=" \ + | jq '.items[0] | {number, state, created_at}' + +# Get workflow status for a pipeline +curl -s -H "Circle-Token: $(cat ~/.circleci/cli.yml | grep token | awk '{print $2}')" \ + "https://circleci.com/api/v2/pipeline//workflow" \ + | jq '.items[] | {name, status}' +``` + +### Poll CI Until Completion +```bash +# Poll current branch +lisa pr checks + +# Or use gh CLI directly +gh pr checks --watch +``` + +### Bump Version +Bump the semantic version in package.json before pushing: + +```bash +# Bump minor version (default): 1.2.3 → 1.3.0 +lisa bump-version + +# Bump patch version: 1.2.3 → 1.2.4 +lisa bump-version patch + +# Bump major version: 1.2.3 → 2.0.0 +lisa bump-version major +``` + +### Workflow: Push with Version Bump + +1. **Bump version** (default: minor): + ```bash + lisa bump-version + ``` + +2. **Commit the version bump**: + ```bash + git add package.json + git commit -m "chore: bump version to $(node -p "require('./package.json').version")" + ``` + +3. **Push to remote**: + ```bash + git push + ``` + +### Workflow: PR Test Failure + +1. **Identify the failure** - Check CircleCI logs or GitHub checks +2. **Push a fix** - Commit and push the fix to the branch +3. **Retrigger tests** - Toggle the TEST label: + ```bash + gh pr edit --repo --remove-label "TEST" && \ + sleep 2 && \ + gh pr edit --repo --add-label "TEST" + ``` +4. **Monitor** - Watch for the new pipeline to complete + ## Cross-model checklist - Claude: Use JSON output for parsing; concise instructions - Gemini: Explicit commands; minimal formatting @@ -405,11 +493,13 @@ lisa github sync --repo owner/repo --dry-run ## Notes - Requires `gh` CLI v2.0+ or `GITHUB_TOKEN` environment variable +- Requires CircleCI CLI/token for pipeline status - Projects v2 uses GraphQL API (requires appropriate permissions) - Rate limits apply per GitHub API policies - `--repo` flag is always required (no auto-detection) +- TEST label triggers CI workflow via GitHub Actions/CircleCI integration ## See Also -- `/git` skill for PR creation, CI triggers, version bumping +- `/pr` skill for PR creation, polling, and review comment workflows - `/jira` skill for Jira integration (similar command structure) - `/tasks` skill for Lisa's internal task management diff --git a/src/project/.lisa/skills/github/pr-description-template.txt b/src/project/.lisa/skills/github/pr-description-template.txt new file mode 100644 index 0000000..e4d694f --- /dev/null +++ b/src/project/.lisa/skills/github/pr-description-template.txt @@ -0,0 +1,8 @@ +## Summary +{{summary}} + +## Test plan +{{test_plan}} + +## Linked Issues +{{linked_issues}} diff --git a/src/project/.lisa/skills/pr/SKILL.md b/src/project/.lisa/skills/pr/SKILL.md index 3be9279..226e85b 100644 --- a/src/project/.lisa/skills/pr/SKILL.md +++ b/src/project/.lisa/skills/pr/SKILL.md @@ -516,5 +516,4 @@ lisa pr poll 50 - All: Neo4j must be running for watch/watching commands (lisa doctor to verify) ## Related Skills -- `/git` - For version bumping, CI retriggers, and other git workflows -- `/github` - For GitHub Issues and Projects operations +- `/github` - For GitHub Issues, Projects, version bumping, and CI retriggers diff --git a/src/project/.lisa/skills/init-review/SKILL.md b/src/project/.lisa/skills/review/SKILL.md similarity index 87% rename from src/project/.lisa/skills/init-review/SKILL.md rename to src/project/.lisa/skills/review/SKILL.md index 7128fbf..a00394e 100644 --- a/src/project/.lisa/skills/init-review/SKILL.md +++ b/src/project/.lisa/skills/review/SKILL.md @@ -1,11 +1,11 @@ -# Init Review Skill +# Review Skill ## Purpose -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. +Automatically analyzes a codebase when Lisa is installed, creating a foundational memory of the project structure, technologies, and patterns. This review serves as context for all future Claude sessions. ## Triggers Use when the user says things like: -- "run init review" +- "run review" - "analyze this codebase" - "scan the project" - "what is this project about" @@ -14,7 +14,7 @@ Use when the user says things like: ## How to use ### Automatic (during npm install) -The init review runs automatically when Lisa is installed via `npm install @tonycasey/lisa`. It: +The review runs automatically when Lisa is installed via `npm install @tonycasey/lisa`. It: 1. Detects if the folder is a codebase 2. Runs static analysis (language, framework, structure) 3. Stores result as first memory @@ -22,14 +22,14 @@ The init review runs automatically when Lisa is installed via `npm install @tony ### Manual commands ```bash -# Run init review (or re-run with --force) -lisa init-review run [--force] +# Run review (or re-run with --force) +lisa review run [--force] -# Show current init review -lisa init-review show +# Show current review +lisa review show # Check status (done, enriched, etc.) -lisa init-review status +lisa review status ``` ## I/O contract From 7cc3961b3486dfbfc4521b4bf228ffd375d27c3f Mon Sep 17 00:00:00 2001 From: Tony Casey Date: Fri, 6 Feb 2026 10:08:31 +0000 Subject: [PATCH 2/6] fix(skills): use $CIRCLE_TOKEN env var for CircleCI examples (LISA-19) Co-Authored-By: Claude Opus 4.6 --- src/project/.lisa/skills/github/SKILL.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/project/.lisa/skills/github/SKILL.md b/src/project/.lisa/skills/github/SKILL.md index d20fdff..4395cd8 100644 --- a/src/project/.lisa/skills/github/SKILL.md +++ b/src/project/.lisa/skills/github/SKILL.md @@ -421,14 +421,17 @@ gh pr edit --repo --add-label "TEST" ``` ### Check CircleCI Pipeline Status + +**Prerequisites:** Set `CIRCLE_TOKEN` environment variable, or have CircleCI CLI configured at `~/.circleci/cli.yml`. + ```bash # Get latest pipeline for a branch -curl -s -H "Circle-Token: $(cat ~/.circleci/cli.yml | grep token | awk '{print $2}')" \ +curl -s -H "Circle-Token: ${CIRCLE_TOKEN}" \ "https://circleci.com/api/v2/project/gh///pipeline?branch=" \ | jq '.items[0] | {number, state, created_at}' # Get workflow status for a pipeline -curl -s -H "Circle-Token: $(cat ~/.circleci/cli.yml | grep token | awk '{print $2}')" \ +curl -s -H "Circle-Token: ${CIRCLE_TOKEN}" \ "https://circleci.com/api/v2/pipeline//workflow" \ | jq '.items[] | {name, status}' ``` From 625379e2ea0b1e4fdc255ec8290165775399a87b Mon Sep 17 00:00:00 2001 From: Tony Casey Date: Fri, 6 Feb 2026 10:39:42 +0000 Subject: [PATCH 3/6] feat(bump-version): make version bump optional via LISA_AUTO_BUMP_VERSION env (LISA-33) Add LISA_AUTO_BUMP_VERSION setting to .lisa/.env that controls whether version bumping runs: true (default), false (skip), or a bump type (patch/minor/major) to set the default. CLI args always override. Co-Authored-By: Claude Opus 4.6 --- src/lib/skills/github/bump-version.ts | 26 ++++++++- src/project/.lisa/.env.template | 3 + src/project/.lisa/skills/github/SKILL.md | 18 ++++++ .../src/lib/skills/git/bump-version.test.ts | 58 ++++++++++++++++++- 4 files changed, 101 insertions(+), 4 deletions(-) diff --git a/src/lib/skills/github/bump-version.ts b/src/lib/skills/github/bump-version.ts index daa67c7..4574564 100644 --- a/src/lib/skills/github/bump-version.ts +++ b/src/lib/skills/github/bump-version.ts @@ -4,17 +4,41 @@ * * Usage: node bump-version.js [major|minor|patch] * Default: minor + * + * Set LISA_AUTO_BUMP_VERSION in .lisa/.env to control behavior: + * true — enabled (default) + * false — disabled, skip with message + * patch|minor|major — enabled with that bump type as default */ export {}; async function main(): Promise { const { createVersionService } = await import('../shared/services'); + const { loadEnv } = await import('../shared/utils/env'); + + const env = loadEnv(); + const autoBump = env.raw['LISA_AUTO_BUMP_VERSION'] ?? 'true'; + + // Check if version bumping is disabled + if (autoBump.toLowerCase() === 'false') { + const result = { status: 'skipped', reason: 'LISA_AUTO_BUMP_VERSION is false' }; + console.log(JSON.stringify(result)); + console.error('Version bump skipped (LISA_AUTO_BUMP_VERSION=false)'); + return; + } const service = createVersionService(); try { - const bumpType = service.validateBumpType(process.argv[2] || 'minor'); + // Resolve bump type: CLI arg > env default > 'minor' + const explicitArg = process.argv[2]; + let defaultType = 'minor'; + if (['major', 'minor', 'patch'].includes(autoBump.toLowerCase())) { + defaultType = autoBump.toLowerCase(); + } + + const bumpType = service.validateBumpType(explicitArg || defaultType); const result = service.bump(bumpType); console.log(JSON.stringify(result)); diff --git a/src/project/.lisa/.env.template b/src/project/.lisa/.env.template index ab76654..3a9a9c1 100644 --- a/src/project/.lisa/.env.template +++ b/src/project/.lisa/.env.template @@ -25,3 +25,6 @@ NEO4J_DATABASE=neo4j # LLM API Keys # ANTHROPIC_API_KEY= # OPENAI_API_KEY= + +# Auto version bump on push (true, false, or default bump type: patch|minor|major) +# LISA_AUTO_BUMP_VERSION=true diff --git a/src/project/.lisa/skills/github/SKILL.md b/src/project/.lisa/skills/github/SKILL.md index 4395cd8..63e33a4 100644 --- a/src/project/.lisa/skills/github/SKILL.md +++ b/src/project/.lisa/skills/github/SKILL.md @@ -459,6 +459,24 @@ lisa bump-version patch lisa bump-version major ``` +#### Configuration + +Control version bumping via `LISA_AUTO_BUMP_VERSION` in `.lisa/.env`: + +| Value | Behavior | +|-------|----------| +| `true` (default) | Enabled, defaults to `minor` bump | +| `false` | Disabled, bump commands are skipped | +| `patch` / `minor` / `major` | Enabled with that bump type as the default | + +```bash +# In .lisa/.env: +LISA_AUTO_BUMP_VERSION=false # Disable version bumping +LISA_AUTO_BUMP_VERSION=patch # Default to patch bumps +``` + +A CLI argument always overrides the env default: `lisa bump-version major` bumps major regardless of the env setting. + ### Workflow: Push with Version Bump 1. **Bump version** (default: minor): diff --git a/tests/unit/src/lib/skills/git/bump-version.test.ts b/tests/unit/src/lib/skills/git/bump-version.test.ts index 0afa962..b9f6b7f 100644 --- a/tests/unit/src/lib/skills/git/bump-version.test.ts +++ b/tests/unit/src/lib/skills/git/bump-version.test.ts @@ -13,8 +13,8 @@ import * as fs from 'fs'; import * as path from 'path'; import * as os from 'os'; -// Path to the compiled script (now in dist/lib/skills/) -const SCRIPT_PATH = path.join(process.cwd(), 'dist', 'lib', 'skills', 'git', 'bump-version.js'); +// Path to the compiled script (in dist/lib/skills/github/) +const SCRIPT_PATH = path.join(process.cwd(), 'dist', 'lib', 'skills', 'github', 'bump-version.js'); // Create a temp directory for tests const TEST_DIR = path.join(os.tmpdir(), `lisa-bump-test-${Date.now()}`); @@ -25,13 +25,15 @@ const TEST_DIR = path.join(os.tmpdir(), `lisa-bump-test-${Date.now()}`); async function runBumpScript( args: string[] = [], cwd: string = TEST_DIR, - timeoutMs = 5000 + timeoutMs = 5000, + env: Record = {} ): Promise<{ stdout: string; stderr: string; exitCode: number }> { return new Promise((resolve, reject) => { const child = spawn('node', [SCRIPT_PATH, ...args], { cwd, stdio: ['pipe', 'pipe', 'pipe'], timeout: timeoutMs, + env: { ...process.env, ...env }, }); let stdout = ''; @@ -250,6 +252,56 @@ describe('bump-version script', () => { }); }); + describe('LISA_AUTO_BUMP_VERSION', () => { + it('should skip bump when set to false', async () => { + createPackageJson('1.0.0'); + + const result = await runBumpScript([], TEST_DIR, 5000, { + LISA_AUTO_BUMP_VERSION: 'false', + }); + + assert.strictEqual(result.exitCode, 0, 'Should exit with code 0'); + assert.strictEqual(readVersion(), '1.0.0', 'Version should not change'); + + const output = JSON.parse(result.stdout); + assert.strictEqual(output.status, 'skipped'); + assert.ok(result.stderr.includes('skipped'), 'stderr should mention skipped'); + }); + + it('should use env default bump type when set to patch', async () => { + createPackageJson('1.2.3'); + + const result = await runBumpScript([], TEST_DIR, 5000, { + LISA_AUTO_BUMP_VERSION: 'patch', + }); + + assert.strictEqual(result.exitCode, 0); + assert.strictEqual(readVersion(), '1.2.4', 'Should use patch bump from env'); + }); + + it('should allow CLI arg to override env default', async () => { + createPackageJson('1.2.3'); + + const result = await runBumpScript(['major'], TEST_DIR, 5000, { + LISA_AUTO_BUMP_VERSION: 'patch', + }); + + assert.strictEqual(result.exitCode, 0); + assert.strictEqual(readVersion(), '2.0.0', 'CLI arg should override env default'); + }); + + it('should treat unrecognized values as enabled with minor default', async () => { + createPackageJson('1.2.3'); + + const result = await runBumpScript([], TEST_DIR, 5000, { + LISA_AUTO_BUMP_VERSION: 'yes', + }); + + assert.strictEqual(result.exitCode, 0); + assert.strictEqual(readVersion(), '1.3.0', 'Should default to minor bump'); + }); + }); + describe('package.json in parent directory', () => { it('should find package.json in parent directory', async () => { createPackageJson('3.0.0'); From 6ac67d37c74b9b04058cc9bbfc2997df7198ee0c Mon Sep 17 00:00:00 2001 From: Tony Casey Date: Fri, 6 Feb 2026 11:21:51 +0000 Subject: [PATCH 4/6] fix: address PR review comments for LISA-33 - Move bump-version.test.ts from skills/git/ to skills/github/ to mirror source structure - Fix markdownlint MD022/MD031: add blank lines around headings and fenced code blocks in SKILL.md Co-Authored-By: Claude Opus 4.6 --- src/project/.lisa/skills/github/SKILL.md | 7 +++++++ .../src/lib/skills/{git => github}/bump-version.test.ts | 0 2 files changed, 7 insertions(+) rename tests/unit/src/lib/skills/{git => github}/bump-version.test.ts (100%) diff --git a/src/project/.lisa/skills/github/SKILL.md b/src/project/.lisa/skills/github/SKILL.md index 63e33a4..0f49401 100644 --- a/src/project/.lisa/skills/github/SKILL.md +++ b/src/project/.lisa/skills/github/SKILL.md @@ -480,17 +480,20 @@ A CLI argument always overrides the env default: `lisa bump-version major` bumps ### Workflow: Push with Version Bump 1. **Bump version** (default: minor): + ```bash lisa bump-version ``` 2. **Commit the version bump**: + ```bash git add package.json git commit -m "chore: bump version to $(node -p "require('./package.json').version")" ``` 3. **Push to remote**: + ```bash git push ``` @@ -500,6 +503,7 @@ A CLI argument always overrides the env default: `lisa bump-version major` bumps 1. **Identify the failure** - Check CircleCI logs or GitHub checks 2. **Push a fix** - Commit and push the fix to the branch 3. **Retrigger tests** - Toggle the TEST label: + ```bash gh pr edit --repo --remove-label "TEST" && \ sleep 2 && \ @@ -508,11 +512,13 @@ A CLI argument always overrides the env default: `lisa bump-version major` bumps 4. **Monitor** - Watch for the new pipeline to complete ## Cross-model checklist + - Claude: Use JSON output for parsing; concise instructions - Gemini: Explicit commands; minimal formatting - All models: Always include --repo flag; parse JSON responses ## Notes + - Requires `gh` CLI v2.0+ or `GITHUB_TOKEN` environment variable - Requires CircleCI CLI/token for pipeline status - Projects v2 uses GraphQL API (requires appropriate permissions) @@ -521,6 +527,7 @@ A CLI argument always overrides the env default: `lisa bump-version major` bumps - TEST label triggers CI workflow via GitHub Actions/CircleCI integration ## See Also + - `/pr` skill for PR creation, polling, and review comment workflows - `/jira` skill for Jira integration (similar command structure) - `/tasks` skill for Lisa's internal task management diff --git a/tests/unit/src/lib/skills/git/bump-version.test.ts b/tests/unit/src/lib/skills/github/bump-version.test.ts similarity index 100% rename from tests/unit/src/lib/skills/git/bump-version.test.ts rename to tests/unit/src/lib/skills/github/bump-version.test.ts From e1264f626f13445e3e1381ca3bc0db49082395a8 Mon Sep 17 00:00:00 2001 From: Tony Casey Date: Fri, 6 Feb 2026 11:51:10 +0000 Subject: [PATCH 5/6] fix(init): copy missing rules and skill assets during install (LISA-19) - Add git-rules.md, git-rules.local.md, memory-rules.md, task-rules.md to rules scaffolding in init command - Allow .txt and .json files through skills copy filter so pr-description-template.txt is included - Update package.json exports for renamed skill paths (git -> github, init-review -> review) Co-Authored-By: Claude Opus 4.6 --- package.json | 6 +++--- src/lib/commands/init.ts | 5 +++++ .../.lisa/skills/{github => pr}/pr-description-template.txt | 0 3 files changed, 8 insertions(+), 3 deletions(-) rename src/project/.lisa/skills/{github => pr}/pr-description-template.txt (100%) diff --git a/package.json b/package.json index 7cf02f3..3bd0014 100644 --- a/package.json +++ b/package.json @@ -15,12 +15,12 @@ "./skills/memory": "./dist/lib/skills/memory/memory.js", "./skills/tasks": "./dist/lib/skills/tasks/tasks.js", "./skills/jira": "./dist/lib/skills/jira/jira.js", - "./skills/git/bump-version": "./dist/lib/skills/git/bump-version.js", + "./skills/github/bump-version": "./dist/lib/skills/github/bump-version.js", "./skills/lisa/storage": "./dist/lib/skills/lisa/storage.js", "./skills/lisa/compile-skills": "./dist/lib/skills/lisa/compile-skills.js", "./skills/prompt": "./dist/lib/skills/prompt/prompt.js", - "./skills/init-review": "./dist/lib/skills/init-review/init-review.js", - "./skills/init-review/ai-enrich": "./dist/lib/skills/init-review/ai-enrich.js" + "./skills/review": "./dist/lib/skills/review/init-review.js", + "./skills/review/ai-enrich": "./dist/lib/skills/review/ai-enrich.js" }, "engines": { "node": ">=18.0.0" diff --git a/src/lib/commands/init.ts b/src/lib/commands/init.ts index c15006b..f5656d6 100644 --- a/src/lib/commands/init.ts +++ b/src/lib/commands/init.ts @@ -480,6 +480,7 @@ export async function initCommand(opts: IInitOptions, services: ICliServices): P if (relativePath.includes('shared') || relativePath.includes('common')) return false; if (relativePath.includes('scripts')) return false; if (basename === 'SKILL.md' || basename === 'SKILL.local.md') return true; + if (basename.endsWith('.txt') || basename.endsWith('.json')) return true; if (basename === 'cache' || basename === '.gitkeep') return true; return fs.statSync(src).isDirectory(); @@ -502,6 +503,10 @@ export async function initCommand(opts: IInitOptions, services: ICliServices): P copies.push(services.templateCopier.copy('.lisa/rules/shared/clean-architecture.md', path.join(rulesDir, 'shared', 'clean-architecture.md'), replacements, force)); copies.push(services.templateCopier.copy('.lisa/rules/shared/code-quality-rules.md', path.join(rulesDir, 'shared', 'code-quality-rules.md'), replacements, force)); copies.push(services.templateCopier.copy('.lisa/rules/shared/testing-principles.md', path.join(rulesDir, 'shared', 'testing-principles.md'), replacements, force)); + copies.push(services.templateCopier.copy('.lisa/rules/shared/git-rules.md', path.join(rulesDir, 'shared', 'git-rules.md'), replacements, force)); + copies.push(services.templateCopier.copy('.lisa/rules/shared/git-rules.local.md', path.join(rulesDir, 'shared', 'git-rules.local.md'), replacements, force)); + copies.push(services.templateCopier.copy('.lisa/rules/shared/memory-rules.md', path.join(rulesDir, 'shared', 'memory-rules.md'), replacements, force)); + copies.push(services.templateCopier.copy('.lisa/rules/shared/task-rules.md', path.join(rulesDir, 'shared', 'task-rules.md'), replacements, force)); copies.push(services.templateCopier.copy('.lisa/rules/typescript/coding-standards.md', path.join(rulesDir, 'typescript', 'coding-standards.md'), replacements, force)); copies.push(services.templateCopier.copy('.lisa/rules/typescript/testing.md', path.join(rulesDir, 'typescript', 'testing.md'), replacements, force)); copies.push(services.templateCopier.copy('.lisa/rules/typescript/typescript-config-guide.md', path.join(rulesDir, 'typescript', 'typescript-config-guide.md'), replacements, force)); diff --git a/src/project/.lisa/skills/github/pr-description-template.txt b/src/project/.lisa/skills/pr/pr-description-template.txt similarity index 100% rename from src/project/.lisa/skills/github/pr-description-template.txt rename to src/project/.lisa/skills/pr/pr-description-template.txt From d5b49b883087112ec21bd29d4c9223cb1f8f8f60 Mon Sep 17 00:00:00 2001 From: Tony Casey Date: Fri, 6 Feb 2026 11:52:16 +0000 Subject: [PATCH 6/6] fix(skills): restore pr-description-template.txt in github skill (LISA-19) Co-Authored-By: Claude Opus 4.6 --- .../.lisa/skills/github/pr-description-template.txt | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/project/.lisa/skills/github/pr-description-template.txt diff --git a/src/project/.lisa/skills/github/pr-description-template.txt b/src/project/.lisa/skills/github/pr-description-template.txt new file mode 100644 index 0000000..e4d694f --- /dev/null +++ b/src/project/.lisa/skills/github/pr-description-template.txt @@ -0,0 +1,8 @@ +## Summary +{{summary}} + +## Test plan +{{test_plan}} + +## Linked Issues +{{linked_issues}}