@tarcisiopgs/lisa 1.5.0 → 1.7.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 +183 -112
- package/dist/chunk-MUBWKMRZ.js +73 -0
- package/dist/index.js +1985 -1151
- package/dist/kanban-UW2MC2PB.js +481 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -1,91 +1,77 @@
|
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
## Why Lisa?
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>Label an issue. Walk away. Come back to a PR.</strong>
|
|
9
|
+
</p>
|
|
12
10
|
|
|
13
|
-
|
|
11
|
+
<p align="center">
|
|
12
|
+
Lisa is an autonomous issue resolver that turns your backlog into pull requests — no babysitting required.
|
|
13
|
+
</p>
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
---
|
|
16
16
|
|
|
17
|
-
|
|
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.
|
|
22
|
-
- **Guardrails** — Past failures are logged and injected into future prompts so the agent avoids repeating mistakes.
|
|
17
|
+
<!-- Add a GIF or screen recording of the full pipeline here (fetch → implement → PR) -->
|
|
23
18
|
|
|
24
|
-
##
|
|
19
|
+
## Quickstart
|
|
25
20
|
|
|
26
21
|
```bash
|
|
27
22
|
npm install -g @tarcisiopgs/lisa
|
|
23
|
+
lisa init
|
|
24
|
+
lisa run
|
|
28
25
|
```
|
|
29
26
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
# Required (at least one)
|
|
34
|
-
export GITHUB_TOKEN="" # or have `gh` CLI authenticated
|
|
35
|
-
|
|
36
|
-
# Required when source = linear
|
|
37
|
-
export LINEAR_API_KEY=""
|
|
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.
|
|
38
28
|
|
|
39
|
-
|
|
40
|
-
export TRELLO_API_KEY=""
|
|
41
|
-
export TRELLO_TOKEN=""
|
|
42
|
-
```
|
|
29
|
+
## Try it safely first
|
|
43
30
|
|
|
44
|
-
|
|
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.
|
|
45
32
|
|
|
46
33
|
```bash
|
|
47
|
-
|
|
48
|
-
|
|
34
|
+
lisa run --once --dry-run
|
|
35
|
+
```
|
|
49
36
|
|
|
50
|
-
|
|
51
|
-
lisa run
|
|
37
|
+
Example output:
|
|
52
38
|
|
|
53
|
-
|
|
54
|
-
|
|
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
|
+
```
|
|
55
45
|
|
|
56
|
-
|
|
57
|
-
lisa run --issue INT-150
|
|
46
|
+
If the output looks correct, you're ready to run Lisa for real.
|
|
58
47
|
|
|
59
|
-
|
|
60
|
-
lisa run --limit 5
|
|
48
|
+
## What Lisa Does
|
|
61
49
|
|
|
62
|
-
|
|
63
|
-
lisa run --dry-run
|
|
50
|
+
Lisa follows a deterministic pipeline:
|
|
64
51
|
|
|
65
|
-
|
|
66
|
-
|
|
52
|
+
```
|
|
53
|
+
┌─────────┐ ┌──────────┐ ┌───────────┐ ┌──────────┐ ┌────┐ ┌────────┐
|
|
54
|
+
│ Fetch │───▶│ Activate │───▶│ Implement │───▶│ Validate │───▶│ PR │───▶│ Update │
|
|
55
|
+
└─────────┘ └──────────┘ └───────────┘ └──────────┘ └────┘ └────────┘
|
|
67
56
|
```
|
|
68
57
|
|
|
69
|
-
|
|
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.
|
|
70
65
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
| `lisa run --label NAME` | Override label filter |
|
|
81
|
-
| `lisa run --github METHOD` | Override GitHub method (cli, token) |
|
|
82
|
-
| `lisa run --json` | Output as JSON lines |
|
|
83
|
-
| `lisa run --quiet` | Suppress non-essential output |
|
|
84
|
-
| `lisa config` | Interactive config wizard |
|
|
85
|
-
| `lisa config --show` | Show current config |
|
|
86
|
-
| `lisa config --set key=value` | Set a config value |
|
|
87
|
-
| `lisa init` | Create `.lisa/config.yaml` |
|
|
88
|
-
| `lisa status` | Show session stats |
|
|
66
|
+
### What makes it different
|
|
67
|
+
|
|
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.
|
|
74
|
+
- **Guardrails** — Past failures are logged and injected into future prompts so the agent avoids repeating mistakes.
|
|
89
75
|
|
|
90
76
|
## Providers
|
|
91
77
|
|
|
@@ -94,14 +80,16 @@ lisa run --provider gemini --once
|
|
|
94
80
|
| Claude Code | `claude` | `--dangerously-skip-permissions` |
|
|
95
81
|
| Gemini CLI | `gemini` | `--yolo` |
|
|
96
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` |
|
|
97
87
|
|
|
98
88
|
At least one provider must be installed and available in your PATH.
|
|
99
89
|
|
|
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
90
|
### Fallback Chain
|
|
103
91
|
|
|
104
|
-
Configure
|
|
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.
|
|
105
93
|
|
|
106
94
|
```yaml
|
|
107
95
|
provider: claude
|
|
@@ -111,26 +99,67 @@ models:
|
|
|
111
99
|
- claude-haiku-4-5 # fallback 2
|
|
112
100
|
```
|
|
113
101
|
|
|
114
|
-
|
|
102
|
+
## Install
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
npm install -g @tarcisiopgs/lisa
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Environment Variables
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# Required (at least one)
|
|
112
|
+
export GITHUB_TOKEN="" # or have `gh` CLI authenticated
|
|
115
113
|
|
|
116
|
-
|
|
114
|
+
# Required when source = linear
|
|
115
|
+
export LINEAR_API_KEY=""
|
|
117
116
|
|
|
118
|
-
|
|
117
|
+
# Required when source = trello
|
|
118
|
+
export TRELLO_API_KEY=""
|
|
119
|
+
export TRELLO_TOKEN=""
|
|
119
120
|
|
|
120
|
-
|
|
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
|
|
121
125
|
|
|
122
|
-
|
|
126
|
+
# Required when source = shortcut
|
|
127
|
+
export SHORTCUT_API_TOKEN=""
|
|
123
128
|
|
|
124
|
-
|
|
129
|
+
# Required when source = gitlab-issues
|
|
130
|
+
export GITLAB_TOKEN=""
|
|
131
|
+
export GITLAB_BASE_URL="" # optional; defaults to https://gitlab.com
|
|
125
132
|
|
|
126
|
-
|
|
133
|
+
# Required when source = github-issues
|
|
134
|
+
export GITHUB_TOKEN="" # same token used for PR creation
|
|
127
135
|
|
|
128
|
-
|
|
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
|
|
140
|
+
```
|
|
129
141
|
|
|
130
|
-
|
|
131
|
-
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.
|
|
142
|
+
## Commands
|
|
132
143
|
|
|
133
|
-
|
|
144
|
+
| Command | Description |
|
|
145
|
+
|---------|-------------|
|
|
146
|
+
| `lisa run` | Run the agent loop |
|
|
147
|
+
| `lisa run --once` | Process a single issue |
|
|
148
|
+
| `lisa run --once --dry-run` | **Recommended first step** — preview config without executing |
|
|
149
|
+
| `lisa run --issue ID` | Process a specific issue by identifier or URL |
|
|
150
|
+
| `lisa run --limit N` | Process up to N issues |
|
|
151
|
+
| `lisa run --dry-run` | Preview without executing |
|
|
152
|
+
| `lisa run --provider NAME` | Override AI provider |
|
|
153
|
+
| `lisa run --source NAME` | Override issue source (linear, trello, plane, shortcut, gitlab-issues, github-issues, jira) |
|
|
154
|
+
| `lisa run --label NAME` | Override label filter |
|
|
155
|
+
| `lisa run --github METHOD` | Override GitHub method (cli, token) |
|
|
156
|
+
| `lisa run --json` | Output as JSON lines |
|
|
157
|
+
| `lisa run --quiet` | Suppress non-essential output |
|
|
158
|
+
| `lisa config` | Interactive config wizard |
|
|
159
|
+
| `lisa config --show` | Show current config |
|
|
160
|
+
| `lisa config --set key=value` | Set a config value |
|
|
161
|
+
| `lisa init` | Create `.lisa/config.yaml` |
|
|
162
|
+
| `lisa status` | Show session stats |
|
|
134
163
|
|
|
135
164
|
## Configuration
|
|
136
165
|
|
|
@@ -179,14 +208,80 @@ overseer:
|
|
|
179
208
|
|
|
180
209
|
### Source-Specific Fields
|
|
181
210
|
|
|
182
|
-
| Field | Linear | Trello |
|
|
183
|
-
|
|
184
|
-
| `team` | Team name | Board name |
|
|
185
|
-
| `project` | Project name | — |
|
|
186
|
-
| `pick_from` | Status to pick issues from | List to pick cards from |
|
|
187
|
-
| `label` | Label to filter issues | Label to filter cards |
|
|
188
|
-
| `in_progress` | In-progress status | In-progress column |
|
|
189
|
-
| `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.
|
|
190
285
|
|
|
191
286
|
### Lifecycle Resources
|
|
192
287
|
|
|
@@ -209,46 +304,22 @@ repos:
|
|
|
209
304
|
- "npx prisma db push"
|
|
210
305
|
```
|
|
211
306
|
|
|
212
|
-
Lisa starts resources before the agent runs, waits for the port to be ready, runs setup commands, then stops everything after the session.
|
|
213
|
-
|
|
214
|
-
## How It Works
|
|
215
|
-
|
|
216
|
-
```
|
|
217
|
-
┌─────────┐ ┌──────────┐ ┌───────────┐ ┌──────────┐ ┌────┐ ┌────────┐
|
|
218
|
-
│ Fetch │───▶│ Activate │───▶│ Implement │───▶│ Validate │───▶│ PR │───▶│ Update │
|
|
219
|
-
└─────────┘ └──────────┘ └───────────┘ └──────────┘ └────┘ └────────┘
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
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.
|
|
223
|
-
2. **Activate** — Moves the issue to `in_progress` so your team knows it's being worked on.
|
|
224
|
-
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.
|
|
225
|
-
4. **Validate** — Runs the project's test suite. If tests fail, the session is aborted and the issue reverts.
|
|
226
|
-
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).
|
|
227
|
-
6. **Update** — Moves the issue to the `done` status and removes the pickup label in a single atomic operation.
|
|
228
|
-
7. **Next** — Picks the next issue. When there are no more matching issues, Lisa stops.
|
|
307
|
+
Lisa starts resources before the agent runs, waits for the port to be ready, runs setup commands, then stops everything after the session.
|
|
229
308
|
|
|
230
309
|
### Recovery Mechanisms
|
|
231
310
|
|
|
232
|
-
- **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`.
|
|
233
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.
|
|
234
313
|
- **Signal handling** — SIGINT/SIGTERM gracefully revert the active issue to its previous status before exiting.
|
|
235
314
|
- **Guardrails** — Failed sessions are logged to `.lisa/guardrails.md` and injected into future prompts so the agent avoids repeating the same mistakes.
|
|
236
315
|
|
|
237
316
|
### Overseer
|
|
238
317
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
### Test Runner and Package Manager Auto-Detection
|
|
242
|
-
|
|
243
|
-
Lisa auto-detects `vitest` or `jest` in the project's `package.json` dependencies. It also detects the package manager from lockfiles (`bun.lockb`/`bun.lock` → `bun`, `pnpm-lock.yaml` → `pnpm`, `yarn.lock` → `yarn`, otherwise `npm`). When a test runner is found, mandatory test instructions are injected into the agent prompt with the correct test command (e.g., `bun run test`, `pnpm run test`).
|
|
244
|
-
|
|
245
|
-
### PR Body Formatting
|
|
246
|
-
|
|
247
|
-
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.
|
|
248
319
|
|
|
249
|
-
###
|
|
320
|
+
### Auto-Detection
|
|
250
321
|
|
|
251
|
-
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`).
|
|
252
323
|
|
|
253
324
|
## License
|
|
254
325
|
|
|
@@ -0,0 +1,73 @@
|
|
|
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
|
+
const [isEmpty, setIsEmpty] = useState(false);
|
|
12
|
+
const [workComplete, setWorkComplete] = useState(
|
|
13
|
+
null
|
|
14
|
+
);
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
const onQueued = (issue) => {
|
|
17
|
+
setCards((prev) => {
|
|
18
|
+
if (prev.some((c) => c.id === issue.id)) return prev;
|
|
19
|
+
return [...prev, { id: issue.id, title: issue.title, column: "backlog", outputLog: "" }];
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
const onStarted = (issueId) => {
|
|
23
|
+
setCards(
|
|
24
|
+
(prev) => prev.map(
|
|
25
|
+
(c) => c.id === issueId ? { ...c, column: "in_progress", startedAt: Date.now(), hasError: false } : c
|
|
26
|
+
)
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
const onDone = (issueId, prUrl) => {
|
|
30
|
+
setCards(
|
|
31
|
+
(prev) => prev.map(
|
|
32
|
+
(c) => c.id === issueId ? { ...c, column: "done", prUrl, finishedAt: Date.now() } : c
|
|
33
|
+
)
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
const onReverted = (issueId) => {
|
|
37
|
+
setCards(
|
|
38
|
+
(prev) => prev.map(
|
|
39
|
+
(c) => c.id === issueId ? { ...c, column: "backlog", startedAt: void 0, hasError: true } : c
|
|
40
|
+
)
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
const onOutput = (issueId, text) => {
|
|
44
|
+
setCards(
|
|
45
|
+
(prev) => prev.map((c) => c.id === issueId ? { ...c, outputLog: c.outputLog + text } : c)
|
|
46
|
+
);
|
|
47
|
+
};
|
|
48
|
+
kanbanEmitter.on("issue:queued", onQueued);
|
|
49
|
+
kanbanEmitter.on("issue:started", onStarted);
|
|
50
|
+
kanbanEmitter.on("issue:done", onDone);
|
|
51
|
+
kanbanEmitter.on("issue:reverted", onReverted);
|
|
52
|
+
kanbanEmitter.on("issue:output", onOutput);
|
|
53
|
+
const onEmpty = () => setIsEmpty(true);
|
|
54
|
+
const onComplete = (data) => setWorkComplete(data);
|
|
55
|
+
kanbanEmitter.on("work:empty", onEmpty);
|
|
56
|
+
kanbanEmitter.on("work:complete", onComplete);
|
|
57
|
+
return () => {
|
|
58
|
+
kanbanEmitter.off("issue:queued", onQueued);
|
|
59
|
+
kanbanEmitter.off("issue:started", onStarted);
|
|
60
|
+
kanbanEmitter.off("issue:done", onDone);
|
|
61
|
+
kanbanEmitter.off("issue:reverted", onReverted);
|
|
62
|
+
kanbanEmitter.off("issue:output", onOutput);
|
|
63
|
+
kanbanEmitter.off("work:empty", onEmpty);
|
|
64
|
+
kanbanEmitter.off("work:complete", onComplete);
|
|
65
|
+
};
|
|
66
|
+
}, []);
|
|
67
|
+
return { cards, isEmpty, workComplete };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export {
|
|
71
|
+
kanbanEmitter,
|
|
72
|
+
useKanbanState
|
|
73
|
+
};
|