@tarcisiopgs/lisa 1.7.5 → 1.7.6
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 +50 -21
- package/dist/index.js +31 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,8 +14,6 @@
|
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
17
|
-
<!-- Add a GIF or screen recording of the full pipeline here (fetch → implement → PR) -->
|
|
18
|
-
|
|
19
17
|
## Quickstart
|
|
20
18
|
|
|
21
19
|
```bash
|
|
@@ -57,9 +55,9 @@ Lisa follows a deterministic pipeline:
|
|
|
57
55
|
|
|
58
56
|
1. **Fetch** — Pulls the next issue from Linear, Trello, Plane, Shortcut, GitLab Issues, GitHub Issues, or Jira matching the configured label, team, and project. Issues are sorted by priority. Blocked issues are skipped.
|
|
59
57
|
2. **Activate** — Moves the issue to `in_progress` so your team knows it's being worked on.
|
|
60
|
-
3. **Implement** — Builds a structured prompt with full issue context and sends it to the AI agent. The agent works in a worktree or branch, implements the change, and commits.
|
|
61
|
-
4. **Validate** —
|
|
62
|
-
5. **PR** — Pushes the branch and creates a pull request referencing the original issue.
|
|
58
|
+
3. **Implement** — Builds a structured prompt with full issue context and sends it to the AI agent. The agent works in a worktree or branch, implements the change, runs tests, and commits.
|
|
59
|
+
4. **Validate** — If the agent's tests pass and pre-push hooks succeed, the branch is pushed. If hooks fail, Lisa re-invokes the agent with the error output and retries.
|
|
60
|
+
5. **PR** — Pushes the branch and creates a pull request referencing the original issue. The PR body includes a footer crediting the provider that resolved it.
|
|
63
61
|
6. **Update** — Moves the issue to the `done` status and removes the pickup label.
|
|
64
62
|
7. **Next** — Picks the next issue. When there are no more matching issues, Lisa stops.
|
|
65
63
|
|
|
@@ -75,15 +73,15 @@ Lisa follows a deterministic pipeline:
|
|
|
75
73
|
|
|
76
74
|
## Providers
|
|
77
75
|
|
|
78
|
-
| Provider |
|
|
79
|
-
|
|
80
|
-
| Claude Code | `claude` |
|
|
81
|
-
| Gemini CLI | `gemini` |
|
|
82
|
-
| OpenCode | `opencode` |
|
|
83
|
-
| GitHub Copilot CLI | `copilot` |
|
|
84
|
-
| Cursor Agent | `
|
|
85
|
-
| Goose | `goose` |
|
|
86
|
-
| Aider | `aider` |
|
|
76
|
+
| Provider | Key | Command |
|
|
77
|
+
|----------|-----|---------|
|
|
78
|
+
| Claude Code | `claude` | `claude` |
|
|
79
|
+
| Gemini CLI | `gemini` | `gemini` |
|
|
80
|
+
| OpenCode | `opencode` | `opencode` |
|
|
81
|
+
| GitHub Copilot CLI | `copilot` | `copilot` |
|
|
82
|
+
| Cursor Agent | `cursor` | `agent` / `cursor-agent` |
|
|
83
|
+
| Goose | `goose` | `goose` |
|
|
84
|
+
| Aider | `aider` | `aider` |
|
|
87
85
|
|
|
88
86
|
At least one provider must be installed and available in your PATH.
|
|
89
87
|
|
|
@@ -108,7 +106,7 @@ npm install -g @tarcisiopgs/lisa
|
|
|
108
106
|
## Environment Variables
|
|
109
107
|
|
|
110
108
|
```bash
|
|
111
|
-
# Required (at least one)
|
|
109
|
+
# Required for PR creation (at least one)
|
|
112
110
|
export GITHUB_TOKEN="" # or have `gh` CLI authenticated
|
|
113
111
|
|
|
114
112
|
# Required when source = linear
|
|
@@ -150,16 +148,47 @@ export JIRA_API_TOKEN="" # Atlassian API token
|
|
|
150
148
|
| `lisa run --limit N` | Process up to N issues |
|
|
151
149
|
| `lisa run --dry-run` | Preview without executing |
|
|
152
150
|
| `lisa run --provider NAME` | Override AI provider |
|
|
153
|
-
| `lisa run --source NAME` | Override issue source
|
|
151
|
+
| `lisa run --source NAME` | Override issue source |
|
|
154
152
|
| `lisa run --label NAME` | Override label filter |
|
|
155
|
-
| `lisa run --github METHOD` | Override GitHub method (cli
|
|
153
|
+
| `lisa run --github METHOD` | Override GitHub method (`cli` or `token`) |
|
|
156
154
|
| `lisa run --json` | Output as JSON lines |
|
|
157
155
|
| `lisa run --quiet` | Suppress non-essential output |
|
|
158
|
-
| `lisa
|
|
159
|
-
| `lisa config
|
|
160
|
-
| `lisa config --
|
|
161
|
-
| `lisa
|
|
156
|
+
| `lisa init` | Create `.lisa/config.yaml` interactively |
|
|
157
|
+
| `lisa config` | Edit config interactively |
|
|
158
|
+
| `lisa config --show` | Print current config as JSON |
|
|
159
|
+
| `lisa config --set key=value` | Set a single config value |
|
|
162
160
|
| `lisa status` | Show session stats |
|
|
161
|
+
| `lisa issue get <id>` | Fetch full issue details as JSON (for use inside worktrees) |
|
|
162
|
+
| `lisa issue done <id> --pr-url <url>` | Complete issue, attach PR, update status, remove label |
|
|
163
|
+
|
|
164
|
+
## TUI
|
|
165
|
+
|
|
166
|
+
When running in an interactive terminal, `lisa run` renders a real-time Kanban board:
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
┌──────────────────────────┐ ┌───────────────────────────┐ ┌───────────────────────────┐
|
|
170
|
+
│ ▶ BACKLOG [3] │ │ ▶ IN PROGRESS [1] │ │ ▶ IN REVIEW [2] │
|
|
171
|
+
│ │ │ │ │ │
|
|
172
|
+
│ ┌────────────────────┐ │ │ ┌─────────────────────┐ │ │ ┌─────────────────────┐ │
|
|
173
|
+
│ │ ENG-42 │ │ │ │ ● ENG-38 │ │ │ │ ✓ ENG-35 │ │
|
|
174
|
+
│ │ Add dark mode │ │ │ │ Fix login redirect │ │ │ │ Update dependencies │ │
|
|
175
|
+
│ │ ready │ │ │ │ ~1 running │ │ │ │ PR created │ │
|
|
176
|
+
│ └────────────────────┘ │ │ └─────────────────────┘ │ │ └─────────────────────┘ │
|
|
177
|
+
└──────────────────────────┘ └───────────────────────────┘ └───────────────────────────┘
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Keyboard shortcuts
|
|
181
|
+
|
|
182
|
+
| Key | Action |
|
|
183
|
+
|-----|--------|
|
|
184
|
+
| `Tab` | Move to next column |
|
|
185
|
+
| `Shift+Tab` | Move to previous column |
|
|
186
|
+
| `↑` / `↓` | Navigate cards within a column |
|
|
187
|
+
| `Enter` | Open issue detail view (streams provider output) |
|
|
188
|
+
| `Esc` | Close detail view, return to board |
|
|
189
|
+
| `q` | Quit |
|
|
190
|
+
|
|
191
|
+
The terminal tab title also updates in real time: it shows a spinner with the active issue ID while work is in progress, and a checkmark when done.
|
|
163
192
|
|
|
164
193
|
## Configuration
|
|
165
194
|
|
package/dist/index.js
CHANGED
|
@@ -179,6 +179,33 @@ async function isGhCliAvailable() {
|
|
|
179
179
|
return false;
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
|
+
var PROVIDER_DISPLAY_NAMES = {
|
|
183
|
+
claude: "Claude Code",
|
|
184
|
+
gemini: "Gemini CLI",
|
|
185
|
+
opencode: "OpenCode",
|
|
186
|
+
copilot: "GitHub Copilot CLI",
|
|
187
|
+
cursor: "Cursor Agent",
|
|
188
|
+
goose: "Goose",
|
|
189
|
+
aider: "Aider"
|
|
190
|
+
};
|
|
191
|
+
function formatProviderName(providerUsed) {
|
|
192
|
+
const providerKey = providerUsed.split("/")[0] ?? providerUsed;
|
|
193
|
+
return PROVIDER_DISPLAY_NAMES[providerKey] ?? providerKey;
|
|
194
|
+
}
|
|
195
|
+
async function appendPrAttribution(prUrl, providerUsed) {
|
|
196
|
+
try {
|
|
197
|
+
const { stdout: bodyJson } = await execa("gh", ["pr", "view", prUrl, "--json", "body"]);
|
|
198
|
+
const { body } = JSON.parse(bodyJson);
|
|
199
|
+
const providerName = formatProviderName(providerUsed);
|
|
200
|
+
const attribution = `
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
\u{1F916} Resolved by [lisa](https://github.com/tarcisiopgs/lisa) using **${providerName}**`;
|
|
204
|
+
const newBody = (body ?? "") + attribution;
|
|
205
|
+
await execa("gh", ["pr", "edit", prUrl, "--body", newBody]);
|
|
206
|
+
} catch {
|
|
207
|
+
}
|
|
208
|
+
}
|
|
182
209
|
|
|
183
210
|
// src/git/worktree.ts
|
|
184
211
|
import { appendFileSync, existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
@@ -3602,6 +3629,7 @@ ${result.output}
|
|
|
3602
3629
|
}
|
|
3603
3630
|
const worktreePath = await findWorktreeForBranch(repoPath, manifest.branch ?? "");
|
|
3604
3631
|
ok(`PR created by provider: ${manifest.prUrl}`);
|
|
3632
|
+
await appendPrAttribution(manifest.prUrl, result.providerUsed);
|
|
3605
3633
|
if (worktreePath) await cleanupWorktree(repoPath, worktreePath);
|
|
3606
3634
|
ok(`Session ${session} complete for ${issue2.id}`);
|
|
3607
3635
|
return {
|
|
@@ -3708,6 +3736,7 @@ ${result.output}
|
|
|
3708
3736
|
return { success: false, providerUsed: result.providerUsed, prUrls: [], fallback: result };
|
|
3709
3737
|
}
|
|
3710
3738
|
ok(`PR created by provider: ${manifest.prUrl}`);
|
|
3739
|
+
await appendPrAttribution(manifest.prUrl, result.providerUsed);
|
|
3711
3740
|
await cleanupWorktree(repoPath, worktreePath);
|
|
3712
3741
|
ok(`Session ${session} complete for ${issue2.id}`);
|
|
3713
3742
|
return {
|
|
@@ -3896,6 +3925,7 @@ ${result.output}
|
|
|
3896
3925
|
return { ...failResult(result.providerUsed, result), branch: branchName };
|
|
3897
3926
|
}
|
|
3898
3927
|
await cleanupWorktree(repoPath, worktreePath);
|
|
3928
|
+
await appendPrAttribution(manifest.prUrl, result.providerUsed);
|
|
3899
3929
|
ok(`Step ${stepNum} complete: ${repoPath} \u2014 PR: ${manifest.prUrl}`);
|
|
3900
3930
|
return {
|
|
3901
3931
|
success: true,
|
|
@@ -3976,6 +4006,7 @@ ${result.output}
|
|
|
3976
4006
|
return { success: false, providerUsed: result.providerUsed, prUrls: [], fallback: result };
|
|
3977
4007
|
}
|
|
3978
4008
|
ok(`PR created by provider: ${manifest.prUrl}`);
|
|
4009
|
+
await appendPrAttribution(manifest.prUrl, result.providerUsed);
|
|
3979
4010
|
ok(`Session ${session} complete for ${issue2.id}`);
|
|
3980
4011
|
return {
|
|
3981
4012
|
success: true,
|