@fieldwangai/agentflow 0.1.117 → 0.1.119
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/bin/lib/ui-server.mjs
CHANGED
|
@@ -3337,9 +3337,11 @@ function prdWorkflowShareLinkSummary(record, shareToken, publicBaseUrl, userId =
|
|
|
3337
3337
|
workflowShare: token,
|
|
3338
3338
|
});
|
|
3339
3339
|
const base = String(publicBaseUrl || "").replace(/\/+$/, "");
|
|
3340
|
+
const shortUrl = `${base}/w/${encodeURIComponent(token)}`;
|
|
3340
3341
|
return {
|
|
3341
3342
|
tapdId: String(record.tapdId || ""),
|
|
3342
3343
|
url: `${base}/workspace?${query.toString()}`,
|
|
3344
|
+
shortUrl,
|
|
3343
3345
|
active: true,
|
|
3344
3346
|
readOnly: true,
|
|
3345
3347
|
createdAt: record.shareCreatedAt || "",
|
|
@@ -7776,7 +7778,7 @@ function prdWorkflowReviewIdFromRequest(tapdId, payload = {}, durability = "temp
|
|
|
7776
7778
|
return prdWorkflowSafeStateId(["review", tapdId, stageHead, digest].filter(Boolean).join("-")).slice(0, 64);
|
|
7777
7779
|
}
|
|
7778
7780
|
|
|
7779
|
-
function prdWorkflowReviewArtifactKey(tapdId, payload = {}
|
|
7781
|
+
function prdWorkflowReviewArtifactKey(tapdId, payload = {}) {
|
|
7780
7782
|
const explicit = String(payload.artifactKey || payload.artifact_key || "").trim();
|
|
7781
7783
|
if (explicit) return explicit.slice(0, 500);
|
|
7782
7784
|
const issueKey = prdWorkflowSafeStateId(
|
|
@@ -7798,7 +7800,6 @@ function prdWorkflowReviewArtifactKey(tapdId, payload = {}, durability = "tempor
|
|
|
7798
7800
|
issueKey,
|
|
7799
7801
|
platform,
|
|
7800
7802
|
stage,
|
|
7801
|
-
String(durability || "temporary").trim().toLowerCase() || "temporary",
|
|
7802
7803
|
].join(":").slice(0, 500);
|
|
7803
7804
|
}
|
|
7804
7805
|
|
|
@@ -9094,16 +9095,54 @@ function prdWorkflowNormalizeStoredRuntimeEvent(tapdId, event = {}) {
|
|
|
9094
9095
|
const kind = String(item.kind || "").trim();
|
|
9095
9096
|
const hasReviewUrl = /\/api\/prd-workflow\/review\//.test(String(item.url || item.href || ""));
|
|
9096
9097
|
if (!kind && !hasReviewUrl) return item;
|
|
9098
|
+
const originalKey = String(item.key || item.artifactKey || item.artifact_key || "").trim();
|
|
9099
|
+
const logicalKey = /^prd-review:/i.test(originalKey)
|
|
9100
|
+
? originalKey.replace(/:(?:temporary|durable)$/i, "")
|
|
9101
|
+
: originalKey && !/^(?:temporary-)?review:https?:/i.test(originalKey)
|
|
9102
|
+
? originalKey
|
|
9103
|
+
: prdWorkflowReviewArtifactKey(tapdId, out);
|
|
9097
9104
|
return {
|
|
9098
9105
|
...item,
|
|
9106
|
+
key: logicalKey,
|
|
9099
9107
|
persistence: item.persistence || "runtime",
|
|
9100
9108
|
source: item.source && typeof item.source === "object" && !Array.isArray(item.source) ? item.source : sourceArtifact,
|
|
9101
9109
|
};
|
|
9102
9110
|
};
|
|
9103
9111
|
if (Array.isArray(out.artifacts)) out.artifacts = out.artifacts.map(normalizeReviewRef);
|
|
9104
9112
|
if (Array.isArray(out.links)) out.links = out.links.map(normalizeReviewRef);
|
|
9105
|
-
|
|
9113
|
+
const reviewArtifactKey = String(
|
|
9114
|
+
out.artifacts?.[0]?.key
|
|
9115
|
+
|| out.links?.[0]?.key
|
|
9116
|
+
|| "",
|
|
9117
|
+
).trim();
|
|
9118
|
+
out.aggregateByStage = false;
|
|
9119
|
+
if (reviewArtifactKey) out.id = `review-link:${reviewArtifactKey}`;
|
|
9120
|
+
}
|
|
9121
|
+
const canonicalStage = prdWorkflowRuntimeEventCanonicalStage(out);
|
|
9122
|
+
const canonicalAction = prdWorkflowRuntimeEventCanonicalAction(canonicalStage);
|
|
9123
|
+
const rawStage = String(out.stageKey || out.stage_key || out.stage || "").trim();
|
|
9124
|
+
if (canonicalStage) {
|
|
9125
|
+
if (rawStage && rawStage !== canonicalStage) out.sourceStage = out.sourceStage || rawStage;
|
|
9126
|
+
out.stage = canonicalStage;
|
|
9127
|
+
out.stageKey = canonicalStage;
|
|
9128
|
+
}
|
|
9129
|
+
if (canonicalAction && (type === "workflow-marker" || String(out.action || "") === "mark")) {
|
|
9130
|
+
out.action = canonicalAction;
|
|
9131
|
+
out.actionId = canonicalAction;
|
|
9132
|
+
}
|
|
9133
|
+
if (type === "workflow-report" && !out.action && (
|
|
9134
|
+
String(out.artifactScope || out.artifact_scope || out.scope || "").toLowerCase() === "global"
|
|
9135
|
+
|| out.aggregateByStage === false
|
|
9136
|
+
|| out.aggregate_by_stage === false
|
|
9137
|
+
)) {
|
|
9138
|
+
out.auxiliary = true;
|
|
9139
|
+
}
|
|
9140
|
+
out.artifacts = prdWorkflowRuntimeOwnedArtifacts(out.artifacts, canonicalStage);
|
|
9141
|
+
out.links = prdWorkflowRuntimeOwnedArtifacts(out.links, canonicalStage);
|
|
9106
9142
|
out.tapdId = String(out.tapdId || out.tapd_id || tapdId || "");
|
|
9143
|
+
const canonicalId = prdWorkflowRuntimeEventId(out);
|
|
9144
|
+
if (out.id && out.id !== canonicalId) out.sourceEventId = out.sourceEventId || out.id;
|
|
9145
|
+
out.id = canonicalId;
|
|
9107
9146
|
return out;
|
|
9108
9147
|
}
|
|
9109
9148
|
|
|
@@ -9156,15 +9195,63 @@ function prdWorkflowRuntimeEventStatus(type, status) {
|
|
|
9156
9195
|
function prdWorkflowRuntimeEventCanonicalStage(event = {}) {
|
|
9157
9196
|
const issue = String(event.issueKey || event.issue_key || event.issue || "").trim();
|
|
9158
9197
|
const action = String(event.action || event.actionId || event.action_id || "").trim();
|
|
9159
|
-
const rawStage = String(event.
|
|
9160
|
-
const
|
|
9198
|
+
const rawStage = String(event.stageKey || event.stage_key || event.stage || event.phase || event.code || action || "").trim();
|
|
9199
|
+
const normalizedStage = rawStage.toLowerCase();
|
|
9200
|
+
const tokens = [rawStage, action, event.code, event.type]
|
|
9201
|
+
.map((value) => String(value || "").trim().toLowerCase())
|
|
9202
|
+
.filter(Boolean);
|
|
9161
9203
|
if (issue) {
|
|
9162
|
-
if (
|
|
9163
|
-
if (
|
|
9204
|
+
if (/^(?:issue-plan|issue-gitlab|implementation|bugfix|integration):/.test(normalizedStage)) return rawStage;
|
|
9205
|
+
if (tokens.some((value) => /^code-review(?::|$)/.test(value) || value === "code_review_completed")) {
|
|
9206
|
+
return `implementation:${issue}`;
|
|
9207
|
+
}
|
|
9208
|
+
if (tokens.some((value) => /plan_draft_local|submit-plan|plan-doc/.test(value) || ["plan_mr", "plan_approved", "issue-plan"].includes(value))) {
|
|
9209
|
+
return `issue-plan:${issue}`;
|
|
9210
|
+
}
|
|
9211
|
+
if (tokens.some((value) => /gitlab_issue_missing|ensure-gitlab-issue/.test(value) || value === "issue-gitlab")) {
|
|
9212
|
+
return `issue-gitlab:${issue}`;
|
|
9213
|
+
}
|
|
9214
|
+
if (tokens.some((value) => ["fix_mr", "bugfix"].includes(value))) return `bugfix:${issue}`;
|
|
9215
|
+
if (tokens.some((value) => ["integration_mr", "integrated", "integration"].includes(value))) return `integration:${issue}`;
|
|
9216
|
+
if (tokens.some((value) => [
|
|
9217
|
+
"implementation_mr",
|
|
9218
|
+
"implementation_done",
|
|
9219
|
+
"implementation_merged",
|
|
9220
|
+
"impl_mr",
|
|
9221
|
+
"impl_done",
|
|
9222
|
+
"impl_merged",
|
|
9223
|
+
"runtime_marker",
|
|
9224
|
+
"status",
|
|
9225
|
+
"implementation",
|
|
9226
|
+
].includes(value))) {
|
|
9227
|
+
return `implementation:${issue}`;
|
|
9228
|
+
}
|
|
9164
9229
|
}
|
|
9165
9230
|
return rawStage || action;
|
|
9166
9231
|
}
|
|
9167
9232
|
|
|
9233
|
+
function prdWorkflowRuntimeEventCanonicalAction(stage = "") {
|
|
9234
|
+
const prefix = String(stage || "").trim().split(":", 1)[0];
|
|
9235
|
+
return ["issue-plan", "issue-gitlab", "implementation", "bugfix", "integration"].includes(prefix)
|
|
9236
|
+
? prefix
|
|
9237
|
+
: "";
|
|
9238
|
+
}
|
|
9239
|
+
|
|
9240
|
+
function prdWorkflowRuntimeOwnedArtifacts(values, stage = "") {
|
|
9241
|
+
if (!Array.isArray(values)) return values;
|
|
9242
|
+
const ownsOnlyChangedArtifact = /^(?:issue-plan|implementation|bugfix|integration):/.test(String(stage || ""));
|
|
9243
|
+
if (!ownsOnlyChangedArtifact) return values;
|
|
9244
|
+
return values.filter((item) => {
|
|
9245
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return true;
|
|
9246
|
+
const kind = String(item.kind || item.type || "").trim().toLowerCase();
|
|
9247
|
+
const key = String(item.key || item.artifactKey || item.artifact_key || "").trim().toLowerCase();
|
|
9248
|
+
return !(
|
|
9249
|
+
["gitlab-epic", "gitlab-issue"].includes(kind)
|
|
9250
|
+
|| /^(?:gitlab-epic|gitlab-issue):/.test(key)
|
|
9251
|
+
);
|
|
9252
|
+
});
|
|
9253
|
+
}
|
|
9254
|
+
|
|
9168
9255
|
function prdWorkflowRuntimeEventId(event = {}) {
|
|
9169
9256
|
const stage = prdWorkflowRuntimeEventCanonicalStage(event);
|
|
9170
9257
|
const action = String(event.action || event.actionId || event.action_id || "").trim();
|
|
@@ -9201,8 +9288,13 @@ function prdWorkflowCompactRuntimeValue(value, maxChars = 24000) {
|
|
|
9201
9288
|
function prdWorkflowNormalizeRuntimeEvent(tapdId, event = {}) {
|
|
9202
9289
|
const now = new Date().toISOString();
|
|
9203
9290
|
const type = String(event.type || event.kind || "workflow-event").trim().slice(0, 120);
|
|
9204
|
-
const
|
|
9205
|
-
const
|
|
9291
|
+
const rawAction = String(event.action || event.actionId || event.action_id || "").trim().slice(0, 160);
|
|
9292
|
+
const rawStage = String(event.stageKey || event.stage_key || event.stage || event.phase || rawAction || "").trim().slice(0, 160);
|
|
9293
|
+
const stage = prdWorkflowRuntimeEventCanonicalStage(event).slice(0, 160);
|
|
9294
|
+
const canonicalAction = prdWorkflowRuntimeEventCanonicalAction(stage);
|
|
9295
|
+
const action = canonicalAction && (type === "workflow-marker" || rawAction === "mark")
|
|
9296
|
+
? canonicalAction
|
|
9297
|
+
: rawAction;
|
|
9206
9298
|
const scope = String(event.scope || "").trim().slice(0, 80);
|
|
9207
9299
|
const platform = String(event.platform || "").trim().slice(0, 80);
|
|
9208
9300
|
const status = prdWorkflowRuntimeEventStatus(type, event.status);
|
|
@@ -9228,6 +9320,7 @@ function prdWorkflowNormalizeRuntimeEvent(tapdId, event = {}) {
|
|
|
9228
9320
|
authority,
|
|
9229
9321
|
updatedAt: now,
|
|
9230
9322
|
};
|
|
9323
|
+
if (rawStage && rawStage !== stage) entry.sourceStage = rawStage;
|
|
9231
9324
|
const sourceEventId = String(event.id || event.eventId || event.event_id || "").trim();
|
|
9232
9325
|
if (sourceEventId && sourceEventId !== entry.id) entry.sourceEventId = sourceEventId.slice(0, 160);
|
|
9233
9326
|
if (action) {
|
|
@@ -9236,8 +9329,10 @@ function prdWorkflowNormalizeRuntimeEvent(tapdId, event = {}) {
|
|
|
9236
9329
|
}
|
|
9237
9330
|
if (stage) {
|
|
9238
9331
|
entry.stage = stage;
|
|
9239
|
-
entry.stageKey =
|
|
9332
|
+
entry.stageKey = stage;
|
|
9240
9333
|
}
|
|
9334
|
+
entry.artifacts = prdWorkflowRuntimeOwnedArtifacts(entry.artifacts, stage);
|
|
9335
|
+
entry.links = prdWorkflowRuntimeOwnedArtifacts(entry.links, stage);
|
|
9241
9336
|
if (scope) entry.scope = scope;
|
|
9242
9337
|
if (platform) entry.platform = platform;
|
|
9243
9338
|
if (!entry.createdAt) entry.createdAt = event.startedAt || now;
|
|
@@ -9256,26 +9351,50 @@ function prdWorkflowNormalizeRuntimeEvent(tapdId, event = {}) {
|
|
|
9256
9351
|
function prdWorkflowMergeRuntimeEventArrays(left, right) {
|
|
9257
9352
|
const out = [];
|
|
9258
9353
|
const seen = new Map();
|
|
9354
|
+
const aliasesFor = (value) => {
|
|
9355
|
+
if (typeof value === "string") return [`value:${value}`];
|
|
9356
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return [];
|
|
9357
|
+
const aliases = [];
|
|
9358
|
+
const explicitKey = String(value.key || value.artifactKey || value.artifact_key || "").trim();
|
|
9359
|
+
if (explicitKey) aliases.push(`key:${explicitKey}`);
|
|
9360
|
+
const rawUrl = String(
|
|
9361
|
+
value.canonicalUrl
|
|
9362
|
+
|| value.canonical_url
|
|
9363
|
+
|| value.href
|
|
9364
|
+
|| value.url
|
|
9365
|
+
|| "",
|
|
9366
|
+
).trim();
|
|
9367
|
+
if (rawUrl) {
|
|
9368
|
+
try {
|
|
9369
|
+
const parsed = new URL(rawUrl, "http://agentflow.local");
|
|
9370
|
+
aliases.push(`url:${parsed.origin}${parsed.pathname.replace(/\/+$/, "") || "/"}`);
|
|
9371
|
+
} catch {
|
|
9372
|
+
aliases.push(`url:${rawUrl.split(/[?#]/)[0].replace(/\/+$/, "")}`);
|
|
9373
|
+
}
|
|
9374
|
+
}
|
|
9375
|
+
const itemPath = String(value.path || "").trim();
|
|
9376
|
+
if (itemPath) aliases.push(`path:${itemPath}`);
|
|
9377
|
+
if (!aliases.length) {
|
|
9378
|
+
try {
|
|
9379
|
+
aliases.push(`value:${JSON.stringify(value)}`);
|
|
9380
|
+
} catch {
|
|
9381
|
+
aliases.push(`value:${String(value)}`);
|
|
9382
|
+
}
|
|
9383
|
+
}
|
|
9384
|
+
return aliases;
|
|
9385
|
+
};
|
|
9259
9386
|
for (const value of [...(Array.isArray(left) ? left : []), ...(Array.isArray(right) ? right : [])]) {
|
|
9260
9387
|
if (value == null) continue;
|
|
9261
|
-
const
|
|
9262
|
-
|
|
9263
|
-
: "";
|
|
9264
|
-
let key = explicitKey ? `key:${explicitKey}` : "";
|
|
9265
|
-
try {
|
|
9266
|
-
if (!key) key = typeof value === "string" ? value : JSON.stringify(value);
|
|
9267
|
-
} catch {
|
|
9268
|
-
key = String(value);
|
|
9269
|
-
}
|
|
9270
|
-
const index = seen.get(key);
|
|
9388
|
+
const aliases = aliasesFor(value);
|
|
9389
|
+
const index = aliases.map((alias) => seen.get(alias)).find((candidate) => candidate != null);
|
|
9271
9390
|
if (index == null) {
|
|
9272
|
-
|
|
9391
|
+
const nextIndex = out.length;
|
|
9273
9392
|
out.push(value);
|
|
9393
|
+
aliases.forEach((alias) => seen.set(alias, nextIndex));
|
|
9274
9394
|
continue;
|
|
9275
9395
|
}
|
|
9276
|
-
|
|
9277
|
-
|
|
9278
|
-
}
|
|
9396
|
+
out[index] = value;
|
|
9397
|
+
aliasesFor(value).forEach((alias) => seen.set(alias, index));
|
|
9279
9398
|
}
|
|
9280
9399
|
return out;
|
|
9281
9400
|
}
|
|
@@ -11096,6 +11215,40 @@ export function startUiServer({
|
|
|
11096
11215
|
isAdmin: Boolean(authUser.isAdmin),
|
|
11097
11216
|
adminOwnerId: String(url.searchParams.get("adminOwnerId") || "").trim(),
|
|
11098
11217
|
} : {};
|
|
11218
|
+
if (req.method === "GET" && url.pathname.startsWith("/w/")) {
|
|
11219
|
+
const parts = url.pathname.split("/").filter(Boolean);
|
|
11220
|
+
if (parts.length !== 2) {
|
|
11221
|
+
res.writeHead(404);
|
|
11222
|
+
res.end("Not found");
|
|
11223
|
+
return;
|
|
11224
|
+
}
|
|
11225
|
+
let shareToken = "";
|
|
11226
|
+
try {
|
|
11227
|
+
shareToken = decodeURIComponent(parts[1] || "");
|
|
11228
|
+
} catch {
|
|
11229
|
+
res.writeHead(404);
|
|
11230
|
+
res.end("Not found");
|
|
11231
|
+
return;
|
|
11232
|
+
}
|
|
11233
|
+
const record = getPrdWorkflowCollaborationByShareToken(shareToken);
|
|
11234
|
+
if (!record) {
|
|
11235
|
+
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
|
|
11236
|
+
res.end("Workflow share link is invalid or has been revoked");
|
|
11237
|
+
return;
|
|
11238
|
+
}
|
|
11239
|
+
const query = new URLSearchParams({
|
|
11240
|
+
view: "workflow",
|
|
11241
|
+
tapdId: String(record.tapdId || ""),
|
|
11242
|
+
workflowShare: shareToken,
|
|
11243
|
+
});
|
|
11244
|
+
res.writeHead(302, {
|
|
11245
|
+
Location: `/workspace?${query.toString()}`,
|
|
11246
|
+
"Cache-Control": "no-store",
|
|
11247
|
+
"Referrer-Policy": "no-referrer",
|
|
11248
|
+
});
|
|
11249
|
+
res.end();
|
|
11250
|
+
return;
|
|
11251
|
+
}
|
|
11099
11252
|
if (req.method === "GET" && url.pathname === "/api/auth/session-token") {
|
|
11100
11253
|
if (!authUser?.userId) {
|
|
11101
11254
|
json(res, 401, { error: "Unauthorized" });
|
|
@@ -11418,7 +11571,7 @@ export function startUiServer({
|
|
|
11418
11571
|
json(res, 200, {
|
|
11419
11572
|
ok: true,
|
|
11420
11573
|
snapshot,
|
|
11421
|
-
...(workflowShare ? { workflowShare, shareUrl: workflowShare.url } : {}),
|
|
11574
|
+
...(workflowShare ? { workflowShare, shareUrl: workflowShare.shortUrl || workflowShare.url } : {}),
|
|
11422
11575
|
});
|
|
11423
11576
|
} catch (e) {
|
|
11424
11577
|
json(res, 500, { error: (e && e.message) || String(e) });
|
|
@@ -11607,7 +11760,7 @@ export function startUiServer({
|
|
|
11607
11760
|
json(res, 200, {
|
|
11608
11761
|
ok: true,
|
|
11609
11762
|
snapshot: withDiagnostic,
|
|
11610
|
-
...(workflowShare ? { workflowShare, shareUrl: workflowShare.url } : {}),
|
|
11763
|
+
...(workflowShare ? { workflowShare, shareUrl: workflowShare.shortUrl || workflowShare.url } : {}),
|
|
11611
11764
|
});
|
|
11612
11765
|
} catch (e) {
|
|
11613
11766
|
json(res, 500, { error: (e && e.message) || String(e) });
|
|
@@ -12332,7 +12485,15 @@ export function startUiServer({
|
|
|
12332
12485
|
const shortUrl = shortLink?.shortUrl || "";
|
|
12333
12486
|
const displayUrl = shortUrl || reviewUrl;
|
|
12334
12487
|
const durability = review.durability || "temporary";
|
|
12335
|
-
const artifactKey = prdWorkflowReviewArtifactKey(tapdId, payload
|
|
12488
|
+
const artifactKey = prdWorkflowReviewArtifactKey(tapdId, payload);
|
|
12489
|
+
const reviewStageKey = prdWorkflowRuntimeEventCanonicalStage(payload)
|
|
12490
|
+
|| payload.stageKey
|
|
12491
|
+
|| payload.stage_key
|
|
12492
|
+
|| payload.stage
|
|
12493
|
+
|| "review";
|
|
12494
|
+
const reviewMrUrl = String(payload.mrUrl || payload.mr_url || "").trim();
|
|
12495
|
+
const reviewMrIid = String(payload.mrIid || payload.mr_iid || "").trim();
|
|
12496
|
+
const reviewCommitSha = String(payload.commitSha || payload.commit_sha || "").trim();
|
|
12336
12497
|
const reviewSource = review.source && typeof review.source === "object" && !Array.isArray(review.source)
|
|
12337
12498
|
? review.source
|
|
12338
12499
|
: { kind: durability === "durable" ? "ai-doc" : "local-draft", durability };
|
|
@@ -12351,19 +12512,32 @@ export function startUiServer({
|
|
|
12351
12512
|
canonicalUrl: reviewUrl,
|
|
12352
12513
|
shortUrl,
|
|
12353
12514
|
expiresAt: review.expiresAt || "",
|
|
12515
|
+
issueKey: payload.issueKey || payload.issue_key || "",
|
|
12516
|
+
platform: payload.platform || "",
|
|
12517
|
+
stageKey: reviewStageKey,
|
|
12518
|
+
...(reviewMrUrl ? { mrUrl: reviewMrUrl } : {}),
|
|
12519
|
+
...(reviewMrIid ? { mrIid: reviewMrIid } : {}),
|
|
12520
|
+
...(reviewCommitSha ? { commitSha: reviewCommitSha } : {}),
|
|
12354
12521
|
};
|
|
12355
12522
|
const event = prdWorkflowAppendRuntimeEvent(scopedRoot, tapdId, {
|
|
12523
|
+
id: `review-link:${artifactKey}`,
|
|
12356
12524
|
type: "review-link",
|
|
12357
12525
|
auxiliary: true,
|
|
12526
|
+
aggregateByStage: false,
|
|
12358
12527
|
conflictOnArtifact: false,
|
|
12359
12528
|
truth: "runtime_event",
|
|
12360
12529
|
persistence: "runtime",
|
|
12361
12530
|
action: payload.action || payload.actionId || "",
|
|
12362
|
-
stage:
|
|
12531
|
+
stage: reviewStageKey,
|
|
12532
|
+
stageKey: reviewStageKey,
|
|
12363
12533
|
title: payload.title || "临时 Markdown Review",
|
|
12364
12534
|
detail: "已生成临时 Markdown review 链接",
|
|
12365
12535
|
status: "current",
|
|
12366
12536
|
issueKey: payload.issueKey || payload.issue_key || "",
|
|
12537
|
+
platform: payload.platform || "",
|
|
12538
|
+
...(reviewMrUrl ? { mrUrl: reviewMrUrl } : {}),
|
|
12539
|
+
...(reviewMrIid ? { mrIid: reviewMrIid } : {}),
|
|
12540
|
+
...(reviewCommitSha ? { commitSha: reviewCommitSha } : {}),
|
|
12367
12541
|
idempotencyKey,
|
|
12368
12542
|
durability,
|
|
12369
12543
|
sourceArtifact: reviewSource,
|
|
@@ -12380,6 +12554,12 @@ export function startUiServer({
|
|
|
12380
12554
|
durability,
|
|
12381
12555
|
source: reviewSource,
|
|
12382
12556
|
expiresAt: review.expiresAt || "",
|
|
12557
|
+
issueKey: artifact.issueKey,
|
|
12558
|
+
platform: artifact.platform,
|
|
12559
|
+
stageKey: artifact.stageKey,
|
|
12560
|
+
...(artifact.mrUrl ? { mrUrl: artifact.mrUrl } : {}),
|
|
12561
|
+
...(artifact.mrIid ? { mrIid: artifact.mrIid } : {}),
|
|
12562
|
+
...(artifact.commitSha ? { commitSha: artifact.commitSha } : {}),
|
|
12383
12563
|
}],
|
|
12384
12564
|
reviewId: review.id,
|
|
12385
12565
|
reviewShortCode: shortLink?.shortCode || "",
|
|
@@ -233,6 +233,7 @@ export function normalizeWorkflowReport(payload = {}) {
|
|
|
233
233
|
workflow,
|
|
234
234
|
workflowKey: workflow.key,
|
|
235
235
|
aggregateByStage: Boolean(action),
|
|
236
|
+
auxiliary: !action,
|
|
236
237
|
conflictOnArtifact: payload.conflictOnArtifact === true || payload.conflict_on_artifact === true,
|
|
237
238
|
artifactScope: action ? "action" : "global",
|
|
238
239
|
...(action ? {
|
|
@@ -395,16 +396,51 @@ export function mergeWorkflowArtifacts(baseArtifacts = [], runtimeEvents = []) {
|
|
|
395
396
|
export function mergeWorkflowArtifactLists(left = [], right = [], defaultScope = "action") {
|
|
396
397
|
const out = [];
|
|
397
398
|
const seen = new Map();
|
|
399
|
+
const normalizedUrl = (value) => {
|
|
400
|
+
const raw = cleanString(value, 4000);
|
|
401
|
+
if (!raw) return "";
|
|
402
|
+
try {
|
|
403
|
+
const parsed = new URL(raw, "http://agentflow.local");
|
|
404
|
+
return `${parsed.origin}${parsed.pathname.replace(/\/+$/, "") || "/"}`;
|
|
405
|
+
} catch {
|
|
406
|
+
return raw.split(/[?#]/)[0].replace(/\/+$/, "");
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
const artifactAliases = (artifact) => {
|
|
410
|
+
const aliases = [];
|
|
411
|
+
const explicitKey = cleanString(
|
|
412
|
+
artifact?.key || artifact?.artifactKey || artifact?.artifact_key,
|
|
413
|
+
500,
|
|
414
|
+
);
|
|
415
|
+
if (explicitKey) aliases.push(`key:${explicitKey}`);
|
|
416
|
+
const url = normalizedUrl(
|
|
417
|
+
artifact?.canonicalUrl
|
|
418
|
+
|| artifact?.canonical_url
|
|
419
|
+
|| artifact?.href
|
|
420
|
+
|| artifact?.url,
|
|
421
|
+
);
|
|
422
|
+
if (url) aliases.push(`url:${url}`);
|
|
423
|
+
const artifactPath = cleanString(artifact?.path, 4000);
|
|
424
|
+
if (artifactPath) aliases.push(`path:${artifactPath}`);
|
|
425
|
+
return aliases;
|
|
426
|
+
};
|
|
398
427
|
const add = (artifact) => {
|
|
399
428
|
if (!artifact || typeof artifact !== "object" || Array.isArray(artifact)) return;
|
|
429
|
+
const rawAliases = artifactAliases(artifact);
|
|
400
430
|
const normalized = normalizeWorkflowArtifact(artifact, out.length, defaultScope);
|
|
401
|
-
const
|
|
402
|
-
|
|
431
|
+
const aliases = uniqueValues([
|
|
432
|
+
...rawAliases,
|
|
433
|
+
...artifactAliases(normalized),
|
|
434
|
+
...(!rawAliases.length ? [`value:${normalized.type}:${normalized.title}`] : []),
|
|
435
|
+
]);
|
|
436
|
+
const existing = aliases.map((alias) => seen.get(alias)).find((value) => value != null);
|
|
403
437
|
if (existing == null) {
|
|
404
|
-
|
|
438
|
+
const index = out.length;
|
|
405
439
|
out.push(normalized);
|
|
440
|
+
aliases.forEach((alias) => seen.set(alias, index));
|
|
406
441
|
} else {
|
|
407
442
|
out[existing] = { ...out[existing], ...normalized };
|
|
443
|
+
artifactAliases(out[existing]).forEach((alias) => seen.set(alias, existing));
|
|
408
444
|
}
|
|
409
445
|
};
|
|
410
446
|
for (const artifact of Array.isArray(left) ? left : []) add(artifact);
|