@zq-silk/yui 2.1.0 → 2.3.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.
- package/README.md +8 -2
- package/dist/cli/commandCatalog.js +32 -6
- package/dist/cli/commandDiscovery.js +4 -1
- package/dist/cli/interactionPolicy.js +4 -0
- package/dist/cli.js +23 -3078
- package/dist/commands/taskCommands.js +84 -28
- package/dist/commands/taskIntegrationCommands.js +8 -17
- package/dist/commands/taskUpstreamCommands.js +3 -1
- package/dist/context/runContextPack.js +132 -5
- package/dist/context/sourceRunContext.js +4 -2
- package/dist/context/taskContext.js +6 -1
- package/dist/controlPlaneCli.js +3099 -0
- package/dist/controller/clientRuntime.js +3 -2
- package/dist/controller/fileSchedulerStoreAdapter.js +19 -6
- package/dist/controller/jobControl.js +21 -0
- package/dist/executor/agentExecutor.js +1 -1
- package/dist/executor/effectiveLaunch.js +18 -5
- package/dist/executor/fileRoleLaunchPlanner.js +15 -19
- package/dist/integration/gitIntegrationService.js +58 -82
- package/dist/job/jobCleanupInspection.js +67 -0
- package/dist/message/messageContinuation.js +7 -2
- package/dist/nativeAgent/agent.js +176 -74
- package/dist/nativeAgent/cliDemo.js +37 -0
- package/dist/nativeAgent/codingTools.js +11 -0
- package/dist/nativeAgent/commandTool.js +215 -0
- package/dist/nativeAgent/compactionDemo.js +158 -0
- package/dist/nativeAgent/composition.js +71 -0
- package/dist/nativeAgent/context/budget.js +44 -0
- package/dist/nativeAgent/context/index.js +339 -0
- package/dist/nativeAgent/context/providerCompressor.js +103 -0
- package/dist/nativeAgent/demo.js +12 -1
- package/dist/nativeAgent/evaluation/cases.js +38 -0
- package/dist/nativeAgent/evaluation/checks.js +91 -0
- package/dist/nativeAgent/evaluation/demo.js +19 -0
- package/dist/nativeAgent/evaluation/files.js +54 -0
- package/dist/nativeAgent/evaluation/fixture.js +36 -0
- package/dist/nativeAgent/evaluation/index.js +239 -0
- package/dist/nativeAgent/executionOwner.js +209 -0
- package/dist/nativeAgent/filePatterns.js +170 -0
- package/dist/nativeAgent/fileToolsSupport.js +202 -0
- package/dist/nativeAgent/index.js +13 -0
- package/dist/nativeAgent/interaction/cli.js +358 -0
- package/dist/nativeAgent/interaction/contracts.js +1 -0
- package/dist/nativeAgent/interaction/index.js +3 -0
- package/dist/nativeAgent/interaction/memoryDemo.js +115 -0
- package/dist/nativeAgent/interaction/renderer.js +34 -0
- package/dist/nativeAgent/localSafety.js +258 -0
- package/dist/nativeAgent/model/anthropicMessages.js +204 -0
- package/dist/nativeAgent/model/chatCompletions.js +210 -0
- package/dist/nativeAgent/model/errors.js +47 -0
- package/dist/nativeAgent/model/gateway.js +423 -0
- package/dist/nativeAgent/model/index.js +7 -0
- package/dist/nativeAgent/model/observationAdapter.js +21 -0
- package/dist/nativeAgent/model/protocols.js +19 -0
- package/dist/nativeAgent/model/responses.js +263 -0
- package/dist/nativeAgent/model/types.js +1 -0
- package/dist/nativeAgent/model/wire.js +73 -0
- package/dist/nativeAgent/observability/index.js +220 -0
- package/dist/nativeAgent/product/catalog.js +82 -0
- package/dist/nativeAgent/product/config.js +295 -0
- package/dist/nativeAgent/product/facts.js +30 -0
- package/dist/nativeAgent/product/index.js +62 -0
- package/dist/nativeAgent/product/location.js +44 -0
- package/dist/nativeAgent/product/runtime.js +276 -0
- package/dist/nativeAgent/product/storage.js +49 -0
- package/dist/nativeAgent/product/tools.js +47 -0
- package/dist/nativeAgent/product/transport.js +54 -0
- package/dist/nativeAgent/projectGuidance/index.js +425 -0
- package/dist/nativeAgent/searchTools.js +305 -0
- package/dist/nativeAgent/session/backends.js +293 -0
- package/dist/nativeAgent/session/catalog.js +97 -0
- package/dist/nativeAgent/session/catalogDemo.js +87 -0
- package/dist/nativeAgent/session/contracts.js +1 -0
- package/dist/nativeAgent/session/format.js +269 -0
- package/dist/nativeAgent/session/index.js +5 -0
- package/dist/nativeAgent/session/location.js +36 -0
- package/dist/nativeAgent/session/sqliteFormat.js +134 -0
- package/dist/nativeAgent/session/store.js +248 -0
- package/dist/nativeAgent/textTools.js +270 -133
- package/dist/nativeAgent/toolManager/executor.js +290 -0
- package/dist/nativeAgent/toolManager/index.js +4 -0
- package/dist/nativeAgent/validation.js +2 -2
- package/dist/repository/gitWorkspace.js +41 -12
- package/dist/repository/taskWorkspaceCoordinator.js +72 -145
- package/dist/repository/taskWorkspacePreparer.js +39 -43
- package/dist/repository/workspaceCleanupInspection.js +88 -7
- package/dist/resources/resourceRegistrar.js +16 -10
- package/dist/runtime/integrationRuntimeIsolation.js +21 -0
- package/dist/runtime/taskRuntimeIsolation.js +91 -21
- package/dist/task/archiveDiagnostics.js +26 -8
- package/dist/task/archivePreflight.js +26 -9
- package/dist/task/leaderArchive.js +9 -15
- package/dist/task/taskAuthority.js +56 -0
- package/dist/web/assets/client/api.js +8 -0
- package/dist/web/assets/client/app.js +74 -9
- package/dist/web/assets/client/components.js +95 -36
- package/dist/web/assets/client/detail.js +110 -64
- package/dist/web/assets/client/dock.js +95 -11
- package/dist/web/assets/client/evidence.js +286 -94
- package/dist/web/assets/client/i18n.js +182 -62
- package/dist/web/assets/client/overview.js +9 -10
- package/dist/web/assets/client/records.js +142 -7
- package/dist/web/assets/client/sections.js +234 -198
- package/dist/web/assets/client/sidebar.js +31 -2
- package/dist/web/assets/icons.js +4 -0
- package/dist/web/assets/shell.js +2 -1
- package/dist/web/assets/styles/components.js +64 -15
- package/dist/web/assets/styles/layout.js +11 -4
- package/dist/web/assets/styles/responsive.js +16 -6
- package/dist/web/assets/styles/tokens.js +1 -1
- package/dist/web/assets/styles/views.js +62 -42
- package/dist/web/webServer.js +12 -1
- package/dist/web/webTaskSurface.js +8 -1
- package/docs/agent-result-consumption.md +16 -0
- package/docs/agent-result-consumption.zh-CN.md +13 -0
- package/docs/examples/agent-offline.mjs +194 -0
- package/docs/native-agent.md +283 -0
- package/docs/observability/README.md +13 -3
- package/docs/observability/README.zh-CN.md +10 -3
- package/docs/release-workflow.md +72 -9
- package/docs/release-workflow.zh-CN.md +55 -6
- package/docs/roles-and-configuration.md +32 -0
- package/docs/roles-and-configuration.zh-CN.md +26 -0
- package/docs/task-delivery.md +36 -8
- package/docs/task-delivery.zh-CN.md +24 -7
- package/i18n/README.zh-CN.md +3 -2
- package/package.json +1 -1
- package/skills/yui-leader/SKILL.md +9 -0
- package/skills/yui-leader/references/execution.md +2 -1
- package/skills/yui-leader/references/integration.md +20 -0
- package/skills/yui-operator/SKILL.md +4 -0
- package/skills/yui-reviewer/SKILL.md +8 -0
- package/skills/yui-runtime/SKILL.md +11 -0
- package/skills/yui-runtime/references/publication.md +20 -4
- package/skills/yui-worker/SKILL.md +3 -0
|
@@ -1,18 +1,290 @@
|
|
|
1
1
|
export const EVIDENCE_SCRIPT = String.raw `
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
2
|
+
// The Delivery tab: work items, reviews, integration and remote delivery,
|
|
3
|
+
// saved files and retained workspaces. Opening the tab reads the original
|
|
4
|
+
// evidence once per Context cursor; reading never accepts, publishes,
|
|
5
|
+
// executes or cleans anything.
|
|
5
6
|
import { h, icon, clear } from "/assets/js/dom.js";
|
|
6
|
-
import { formatBytes } from "/assets/js/format.js";
|
|
7
|
-
import {
|
|
7
|
+
import { formatBytes, formatClock } from "/assets/js/format.js";
|
|
8
|
+
import {
|
|
9
|
+
card, listCard, setCardCount, button, note, mono, chip, emptyState, richText, badge, statusBadge, label, tone, dot,
|
|
10
|
+
timeTag, disclosure, workItemCard, workItemBody, reviewCard
|
|
11
|
+
} from "/assets/js/components.js";
|
|
12
|
+
import { entriesOf, valuesOf, totalOf, summaryFields, readExact, exactRow, lazyRow, familyState, loadFamily } from "/assets/js/records.js";
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
const DELIVERY_TONES = { merged: "ok", partial: "warn", unverified: "warn", uncovered: "warn", pending: "info", none: "idle", unavailable: "idle" };
|
|
15
|
+
|
|
16
|
+
function newest(left, right) {
|
|
17
|
+
return Date.parse(right.createdAt || 0) - Date.parse(left.createdAt || 0);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Only http(s) links without credentials leave the page.
|
|
21
|
+
function safeUrl(value) {
|
|
22
|
+
try {
|
|
23
|
+
const url = new URL(value);
|
|
24
|
+
return ["http:", "https:"].includes(url.protocol) && !url.username && !url.password ? url.href : null;
|
|
25
|
+
} catch { return null; }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function renderDelivery(panel, data, t, locale, ctx) {
|
|
29
|
+
const view = data.viewState;
|
|
30
|
+
const core = data.core;
|
|
31
|
+
const task = data.task;
|
|
32
|
+
view.exact = view.exact || {};
|
|
33
|
+
view.openRows = view.openRows || {};
|
|
34
|
+
view.reports = view.reports || {};
|
|
35
|
+
view.panels = view.panels || {};
|
|
36
|
+
view.panels.delivery = panel;
|
|
37
|
+
|
|
38
|
+
// --- Work items ------------------------------------------------------------
|
|
39
|
+
const work = listCard({ id: "detail-work", title: t("work.title"), icon: "layers", count: totalOf(core, "work-item") || null, hint: t("work.openHint") });
|
|
40
|
+
function drawWork() {
|
|
41
|
+
clear(work.list);
|
|
42
|
+
const family = familyState(view, "work-item");
|
|
43
|
+
const entries = entriesOf(core, "work-item");
|
|
44
|
+
const titles = {};
|
|
45
|
+
family.items.forEach(function (item) { const fields = summaryFields(item.summary); if (fields.title) titles[item.ref.refId] = fields.title; });
|
|
46
|
+
valuesOf(core, "work-item").forEach(function (item) { titles[item.id] = item.title; });
|
|
47
|
+
const shown = new Set(entries.map(function (entry) { return entry.ref.refId; }));
|
|
48
|
+
const extraOpen = family.items.filter(function (item) { return item.status === "open" && !shown.has(item.ref.refId); });
|
|
49
|
+
const finished = family.items.filter(function (item) { return item.status !== "open"; });
|
|
50
|
+
entries.forEach(function (entry) {
|
|
51
|
+
work.list.append(exactRow(entry, task.id, t, ctx, view.exact, function (value) { return workItemCard(value, t, locale, titles); }));
|
|
52
|
+
});
|
|
53
|
+
extraOpen.forEach(function (item) { work.list.append(workRow(item, titles)); });
|
|
54
|
+
const loaded = family.key && family.pages;
|
|
55
|
+
if (loaded) setCardCount(work, family.total || null);
|
|
56
|
+
if (!entries.length && !extraOpen.length) {
|
|
57
|
+
work.list.append(emptyState(loaded && family.total === 0 ? t("work.none") : t("work.noneOpen"), "layers"));
|
|
58
|
+
}
|
|
59
|
+
if (family.error) work.list.append(note(t("records.unavailable") + " " + family.error, "bad"));
|
|
60
|
+
if (!loaded) {
|
|
61
|
+
if (family.pending) work.list.append(h("p.row-label", null, t("work.reading")));
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const finishedTotal = Math.max(finished.length, (family.total || 0) - totalOf(core, "work-item"));
|
|
65
|
+
if (!finishedTotal) return;
|
|
66
|
+
const group = h("div.row-stack.is-finished", null, h("p.row-label", null, t("work.finished") + " · " + finishedTotal));
|
|
67
|
+
finished.forEach(function (item) { group.append(workRow(item, titles)); });
|
|
68
|
+
work.list.append(group);
|
|
69
|
+
if (family.nextCursor) work.list.append(listFoot(family, function () {
|
|
70
|
+
return loadFamily(view, task.id, "work-item", family.key, ctx, { more: true, limit: 40 });
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
function workRow(item, titles) {
|
|
74
|
+
const fields = summaryFields(item.summary);
|
|
75
|
+
return lazyRow(item, task.id, t, ctx, {
|
|
76
|
+
cache: view.exact, openRows: view.openRows,
|
|
77
|
+
head: [dot(tone("work", item.status)), h("span.lazy-title", null, fields.title || item.ref.refId),
|
|
78
|
+
item.assignee ? h("span.faint.small.lazy-meta", null, item.assignee) : null,
|
|
79
|
+
statusBadge(t, "work", "work", item.status)],
|
|
80
|
+
render: function (value) { return workItemBody(value, t, locale, titles); }
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function listFoot(family, more) {
|
|
84
|
+
const next = button(t("history.more"), { icon: "chevron", variant: "ghost" });
|
|
85
|
+
next.addEventListener("click", function () {
|
|
86
|
+
next.disabled = true;
|
|
87
|
+
more().then(refresh);
|
|
88
|
+
});
|
|
89
|
+
return h("div.list-foot", null,
|
|
90
|
+
h("span.faint.small", null, t("history.loaded").replace("{shown}", String(family.items.length)).replace("{total}", String(family.total))),
|
|
91
|
+
next);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// --- Reviews ---------------------------------------------------------------
|
|
95
|
+
const reviews = listCard({ id: "detail-reviews", title: t("reviews.title"), icon: "eye", hint: t("reviews.hint") });
|
|
96
|
+
function drawReviews() {
|
|
97
|
+
clear(reviews.list);
|
|
98
|
+
const evidence = view.evidence && view.evidence.key && view.evidence.value;
|
|
99
|
+
if (evidence) {
|
|
100
|
+
const rounds = evidence.reviews.slice().sort(newest);
|
|
101
|
+
setCardCount(reviews, rounds.length || null);
|
|
102
|
+
if (!rounds.length) reviews.list.append(emptyState(t("reviews.none"), "eye"));
|
|
103
|
+
rounds.forEach(function (round) { reviews.list.append(reviewRow(round)); });
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const entries = entriesOf(core, "review-round");
|
|
107
|
+
setCardCount(reviews, entries.length || null);
|
|
108
|
+
entries.forEach(function (entry) {
|
|
109
|
+
reviews.list.append(exactRow(entry, task.id, t, ctx, view.exact, function (value) { return reviewRow(value); }));
|
|
110
|
+
});
|
|
111
|
+
if (view.evidence && view.evidence.error) reviews.list.append(note(t("records.unavailable") + " " + view.evidence.error, "bad"));
|
|
112
|
+
else reviews.list.append(h("p.row-label", null, t("evidence.loading")));
|
|
113
|
+
}
|
|
114
|
+
function reviewRow(round) {
|
|
115
|
+
const element = reviewCard(round, t, locale);
|
|
116
|
+
if (!round.reviewerRunId) return element;
|
|
117
|
+
const holder = h("div.stack");
|
|
118
|
+
const cached = view.reports[round.id];
|
|
119
|
+
if (cached) { holder.append(richText(t("evidence.report"), cached, t, { threshold: 480 })); element.append(holder); return element; }
|
|
120
|
+
const report = button(t("evidence.readReport"), { icon: "eye", variant: "link" });
|
|
121
|
+
report.addEventListener("click", async function () {
|
|
122
|
+
report.disabled = true;
|
|
123
|
+
try {
|
|
124
|
+
const source = await ctx.inspect(task.id, { store: "run", refId: round.reviewerRunId });
|
|
125
|
+
const output = (source.result && source.result.output) || (source.value && source.value.result && source.value.result.output) || t("evidence.noReport");
|
|
126
|
+
view.reports[round.id] = output;
|
|
127
|
+
holder.append(richText(t("evidence.report"), output, t, { threshold: 480 }));
|
|
128
|
+
report.remove();
|
|
129
|
+
} catch (error) { holder.append(note(error.message, "bad")); report.disabled = false; }
|
|
130
|
+
});
|
|
131
|
+
element.append(h("div.record-actions", null, report), holder);
|
|
132
|
+
return element;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// --- Integration and remote delivery ------------------------------------------
|
|
136
|
+
const delivery = card({ id: "detail-results", title: t("delivery.title"), icon: "merge", hint: t("delivery.hint") });
|
|
137
|
+
const deliveryBody = h("div.stack.delivery-stack");
|
|
138
|
+
delivery.body.append(deliveryBody);
|
|
139
|
+
function remoteDelivery() {
|
|
140
|
+
const entry = entriesOf(core, "remote-delivery")[0];
|
|
141
|
+
if (entry && !entry.omitted) return entry.value;
|
|
142
|
+
const cached = entry && view.exact["remote-delivery/" + entry.ref.refId];
|
|
143
|
+
if (cached && cached.digest === entry.ref.digest && cached.result) return cached.result.value;
|
|
144
|
+
return (data.runtime && data.runtime.remoteDelivery) || null;
|
|
145
|
+
}
|
|
146
|
+
function drawDelivery() {
|
|
147
|
+
clear(deliveryBody);
|
|
148
|
+
const remote = remoteDelivery();
|
|
149
|
+
if (remote) {
|
|
150
|
+
deliveryBody.append(h("h4.sub-head", null, icon("package", "icon-sm"), h("span", null, t("evidence.remote")),
|
|
151
|
+
badge(t("remoteDelivery." + remote.status, remote.status), DELIVERY_TONES[remote.status] || "idle", { dot: true })));
|
|
152
|
+
if (remote.codeProjectCount) {
|
|
153
|
+
deliveryBody.append(h("p.faint.small", null, t("delivery.counts")
|
|
154
|
+
.replace("{merged}", String(remote.mergedProjectCount)).replace("{verified}", String(remote.verifiedProjectCount))
|
|
155
|
+
.split("{total}").join(String(remote.codeProjectCount))));
|
|
156
|
+
}
|
|
157
|
+
(remote.projects || []).forEach(function (project) { deliveryBody.append(projectRow(project)); });
|
|
158
|
+
if (!(remote.projects || []).length) deliveryBody.append(note(t("delivery.noProjects")));
|
|
159
|
+
} else deliveryBody.append(note(t("evidence.observationUnavailable")));
|
|
160
|
+
|
|
161
|
+
const state = view.evidence || {};
|
|
162
|
+
const evidence = state.key && state.value;
|
|
163
|
+
deliveryBody.append(h("h4.sub-head", null, icon("merge", "icon-sm"), h("span", null, t("evidence.integrations")),
|
|
164
|
+
evidence ? h("span.count", null, String(evidence.integrations.length)) : null));
|
|
165
|
+
if (!evidence) {
|
|
166
|
+
deliveryBody.append(state.error ? note(t("evidence.originalUnavailable") + " " + state.error, "bad") : h("p.faint.small", null, t("evidence.loading")));
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (!evidence.integrations.length) deliveryBody.append(note(t("evidence.noIntegrations")));
|
|
170
|
+
const rows = h("div.row-stack.boxed");
|
|
171
|
+
evidence.integrations.slice().sort(newest).forEach(function (attempt) { rows.append(integrationRow(attempt)); });
|
|
172
|
+
if (rows.childNodes.length) deliveryBody.append(rows);
|
|
173
|
+
deliveryBody.append(h("p.faint.small", null, t("delivery.readAt") + " " + formatClock(state.readAt, locale)
|
|
174
|
+
+ (state.pending ? " · " + t("evidence.loading") : "")));
|
|
175
|
+
}
|
|
176
|
+
function projectRow(project) {
|
|
177
|
+
const publication = project.publication;
|
|
178
|
+
const href = publication && publication.externalUrl && safeUrl(publication.externalUrl);
|
|
179
|
+
const element = h("article.record.delivery-project");
|
|
180
|
+
element.append(h("header.record-head", null, icon("folder", "icon-sm"), h("strong", null, project.directory || project.projectId),
|
|
181
|
+
project.coverage ? chip(label(t, "coverage", project.coverage)) : null,
|
|
182
|
+
h("span.spacer"),
|
|
183
|
+
publication ? (href
|
|
184
|
+
? h("a.link", { href: href, rel: "noopener noreferrer", target: "_blank" }, label(t, "publication", publication.externalKind) + " #" + publication.externalId)
|
|
185
|
+
: mono(publication.externalKind + " " + publication.externalId)) : null));
|
|
186
|
+
if (publication && publication.title) element.append(h("p.small", null, publication.title));
|
|
187
|
+
if (project.reason) element.append(h("p.faint.small", null, project.reason));
|
|
188
|
+
element.append(h("div.meta-line", null,
|
|
189
|
+
h("span", null, t("evidence.expectedCommit") + " "), mono(project.expectedLocalCommit ? project.expectedLocalCommit.slice(0, 12) : t("common.unknown")),
|
|
190
|
+
project.state ? chip(label(t, "publicationState", project.state)) : null,
|
|
191
|
+
project.verification ? chip(t("evidence.verification") + " · " + label(t, "verification", project.verification)) : null,
|
|
192
|
+
project.adoption ? h("span", null, t("evidence.adoption") + " ", mono(project.adoption.id)) : null));
|
|
193
|
+
return element;
|
|
194
|
+
}
|
|
195
|
+
function integrationRow(attempt) {
|
|
196
|
+
const source = attempt.source || {};
|
|
197
|
+
const element = h("article.record.integration-row");
|
|
198
|
+
element.dataset.status = attempt.status;
|
|
199
|
+
element.append(h("header.record-head", null, dot(tone("integration", attempt.status)), mono(attempt.id),
|
|
200
|
+
chip(label(t, "integration.source", source.kind) + (source.workItemId ? " · " + source.workItemId : "")),
|
|
201
|
+
source.strategy ? chip(source.strategy) : null,
|
|
202
|
+
h("span.spacer"),
|
|
203
|
+
statusBadge(t, "integration", "integration", attempt.status)));
|
|
204
|
+
if (attempt.summary) element.append(h("p.small", null, attempt.summary));
|
|
205
|
+
element.append(h("div.meta-line", null,
|
|
206
|
+
attempt.projectId ? h("span", null, attempt.projectId) : null,
|
|
207
|
+
attempt.targetRef ? mono(attempt.targetRef) : null,
|
|
208
|
+
h("span", null, t("evidence.candidate") + " "), mono(attempt.candidateCommit ? attempt.candidateCommit.slice(0, 12) : t("evidence.noCandidate")),
|
|
209
|
+
timeTag(attempt.createdAt, locale, t)));
|
|
210
|
+
if (attempt.checks && attempt.checks.length) {
|
|
211
|
+
element.append(h("ul.check-list", null, attempt.checks.map(function (check) {
|
|
212
|
+
return h("li", null, dot(check.outcome === "passed" ? "ok" : check.outcome === "failed" ? "bad" : "idle"),
|
|
213
|
+
h("span.mono-line", null, check.name), h("span.faint", null, label(t, "check", check.outcome)),
|
|
214
|
+
check.details ? h("span.faint.small.check-details", null, check.details) : null);
|
|
215
|
+
})));
|
|
216
|
+
} else element.append(h("p.faint.small", null, t("evidence.noChecks")));
|
|
217
|
+
return element;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// --- Workspaces and cleanup --------------------------------------------------
|
|
221
|
+
const workspaces = disclosure(t("workspaces.title"), "workspaces", { className: "card-disclosure", meta: String(totalOf(core, "managed-workspace")) });
|
|
222
|
+
workspaces.id = "detail-workspaces";
|
|
223
|
+
function drawWorkspaces() {
|
|
224
|
+
clear(workspaces.body);
|
|
225
|
+
const evidence = view.evidence && view.evidence.key && view.evidence.value;
|
|
226
|
+
const list = evidence ? evidence.workspaces : valuesOf(core, "managed-workspace");
|
|
227
|
+
if (!list.length) workspaces.body.append(note(t("evidence.noWorkspaces")));
|
|
228
|
+
const rows = h("div.row-stack.boxed");
|
|
229
|
+
list.forEach(function (workspace) {
|
|
230
|
+
const owner = workspace.owner || {};
|
|
231
|
+
const ownerId = owner.workItemId || owner.reviewRoundId || owner.integrationAttemptId
|
|
232
|
+
|| (owner.executionGroupId ? owner.executionGroupId + (owner.executionLaneId ? "/" + owner.executionLaneId : "") : "") || owner.taskId || "";
|
|
233
|
+
rows.append(h("article.record.is-compact", null,
|
|
234
|
+
h("header.record-head", null, chip(label(t, "workspace.owner", owner.type)), mono(ownerId), h("span.spacer"), timeTag(workspace.updatedAt, locale, t)),
|
|
235
|
+
h("p.small.mono-line", null, workspace.root),
|
|
236
|
+
(workspace.entries || []).length ? h("div.meta-line", null, workspace.entries.map(function (entry) {
|
|
237
|
+
return h("span", null, entry.directory + " · ", mono(entry.branch || entry.baseRef || ""));
|
|
238
|
+
})) : null));
|
|
239
|
+
});
|
|
240
|
+
if (rows.childNodes.length) workspaces.body.append(rows);
|
|
241
|
+
workspaces.body.append(note(t("evidence.cleanupNote")), h("pre.code-block", null, "yui task archive-preflight " + task.id + " --integrated"));
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
panel.append(work, reviews, delivery, filesCard(data, t, locale, ctx), workspaces);
|
|
245
|
+
panel.redraw = function () { drawWork(); drawReviews(); drawDelivery(); drawWorkspaces(); };
|
|
246
|
+
panel.redraw();
|
|
247
|
+
|
|
248
|
+
// Reads outlive one render: they redraw whichever Delivery panel is current
|
|
249
|
+
// and re-read when the Context cursor moved while they were in flight.
|
|
250
|
+
function refresh() {
|
|
251
|
+
const current = view.panels.delivery;
|
|
252
|
+
if (!current || !current.isConnected) return;
|
|
253
|
+
current.redraw();
|
|
254
|
+
if (!current.hidden) current.onShow();
|
|
255
|
+
}
|
|
256
|
+
panel.onShow = function () {
|
|
257
|
+
const key = core.coreCursor;
|
|
258
|
+
const previous = view.evidence || {};
|
|
259
|
+
if (previous.key !== key && previous.errorKey !== key && !previous.pending) {
|
|
260
|
+
view.evidence = { key: previous.key, value: previous.value, readAt: previous.readAt, error: null, pending: true };
|
|
261
|
+
ctx.evidence(task.id).then(function (value) {
|
|
262
|
+
view.evidence = { key: key, value: value, readAt: new Date().toISOString(), error: null, pending: false };
|
|
263
|
+
}, function (error) {
|
|
264
|
+
view.evidence = { key: previous.key, value: previous.value, readAt: previous.readAt, error: error.message, errorKey: key, pending: false };
|
|
265
|
+
}).then(refresh);
|
|
266
|
+
}
|
|
267
|
+
const entry = entriesOf(core, "remote-delivery")[0];
|
|
268
|
+
if (entry && entry.omitted && !(data.runtime && data.runtime.remoteDelivery)) {
|
|
269
|
+
const hit = view.exact["remote-delivery/" + entry.ref.refId];
|
|
270
|
+
if (!(hit && hit.digest === entry.ref.digest && hit.result)) {
|
|
271
|
+
readExact(entry, task.id, ctx, view.exact).then(refresh, function () {});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
const family = familyState(view, "work-item");
|
|
275
|
+
if (family.key !== key && family.errorKey !== key && !family.pending) loadFamily(view, task.id, "work-item", key, ctx, { limit: 40 }).then(refresh);
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// --- Saved files ------------------------------------------------------------------
|
|
280
|
+
// Files are read on request at a fixed revision; the selected revision
|
|
281
|
+
// survives refreshes.
|
|
282
|
+
function filesCard(data, t, locale, actions) {
|
|
10
283
|
const state = data.viewState;
|
|
11
|
-
const
|
|
284
|
+
const load = button(state.artifactList ? t("evidence.reload") : t("evidence.load"), { icon: "refresh", variant: "ghost" });
|
|
285
|
+
const files = card({ id: "detail-files", title: t("evidence.files"), icon: "file", hint: t("evidence.filesHint"), actions: load });
|
|
12
286
|
const list = h("div.file-list");
|
|
13
287
|
const viewer = h("div.file-viewer");
|
|
14
|
-
const load = button(state.artifactList ? t("evidence.reload") : t("evidence.load"), { icon: "refresh", variant: "ghost" });
|
|
15
|
-
files.querySelector(".card-head").append(h("div.card-actions", null, load));
|
|
16
288
|
let readSequence = 0;
|
|
17
289
|
async function read(path, commit) {
|
|
18
290
|
const sequence = ++readSequence;
|
|
@@ -41,8 +313,7 @@ export function renderEvidence(container, data, t, locale, actions) {
|
|
|
41
313
|
viewer.append(h("header.viewer-head", null, icon("file"), h("strong", null, value.relativePath), h("span.spacer"), copy));
|
|
42
314
|
viewer.append(h("p.viewer-ref", null, mono(ref)));
|
|
43
315
|
viewer.append(h("p.faint.small", null, t("evidence.fixedNote")));
|
|
44
|
-
|
|
45
|
-
viewer.append(content);
|
|
316
|
+
viewer.append(h("pre.code-block.artifact-text", { tabIndex: 0, "aria-label": t("evidence.fixedText") }, value.content));
|
|
46
317
|
}
|
|
47
318
|
function drawList() {
|
|
48
319
|
clear(list);
|
|
@@ -63,6 +334,7 @@ export function renderEvidence(container, data, t, locale, actions) {
|
|
|
63
334
|
list.dataset.reading = "true";
|
|
64
335
|
try {
|
|
65
336
|
state.artifactList = await actions.artifacts(data.task.id);
|
|
337
|
+
if (placeholder) { placeholder.remove(); placeholder = null; }
|
|
66
338
|
drawList();
|
|
67
339
|
} catch (error) {
|
|
68
340
|
clear(list);
|
|
@@ -82,91 +354,11 @@ export function renderEvidence(container, data, t, locale, actions) {
|
|
|
82
354
|
referenced.append(h("button.file-row", { type: "button", onclick: function () { read(match[2], match[1]); } },
|
|
83
355
|
icon("flag", "icon-sm"), h("span.file-name", null, match[2]), badge(t("evidence.referenced"), "accent")));
|
|
84
356
|
});
|
|
85
|
-
|
|
357
|
+
let placeholder = !state.artifactList && !seen.size ? emptyState(t("evidence.notLoaded"), "file") : null;
|
|
358
|
+
if (placeholder) files.body.append(placeholder);
|
|
86
359
|
files.body.append(referenced, list, viewer);
|
|
87
360
|
drawList();
|
|
88
361
|
drawViewer();
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const delivery = card({ title: t("evidence.delivery"), icon: "layers", hint: t("evidence.deliveryHint") });
|
|
92
|
-
const output = h("div.stack");
|
|
93
|
-
const open = button(t("evidence.readDelivery"), { icon: "eye", variant: "ghost" });
|
|
94
|
-
delivery.querySelector(".card-head").append(h("div.card-actions", null, open));
|
|
95
|
-
delivery.body.append(output);
|
|
96
|
-
open.addEventListener("click", function () {
|
|
97
|
-
open.disabled = true;
|
|
98
|
-
drawDelivery(output, data, t, actions).finally(function () { open.disabled = false; });
|
|
99
|
-
});
|
|
100
|
-
container.append(delivery);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
async function drawDelivery(output, data, t, actions) {
|
|
104
|
-
clear(output);
|
|
105
|
-
const runtime = data.runtimeStatus === "available" ? data.runtime : null;
|
|
106
|
-
if (!runtime) output.append(note(t("evidence.observationUnavailable")));
|
|
107
|
-
const remote = runtime && runtime.remoteDelivery;
|
|
108
|
-
if (remote) {
|
|
109
|
-
output.append(h("h4.sub-head", null, t("evidence.remote"), badge(t("remoteDelivery." + remote.status, remote.status), remote.status === "merged" ? "ok" : "idle")));
|
|
110
|
-
remote.projects.forEach(function (project) {
|
|
111
|
-
output.append(h("article.record", null,
|
|
112
|
-
h("header.record-head", null, h("strong", null, project.directory), h("span.faint.small", null, project.coverage)),
|
|
113
|
-
h("p.small", null, project.reason),
|
|
114
|
-
h("p.faint.small", null, t("evidence.expectedCommit") + " ", mono(project.expectedLocalCommit || t("common.unknown"))),
|
|
115
|
-
h("p.faint.small", null, "PR/MR · " + (project.state || "none") + " · " + t("evidence.verification") + " " + (project.verification || "unverified")),
|
|
116
|
-
project.adoption ? h("p.faint.small", null, t("evidence.adoption") + " ", mono(project.adoption.id)) : null));
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
const original = h("div.stack", null, h("p.faint", null, t("evidence.readingOriginal")));
|
|
120
|
-
output.append(original);
|
|
121
|
-
try {
|
|
122
|
-
const evidence = await actions.evidence(data.task.id);
|
|
123
|
-
clear(original);
|
|
124
|
-
original.append(h("h4.sub-head", null, t("evidence.integrations")));
|
|
125
|
-
if (!evidence.integrations.length) original.append(note(t("evidence.noIntegrations")));
|
|
126
|
-
evidence.integrations.forEach(function (attempt) {
|
|
127
|
-
const element = h("article.record", null,
|
|
128
|
-
h("header.record-head", null, mono(attempt.id), h("span.spacer"), badge(attempt.status, attempt.status === "succeeded" ? "ok" : "idle")),
|
|
129
|
-
h("p.faint.small", null, t("evidence.candidate") + " ", mono(attempt.candidateCommit || t("evidence.noCandidate"))));
|
|
130
|
-
if (!attempt.checks || !attempt.checks.length) element.append(h("p.faint.small", null, t("evidence.noChecks")));
|
|
131
|
-
(attempt.checks || []).forEach(function (check) {
|
|
132
|
-
element.append(h("p.small", null, check.name + " · " + check.outcome));
|
|
133
|
-
if (check.details) element.append(h("p.faint.small", null, check.details));
|
|
134
|
-
});
|
|
135
|
-
original.append(element);
|
|
136
|
-
});
|
|
137
|
-
original.append(h("h4.sub-head", null, t("evidence.reviews")));
|
|
138
|
-
if (!evidence.reviews.length) original.append(note(t("evidence.noReviews")));
|
|
139
|
-
evidence.reviews.forEach(function (round) {
|
|
140
|
-
const element = h("article.record", null,
|
|
141
|
-
h("header.record-head", null, mono(round.id), h("span.spacer"), badge(round.status, round.status === "completed" ? "ok" : "idle")),
|
|
142
|
-
h("p.faint.small.mono-line", null, round.taskCandidate
|
|
143
|
-
? round.taskCandidate.projects.map(function (p) { return p.projectId + " · " + p.commit; }).join(" ")
|
|
144
|
-
: [round.workItemId, round.candidateId, round.reviewBaseCommit].filter(Boolean).join(" · ")));
|
|
145
|
-
if (round.reviewerRunId) {
|
|
146
|
-
const report = button(t("evidence.readReport"), { icon: "eye", variant: "link" });
|
|
147
|
-
report.addEventListener("click", async function () {
|
|
148
|
-
report.disabled = true;
|
|
149
|
-
try {
|
|
150
|
-
const source = await actions.inspect(data.task.id, { store: "run", refId: round.reviewerRunId });
|
|
151
|
-
element.append(richText(round.reviewerRunId, (source.value.result && source.value.result.output) || t("evidence.noReport"), t));
|
|
152
|
-
report.remove();
|
|
153
|
-
} catch (error) { element.append(note(error.message, "bad")); report.disabled = false; }
|
|
154
|
-
});
|
|
155
|
-
element.append(report);
|
|
156
|
-
}
|
|
157
|
-
original.append(element);
|
|
158
|
-
});
|
|
159
|
-
original.append(h("h4.sub-head", null, t("evidence.workspaces")));
|
|
160
|
-
if (!evidence.workspaces.length) original.append(note(t("evidence.noWorkspaces")));
|
|
161
|
-
evidence.workspaces.forEach(function (workspace) {
|
|
162
|
-
original.append(h("p.small.mono-line", null, workspace.owner.type + " · " + workspace.root));
|
|
163
|
-
});
|
|
164
|
-
original.append(note(t("evidence.cleanupNote")), h("pre.code-block", null, "yui task archive-preflight " + data.task.id + " --integrated"));
|
|
165
|
-
} catch (error) {
|
|
166
|
-
clear(original);
|
|
167
|
-
original.append(note(t("evidence.originalUnavailable") + " " + error.message, "bad"));
|
|
168
|
-
}
|
|
169
|
-
const metrics = runtime && observabilityMetricCard(runtime.observability, t);
|
|
170
|
-
if (metrics) output.append(h("h4.sub-head", null, t("evidence.usage")), metrics);
|
|
362
|
+
return files;
|
|
171
363
|
}
|
|
172
364
|
`;
|