@tarcisiopgs/lisa 1.12.2 → 1.13.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.
|
@@ -229,8 +229,10 @@ var GitHubIssuesSource = class {
|
|
|
229
229
|
name = "github-issues";
|
|
230
230
|
async fetchNextIssue(config) {
|
|
231
231
|
const { owner, repo } = parseOwnerRepo(config.team);
|
|
232
|
-
const
|
|
233
|
-
const
|
|
232
|
+
const validStates = ["open", "closed", "all"];
|
|
233
|
+
const isOrphanDetection = !!config.pick_from && !validStates.includes(config.pick_from);
|
|
234
|
+
const filterLabels = isOrphanDetection ? [config.pick_from] : Array.isArray(config.label) ? config.label : [config.label];
|
|
235
|
+
const label = filterLabels.map((l) => encodeURIComponent(l)).join(",");
|
|
234
236
|
const path = `/repos/${owner}/${repo}/issues?labels=${label}&state=open&sort=created&direction=asc&per_page=100`;
|
|
235
237
|
const issues = await githubGet(path);
|
|
236
238
|
if (issues.length === 0) return null;
|
|
@@ -310,8 +312,36 @@ var GitHubIssuesSource = class {
|
|
|
310
312
|
return null;
|
|
311
313
|
}
|
|
312
314
|
}
|
|
313
|
-
async updateStatus(issueId, labelToAdd) {
|
|
315
|
+
async updateStatus(issueId, labelToAdd, config) {
|
|
314
316
|
const ref = parseGitHubIssueNumber(issueId);
|
|
317
|
+
if (config && config.in_progress !== config.pick_from) {
|
|
318
|
+
const filterLabels = Array.isArray(config.label) ? config.label : [config.label];
|
|
319
|
+
const isMovingToInProgress = labelToAdd === config.in_progress;
|
|
320
|
+
if (isMovingToInProgress) {
|
|
321
|
+
await githubPost(`/repos/${ref.owner}/${ref.repo}/issues/${ref.number}/labels`, {
|
|
322
|
+
labels: [labelToAdd]
|
|
323
|
+
});
|
|
324
|
+
for (const label of filterLabels) {
|
|
325
|
+
try {
|
|
326
|
+
await githubDelete(
|
|
327
|
+
`/repos/${ref.owner}/${ref.repo}/issues/${ref.number}/labels/${encodeURIComponent(label)}`
|
|
328
|
+
);
|
|
329
|
+
} catch {
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
await githubPost(`/repos/${ref.owner}/${ref.repo}/issues/${ref.number}/labels`, {
|
|
335
|
+
labels: filterLabels
|
|
336
|
+
});
|
|
337
|
+
try {
|
|
338
|
+
await githubDelete(
|
|
339
|
+
`/repos/${ref.owner}/${ref.repo}/issues/${ref.number}/labels/${encodeURIComponent(config.in_progress)}`
|
|
340
|
+
);
|
|
341
|
+
} catch {
|
|
342
|
+
}
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
315
345
|
await githubPost(`/repos/${ref.owner}/${ref.repo}/issues/${ref.number}/labels`, {
|
|
316
346
|
labels: [labelToAdd]
|
|
317
347
|
});
|
|
@@ -322,7 +352,7 @@ var GitHubIssuesSource = class {
|
|
|
322
352
|
body: `Pull request: ${prUrl}`
|
|
323
353
|
});
|
|
324
354
|
}
|
|
325
|
-
async completeIssue(issueId, _status, labelToRemove) {
|
|
355
|
+
async completeIssue(issueId, _status, labelToRemove, config) {
|
|
326
356
|
const ref = parseGitHubIssueNumber(issueId);
|
|
327
357
|
await githubPatch(`/repos/${ref.owner}/${ref.repo}/issues/${ref.number}`, {
|
|
328
358
|
state: "closed"
|
|
@@ -330,6 +360,14 @@ var GitHubIssuesSource = class {
|
|
|
330
360
|
if (labelToRemove) {
|
|
331
361
|
await this.removeLabel(issueId, labelToRemove);
|
|
332
362
|
}
|
|
363
|
+
if (config && config.in_progress !== config.pick_from) {
|
|
364
|
+
try {
|
|
365
|
+
await githubDelete(
|
|
366
|
+
`/repos/${ref.owner}/${ref.repo}/issues/${ref.number}/labels/${encodeURIComponent(config.in_progress)}`
|
|
367
|
+
);
|
|
368
|
+
} catch {
|
|
369
|
+
}
|
|
370
|
+
}
|
|
333
371
|
}
|
|
334
372
|
async listIssues(config) {
|
|
335
373
|
const { owner, repo } = parseOwnerRepo(config.team);
|
|
@@ -436,8 +474,10 @@ var GitLabIssuesSource = class {
|
|
|
436
474
|
name = "gitlab-issues";
|
|
437
475
|
async fetchNextIssue(config) {
|
|
438
476
|
const project = parseGitLabProject(config.team);
|
|
439
|
-
const
|
|
440
|
-
const
|
|
477
|
+
const validStates = ["opened", "closed", "all"];
|
|
478
|
+
const isOrphanDetection = !!config.pick_from && !validStates.includes(config.pick_from);
|
|
479
|
+
const filterLabels = isOrphanDetection ? [config.pick_from] : Array.isArray(config.label) ? config.label : [config.label];
|
|
480
|
+
const label = filterLabels.map((l) => encodeURIComponent(l)).join(",");
|
|
441
481
|
const path = `/projects/${project}/issues?labels=${label}&state=opened&per_page=100`;
|
|
442
482
|
const issues = await gitlabGet(path);
|
|
443
483
|
if (issues.length === 0) return null;
|
|
@@ -500,10 +540,30 @@ var GitLabIssuesSource = class {
|
|
|
500
540
|
return null;
|
|
501
541
|
}
|
|
502
542
|
}
|
|
503
|
-
async updateStatus(issueId, labelToAdd) {
|
|
543
|
+
async updateStatus(issueId, labelToAdd, config) {
|
|
504
544
|
const { project, iid } = splitIssueId(issueId);
|
|
505
545
|
const encodedProject = parseGitLabProject(project);
|
|
506
546
|
const issue = await gitlabGet(`/projects/${encodedProject}/issues/${iid}`);
|
|
547
|
+
if (config && config.in_progress !== config.pick_from) {
|
|
548
|
+
const filterLabels = Array.isArray(config.label) ? config.label : [config.label];
|
|
549
|
+
const isMovingToInProgress = labelToAdd === config.in_progress;
|
|
550
|
+
if (isMovingToInProgress) {
|
|
551
|
+
const updated2 = [.../* @__PURE__ */ new Set([...issue.labels, labelToAdd])].filter(
|
|
552
|
+
(l) => !filterLabels.includes(l)
|
|
553
|
+
);
|
|
554
|
+
await gitlabPut(`/projects/${encodedProject}/issues/${iid}`, {
|
|
555
|
+
labels: updated2.join(",")
|
|
556
|
+
});
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
const updated = [.../* @__PURE__ */ new Set([...issue.labels, ...filterLabels])].filter(
|
|
560
|
+
(l) => l !== config.in_progress
|
|
561
|
+
);
|
|
562
|
+
await gitlabPut(`/projects/${encodedProject}/issues/${iid}`, {
|
|
563
|
+
labels: updated.join(",")
|
|
564
|
+
});
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
507
567
|
const labels = [.../* @__PURE__ */ new Set([...issue.labels, labelToAdd])];
|
|
508
568
|
await gitlabPut(`/projects/${encodedProject}/issues/${iid}`, { labels: labels.join(",") });
|
|
509
569
|
}
|
|
@@ -514,11 +574,14 @@ var GitLabIssuesSource = class {
|
|
|
514
574
|
body: `Pull request: ${prUrl}`
|
|
515
575
|
});
|
|
516
576
|
}
|
|
517
|
-
async completeIssue(issueId, _status, labelToRemove) {
|
|
577
|
+
async completeIssue(issueId, _status, labelToRemove, config) {
|
|
518
578
|
const { project, iid } = splitIssueId(issueId);
|
|
519
579
|
const encodedProject = parseGitLabProject(project);
|
|
520
580
|
const issue = await gitlabGet(`/projects/${encodedProject}/issues/${iid}`);
|
|
521
|
-
|
|
581
|
+
let labels = labelToRemove ? issue.labels.filter((l) => l.toLowerCase() !== labelToRemove.toLowerCase()) : issue.labels;
|
|
582
|
+
if (config && config.in_progress !== config.pick_from) {
|
|
583
|
+
labels = labels.filter((l) => l !== config.in_progress);
|
|
584
|
+
}
|
|
522
585
|
await gitlabPut(`/projects/${encodedProject}/issues/${iid}`, {
|
|
523
586
|
state_event: "close",
|
|
524
587
|
labels: labels.join(",")
|
package/dist/index.js
CHANGED
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
startSpinner,
|
|
38
38
|
stopSpinner,
|
|
39
39
|
warn
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-JSRHJYX2.js";
|
|
41
41
|
|
|
42
42
|
// src/telemetry.ts
|
|
43
43
|
import { readFileSync } from "fs";
|
|
@@ -404,7 +404,8 @@ import { execa as execa2 } from "execa";
|
|
|
404
404
|
var WORKTREES_DIR = ".worktrees";
|
|
405
405
|
function generateBranchName(issueId, title) {
|
|
406
406
|
const slug = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").substring(0, 40).replace(/^-|-$/g, "");
|
|
407
|
-
|
|
407
|
+
const safeId = issueId.toLowerCase().replace(/[^a-z0-9-]/g, "-");
|
|
408
|
+
return `feat/${safeId}-${slug}`;
|
|
408
409
|
}
|
|
409
410
|
async function cleanupOrphanedWorktree(repoRoot, branchName) {
|
|
410
411
|
const { stdout: branchList } = await execa2("git", ["branch", "--list", branchName], {
|
|
@@ -3652,7 +3653,7 @@ var PlaneSource = class {
|
|
|
3652
3653
|
const data = await planeGet(
|
|
3653
3654
|
`/workspaces/${workspaceSlug}/projects/${projectId}/issues/?state=${stateId}&per_page=100`
|
|
3654
3655
|
);
|
|
3655
|
-
const matching = data.results.filter((i) => labelIds.every((lid) => i.labels.includes(lid)));
|
|
3656
|
+
const matching = data.results.filter((i) => i.state === stateId).filter((i) => labelIds.every((lid) => i.labels.includes(lid)));
|
|
3656
3657
|
if (matching.length === 0) return null;
|
|
3657
3658
|
const allStates = await fetchAll(
|
|
3658
3659
|
`/workspaces/${workspaceSlug}/projects/${projectId}/states/`
|
|
@@ -3756,7 +3757,7 @@ var PlaneSource = class {
|
|
|
3756
3757
|
const data = await planeGet(
|
|
3757
3758
|
`/workspaces/${workspaceSlug}/projects/${projectId}/issues/?state=${stateId}&per_page=100`
|
|
3758
3759
|
);
|
|
3759
|
-
return data.results.filter((i) => labelIds.every((lid) => i.labels.includes(lid))).map((i) => {
|
|
3760
|
+
return data.results.filter((i) => i.state === stateId).filter((i) => labelIds.every((lid) => i.labels.includes(lid))).map((i) => {
|
|
3760
3761
|
const webUrl = `${getAppUrl()}/${workspaceSlug}/projects/${projectId}/issues/${i.id}`;
|
|
3761
3762
|
return {
|
|
3762
3763
|
id: makeIssueId(workspaceSlug, projectId, i.id),
|
|
@@ -3814,6 +3815,10 @@ async function shortcutPost(path, body) {
|
|
|
3814
3815
|
async function shortcutPut(path, body) {
|
|
3815
3816
|
return shortcutFetch("PUT", path, body);
|
|
3816
3817
|
}
|
|
3818
|
+
function extractStories(result) {
|
|
3819
|
+
if (Array.isArray(result)) return result;
|
|
3820
|
+
return result.data ?? [];
|
|
3821
|
+
}
|
|
3817
3822
|
async function resolveWorkflowStateId(stateName) {
|
|
3818
3823
|
const workflows = await shortcutGet("/api/v3/workflows");
|
|
3819
3824
|
for (const workflow of workflows) {
|
|
@@ -3875,12 +3880,15 @@ var ShortcutSource = class {
|
|
|
3875
3880
|
const seen = /* @__PURE__ */ new Set();
|
|
3876
3881
|
const allStories = [];
|
|
3877
3882
|
for (const stateId of stateIds) {
|
|
3878
|
-
const searchResult = await shortcutPost(
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3883
|
+
const searchResult = await shortcutPost(
|
|
3884
|
+
"/api/v3/stories/search",
|
|
3885
|
+
{
|
|
3886
|
+
workflow_state_id: stateId,
|
|
3887
|
+
label_name: primaryLabel,
|
|
3888
|
+
archived: false
|
|
3889
|
+
}
|
|
3890
|
+
);
|
|
3891
|
+
for (const story2 of extractStories(searchResult)) {
|
|
3884
3892
|
if (!seen.has(story2.id)) {
|
|
3885
3893
|
seen.add(story2.id);
|
|
3886
3894
|
allStories.push(story2);
|
|
@@ -3976,12 +3984,15 @@ var ShortcutSource = class {
|
|
|
3976
3984
|
const seen = /* @__PURE__ */ new Set();
|
|
3977
3985
|
const allStories = [];
|
|
3978
3986
|
for (const stateId of stateIds) {
|
|
3979
|
-
const searchResult = await shortcutPost(
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3987
|
+
const searchResult = await shortcutPost(
|
|
3988
|
+
"/api/v3/stories/search",
|
|
3989
|
+
{
|
|
3990
|
+
workflow_state_id: stateId,
|
|
3991
|
+
label_name: primaryLabel,
|
|
3992
|
+
archived: false
|
|
3993
|
+
}
|
|
3994
|
+
);
|
|
3995
|
+
for (const story of extractStories(searchResult)) {
|
|
3985
3996
|
if (!seen.has(story.id)) {
|
|
3986
3997
|
seen.add(story.id);
|
|
3987
3998
|
allStories.push(story);
|
|
@@ -4410,10 +4421,10 @@ function installSignalHandlers() {
|
|
|
4410
4421
|
}
|
|
4411
4422
|
}
|
|
4412
4423
|
const revertPromises = [...activeCleanups.entries()].map(
|
|
4413
|
-
async ([issueId, { previousStatus, source }]) => {
|
|
4424
|
+
async ([issueId, { previousStatus, source, sourceConfig }]) => {
|
|
4414
4425
|
try {
|
|
4415
4426
|
await Promise.race([
|
|
4416
|
-
source.updateStatus(issueId, previousStatus),
|
|
4427
|
+
source.updateStatus(issueId, previousStatus, sourceConfig),
|
|
4417
4428
|
new Promise(
|
|
4418
4429
|
(_, reject) => setTimeout(() => reject(new Error("Revert timed out")), 5e3)
|
|
4419
4430
|
)
|
|
@@ -4483,7 +4494,7 @@ async function recoverOrphanIssues(source, config2) {
|
|
|
4483
4494
|
`Found orphan issue ${orphan.id} stuck in "${config2.source_config.in_progress}". Reverting to "${config2.source_config.pick_from}".`
|
|
4484
4495
|
);
|
|
4485
4496
|
try {
|
|
4486
|
-
await source.updateStatus(orphan.id, config2.source_config.pick_from);
|
|
4497
|
+
await source.updateStatus(orphan.id, config2.source_config.pick_from, config2.source_config);
|
|
4487
4498
|
ok(`Recovered orphan ${orphan.id}`);
|
|
4488
4499
|
} catch (err) {
|
|
4489
4500
|
error(
|
|
@@ -4643,12 +4654,12 @@ async function runSequentialLoop(config2, source, models, workspace, opts) {
|
|
|
4643
4654
|
try {
|
|
4644
4655
|
const inProgress = config2.source_config.in_progress;
|
|
4645
4656
|
kanbanEmitter.emit("issue:started", issue2.id);
|
|
4646
|
-
await source.updateStatus(issue2.id, inProgress);
|
|
4657
|
+
await source.updateStatus(issue2.id, inProgress, config2.source_config);
|
|
4647
4658
|
ok(`Moved ${issue2.id} to "${inProgress}"`);
|
|
4648
4659
|
} catch (err) {
|
|
4649
4660
|
warn(`Failed to update status: ${err instanceof Error ? err.message : String(err)}`);
|
|
4650
4661
|
}
|
|
4651
|
-
activeCleanups.set(issue2.id, { previousStatus, source });
|
|
4662
|
+
activeCleanups.set(issue2.id, { previousStatus, source, sourceConfig: config2.source_config });
|
|
4652
4663
|
let sessionResult;
|
|
4653
4664
|
try {
|
|
4654
4665
|
sessionResult = config2.workflow === "worktree" ? await runWorktreeSession(config2, issue2, logFile, session, models) : await runBranchSession(config2, issue2, logFile, session, models);
|
|
@@ -4658,7 +4669,7 @@ async function runSequentialLoop(config2, source, models, workspace, opts) {
|
|
|
4658
4669
|
`Unhandled error in session for ${issue2.id}: ${err instanceof Error ? err.message : String(err)}`
|
|
4659
4670
|
);
|
|
4660
4671
|
try {
|
|
4661
|
-
await source.updateStatus(issue2.id, previousStatus);
|
|
4672
|
+
await source.updateStatus(issue2.id, previousStatus, config2.source_config);
|
|
4662
4673
|
ok(`Reverted ${issue2.id} to "${previousStatus}"`);
|
|
4663
4674
|
} catch (revertErr) {
|
|
4664
4675
|
error(
|
|
@@ -4753,12 +4764,12 @@ async function runConcurrentLoop(config2, source, models, workspace, opts) {
|
|
|
4753
4764
|
const previousStatus = config2.source_config.pick_from;
|
|
4754
4765
|
try {
|
|
4755
4766
|
kanbanEmitter.emit("issue:started", issue2.id);
|
|
4756
|
-
await source.updateStatus(issue2.id, config2.source_config.in_progress);
|
|
4767
|
+
await source.updateStatus(issue2.id, config2.source_config.in_progress, config2.source_config);
|
|
4757
4768
|
ok(`Moved ${issue2.id} to "${config2.source_config.in_progress}"`);
|
|
4758
4769
|
} catch (err) {
|
|
4759
4770
|
warn(`Failed to update status: ${err instanceof Error ? err.message : String(err)}`);
|
|
4760
4771
|
}
|
|
4761
|
-
activeCleanups.set(issue2.id, { previousStatus, source });
|
|
4772
|
+
activeCleanups.set(issue2.id, { previousStatus, source, sourceConfig: config2.source_config });
|
|
4762
4773
|
let sessionResult;
|
|
4763
4774
|
try {
|
|
4764
4775
|
sessionResult = await runWorktreeSession(config2, issue2, logFile, session, models);
|
|
@@ -4767,7 +4778,7 @@ async function runConcurrentLoop(config2, source, models, workspace, opts) {
|
|
|
4767
4778
|
`Unhandled error in session for ${issue2.id}: ${err instanceof Error ? err.message : String(err)}`
|
|
4768
4779
|
);
|
|
4769
4780
|
try {
|
|
4770
|
-
await source.updateStatus(issue2.id, previousStatus);
|
|
4781
|
+
await source.updateStatus(issue2.id, previousStatus, config2.source_config);
|
|
4771
4782
|
ok(`Reverted ${issue2.id} to "${previousStatus}"`);
|
|
4772
4783
|
} catch (revertErr) {
|
|
4773
4784
|
error(
|
|
@@ -4882,7 +4893,7 @@ async function handleSessionResult(sessionResult, issue2, previousStatus, source
|
|
|
4882
4893
|
providerPausedSet.delete(issue2.id);
|
|
4883
4894
|
warn(`Issue ${issue2.id} killed by user.`);
|
|
4884
4895
|
try {
|
|
4885
|
-
await source.updateStatus(issue2.id, previousStatus);
|
|
4896
|
+
await source.updateStatus(issue2.id, previousStatus, config2.source_config);
|
|
4886
4897
|
ok(`Reverted ${issue2.id} to "${previousStatus}"`);
|
|
4887
4898
|
} catch (err) {
|
|
4888
4899
|
error(
|
|
@@ -4898,7 +4909,7 @@ async function handleSessionResult(sessionResult, issue2, previousStatus, source
|
|
|
4898
4909
|
providerPausedSet.delete(issue2.id);
|
|
4899
4910
|
warn(`Issue ${issue2.id} skipped by user.`);
|
|
4900
4911
|
try {
|
|
4901
|
-
await source.updateStatus(issue2.id, previousStatus);
|
|
4912
|
+
await source.updateStatus(issue2.id, previousStatus, config2.source_config);
|
|
4902
4913
|
ok(`Reverted ${issue2.id} to "${previousStatus}"`);
|
|
4903
4914
|
} catch (err) {
|
|
4904
4915
|
error(
|
|
@@ -4913,7 +4924,7 @@ async function handleSessionResult(sessionResult, issue2, previousStatus, source
|
|
|
4913
4924
|
error(`All models failed for ${issue2.id}. Reverting to "${previousStatus}".`);
|
|
4914
4925
|
logAttemptHistory(sessionResult);
|
|
4915
4926
|
try {
|
|
4916
|
-
await source.updateStatus(issue2.id, previousStatus);
|
|
4927
|
+
await source.updateStatus(issue2.id, previousStatus, config2.source_config);
|
|
4917
4928
|
ok(`Reverted ${issue2.id} to "${previousStatus}"`);
|
|
4918
4929
|
kanbanEmitter.emit("issue:reverted", issue2.id);
|
|
4919
4930
|
} catch (err) {
|
|
@@ -4928,7 +4939,7 @@ async function handleSessionResult(sessionResult, issue2, previousStatus, source
|
|
|
4928
4939
|
`Session succeeded but no PRs created for ${issue2.id}. Reverting to "${previousStatus}".`
|
|
4929
4940
|
);
|
|
4930
4941
|
try {
|
|
4931
|
-
await source.updateStatus(issue2.id, previousStatus);
|
|
4942
|
+
await source.updateStatus(issue2.id, previousStatus, config2.source_config);
|
|
4932
4943
|
ok(`Reverted ${issue2.id} to "${previousStatus}"`);
|
|
4933
4944
|
kanbanEmitter.emit("issue:reverted", issue2.id);
|
|
4934
4945
|
} catch (err) {
|
|
@@ -4956,7 +4967,7 @@ async function handleSessionResult(sessionResult, issue2, previousStatus, source
|
|
|
4956
4967
|
try {
|
|
4957
4968
|
const doneStatus = config2.source_config.done;
|
|
4958
4969
|
const labelToRemove = opts.issueId ? void 0 : getRemoveLabel(config2.source_config);
|
|
4959
|
-
await source.completeIssue(issue2.id, doneStatus, labelToRemove);
|
|
4970
|
+
await source.completeIssue(issue2.id, doneStatus, labelToRemove, config2.source_config);
|
|
4960
4971
|
ok(`Updated ${issue2.id} status to "${doneStatus}"`);
|
|
4961
4972
|
if (labelToRemove) {
|
|
4962
4973
|
ok(`Removed label "${labelToRemove}" from ${issue2.id}`);
|
|
@@ -5760,7 +5771,7 @@ Add them to your ${shell} and run: source ${shell}`));
|
|
|
5760
5771
|
if (isTTY) {
|
|
5761
5772
|
const { render } = await import("ink");
|
|
5762
5773
|
const { createElement } = await import("react");
|
|
5763
|
-
const { KanbanApp } = await import("./kanban-
|
|
5774
|
+
const { KanbanApp } = await import("./kanban-MJCCS3ZP.js");
|
|
5764
5775
|
render(createElement(KanbanApp, { config: merged }), { exitOnCtrlC: false });
|
|
5765
5776
|
}
|
|
5766
5777
|
await runLoop(merged, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tarcisiopgs/lisa",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"description": "Autonomous issue resolver",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"loop",
|
|
@@ -50,6 +50,9 @@
|
|
|
50
50
|
"vitest": "^4.0.18",
|
|
51
51
|
"ink-testing-library": "^3.0.0"
|
|
52
52
|
},
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=20"
|
|
55
|
+
},
|
|
53
56
|
"publishConfig": {
|
|
54
57
|
"access": "public"
|
|
55
58
|
},
|