@neriros/ralphy 3.10.4 → 3.10.5
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/shell/index.js +178 -43
- package/package.json +1 -1
package/dist/shell/index.js
CHANGED
|
@@ -18928,8 +18928,8 @@ import { readFileSync } from "fs";
|
|
|
18928
18928
|
import { resolve } from "path";
|
|
18929
18929
|
function getVersion() {
|
|
18930
18930
|
try {
|
|
18931
|
-
if ("3.10.
|
|
18932
|
-
return "3.10.
|
|
18931
|
+
if ("3.10.5")
|
|
18932
|
+
return "3.10.5";
|
|
18933
18933
|
} catch {}
|
|
18934
18934
|
const dirsToTry = [];
|
|
18935
18935
|
try {
|
|
@@ -80505,7 +80505,21 @@ var init_zod = __esm(() => {
|
|
|
80505
80505
|
});
|
|
80506
80506
|
|
|
80507
80507
|
// packages/workflow/src/schema.ts
|
|
80508
|
-
|
|
80508
|
+
function foldLegacyAssignee(v) {
|
|
80509
|
+
if (!v || typeof v !== "object" || Array.isArray(v))
|
|
80510
|
+
return v;
|
|
80511
|
+
const obj = v;
|
|
80512
|
+
if (!("assignee" in obj))
|
|
80513
|
+
return v;
|
|
80514
|
+
const { assignee, ...rest2 } = obj;
|
|
80515
|
+
if (rest2["filter"] === undefined) {
|
|
80516
|
+
const raw = typeof assignee === "string" ? assignee.trim() : "";
|
|
80517
|
+
const value = raw === "" || raw.toLowerCase() === "unassigned" ? "unassigned" : raw;
|
|
80518
|
+
rest2["filter"] = `assignee = ${value}`;
|
|
80519
|
+
}
|
|
80520
|
+
return rest2;
|
|
80521
|
+
}
|
|
80522
|
+
var CURRENT_WORKFLOW_VERSION = 3, MarkerSchema, SET_INDICATOR_KEYS, GetIndicatorSchema, SetIndicatorSchema, IndicatorsSchema, ProjectSchema, CommandsSchema, DEFAULT_META_ONLY_FILES, BoundariesSchema, WorkflowConfigSchema;
|
|
80509
80523
|
var init_schema = __esm(() => {
|
|
80510
80524
|
init_zod();
|
|
80511
80525
|
MarkerSchema = exports_external.discriminatedUnion("type", [
|
|
@@ -80635,9 +80649,9 @@ var init_schema = __esm(() => {
|
|
|
80635
80649
|
ignoreCiChecks: exports_external.array(exports_external.string()).default([]),
|
|
80636
80650
|
engine: exports_external.enum(["claude", "codex"]).default("claude"),
|
|
80637
80651
|
model: exports_external.enum(["haiku", "sonnet", "opus"]).default("opus"),
|
|
80638
|
-
linear: exports_external.object({
|
|
80652
|
+
linear: exports_external.preprocess(foldLegacyAssignee, exports_external.object({
|
|
80639
80653
|
team: exports_external.string().optional(),
|
|
80640
|
-
|
|
80654
|
+
filter: exports_external.string().default("assignee = me"),
|
|
80641
80655
|
postComments: exports_external.boolean().default(true),
|
|
80642
80656
|
updateEveryIterations: exports_external.number().int().nonnegative().default(10),
|
|
80643
80657
|
mentionTrigger: exports_external.boolean().default(true),
|
|
@@ -80657,7 +80671,8 @@ var init_schema = __esm(() => {
|
|
|
80657
80671
|
maxConfirmationRounds: 3
|
|
80658
80672
|
}),
|
|
80659
80673
|
indicators: IndicatorsSchema.default({})
|
|
80660
|
-
}).strict().default({
|
|
80674
|
+
}).strict()).default({
|
|
80675
|
+
filter: "assignee = me",
|
|
80661
80676
|
postComments: true,
|
|
80662
80677
|
updateEveryIterations: 10,
|
|
80663
80678
|
mentionTrigger: true,
|
|
@@ -80746,7 +80761,7 @@ var init_schema = __esm(() => {
|
|
|
80746
80761
|
var FRONTMATTER_RE, DEFAULT_WORKFLOW_MD = `---
|
|
80747
80762
|
# WORKFLOW.md schema version \u2014 managed by \`ralphy init\`. When a newer version
|
|
80748
80763
|
# ships, re-running init migrates this file and fills in the new settings.
|
|
80749
|
-
version:
|
|
80764
|
+
version: 2
|
|
80750
80765
|
|
|
80751
80766
|
project:
|
|
80752
80767
|
name: ralphy
|
|
@@ -80810,6 +80825,7 @@ preExistingErrorCheck:
|
|
|
80810
80825
|
outputCharLimit: 4000
|
|
80811
80826
|
|
|
80812
80827
|
linear:
|
|
80828
|
+
filter: assignee = me
|
|
80813
80829
|
postComments: true
|
|
80814
80830
|
updateEveryIterations: 10
|
|
80815
80831
|
mentionTrigger: true
|
|
@@ -81056,7 +81072,7 @@ function modelOptionValues() {
|
|
|
81056
81072
|
const field = findField("model");
|
|
81057
81073
|
return field && field.spec.kind === "select" ? field.spec.options.map((o) => o.value) : [];
|
|
81058
81074
|
}
|
|
81059
|
-
var PROMPT_BODY_FIELD_ID = "promptBody", REPO_LINK_FIELD_ID = "repo.link", yes = () => ({ kind: "confirm", defaultChoice: "confirm" }), no = () => ({ kind: "confirm", defaultChoice: "cancel" }), PROJECT_NAME, LINEAR_TEAM, REPO_LINK,
|
|
81075
|
+
var PROMPT_BODY_FIELD_ID = "promptBody", REPO_LINK_FIELD_ID = "repo.link", yes = () => ({ kind: "confirm", defaultChoice: "confirm" }), no = () => ({ kind: "confirm", defaultChoice: "cancel" }), PROJECT_NAME, LINEAR_TEAM, REPO_LINK, LINEAR_FILTER, QUICK_FIELDS, isOn = (id) => (answers) => answers[id] === true, CUSTOMIZED_FIELDS, COMMON_CLI_OPTIONS, FIELD_DESCRIPTIONS;
|
|
81060
81076
|
var init_fields = __esm(() => {
|
|
81061
81077
|
PROJECT_NAME = {
|
|
81062
81078
|
id: "project.name",
|
|
@@ -81079,15 +81095,15 @@ var init_fields = __esm(() => {
|
|
|
81079
81095
|
spec: yes(),
|
|
81080
81096
|
when: (answers) => typeof answers["repo.name"] === "string" && answers["repo.name"] !== ""
|
|
81081
81097
|
};
|
|
81082
|
-
|
|
81083
|
-
id: "linear.
|
|
81084
|
-
label: "Linear
|
|
81085
|
-
hint: "
|
|
81086
|
-
description: "
|
|
81087
|
-
emptyLabel: "
|
|
81088
|
-
spec: { kind: "text" }
|
|
81098
|
+
LINEAR_FILTER = {
|
|
81099
|
+
id: "linear.filter",
|
|
81100
|
+
label: "Linear filter",
|
|
81101
|
+
hint: "e.g. 'assignee = me', 'assignee = any', 'assignee = unassigned', or an email/user-id",
|
|
81102
|
+
description: "Global filter applied to every Linear ticket fetch. The only clause today is 'assignee = <value>', where <value> is 'me' (issues assigned to you), 'any' (regardless of assignee), 'unassigned', a Linear user id, or an email. Blank defaults to 'assignee = me'.",
|
|
81103
|
+
emptyLabel: "assignee = me",
|
|
81104
|
+
spec: { kind: "text", placeholder: "assignee = me" }
|
|
81089
81105
|
};
|
|
81090
|
-
QUICK_FIELDS = [PROJECT_NAME, LINEAR_TEAM, REPO_LINK,
|
|
81106
|
+
QUICK_FIELDS = [PROJECT_NAME, LINEAR_TEAM, REPO_LINK, LINEAR_FILTER];
|
|
81091
81107
|
CUSTOMIZED_FIELDS = [
|
|
81092
81108
|
PROJECT_NAME,
|
|
81093
81109
|
{
|
|
@@ -81336,7 +81352,7 @@ var init_fields = __esm(() => {
|
|
|
81336
81352
|
},
|
|
81337
81353
|
LINEAR_TEAM,
|
|
81338
81354
|
REPO_LINK,
|
|
81339
|
-
|
|
81355
|
+
LINEAR_FILTER,
|
|
81340
81356
|
{
|
|
81341
81357
|
id: "linear.postComments",
|
|
81342
81358
|
label: "Post progress comments on the Linear issue?",
|
|
@@ -81725,6 +81741,34 @@ function describeApprovalMarker(indicator) {
|
|
|
81725
81741
|
return `${phrases.slice(0, -1).join(", ")}, or ${phrases[phrases.length - 1]}`;
|
|
81726
81742
|
}
|
|
81727
81743
|
|
|
81744
|
+
// packages/workflow/src/linear-filter.ts
|
|
81745
|
+
function parseLinearFilter(filter2) {
|
|
81746
|
+
const trimmed = filter2.trim();
|
|
81747
|
+
if (trimmed === "")
|
|
81748
|
+
return { assignee: "me" };
|
|
81749
|
+
const eq = trimmed.indexOf("=");
|
|
81750
|
+
if (eq < 0) {
|
|
81751
|
+
throw new Error(`Invalid linear.filter "${filter2}": expected "<key> = <value>" (e.g. "assignee = me").`);
|
|
81752
|
+
}
|
|
81753
|
+
const key = trimmed.slice(0, eq).trim().toLowerCase();
|
|
81754
|
+
const value = trimmed.slice(eq + 1).trim();
|
|
81755
|
+
if (!SUPPORTED_KEYS.has(key)) {
|
|
81756
|
+
throw new Error(`Unrecognized linear.filter key "${key}" in "${filter2}". Supported keys: ${[...SUPPORTED_KEYS].join(", ")}.`);
|
|
81757
|
+
}
|
|
81758
|
+
const lower = value.toLowerCase();
|
|
81759
|
+
if (lower === "any")
|
|
81760
|
+
return { anyAssignee: true };
|
|
81761
|
+
if (lower === "" || lower === "unassigned")
|
|
81762
|
+
return { assignee: "unassigned" };
|
|
81763
|
+
if (lower === "me")
|
|
81764
|
+
return { assignee: "me" };
|
|
81765
|
+
return { assignee: value };
|
|
81766
|
+
}
|
|
81767
|
+
var SUPPORTED_KEYS;
|
|
81768
|
+
var init_linear_filter = __esm(() => {
|
|
81769
|
+
SUPPORTED_KEYS = new Set(["assignee"]);
|
|
81770
|
+
});
|
|
81771
|
+
|
|
81728
81772
|
// packages/workflow/src/workflow.ts
|
|
81729
81773
|
var exports_workflow = {};
|
|
81730
81774
|
__export(exports_workflow, {
|
|
@@ -81733,6 +81777,7 @@ __export(exports_workflow, {
|
|
|
81733
81777
|
renderWorkflowPrompt: () => renderWorkflowPrompt,
|
|
81734
81778
|
renderTemplate: () => renderTemplate,
|
|
81735
81779
|
parseWorkflow: () => parseWorkflow,
|
|
81780
|
+
parseLinearFilter: () => parseLinearFilter,
|
|
81736
81781
|
matchesIndicator: () => matchesIndicator,
|
|
81737
81782
|
loadWorkflow: () => loadWorkflow,
|
|
81738
81783
|
ensureWorkflow: () => ensureWorkflow,
|
|
@@ -81896,6 +81941,7 @@ var init_workflow = __esm(() => {
|
|
|
81896
81941
|
init_wizard();
|
|
81897
81942
|
init_schema();
|
|
81898
81943
|
init_default();
|
|
81944
|
+
init_linear_filter();
|
|
81899
81945
|
import_yaml2 = __toESM(require_dist(), 1);
|
|
81900
81946
|
});
|
|
81901
81947
|
|
|
@@ -83968,6 +84014,11 @@ var init_migrations = __esm(() => {
|
|
|
83968
84014
|
version: 2,
|
|
83969
84015
|
description: "Ralphy now detects the current git repo and records it in WORKFLOW.md, " + "linking it to your Linear team. Confirm the detected repo to adopt it.",
|
|
83970
84016
|
fields: ["repo.link"]
|
|
84017
|
+
},
|
|
84018
|
+
{
|
|
84019
|
+
version: 3,
|
|
84020
|
+
description: "The per-workflow `linear.assignee` setting is replaced by a global " + "`linear.filter` expression (e.g. `assignee = me`) applied to every " + "ticket fetch. Existing `assignee` values are folded in automatically; " + "note that an empty filter now defaults to `assignee = me` (it previously " + "meant unassigned-only).",
|
|
84021
|
+
fields: ["linear.filter"]
|
|
83971
84022
|
}
|
|
83972
84023
|
];
|
|
83973
84024
|
LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max2, migration) => Math.max(max2, migration.version), 0);
|
|
@@ -84055,8 +84106,8 @@ function initialValuesFromConfig(config2) {
|
|
|
84055
84106
|
values2["useWorktree"] = config2.useWorktree;
|
|
84056
84107
|
if (config2.linear.team)
|
|
84057
84108
|
values2["linear.team"] = config2.linear.team;
|
|
84058
|
-
if (config2.linear.
|
|
84059
|
-
values2["linear.
|
|
84109
|
+
if (config2.linear.filter)
|
|
84110
|
+
values2["linear.filter"] = config2.linear.filter;
|
|
84060
84111
|
return values2;
|
|
84061
84112
|
}
|
|
84062
84113
|
async function promptEditOrExit() {
|
|
@@ -101403,6 +101454,7 @@ async function parseAgentArgs(argv) {
|
|
|
101403
101454
|
...common2,
|
|
101404
101455
|
mode: "agent",
|
|
101405
101456
|
linearTeam: "",
|
|
101457
|
+
linearFilter: "",
|
|
101406
101458
|
linearAssignee: "",
|
|
101407
101459
|
pollInterval: 0,
|
|
101408
101460
|
concurrency: 0,
|
|
@@ -101423,6 +101475,7 @@ async function parseAgentArgs(argv) {
|
|
|
101423
101475
|
};
|
|
101424
101476
|
const state = emptyParseState();
|
|
101425
101477
|
let expectLinearTeam = false;
|
|
101478
|
+
let expectLinearFilter = false;
|
|
101426
101479
|
let expectLinearAssignee = false;
|
|
101427
101480
|
let expectPollInterval = false;
|
|
101428
101481
|
let expectConcurrency = false;
|
|
@@ -101436,6 +101489,11 @@ async function parseAgentArgs(argv) {
|
|
|
101436
101489
|
expectLinearTeam = false;
|
|
101437
101490
|
continue;
|
|
101438
101491
|
}
|
|
101492
|
+
if (expectLinearFilter) {
|
|
101493
|
+
result2.linearFilter = arg;
|
|
101494
|
+
expectLinearFilter = false;
|
|
101495
|
+
continue;
|
|
101496
|
+
}
|
|
101439
101497
|
if (expectLinearAssignee) {
|
|
101440
101498
|
result2.linearAssignee = arg;
|
|
101441
101499
|
expectLinearAssignee = false;
|
|
@@ -101481,6 +101539,9 @@ async function parseAgentArgs(argv) {
|
|
|
101481
101539
|
case "--linear-team":
|
|
101482
101540
|
expectLinearTeam = true;
|
|
101483
101541
|
break;
|
|
101542
|
+
case "--linear-filter":
|
|
101543
|
+
expectLinearFilter = true;
|
|
101544
|
+
break;
|
|
101484
101545
|
case "--linear-assignee":
|
|
101485
101546
|
expectLinearAssignee = true;
|
|
101486
101547
|
break;
|
|
@@ -101605,7 +101666,8 @@ var init_cli2 = __esm(() => {
|
|
|
101605
101666
|
" --log Log raw engine stream",
|
|
101606
101667
|
" --verbose Verbose output",
|
|
101607
101668
|
" --linear-team <key> Linear team key (e.g. ENG)",
|
|
101608
|
-
" --linear-
|
|
101669
|
+
" --linear-filter <expr> Global Linear filter (e.g. 'assignee = me', 'assignee = any')",
|
|
101670
|
+
" --linear-assignee <id> [deprecated] Filter by assignee; use --linear-filter instead",
|
|
101609
101671
|
" --poll-interval <s> Seconds between Linear polls (default: 60)",
|
|
101610
101672
|
" --concurrency <n> Max concurrent task loops (default: 1)",
|
|
101611
101673
|
" --worktree Run each task in its own git worktree",
|
|
@@ -102290,9 +102352,11 @@ async function fetchMentionScanIssues(apiKey, spec) {
|
|
|
102290
102352
|
const where = branches.length === 1 ? { ...branches[0] } : { or: branches };
|
|
102291
102353
|
if (spec.team)
|
|
102292
102354
|
where.team = { key: { eq: spec.team } };
|
|
102293
|
-
if (spec.assignee) {
|
|
102355
|
+
if (spec.anyAssignee || spec.assignee === "any") {} else if (spec.assignee) {
|
|
102294
102356
|
if (spec.assignee === "me")
|
|
102295
102357
|
where.assignee = { isMe: { eq: true } };
|
|
102358
|
+
else if (spec.assignee === "unassigned")
|
|
102359
|
+
where.assignee = { null: true };
|
|
102296
102360
|
else if (spec.assignee.includes("@"))
|
|
102297
102361
|
where.assignee = { email: { eq: spec.assignee } };
|
|
102298
102362
|
else
|
|
@@ -104893,6 +104957,7 @@ class AgentCoordinator {
|
|
|
104893
104957
|
ciFailed: 0,
|
|
104894
104958
|
review: 0,
|
|
104895
104959
|
mentions: mentions.length,
|
|
104960
|
+
quarantined: 0,
|
|
104896
104961
|
awaiting: awaitingCount
|
|
104897
104962
|
};
|
|
104898
104963
|
const found2 = buckets2.todo + buckets2.inProgress + buckets2.mentions + buckets2.awaiting;
|
|
@@ -104987,6 +105052,7 @@ class AgentCoordinator {
|
|
|
104987
105052
|
ciFailed: prStatus.ciFailed,
|
|
104988
105053
|
review: 0,
|
|
104989
105054
|
mentions: mentions.length,
|
|
105055
|
+
quarantined: prStatus.quarantined,
|
|
104990
105056
|
awaiting: awaitingCount
|
|
104991
105057
|
};
|
|
104992
105058
|
const found = buckets.todo + buckets.inProgress + buckets.conflicted + buckets.ciFailed + buckets.mentions + buckets.awaiting;
|
|
@@ -105182,6 +105248,7 @@ class AgentCoordinator {
|
|
|
105182
105248
|
return counts;
|
|
105183
105249
|
const preQueue = this.queue.map((q) => ({ id: q.issue.id, trigger: q.trigger }));
|
|
105184
105250
|
const preWorkers = this.workers.map((w) => ({ id: w.issueId, trigger: w.trigger }));
|
|
105251
|
+
const tracker = this.opts.prTracker;
|
|
105185
105252
|
for (const issue2 of candidates) {
|
|
105186
105253
|
if (this.workers.some((w) => w.issueId === issue2.id))
|
|
105187
105254
|
continue;
|
|
@@ -105189,6 +105256,13 @@ class AgentCoordinator {
|
|
|
105189
105256
|
continue;
|
|
105190
105257
|
if (this.queue.some((q) => q.issue.id === issue2.id))
|
|
105191
105258
|
continue;
|
|
105259
|
+
if (tracker?.isBailed(issue2.identifier) && this.errorMarkerCleared(issue2)) {
|
|
105260
|
+
await tracker.clear(issue2.identifier).catch(() => {});
|
|
105261
|
+
this.conflictNotified.delete(issue2.id);
|
|
105262
|
+
this.ciFailedNotified.delete(issue2.id);
|
|
105263
|
+
this.conflictPromoted.delete(issue2.id);
|
|
105264
|
+
this.deps.onLog(` ${issue2.identifier}: pr-tracker bail cleared (ticket back in Todo) \u2014 retrying recovery`, "cyan");
|
|
105265
|
+
}
|
|
105192
105266
|
let pr;
|
|
105193
105267
|
try {
|
|
105194
105268
|
pr = await this.deps.checkPrStatus(issue2);
|
|
@@ -105208,10 +105282,18 @@ class AgentCoordinator {
|
|
|
105208
105282
|
}
|
|
105209
105283
|
}
|
|
105210
105284
|
if (pr.status === "conflicted") {
|
|
105285
|
+
if (tracker?.isBailed(issue2.identifier)) {
|
|
105286
|
+
counts.quarantined += 1;
|
|
105287
|
+
continue;
|
|
105288
|
+
}
|
|
105289
|
+
counts.conflicted += 1;
|
|
105211
105290
|
if (this.conflictNotified.has(issue2.id))
|
|
105212
105291
|
continue;
|
|
105213
|
-
if (await this.prTrackerBail(issue2, pr.url, "conflicting"))
|
|
105292
|
+
if (await this.prTrackerBail(issue2, pr.url, "conflicting")) {
|
|
105293
|
+
counts.conflicted -= 1;
|
|
105294
|
+
counts.quarantined += 1;
|
|
105214
105295
|
continue;
|
|
105296
|
+
}
|
|
105215
105297
|
emitCapture(this.bus, "agent_conflict_detected", { issue_identifier: issue2.identifier });
|
|
105216
105298
|
this.conflictNotified.add(issue2.id);
|
|
105217
105299
|
this.deps.onLog(` ${issue2.identifier}: PR ${pr.url} conflicting \u2014 queued (conflict-fix)`, "yellow");
|
|
@@ -105230,14 +105312,21 @@ class AgentCoordinator {
|
|
|
105230
105312
|
trigger: "conflict-fix",
|
|
105231
105313
|
priority: defaultPriorityFor("conflict-fix")
|
|
105232
105314
|
});
|
|
105233
|
-
counts.conflicted += 1;
|
|
105234
105315
|
continue;
|
|
105235
105316
|
}
|
|
105236
105317
|
if (pr.status === "ci_failed") {
|
|
105318
|
+
if (tracker?.isBailed(issue2.identifier)) {
|
|
105319
|
+
counts.quarantined += 1;
|
|
105320
|
+
continue;
|
|
105321
|
+
}
|
|
105322
|
+
counts.ciFailed += 1;
|
|
105237
105323
|
if (this.ciFailedNotified.has(issue2.id))
|
|
105238
105324
|
continue;
|
|
105239
|
-
if (await this.prTrackerBail(issue2, pr.url, "ci_failed"))
|
|
105325
|
+
if (await this.prTrackerBail(issue2, pr.url, "ci_failed")) {
|
|
105326
|
+
counts.ciFailed -= 1;
|
|
105327
|
+
counts.quarantined += 1;
|
|
105240
105328
|
continue;
|
|
105329
|
+
}
|
|
105241
105330
|
emitCapture(this.bus, "agent_ci_failed_detected", { issue_identifier: issue2.identifier });
|
|
105242
105331
|
this.ciFailedNotified.add(issue2.id);
|
|
105243
105332
|
this.deps.onLog(` ${issue2.identifier}: PR ${pr.url} CI failing \u2014 queued (ci-fix)`, "yellow");
|
|
@@ -105256,7 +105345,6 @@ class AgentCoordinator {
|
|
|
105256
105345
|
trigger: "ci-fix",
|
|
105257
105346
|
priority: defaultPriorityFor("ci-fix")
|
|
105258
105347
|
});
|
|
105259
|
-
counts.ciFailed += 1;
|
|
105260
105348
|
}
|
|
105261
105349
|
}
|
|
105262
105350
|
for (const q of preQueue) {
|
|
@@ -105273,6 +105361,16 @@ class AgentCoordinator {
|
|
|
105273
105361
|
}
|
|
105274
105362
|
return counts;
|
|
105275
105363
|
}
|
|
105364
|
+
errorMarkerCleared(issue2) {
|
|
105365
|
+
const se = this.opts.setError;
|
|
105366
|
+
if (!se)
|
|
105367
|
+
return false;
|
|
105368
|
+
const wantLabels = markersOf(se).filter((m) => m.type === "label").map((m) => m.value.toLowerCase());
|
|
105369
|
+
if (wantLabels.length === 0)
|
|
105370
|
+
return false;
|
|
105371
|
+
const have = new Set(issue2.labels.map((l) => l.toLowerCase()));
|
|
105372
|
+
return !wantLabels.some((v) => have.has(v));
|
|
105373
|
+
}
|
|
105276
105374
|
async prTrackerBail(issue2, prUrl, reason) {
|
|
105277
105375
|
const tracker = this.opts.prTracker;
|
|
105278
105376
|
if (!tracker)
|
|
@@ -105652,7 +105750,12 @@ function triggerToFlowId(trigger) {
|
|
|
105652
105750
|
return "review-followup";
|
|
105653
105751
|
return "implement";
|
|
105654
105752
|
}
|
|
105655
|
-
var emptyPrStatus = () => ({
|
|
105753
|
+
var emptyPrStatus = () => ({
|
|
105754
|
+
mergeable: 0,
|
|
105755
|
+
conflicted: 0,
|
|
105756
|
+
ciFailed: 0,
|
|
105757
|
+
quarantined: 0
|
|
105758
|
+
}), emptyPollResult = () => ({
|
|
105656
105759
|
found: 0,
|
|
105657
105760
|
added: 0,
|
|
105658
105761
|
buckets: {
|
|
@@ -105662,6 +105765,7 @@ var emptyPrStatus = () => ({ mergeable: 0, conflicted: 0, ciFailed: 0 }), emptyP
|
|
|
105662
105765
|
ciFailed: 0,
|
|
105663
105766
|
review: 0,
|
|
105664
105767
|
mentions: 0,
|
|
105768
|
+
quarantined: 0,
|
|
105665
105769
|
awaiting: 0
|
|
105666
105770
|
},
|
|
105667
105771
|
prStatus: emptyPrStatus(),
|
|
@@ -105669,6 +105773,7 @@ var emptyPrStatus = () => ({ mergeable: 0, conflicted: 0, ciFailed: 0 }), emptyP
|
|
|
105669
105773
|
flow: {}
|
|
105670
105774
|
});
|
|
105671
105775
|
var init_coordinator = __esm(() => {
|
|
105776
|
+
init_types2();
|
|
105672
105777
|
init_post_task();
|
|
105673
105778
|
init_queue_order();
|
|
105674
105779
|
init_src();
|
|
@@ -106550,10 +106655,10 @@ function unionMarkers(...sets) {
|
|
|
106550
106655
|
}
|
|
106551
106656
|
return out;
|
|
106552
106657
|
}
|
|
106553
|
-
function describeIndicators(indicators, team, assignee) {
|
|
106658
|
+
function describeIndicators(indicators, team, assignee, anyAssignee) {
|
|
106554
106659
|
const parts = [];
|
|
106555
106660
|
parts.push(`team=${team ?? "*"}`);
|
|
106556
|
-
parts.push(`assignee=${assignee ?? "*"}`);
|
|
106661
|
+
parts.push(`assignee=${anyAssignee ? "any" : assignee ?? "*"}`);
|
|
106557
106662
|
if (indicators.getTodo) {
|
|
106558
106663
|
parts.push(`todo=[${indicators.getTodo.filter.map((m) => `${m.type}:${m.value}`).join(",")}]`);
|
|
106559
106664
|
}
|
|
@@ -106568,7 +106673,7 @@ var init_indicators = __esm(() => {
|
|
|
106568
106673
|
|
|
106569
106674
|
// apps/agent/src/agent/wire/linear-resolvers.ts
|
|
106570
106675
|
function createLinearResolvers(input) {
|
|
106571
|
-
const { apiKey, team, assignee, diag } = input;
|
|
106676
|
+
const { apiKey, team, assignee, anyAssignee, diag } = input;
|
|
106572
106677
|
const ticketNumbers = input.ticketNumbers ?? [];
|
|
106573
106678
|
const stateCache = new Map;
|
|
106574
106679
|
const labelCache = new Map;
|
|
@@ -106684,6 +106789,7 @@ function createLinearResolvers(input) {
|
|
|
106684
106789
|
const spec = {
|
|
106685
106790
|
team,
|
|
106686
106791
|
assignee,
|
|
106792
|
+
anyAssignee,
|
|
106687
106793
|
include,
|
|
106688
106794
|
exclude: excl,
|
|
106689
106795
|
...ticketNumbers.length > 0 ? { numbers: ticketNumbers } : {}
|
|
@@ -107417,6 +107523,7 @@ function createMentionScanner(input) {
|
|
|
107417
107523
|
cfg,
|
|
107418
107524
|
team,
|
|
107419
107525
|
assignee,
|
|
107526
|
+
anyAssignee,
|
|
107420
107527
|
indicators,
|
|
107421
107528
|
projectRoot,
|
|
107422
107529
|
useWorktree,
|
|
@@ -107440,6 +107547,7 @@ function createMentionScanner(input) {
|
|
|
107440
107547
|
candidates = await fetchMentionScanIssues(apiKey, {
|
|
107441
107548
|
team,
|
|
107442
107549
|
assignee,
|
|
107550
|
+
anyAssignee,
|
|
107443
107551
|
...ticketNumbers && ticketNumbers.length > 0 ? { numbers: ticketNumbers } : {},
|
|
107444
107552
|
indicators: {
|
|
107445
107553
|
...indicators.getTodo !== undefined ? { getTodo: indicators.getTodo } : {},
|
|
@@ -261179,7 +261287,8 @@ function buildAgentCoordinator(input) {
|
|
|
261179
261287
|
const pollInterval = args.pollInterval || cfg.pollIntervalSeconds;
|
|
261180
261288
|
const indicators = mergeIndicators(cfg.linear.indicators, args.indicators);
|
|
261181
261289
|
const team = args.linearTeam || cfg.linear.team;
|
|
261182
|
-
const assignee = args.linearAssignee || cfg.linear.
|
|
261290
|
+
const effectiveFilter = args.linearFilter || (args.linearAssignee ? `assignee = ${args.linearAssignee}` : "") || cfg.linear.filter;
|
|
261291
|
+
const { assignee, anyAssignee } = parseLinearFilter(effectiveFilter);
|
|
261183
261292
|
const ticketNumbers = resolveTicketNumbers(args.ticketTokens, team);
|
|
261184
261293
|
const excludeFromTodo = unionMarkers(indicators.setDone, indicators.setError);
|
|
261185
261294
|
const gitRunner = input.runners?.git ?? bunGitRunner;
|
|
@@ -261216,6 +261325,7 @@ function buildAgentCoordinator(input) {
|
|
|
261216
261325
|
apiKey,
|
|
261217
261326
|
team,
|
|
261218
261327
|
assignee,
|
|
261328
|
+
anyAssignee,
|
|
261219
261329
|
diag,
|
|
261220
261330
|
...ticketNumbers.length > 0 ? { ticketNumbers } : {}
|
|
261221
261331
|
});
|
|
@@ -261253,6 +261363,7 @@ function buildAgentCoordinator(input) {
|
|
|
261253
261363
|
cfg,
|
|
261254
261364
|
team,
|
|
261255
261365
|
assignee,
|
|
261366
|
+
anyAssignee,
|
|
261256
261367
|
indicators,
|
|
261257
261368
|
projectRoot,
|
|
261258
261369
|
useWorktree,
|
|
@@ -261396,7 +261507,7 @@ function buildAgentCoordinator(input) {
|
|
|
261396
261507
|
...prTracker ? { prTracker } : {}
|
|
261397
261508
|
});
|
|
261398
261509
|
coordRef.current = coord;
|
|
261399
|
-
const filterDesc = describeIndicators(indicators, team, assignee);
|
|
261510
|
+
const filterDesc = describeIndicators(indicators, team, assignee, anyAssignee);
|
|
261400
261511
|
const runBaselineGateOnce = createBaselineGateRunner({
|
|
261401
261512
|
args,
|
|
261402
261513
|
cfg,
|
|
@@ -261432,6 +261543,7 @@ function buildAgentCoordinator(input) {
|
|
|
261432
261543
|
};
|
|
261433
261544
|
}
|
|
261434
261545
|
var init_wire = __esm(() => {
|
|
261546
|
+
init_workflow();
|
|
261435
261547
|
init_src2();
|
|
261436
261548
|
init_coordinator2();
|
|
261437
261549
|
init_linear();
|
|
@@ -262753,6 +262865,19 @@ function AgentMode({
|
|
|
262753
262865
|
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
|
|
262754
262866
|
color: pollStatus.lastPrStatus.ciFailed > 0 ? "red" : "white",
|
|
262755
262867
|
children: pollStatus.lastPrStatus.ciFailed
|
|
262868
|
+
}, undefined, false, undefined, this),
|
|
262869
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
|
|
262870
|
+
dimColor: true,
|
|
262871
|
+
children: "\xB7"
|
|
262872
|
+
}, undefined, false, undefined, this),
|
|
262873
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
|
|
262874
|
+
dimColor: true,
|
|
262875
|
+
children: "quarantined"
|
|
262876
|
+
}, undefined, false, undefined, this),
|
|
262877
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
|
|
262878
|
+
color: pollStatus.lastPrStatus.quarantined > 0 ? "magenta" : "white",
|
|
262879
|
+
bold: true,
|
|
262880
|
+
children: pollStatus.lastPrStatus.quarantined
|
|
262756
262881
|
}, undefined, false, undefined, this)
|
|
262757
262882
|
]
|
|
262758
262883
|
}, undefined, true, undefined, this)
|
|
@@ -263779,18 +263904,23 @@ function buildBuckets(indicators) {
|
|
|
263779
263904
|
{ label: "auto-merge", indicator: indicators.getAutoMerge, exclude: [] }
|
|
263780
263905
|
];
|
|
263781
263906
|
}
|
|
263782
|
-
async function fetchBucketIssues(apiKey, bucket, team, assignee, ticketNumbers) {
|
|
263907
|
+
async function fetchBucketIssues(apiKey, bucket, team, assignee, anyAssignee, ticketNumbers) {
|
|
263783
263908
|
if (!bucket.indicator || bucket.indicator.filter.length === 0)
|
|
263784
263909
|
return [];
|
|
263785
263910
|
const spec = {
|
|
263786
263911
|
team,
|
|
263787
263912
|
assignee,
|
|
263913
|
+
anyAssignee,
|
|
263788
263914
|
include: bucket.indicator.filter,
|
|
263789
263915
|
exclude: bucket.exclude,
|
|
263790
263916
|
...ticketNumbers.length > 0 ? { numbers: ticketNumbers } : {}
|
|
263791
263917
|
};
|
|
263792
263918
|
return fetchOpenIssues(apiKey, spec);
|
|
263793
263919
|
}
|
|
263920
|
+
function resolveLinearFilter(filterOverride, assigneeOverride, configFilter) {
|
|
263921
|
+
const effective = filterOverride || (assigneeOverride ? `assignee = ${assigneeOverride}` : "") || configFilter;
|
|
263922
|
+
return parseLinearFilter(effective);
|
|
263923
|
+
}
|
|
263794
263924
|
function formatReviewCell(prUrl, count) {
|
|
263795
263925
|
if (!prUrl)
|
|
263796
263926
|
return "-";
|
|
@@ -263837,13 +263967,13 @@ function backlogRankByIssueId(issues) {
|
|
|
263837
263967
|
ordered.forEach((o, i) => rankById.set(o.id, i));
|
|
263838
263968
|
return rankById;
|
|
263839
263969
|
}
|
|
263840
|
-
async function fetchAndPrintLinear(apiKey, buckets, team, assignee, cwd2, runner, ignoreCiChecks = [], checks3 = false, review = false, ticketNumbers = []) {
|
|
263970
|
+
async function fetchAndPrintLinear(apiKey, buckets, team, assignee, anyAssignee, cwd2, runner, ignoreCiChecks = [], checks3 = false, review = false, ticketNumbers = []) {
|
|
263841
263971
|
const bucketResults = await Promise.all(buckets.map(async (bucket) => {
|
|
263842
263972
|
if (!bucket.indicator || bucket.indicator.filter.length === 0) {
|
|
263843
263973
|
return { bucket, issues: [], error: null };
|
|
263844
263974
|
}
|
|
263845
263975
|
try {
|
|
263846
|
-
const issues = await fetchBucketIssues(apiKey, bucket, team, assignee, ticketNumbers);
|
|
263976
|
+
const issues = await fetchBucketIssues(apiKey, bucket, team, assignee, anyAssignee, ticketNumbers);
|
|
263847
263977
|
return { bucket, issues, error: null };
|
|
263848
263978
|
} catch (err) {
|
|
263849
263979
|
return {
|
|
@@ -263969,6 +264099,7 @@ async function runList(input) {
|
|
|
263969
264099
|
identifier: name,
|
|
263970
264100
|
projectRoot,
|
|
263971
264101
|
linearTeamOverride: input.linearTeamOverride,
|
|
264102
|
+
linearFilterOverride: input.linearFilterOverride,
|
|
263972
264103
|
linearAssigneeOverride: input.linearAssigneeOverride
|
|
263973
264104
|
});
|
|
263974
264105
|
return;
|
|
@@ -263979,7 +264110,7 @@ async function runList(input) {
|
|
|
263979
264110
|
const apiKey = process.env["LINEAR_API_KEY"];
|
|
263980
264111
|
const indicators = cfg.linear.indicators;
|
|
263981
264112
|
const team = input.linearTeamOverride || cfg.linear.team;
|
|
263982
|
-
const assignee = input.linearAssigneeOverride
|
|
264113
|
+
const { assignee, anyAssignee } = resolveLinearFilter(input.linearFilterOverride, input.linearAssigneeOverride, cfg.linear.filter);
|
|
263983
264114
|
const buckets = buildBuckets(indicators);
|
|
263984
264115
|
const anyConfigured = buckets.some((b2) => b2.indicator && b2.indicator.filter.length > 0);
|
|
263985
264116
|
if (!anyConfigured) {
|
|
@@ -264014,13 +264145,12 @@ Linear: LINEAR_API_KEY not set \u2014 cannot fetch tickets. Configured buckets:
|
|
|
264014
264145
|
process.stdout.write(`
|
|
264015
264146
|
team: ${team}
|
|
264016
264147
|
`);
|
|
264017
|
-
|
|
264018
|
-
process.stdout.write(`assignee: ${assignee}
|
|
264148
|
+
process.stdout.write(`assignee: ${anyAssignee ? "any" : assignee ?? "*"}
|
|
264019
264149
|
`);
|
|
264020
264150
|
if (ticketNumbers.length > 0)
|
|
264021
264151
|
process.stdout.write(`ticket: ${ticketNumbers.join(", ")}
|
|
264022
264152
|
`);
|
|
264023
|
-
await fetchAndPrintLinear(apiKey, buckets, team, assignee, projectRoot, localCmdRunner, cfg.ignoreCiChecks, input.checks, input.review, ticketNumbers);
|
|
264153
|
+
await fetchAndPrintLinear(apiKey, buckets, team, assignee, anyAssignee, projectRoot, localCmdRunner, cfg.ignoreCiChecks, input.checks, input.review, ticketNumbers);
|
|
264024
264154
|
}
|
|
264025
264155
|
function normalizeIdentifier(input) {
|
|
264026
264156
|
let parsed;
|
|
@@ -264077,8 +264207,10 @@ function markerMatches(issue2, marker) {
|
|
|
264077
264207
|
}
|
|
264078
264208
|
return false;
|
|
264079
264209
|
}
|
|
264080
|
-
function assigneeMatches(issue2, assignee) {
|
|
264081
|
-
if (
|
|
264210
|
+
function assigneeMatches(issue2, assignee, anyAssignee) {
|
|
264211
|
+
if (anyAssignee)
|
|
264212
|
+
return true;
|
|
264213
|
+
if (!assignee || assignee === "unassigned")
|
|
264082
264214
|
return issue2.assignee === null;
|
|
264083
264215
|
const a = issue2.assignee;
|
|
264084
264216
|
if (!a)
|
|
@@ -264101,7 +264233,8 @@ async function runListDebug(input) {
|
|
|
264101
264233
|
const cfg = await loadRalphyConfig(projectRoot);
|
|
264102
264234
|
const indicators = cfg.linear.indicators;
|
|
264103
264235
|
const team = input.linearTeamOverride || cfg.linear.team;
|
|
264104
|
-
const assignee = input.linearAssigneeOverride
|
|
264236
|
+
const { assignee, anyAssignee } = resolveLinearFilter(input.linearFilterOverride, input.linearAssigneeOverride, cfg.linear.filter);
|
|
264237
|
+
const assigneeLabel = anyAssignee ? "any" : assignee ?? "*";
|
|
264105
264238
|
const normalized = normalizeIdentifier(identifier);
|
|
264106
264239
|
if (!normalized) {
|
|
264107
264240
|
process.stdout.write(`Error: '${identifier}' does not look like a Linear identifier (expected e.g. DOO-6, or a local change name beginning with one).
|
|
@@ -264141,8 +264274,8 @@ Per-bucket diagnostics:
|
|
|
264141
264274
|
if (team && issue2.team?.key && issue2.team.key !== team) {
|
|
264142
264275
|
reasons.push(`team mismatch: issue=${issue2.team.key}, config=${team}`);
|
|
264143
264276
|
}
|
|
264144
|
-
if (!assigneeMatches(issue2, assignee)) {
|
|
264145
|
-
reasons.push(`assignee mismatch: issue=${issue2.assignee ? issue2.assignee.email ?? issue2.assignee.id : "unassigned"}, config=${
|
|
264277
|
+
if (!assigneeMatches(issue2, assignee, anyAssignee)) {
|
|
264278
|
+
reasons.push(`assignee mismatch: issue=${issue2.assignee ? issue2.assignee.email ?? issue2.assignee.id : "unassigned"}, config=${assigneeLabel}`);
|
|
264146
264279
|
}
|
|
264147
264280
|
const includeMatches = bucket.indicator.filter.some((m2) => markerMatches(issue2, m2));
|
|
264148
264281
|
if (!includeMatches) {
|
|
@@ -264175,6 +264308,7 @@ Per-bucket diagnostics:
|
|
|
264175
264308
|
var localCmdRunner;
|
|
264176
264309
|
var init_list = __esm(() => {
|
|
264177
264310
|
init_context();
|
|
264311
|
+
init_workflow();
|
|
264178
264312
|
init_worktree();
|
|
264179
264313
|
init_config();
|
|
264180
264314
|
init_linear();
|
|
@@ -264488,6 +264622,7 @@ async function main3(argv) {
|
|
|
264488
264622
|
await runWithContext(createDefaultContext({ layout, args }), async () => {
|
|
264489
264623
|
await runList2({
|
|
264490
264624
|
linearTeamOverride: args.linearTeam,
|
|
264625
|
+
linearFilterOverride: args.linearFilter,
|
|
264491
264626
|
linearAssigneeOverride: args.linearAssignee,
|
|
264492
264627
|
debug: args.debug,
|
|
264493
264628
|
name: args.name,
|