@autoclawd/autoclawd 1.1.6 → 1.1.7
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/dist/index.js +53 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31,7 +31,8 @@ var LinearConfigSchema = z.object({
|
|
|
31
31
|
statuses: z.array(z.string()).default(["Todo"]),
|
|
32
32
|
assignToMe: z.boolean().default(true),
|
|
33
33
|
doneStatus: z.string().default("Done"),
|
|
34
|
-
inProgressStatus: z.string().default("In Progress")
|
|
34
|
+
inProgressStatus: z.string().default("In Progress"),
|
|
35
|
+
inReviewStatus: z.string().default("In Review")
|
|
35
36
|
});
|
|
36
37
|
var GitHubConfigSchema = z.object({
|
|
37
38
|
token: z.string(),
|
|
@@ -328,6 +329,20 @@ async function fetchTicket(client, identifier) {
|
|
|
328
329
|
url: issue.url
|
|
329
330
|
};
|
|
330
331
|
}
|
|
332
|
+
async function fetchTicketStatus(client, identifier) {
|
|
333
|
+
const match = identifier.match(/^([A-Za-z]+)-(\d+)$/);
|
|
334
|
+
if (!match) return void 0;
|
|
335
|
+
const [, teamKey, numStr] = match;
|
|
336
|
+
const team = await client.team(teamKey.toUpperCase());
|
|
337
|
+
const result = await team.issues({
|
|
338
|
+
filter: { number: { eq: parseInt(numStr) } },
|
|
339
|
+
first: 1
|
|
340
|
+
});
|
|
341
|
+
const issue = result.nodes[0];
|
|
342
|
+
if (!issue) return void 0;
|
|
343
|
+
const state = await issue.state;
|
|
344
|
+
return state?.name;
|
|
345
|
+
}
|
|
331
346
|
async function claimTicket(client, config, ticketId) {
|
|
332
347
|
log.info(`Claiming ticket, moving to "${config.linear.inProgressStatus}"`);
|
|
333
348
|
await retry(async () => {
|
|
@@ -342,17 +357,23 @@ async function claimTicket(client, config, ticketId) {
|
|
|
342
357
|
await client.updateIssue(ticketId, { stateId: inProgress.id });
|
|
343
358
|
}, { label: "Linear claim", retryIf: isTransientError });
|
|
344
359
|
}
|
|
345
|
-
async function
|
|
360
|
+
async function reviewTicket(client, config, ticketId, comment) {
|
|
346
361
|
await retry(async () => {
|
|
347
362
|
await client.createComment({ issueId: ticketId, body: comment });
|
|
348
363
|
const team = await client.team(config.linear.teamId);
|
|
349
364
|
const states = await team.states();
|
|
350
|
-
const
|
|
351
|
-
const
|
|
352
|
-
if (
|
|
353
|
-
await client.updateIssue(ticketId, { stateId:
|
|
365
|
+
const target = config.linear.inReviewStatus.toLowerCase();
|
|
366
|
+
const review = states.nodes.find((s) => s.name.toLowerCase() === target);
|
|
367
|
+
if (review) {
|
|
368
|
+
await client.updateIssue(ticketId, { stateId: review.id });
|
|
369
|
+
} else {
|
|
370
|
+
const doneTarget = config.linear.doneStatus.toLowerCase();
|
|
371
|
+
const done = states.nodes.find((s) => s.name.toLowerCase() === doneTarget);
|
|
372
|
+
if (done) {
|
|
373
|
+
await client.updateIssue(ticketId, { stateId: done.id });
|
|
374
|
+
}
|
|
354
375
|
}
|
|
355
|
-
}, { label: "Linear
|
|
376
|
+
}, { label: "Linear review", retryIf: isTransientError });
|
|
356
377
|
}
|
|
357
378
|
async function addBranchLabel(client, ticketId, branchName) {
|
|
358
379
|
try {
|
|
@@ -1590,8 +1611,28 @@ async function executeTicket(opts) {
|
|
|
1590
1611
|
let workDir;
|
|
1591
1612
|
let container;
|
|
1592
1613
|
try {
|
|
1593
|
-
|
|
1594
|
-
|
|
1614
|
+
if (ticket.baseBranch) {
|
|
1615
|
+
const parentMatch = ticket.baseBranch.match(/^autoclawd\/([A-Z]+-\d+)/i);
|
|
1616
|
+
if (parentMatch) {
|
|
1617
|
+
const parentId = parentMatch[1].toUpperCase();
|
|
1618
|
+
const parentStatus = await fetchTicketStatus(linearClient, parentId);
|
|
1619
|
+
if (parentStatus) {
|
|
1620
|
+
const statusLower = parentStatus.toLowerCase();
|
|
1621
|
+
const reviewTarget = config.linear.inReviewStatus.toLowerCase();
|
|
1622
|
+
const doneTarget = config.linear.doneStatus.toLowerCase();
|
|
1623
|
+
if (statusLower !== reviewTarget && statusLower !== doneTarget) {
|
|
1624
|
+
log.ticket(ticket.identifier, `Parent ${parentId} is "${parentStatus}" \u2014 waiting for "${config.linear.inReviewStatus}" or "${config.linear.doneStatus}"`);
|
|
1625
|
+
return {
|
|
1626
|
+
ticketId: ticket.identifier,
|
|
1627
|
+
success: false,
|
|
1628
|
+
error: `REQUEUE: parent ${parentId} is "${parentStatus}", not yet in review or done`,
|
|
1629
|
+
iterations: 0
|
|
1630
|
+
};
|
|
1631
|
+
}
|
|
1632
|
+
log.ticket(ticket.identifier, `Parent ${parentId} is "${parentStatus}" \u2014 proceeding`);
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1595
1636
|
const { owner: repoOwner, repo: repoName } = parseRepoUrl(ticket.repoUrl);
|
|
1596
1637
|
const { created: repoCreated } = await ensureRepoExists(octokit, {
|
|
1597
1638
|
owner: repoOwner,
|
|
@@ -1653,6 +1694,8 @@ async function executeTicket(opts) {
|
|
|
1653
1694
|
}
|
|
1654
1695
|
}
|
|
1655
1696
|
execSync3(`git checkout -B ${branchName} --`, { cwd: workDir, stdio: "pipe" });
|
|
1697
|
+
await claimTicket(linearClient, config, ticket.id);
|
|
1698
|
+
log.ticket(ticket.identifier, `Claimed \u2014 ${ticket.repoUrl}`);
|
|
1656
1699
|
container = await createContainer({
|
|
1657
1700
|
dockerConfig: docker2,
|
|
1658
1701
|
workspacePath: workDir,
|
|
@@ -1792,7 +1835,7 @@ async function executeTicket(opts) {
|
|
|
1792
1835
|
}
|
|
1793
1836
|
}
|
|
1794
1837
|
}
|
|
1795
|
-
await
|
|
1838
|
+
await reviewTicket(linearClient, config, ticket.id, `PR opened: ${pr.url}`);
|
|
1796
1839
|
await addBranchLabel(linearClient, ticket.id, branchName);
|
|
1797
1840
|
log.success(`${ticket.identifier} done \u2014 ${pr.url}`);
|
|
1798
1841
|
const result = {
|