@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 +184 -112
- package/dist/chunk-KAME5MG7.js +54 -0
- package/dist/index.js +2033 -1141
- package/dist/kanban-KIPKQ2IL.js +127 -0
- package/package.json +59 -57
package/README.md
CHANGED
|
@@ -1,26 +1,104 @@
|
|
|
1
1
|
# Lisa
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<img src="
|
|
4
|
+
<img src="assets/lisa.png" width="200" alt="Lisa" />
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
|
-
|
|
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
|
-
|
|
15
|
+
---
|
|
10
16
|
|
|
11
|
-
|
|
17
|
+
<!-- Add a GIF or screen recording of the full pipeline here (fetch → implement → PR) -->
|
|
12
18
|
|
|
13
|
-
|
|
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
|
-
|
|
66
|
+
### What makes it different
|
|
16
67
|
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
19
|
-
- **
|
|
20
|
-
- **
|
|
21
|
-
- **
|
|
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
|
-
#
|
|
54
|
-
|
|
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
|
-
#
|
|
57
|
-
|
|
126
|
+
# Required when source = shortcut
|
|
127
|
+
export SHORTCUT_API_TOKEN=""
|
|
58
128
|
|
|
59
|
-
#
|
|
60
|
-
|
|
129
|
+
# Required when source = gitlab-issues
|
|
130
|
+
export GITLAB_TOKEN=""
|
|
131
|
+
export GITLAB_BASE_URL="" # optional; defaults to https://gitlab.com
|
|
61
132
|
|
|
62
|
-
#
|
|
63
|
-
|
|
133
|
+
# Required when source = github-issues
|
|
134
|
+
export GITHUB_TOKEN="" # same token used for PR creation
|
|
64
135
|
|
|
65
|
-
#
|
|
66
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
###
|
|
320
|
+
### Auto-Detection
|
|
249
321
|
|
|
250
|
-
Lisa
|
|
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
|
+
};
|