@mestreyoda/fabrica 0.2.35 → 0.2.37
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 +145 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -113905,8 +113905,8 @@ import fsSync from "node:fs";
|
|
|
113905
113905
|
import path5 from "node:path";
|
|
113906
113906
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
113907
113907
|
function getCurrentVersion() {
|
|
113908
|
-
if ("0.2.
|
|
113909
|
-
return "0.2.
|
|
113908
|
+
if ("0.2.37") {
|
|
113909
|
+
return "0.2.37";
|
|
113910
113910
|
}
|
|
113911
113911
|
try {
|
|
113912
113912
|
const pkgPath = path5.join(THIS_DIR, "..", "..", "package.json");
|
|
@@ -131742,9 +131742,18 @@ async function defaultValidateDeveloperDone(opts) {
|
|
|
131742
131742
|
);
|
|
131743
131743
|
return { ok: true, prStatus };
|
|
131744
131744
|
} catch (error48) {
|
|
131745
|
+
let prStatus;
|
|
131746
|
+
try {
|
|
131747
|
+
const fallbackPr = await opts.provider.getPrStatus(opts.issueId);
|
|
131748
|
+
if (fallbackPr.url && fallbackPr.state !== "merged" && fallbackPr.state !== "closed") {
|
|
131749
|
+
prStatus = fallbackPr;
|
|
131750
|
+
}
|
|
131751
|
+
} catch {
|
|
131752
|
+
}
|
|
131745
131753
|
return {
|
|
131746
131754
|
ok: false,
|
|
131747
|
-
reason: error48 instanceof Error ? error48.message : "developer_validation_failed"
|
|
131755
|
+
reason: error48 instanceof Error ? error48.message : "developer_validation_failed",
|
|
131756
|
+
prStatus
|
|
131748
131757
|
};
|
|
131749
131758
|
}
|
|
131750
131759
|
}
|
|
@@ -131836,9 +131845,24 @@ async function applyWorkerResult(opts) {
|
|
|
131836
131845
|
if (!validation.ok) {
|
|
131837
131846
|
const validationReason = validation.reason ?? "developer_validation_failed";
|
|
131838
131847
|
const feedbackQueueLabel = getQueueLabels(workflow, "developer").find((label) => isFeedbackState(workflow, label)) ?? "To Improve";
|
|
131848
|
+
const convergenceIssueRuntime = validation.prStatus ? {
|
|
131849
|
+
...context2.issueRuntime,
|
|
131850
|
+
currentPrNumber: validation.prStatus.number ?? context2.issueRuntime?.currentPrNumber ?? null,
|
|
131851
|
+
currentPrUrl: validation.prStatus.url ?? context2.issueRuntime?.currentPrUrl ?? null,
|
|
131852
|
+
currentPrState: validation.prStatus.state ?? context2.issueRuntime?.currentPrState ?? null
|
|
131853
|
+
} : context2.issueRuntime;
|
|
131854
|
+
if (validation.prStatus) {
|
|
131855
|
+
await persistDeveloperPrBinding({
|
|
131856
|
+
workspaceDir: opts.workspaceDir,
|
|
131857
|
+
projectSlug: context2.projectSlug,
|
|
131858
|
+
issueId: context2.issueId,
|
|
131859
|
+
prStatus: validation.prStatus
|
|
131860
|
+
}).catch(() => {
|
|
131861
|
+
});
|
|
131862
|
+
}
|
|
131839
131863
|
const convergence = decidePostPrConvergence({
|
|
131840
131864
|
workflow,
|
|
131841
|
-
issueRuntime:
|
|
131865
|
+
issueRuntime: convergenceIssueRuntime,
|
|
131842
131866
|
reason: validationReason,
|
|
131843
131867
|
feedbackQueueLabel
|
|
131844
131868
|
});
|
|
@@ -148927,6 +148951,103 @@ async function checkProjects(dataDir) {
|
|
|
148927
148951
|
return results;
|
|
148928
148952
|
}
|
|
148929
148953
|
|
|
148954
|
+
// lib/setup/doctor-run.ts
|
|
148955
|
+
async function runIssueDoctor(opts) {
|
|
148956
|
+
const data = await readProjects(opts.workspacePath);
|
|
148957
|
+
const project = data.projects[opts.projectSlug];
|
|
148958
|
+
if (!project) throw new Error(`Project not found: ${opts.projectSlug}`);
|
|
148959
|
+
const issueRuntime = getIssueRuntime(project, opts.issueId) ?? null;
|
|
148960
|
+
const hasArtifact = Boolean(
|
|
148961
|
+
issueRuntime?.currentPrUrl || issueRuntime?.currentPrNumber || issueRuntime?.artifactOfRecord
|
|
148962
|
+
);
|
|
148963
|
+
const { provider } = await createProvider({
|
|
148964
|
+
repo: project.repo,
|
|
148965
|
+
provider: project.provider,
|
|
148966
|
+
providerProfile: project.providerProfile,
|
|
148967
|
+
runCommand: opts.runCommand,
|
|
148968
|
+
pluginConfig: opts.pluginConfig
|
|
148969
|
+
});
|
|
148970
|
+
let prStatus = null;
|
|
148971
|
+
try {
|
|
148972
|
+
const pr = await provider.getPrStatus(opts.issueId);
|
|
148973
|
+
if (pr.url || pr.number) prStatus = pr;
|
|
148974
|
+
} catch {
|
|
148975
|
+
prStatus = null;
|
|
148976
|
+
}
|
|
148977
|
+
let issue2 = null;
|
|
148978
|
+
try {
|
|
148979
|
+
issue2 = await provider.getIssue(opts.issueId);
|
|
148980
|
+
} catch {
|
|
148981
|
+
issue2 = null;
|
|
148982
|
+
}
|
|
148983
|
+
const convergenceCause = issueRuntime?.lastConvergenceCause ?? null;
|
|
148984
|
+
const convergenceAction = issueRuntime?.lastConvergenceAction ?? null;
|
|
148985
|
+
const retryCount = issueRuntime?.lastConvergenceRetryCount ?? 0;
|
|
148986
|
+
const convergenceReason = issueRuntime?.lastConvergenceReason ?? issueRuntime?.inconclusiveCompletionReason ?? null;
|
|
148987
|
+
const summaryParts = [
|
|
148988
|
+
hasArtifact ? "artifact_present" : "artifact_missing",
|
|
148989
|
+
convergenceCause ? `cause=${convergenceCause}` : "cause=none",
|
|
148990
|
+
convergenceAction ? `action=${convergenceAction}` : "action=none",
|
|
148991
|
+
retryCount ? `retries=${retryCount}` : "retries=0",
|
|
148992
|
+
prStatus?.state ? `pr=${prStatus.state}` : "pr=unknown"
|
|
148993
|
+
];
|
|
148994
|
+
const likelyNextAction = (() => {
|
|
148995
|
+
if (convergenceAction === "escalate_human") return "human_intervention";
|
|
148996
|
+
if (convergenceCause === "invalid_qa_evidence") return "repair_qa_evidence";
|
|
148997
|
+
if (convergenceCause === "merge_conflict") return "repair_merge_conflict";
|
|
148998
|
+
if (convergenceCause === "stalled_with_artifact") return "force_convergence_review";
|
|
148999
|
+
if (hasArtifact) return "post_pr_convergence";
|
|
149000
|
+
return "redispatch_or_investigate";
|
|
149001
|
+
})();
|
|
149002
|
+
return {
|
|
149003
|
+
projectSlug: project.slug,
|
|
149004
|
+
projectName: project.name,
|
|
149005
|
+
issueId: opts.issueId,
|
|
149006
|
+
issueRuntime,
|
|
149007
|
+
hasArtifact,
|
|
149008
|
+
convergence: {
|
|
149009
|
+
cause: convergenceCause,
|
|
149010
|
+
action: convergenceAction,
|
|
149011
|
+
retryCount,
|
|
149012
|
+
reason: convergenceReason,
|
|
149013
|
+
at: issueRuntime?.lastConvergenceAt ?? null
|
|
149014
|
+
},
|
|
149015
|
+
pr: prStatus ? {
|
|
149016
|
+
url: prStatus.url ?? null,
|
|
149017
|
+
state: prStatus.state ?? null,
|
|
149018
|
+
number: prStatus.number ?? null,
|
|
149019
|
+
mergeable: prStatus.mergeable ?? null,
|
|
149020
|
+
currentIssueMatch: prStatus.currentIssueMatch ?? null,
|
|
149021
|
+
sourceBranch: prStatus.sourceBranch ?? null
|
|
149022
|
+
} : null,
|
|
149023
|
+
issue: issue2 ? {
|
|
149024
|
+
url: issue2.web_url ?? null,
|
|
149025
|
+
state: issue2.state ?? null,
|
|
149026
|
+
labels: issue2.labels ?? [],
|
|
149027
|
+
title: issue2.title ?? null
|
|
149028
|
+
} : null,
|
|
149029
|
+
recommendation: {
|
|
149030
|
+
summary: summaryParts.join(" | "),
|
|
149031
|
+
likelyNextAction
|
|
149032
|
+
}
|
|
149033
|
+
};
|
|
149034
|
+
}
|
|
149035
|
+
function formatIssueDoctor(result) {
|
|
149036
|
+
const lines = [
|
|
149037
|
+
`Issue run doctor \u2014 ${result.projectSlug}#${result.issueId}`,
|
|
149038
|
+
` Artifact: ${result.hasArtifact ? "yes" : "no"}`,
|
|
149039
|
+
` PR: ${result.pr?.url ?? "n/a"} (${result.pr?.state ?? "unknown"})`,
|
|
149040
|
+
` Issue: ${result.issue?.url ?? "n/a"} (${result.issue?.state ?? "unknown"})`,
|
|
149041
|
+
` Labels: ${result.issue?.labels?.join(", ") ?? "n/a"}`,
|
|
149042
|
+
` Convergence cause: ${result.convergence.cause ?? "none"}`,
|
|
149043
|
+
` Convergence action: ${result.convergence.action ?? "none"}`,
|
|
149044
|
+
` Retry count: ${result.convergence.retryCount}`,
|
|
149045
|
+
` Last reason: ${result.convergence.reason ?? "n/a"}`,
|
|
149046
|
+
` Suggested next action: ${result.recommendation.likelyNextAction}`
|
|
149047
|
+
];
|
|
149048
|
+
return lines.join("\n");
|
|
149049
|
+
}
|
|
149050
|
+
|
|
148930
149051
|
// lib/observability/metrics.ts
|
|
148931
149052
|
init_constants();
|
|
148932
149053
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
@@ -149509,6 +149630,26 @@ function registerCli(program, ctx) {
|
|
|
149509
149630
|
${result.checks.length} checks: ${result.errors} errors, ${result.warnings} warnings`);
|
|
149510
149631
|
process.exit(result.errors > 0 ? 1 : 0);
|
|
149511
149632
|
});
|
|
149633
|
+
doctor.command("issue").description("Inspect one Fabrica issue/run with convergence and PR context").requiredOption("-p, --project <slug>", "Project slug").requiredOption("-i, --issue <id>", "Issue number").option("-w, --workspace <path>", "Workspace directory").option("--json", "Emit machine-readable JSON").action(async (opts) => {
|
|
149634
|
+
const workspaceDir = requireWorkspaceDir2(ctx.runtime, opts.workspace);
|
|
149635
|
+
const issueId = Number.parseInt(String(opts.issue), 10);
|
|
149636
|
+
if (!Number.isFinite(issueId)) {
|
|
149637
|
+
console.error(`Invalid issue id: ${opts.issue}`);
|
|
149638
|
+
process.exit(1);
|
|
149639
|
+
}
|
|
149640
|
+
const result = await runIssueDoctor({
|
|
149641
|
+
workspacePath: workspaceDir,
|
|
149642
|
+
projectSlug: String(opts.project),
|
|
149643
|
+
issueId,
|
|
149644
|
+
runCommand: ctx.runCommand,
|
|
149645
|
+
pluginConfig: ctx.pluginConfig
|
|
149646
|
+
});
|
|
149647
|
+
if (opts.json) {
|
|
149648
|
+
console.log(JSON.stringify(result, null, 2));
|
|
149649
|
+
return;
|
|
149650
|
+
}
|
|
149651
|
+
console.log(formatIssueDoctor(result));
|
|
149652
|
+
});
|
|
149512
149653
|
doctor.option("-w, --workspace <path>", "Workspace directory").option("--fix", "Apply fixes for detected issues").action(async (opts) => {
|
|
149513
149654
|
const workspaceDir = requireWorkspaceDir2(ctx.runtime, opts.workspace);
|
|
149514
149655
|
const result = await runDoctor({ workspacePath: workspaceDir, fix: opts.fix ?? false, pluginConfig: ctx.pluginConfig });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mestreyoda/fabrica",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.37",
|
|
4
4
|
"description": "Autonomous software engineering pipeline for OpenClaw. Turns ideas into deployed code via intake, dispatch, review, test, and merge.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|