@tarcisiopgs/lisa 1.4.0 → 1.6.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/README.md CHANGED
@@ -1,26 +1,104 @@
1
1
  # Lisa
2
2
 
3
3
  <p align="center">
4
- <img src="src/assets/lisa.png" width="200" alt="Lisa" />
4
+ <img src="assets/lisa.png" width="200" alt="Lisa" />
5
5
  </p>
6
6
 
7
- While the Ralphs of the world flooded GitHub with mindless agent loops — brute-forcing their way through issues with no context, no workflow awareness, and no regard for the mess they leave behind — Lisa takes a different approach. She reads the issue, understands the workspace, picks the right repo, creates the branch, validates her work, and opens the PR. Then she moves on to the next one. When there's nothing left to do, she stops.
7
+ <p align="center">
8
+ <strong>Label an issue. Walk away. Come back to a PR.</strong>
9
+ </p>
10
+
11
+ <p align="center">
12
+ Lisa is an autonomous issue resolver that turns your backlog into pull requests — no babysitting required.
13
+ </p>
8
14
 
9
- Named after the smartest Simpson, Lisa is an autonomous issue resolver that connects your project tracker (Linear or Trello) to an AI coding agent (Claude Code, Gemini CLI, or OpenCode) and delivers pull requests via GitHub. No MCP servers. No prompt chains. No blind retries. Just structured, end-to-end execution.
15
+ ---
10
16
 
11
- ## Why Lisa?
17
+ <!-- Add a GIF or screen recording of the full pipeline here (fetch → implement → PR) -->
12
18
 
13
- Most AI agent loops work like Ralph — they grab an issue, throw it at a model, and hope for the best. If it fails, retry. If there's nothing to do, keep polling. Every cycle burns tokens, every retry burns money, and you get no visibility into what went wrong.
19
+ ## Quickstart
20
+
21
+ ```bash
22
+ npm install -g @tarcisiopgs/lisa
23
+ lisa init
24
+ lisa run
25
+ ```
26
+
27
+ That's it. Lisa picks up the next labeled issue, implements it, pushes a branch, opens a pull request, and moves the ticket to "In Review" — all without you touching it.
28
+
29
+ ## Try it safely first
30
+
31
+ Before letting Lisa touch real issues, verify your configuration with `--dry-run`. No issues will be fetched, no code will be written, no PRs will be created.
32
+
33
+ ```bash
34
+ lisa run --once --dry-run
35
+ ```
36
+
37
+ Example output:
38
+
39
+ ```
40
+ [dry-run] Would fetch issue from linear (Engineering/Web App)
41
+ [dry-run] Workflow mode: worktree
42
+ [dry-run] Models priority: claude/claude-sonnet-4-6
43
+ [dry-run] Then implement, push, create PR, and update issue status
44
+ ```
45
+
46
+ If the output looks correct, you're ready to run Lisa for real.
47
+
48
+ ## What Lisa Does
49
+
50
+ Lisa follows a deterministic pipeline:
51
+
52
+ ```
53
+ ┌─────────┐ ┌──────────┐ ┌───────────┐ ┌──────────┐ ┌────┐ ┌────────┐
54
+ │ Fetch │───▶│ Activate │───▶│ Implement │───▶│ Validate │───▶│ PR │───▶│ Update │
55
+ └─────────┘ └──────────┘ └───────────┘ └──────────┘ └────┘ └────────┘
56
+ ```
57
+
58
+ 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
+ 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** — Runs the project's test suite. If tests fail, the session is aborted and the issue reverts.
62
+ 5. **PR** — Pushes the branch and creates a pull request referencing the original issue. If pre-push hooks fail, Lisa re-invokes the agent to fix the errors and retries.
63
+ 6. **Update** — Moves the issue to the `done` status and removes the pickup label.
64
+ 7. **Next** — Picks the next issue. When there are no more matching issues, Lisa stops.
14
65
 
15
- Lisa is deterministic. She follows a structured pipeline with clear stages (fetch, activate, implement, validate, PR, update) and stops when the work is done. This means:
66
+ ### What makes it different
16
67
 
17
- - **Token efficiency** — Each issue gets one focused prompt with full context. No wasted retries, no speculative exploration, no idle polling.
18
- - **Multi-repo awareness** — Lisa plans across multiple repos, executes in the correct order (e.g., backend before frontend), and creates one PR per repo.
19
- - **Model fallback** — Configure a chain of models (`claude → gemini → opencode`). Transient errors (429, quota, timeout) trigger the next model; non-transient errors stop the chain.
20
- - **Workflow integration** — Issues move through your board in real time (Backlog In Progress → In Review). Your team always knows what's being worked on.
21
- - **Self-healing** — Orphan issues (stuck in "In Progress" from interrupted runs) are automatically recovered on startup. Pre-push hook failures trigger the agent to fix and retry.
68
+ - **Deterministic, not hopeful** — Each issue follows a structured pipeline with clear stages. No blind retries, no speculative loops.
69
+ - **Token efficiency** — Each issue gets one focused prompt. No wasted retries, no idle polling.
70
+ - **Multi-repo awareness** — Plans across multiple repos, executes in the correct order, creates one PR per repo.
71
+ - **Model fallback** — Configure a chain of models. Transient errors (429, quota, timeout) trigger the next model automatically.
72
+ - **Workflow integration** — Issues move through your board in real time. Your team always knows what's being worked on.
73
+ - **Self-healing** — Orphan issues stuck in "In Progress" are recovered on startup. Pre-push failures trigger the agent to fix and retry.
22
74
  - **Guardrails** — Past failures are logged and injected into future prompts so the agent avoids repeating mistakes.
23
75
 
76
+ ## Providers
77
+
78
+ | Provider | CLI | Auto-approve Flag |
79
+ |----------|-----|-------------------|
80
+ | Claude Code | `claude` | `--dangerously-skip-permissions` |
81
+ | Gemini CLI | `gemini` | `--yolo` |
82
+ | OpenCode | `opencode` | implicit in `run` |
83
+ | GitHub Copilot CLI | `copilot` | `--allow-all` |
84
+ | Cursor Agent | `agent` | `--force` |
85
+ | Goose | `goose` | implicit in `run` |
86
+ | Aider | `aider` | `--yes-always` |
87
+
88
+ At least one provider must be installed and available in your PATH.
89
+
90
+ ### Fallback Chain
91
+
92
+ Configure multiple models — Lisa tries each in order. Transient errors (429, quota, timeout, network) trigger the next model; non-transient errors stop the chain.
93
+
94
+ ```yaml
95
+ provider: claude
96
+ models:
97
+ - claude-sonnet-4-6 # primary
98
+ - claude-opus-4-6 # fallback 1
99
+ - claude-haiku-4-5 # fallback 2
100
+ ```
101
+
24
102
  ## Install
25
103
 
26
104
  ```bash
@@ -39,31 +117,26 @@ export LINEAR_API_KEY=""
39
117
  # Required when source = trello
40
118
  export TRELLO_API_KEY=""
41
119
  export TRELLO_TOKEN=""
42
- ```
43
-
44
- ## Quick Start
45
-
46
- ```bash
47
- # Interactive setup
48
- lisa init
49
-
50
- # Run continuously until all labeled issues are done
51
- lisa run
52
120
 
53
- # Single issue
54
- lisa run --once
121
+ # Required when source = plane
122
+ export PLANE_API_TOKEN=""
123
+ export PLANE_BASE_URL="" # optional; defaults to https://api.plane.so
124
+ export PLANE_WORKSPACE="" # optional; fallback when team is not set in config
55
125
 
56
- # Specific issue by identifier or URL
57
- lisa run --issue INT-150
126
+ # Required when source = shortcut
127
+ export SHORTCUT_API_TOKEN=""
58
128
 
59
- # Process up to N issues
60
- lisa run --limit 5
129
+ # Required when source = gitlab-issues
130
+ export GITLAB_TOKEN=""
131
+ export GITLAB_BASE_URL="" # optional; defaults to https://gitlab.com
61
132
 
62
- # Preview without executing
63
- lisa run --dry-run
133
+ # Required when source = github-issues
134
+ export GITHUB_TOKEN="" # same token used for PR creation
64
135
 
65
- # Override provider for a single run
66
- lisa run --provider gemini --once
136
+ # Required when source = jira
137
+ export JIRA_BASE_URL="" # e.g. https://yourcompany.atlassian.net
138
+ export JIRA_EMAIL="" # Atlassian account email
139
+ export JIRA_API_TOKEN="" # Atlassian API token
67
140
  ```
68
141
 
69
142
  ## Commands
@@ -72,11 +145,12 @@ lisa run --provider gemini --once
72
145
  |---------|-------------|
73
146
  | `lisa run` | Run the agent loop |
74
147
  | `lisa run --once` | Process a single issue |
148
+ | `lisa run --once --dry-run` | **Recommended first step** — preview config without executing |
75
149
  | `lisa run --issue ID` | Process a specific issue by identifier or URL |
76
150
  | `lisa run --limit N` | Process up to N issues |
77
151
  | `lisa run --dry-run` | Preview without executing |
78
152
  | `lisa run --provider NAME` | Override AI provider |
79
- | `lisa run --source NAME` | Override issue source (linear, trello) |
153
+ | `lisa run --source NAME` | Override issue source (linear, trello, plane, shortcut, gitlab-issues, github-issues, jira) |
80
154
  | `lisa run --label NAME` | Override label filter |
81
155
  | `lisa run --github METHOD` | Override GitHub method (cli, token) |
82
156
  | `lisa run --json` | Output as JSON lines |
@@ -87,50 +161,6 @@ lisa run --provider gemini --once
87
161
  | `lisa init` | Create `.lisa/config.yaml` |
88
162
  | `lisa status` | Show session stats |
89
163
 
90
- ## Providers
91
-
92
- | Provider | CLI | Auto-approve Flag |
93
- |----------|-----|-------------------|
94
- | Claude Code | `claude` | `--dangerously-skip-permissions` |
95
- | Gemini CLI | `gemini` | `--yolo` |
96
- | OpenCode | `opencode` | implicit in `run` |
97
-
98
- At least one provider must be installed and available in your PATH.
99
-
100
- All providers use `child_process.spawn` with `sh -c`. Prompts are written to a temp file and passed via `$(cat file)` to avoid argument length limits. Output streams to both stdout and the session log file in real time.
101
-
102
- ### Fallback Chain
103
-
104
- Configure a fallback chain in the `models` array. Lisa tries each provider in order — transient errors (429, quota, timeout, network) trigger the next provider. Non-transient errors stop the chain immediately.
105
-
106
- ```yaml
107
- models:
108
- - claude
109
- - gemini
110
- - opencode
111
- ```
112
-
113
- If `models` is not set, Lisa uses the single `provider` field.
114
-
115
- ## Workflow Modes
116
-
117
- ### Branch
118
-
119
- The AI agent creates a branch directly in your current checkout, implements the changes, and pushes. Simple setup, works everywhere.
120
-
121
- ### Worktree
122
-
123
- Lisa creates an isolated [git worktree](https://git-scm.com/docs/git-worktree) for each issue under `.worktrees/`. The agent works inside the worktree without touching your main checkout. After the PR is created, the worktree is cleaned up automatically.
124
-
125
- **Native worktree support** — When using Claude Code, Lisa delegates worktree lifecycle directly to the provider via the `--worktree` flag. Lisa auto-detects whether the primary provider supports native worktrees and uses the appropriate mode. Other providers use Lisa-managed worktrees.
126
-
127
- **Multi-repo workspaces** — When multiple repos are configured, Lisa uses a two-phase flow:
128
-
129
- 1. **Planning phase** — A planning agent analyzes the issue and produces a `.lisa-plan.json` with ordered steps (one per affected repo), determining which repos need changes and in what order (e.g., backend API before frontend consumer).
130
- 2. **Execution phase** — Lisa executes each step sequentially, creating one worktree and one PR per repo. Cross-repo context (branch names, PR URLs from previous steps) is passed to each subsequent step so the agent can reference them.
131
-
132
- Worktree mode is ideal when you want to keep working in the repo while Lisa resolves issues in the background.
133
-
134
164
  ## Configuration
135
165
 
136
166
  Config lives in `.lisa/config.yaml`. Run `lisa init` to create it interactively.
@@ -178,14 +208,80 @@ overseer:
178
208
 
179
209
  ### Source-Specific Fields
180
210
 
181
- | Field | Linear | Trello |
182
- |-------|--------|--------|
183
- | `team` | Team name | Board name |
184
- | `project` | Project name | — |
185
- | `pick_from` | Status to pick issues from | List to pick cards from |
186
- | `label` | Label to filter issues | Label to filter cards |
187
- | `in_progress` | In-progress status | In-progress column |
188
- | `done` | Destination status after PR | Destination column after PR |
211
+ | Field | Linear | Trello | Plane | Shortcut | GitLab Issues | GitHub Issues | Jira |
212
+ |-------|--------|--------|-------|----------|---------------|---------------|------|
213
+ | `team` | Team name | Board name | Workspace slug | Group name (optional) | Project path (`namespace/project`) or numeric ID | `owner/repo` | Project key (e.g. `ENG`) |
214
+ | `project` | Project name | — | Project identifier or UUID | — | — | — | — |
215
+ | `pick_from` | Status to pick issues from | List to pick cards from | State name to pick issues from | Workflow state to pick stories from | — | — | Status to pick issues from |
216
+ | `label` | Label to filter issues | Label to filter cards | Label to filter issues | Label to filter stories | Label to filter issues | Label to filter issues | Label to filter issues |
217
+ | `in_progress` | In-progress status | In-progress column | In-progress state name | In-progress workflow state | Label to apply on activate | Label to apply on activate | In-progress status name |
218
+ | `done` | Destination status after PR | Destination column after PR | Done state name | Done workflow state | Closes the issue | Closes the issue | Destination status after PR |
219
+
220
+ Plane example:
221
+
222
+ ```yaml
223
+ source: plane
224
+ source_config:
225
+ team: my-workspace # workspace slug (or set PLANE_WORKSPACE env var)
226
+ project: DEV # project identifier or UUID
227
+ label: ready # issues with this label are picked up
228
+ pick_from: Todo # state to fetch issues from
229
+ in_progress: In Progress # state set when Lisa starts working
230
+ done: Done # state set after PR is created
231
+ ```
232
+
233
+ Shortcut example:
234
+
235
+ ```yaml
236
+ source: shortcut
237
+ source_config:
238
+ label: ready # stories with this label are picked up
239
+ pick_from: Ready for Development # workflow state to fetch stories from
240
+ in_progress: In Progress # state set when Lisa starts working
241
+ done: Done # state set after PR is created
242
+ ```
243
+
244
+ GitLab Issues example:
245
+
246
+ ```yaml
247
+ source: gitlab-issues
248
+ source_config:
249
+ team: my-org/my-repo # namespace/project path or numeric project ID
250
+ label: ready # issues with this label are picked up
251
+ in_progress: in-progress # label applied when Lisa starts working
252
+ done: "" # issue is closed after PR (value unused)
253
+ ```
254
+
255
+ GitHub Issues example:
256
+
257
+ ```yaml
258
+ source: github-issues
259
+ source_config:
260
+ team: my-org/my-repo # owner/repo
261
+ label: ready # issues with this label are picked up
262
+ in_progress: in-progress # label applied when Lisa starts working
263
+ done: "" # issue is closed after PR (value unused)
264
+ ```
265
+
266
+ Jira example:
267
+
268
+ ```yaml
269
+ source: jira
270
+ source_config:
271
+ team: ENG # Jira project key
272
+ label: lisa # label to filter issues
273
+ pick_from: Backlog # status to pick issues from
274
+ in_progress: In Progress # status applied when Lisa starts working
275
+ done: In Review # status applied after PR is created
276
+ ```
277
+
278
+ ### Workflow Modes
279
+
280
+ **Branch** — The AI agent creates a branch directly in your current checkout, implements the changes, and pushes. Simple setup, works everywhere.
281
+
282
+ **Worktree** — Lisa creates an isolated [git worktree](https://git-scm.com/docs/git-worktree) for each issue under `.worktrees/`. The agent works in the worktree without touching your main checkout. After the PR is created, the worktree is cleaned up automatically. Ideal when you want to keep working in the repo while Lisa resolves issues in the background.
283
+
284
+ **Multi-repo worktree** — When multiple repos are configured, Lisa runs a two-phase flow: a planning agent produces a `.lisa-plan.json` with ordered steps, then Lisa executes each step sequentially — one worktree and one PR per repo. Cross-repo context (branch names, PR URLs) is passed to each subsequent step.
189
285
 
190
286
  ### Lifecycle Resources
191
287
 
@@ -210,44 +306,20 @@ repos:
210
306
 
211
307
  Lisa starts resources before the agent runs, waits for the port to be ready, runs setup commands, then stops everything after the session.
212
308
 
213
- ## How It Works
214
-
215
- ```
216
- ┌─────────┐ ┌──────────┐ ┌───────────┐ ┌──────────┐ ┌────┐ ┌────────┐
217
- │ Fetch │───▶│ Activate │───▶│ Implement │───▶│ Validate │───▶│ PR │───▶│ Update │
218
- └─────────┘ └──────────┘ └───────────┘ └──────────┘ └────┘ └────────┘
219
- ```
220
-
221
- 1. **Fetch** — Pulls the next issue from Linear or Trello matching the configured label, team, and project. Issues are sorted by priority. Blocked issues (with unresolved dependencies) are skipped.
222
- 2. **Activate** — Moves the issue to `in_progress` so your team knows it's being worked on.
223
- 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 validation, and commits.
224
- 4. **Validate** — Runs the project's test suite. If tests fail, the session is aborted and the issue reverts.
225
- 5. **PR** — Pushes the branch and creates a pull request referencing the original issue. If pre-push hooks fail, Lisa re-invokes the agent to fix the errors and retries (up to 2 recovery attempts).
226
- 6. **Update** — Moves the issue to the `done` status and removes the pickup label in a single atomic operation.
227
- 7. **Next** — Picks the next issue. When there are no more matching issues, Lisa stops.
228
-
229
309
  ### Recovery Mechanisms
230
310
 
231
- - **Orphan recovery** — On startup, Lisa scans for issues stuck in `in_progress` from previous interrupted runs and reverts them to `pick_from`.
311
+ - **Orphan recovery** — On startup, Lisa scans for issues stuck in `in_progress` from interrupted runs and reverts them to `pick_from`.
232
312
  - **Push recovery** — If `git push` fails due to pre-push hooks (linter, typecheck, tests), Lisa re-invokes the agent with the error output and retries the push.
233
313
  - **Signal handling** — SIGINT/SIGTERM gracefully revert the active issue to its previous status before exiting.
234
314
  - **Guardrails** — Failed sessions are logged to `.lisa/guardrails.md` and injected into future prompts so the agent avoids repeating the same mistakes.
235
315
 
236
316
  ### Overseer
237
317
 
238
- Lisa can detect stuck providers — agents that appear to be running but are making no progress. When enabled, the overseer periodically checks `git status` in the working directory. If no changes are detected within the `stuck_threshold`, the provider process is killed and the error is eligible for fallback to the next model in the chain.
239
-
240
- ### Test Runner Auto-Detection
241
-
242
- Lisa auto-detects `vitest` or `jest` in the project's `package.json` dependencies. When a test runner is found, mandatory test instructions are injected into the agent prompt, requiring the agent to write unit tests for new code and run `npm run test` before committing.
243
-
244
- ### PR Body Formatting
245
-
246
- Agent-produced PR descriptions are automatically sanitized before creating the pull request: HTML tags are stripped, `*` bullets are normalized to `-`, and wall-of-text (single-line) descriptions are split into bullet points at sentence boundaries. Agents are also instructed to follow a structured markdown template (What / Why / Key changes / Testing).
318
+ When enabled, the overseer periodically checks `git status` in the working directory. If no changes are detected within `stuck_threshold` seconds, the provider process is killed and the error is eligible for fallback to the next model.
247
319
 
248
- ### Terminal Integration
320
+ ### Auto-Detection
249
321
 
250
- Lisa updates the terminal title to reflect the current activity (fetching, implementing, pushing, cooling down) and plays a bell notification when a session completes. This works in any terminal that supports OSC title sequences.
322
+ Lisa auto-detects `vitest` or `jest` from `package.json` dependencies and injects the correct test command into the agent prompt. It also detects the package manager from lockfiles (`bun.lockb`/`bun.lock` `bun`, `pnpm-lock.yaml` `pnpm`, `yarn.lock` `yarn`, otherwise `npm`).
251
323
 
252
324
  ## License
253
325
 
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/ui/state.ts
4
+ import { EventEmitter } from "events";
5
+ import { useEffect, useState } from "react";
6
+ var KanbanEmitter = class extends EventEmitter {
7
+ };
8
+ var kanbanEmitter = new KanbanEmitter();
9
+ function useKanbanState() {
10
+ const [cards, setCards] = useState([]);
11
+ useEffect(() => {
12
+ const onQueued = (issue) => {
13
+ setCards((prev) => {
14
+ if (prev.some((c) => c.id === issue.id)) return prev;
15
+ return [...prev, { id: issue.id, title: issue.title, column: "backlog" }];
16
+ });
17
+ };
18
+ const onStarted = (issueId) => {
19
+ setCards(
20
+ (prev) => prev.map(
21
+ (c) => c.id === issueId ? { ...c, column: "in_progress", startedAt: Date.now(), hasError: false } : c
22
+ )
23
+ );
24
+ };
25
+ const onDone = (issueId, prUrl) => {
26
+ setCards(
27
+ (prev) => prev.map((c) => c.id === issueId ? { ...c, column: "done", prUrl } : c)
28
+ );
29
+ };
30
+ const onReverted = (issueId) => {
31
+ setCards(
32
+ (prev) => prev.map(
33
+ (c) => c.id === issueId ? { ...c, column: "backlog", startedAt: void 0, hasError: true } : c
34
+ )
35
+ );
36
+ };
37
+ kanbanEmitter.on("issue:queued", onQueued);
38
+ kanbanEmitter.on("issue:started", onStarted);
39
+ kanbanEmitter.on("issue:done", onDone);
40
+ kanbanEmitter.on("issue:reverted", onReverted);
41
+ return () => {
42
+ kanbanEmitter.off("issue:queued", onQueued);
43
+ kanbanEmitter.off("issue:started", onStarted);
44
+ kanbanEmitter.off("issue:done", onDone);
45
+ kanbanEmitter.off("issue:reverted", onReverted);
46
+ };
47
+ }, []);
48
+ return { cards };
49
+ }
50
+
51
+ export {
52
+ kanbanEmitter,
53
+ useKanbanState
54
+ };