@zq-silk/yui 2.2.0 → 2.4.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.
Files changed (206) hide show
  1. package/README.md +19 -3
  2. package/dist/artifacts/artifactCapability.js +39 -10
  3. package/dist/artifacts/imageMetadata.js +120 -0
  4. package/dist/artifacts/managedGit.js +7 -4
  5. package/dist/artifacts/taskArtifactRepository.js +6 -0
  6. package/dist/cli/commandCatalog.js +25 -11
  7. package/dist/cli/interactionPolicy.js +4 -0
  8. package/dist/cli/invocationAuthority.js +1 -1
  9. package/dist/commands/executionAuditCommands.js +5 -0
  10. package/dist/commands/globalRoleCommands.js +41 -3
  11. package/dist/commands/projectCommands.js +89 -94
  12. package/dist/commands/roleSkillValidation.js +4 -8
  13. package/dist/commands/taskCommands.js +30 -9
  14. package/dist/commands/taskIntegrationCommands.js +5 -16
  15. package/dist/commands/taskUsageCommand.js +38 -0
  16. package/dist/context/roleSessionContext.js +18 -2
  17. package/dist/context/runContextPack.js +5 -1
  18. package/dist/context/sessionBootstrapManifest.js +10 -1
  19. package/dist/context/skillCatalog.js +108 -0
  20. package/dist/context/skillPackage.js +161 -0
  21. package/dist/context/taskContext.js +3 -2
  22. package/dist/context/taskSearch.js +127 -0
  23. package/dist/controlPlaneCli.js +51 -39
  24. package/dist/controller/clientRuntime.js +3 -2
  25. package/dist/controller/fileSchedulerStoreAdapter.js +32 -6
  26. package/dist/controller/jobControl.js +2 -0
  27. package/dist/controller/nativeHostInput.js +37 -0
  28. package/dist/controller/runtime.js +93 -2
  29. package/dist/controller/runtimeEventInbox.js +2 -2
  30. package/dist/controller/runtimeEventProcessor.js +3 -3
  31. package/dist/doctor/doctor.js +10 -0
  32. package/dist/execution/reviewMainRun.js +1 -0
  33. package/dist/execution/workItemMainRun.js +1 -0
  34. package/dist/executor/codexConfigConflict.js +6 -4
  35. package/dist/executor/effectiveLaunch.js +24 -1
  36. package/dist/executor/fileRoleLaunchPlanner.js +13 -5
  37. package/dist/integration/gitIntegrationService.js +15 -79
  38. package/dist/integration/integrationSourceApplication.js +4 -2
  39. package/dist/job/httpPreview.js +61 -0
  40. package/dist/job/jobCleanupInspection.js +67 -0
  41. package/dist/job/jobRunner.js +12 -2
  42. package/dist/kernel/builtinCapabilities.js +3 -1
  43. package/dist/message/message.js +15 -1
  44. package/dist/output/rolePresentation.js +4 -1
  45. package/dist/repository/executionLaneGitSnapshot.js +2 -1
  46. package/dist/repository/gitCompatibility.js +62 -0
  47. package/dist/repository/gitWorkspace.js +86 -80
  48. package/dist/repository/gitWorktreeInventory.js +121 -0
  49. package/dist/repository/project.js +74 -25
  50. package/dist/repository/taskWorkspaceCoordinator.js +72 -145
  51. package/dist/repository/taskWorkspacePreparer.js +39 -43
  52. package/dist/repository/workspaceCleanupInspection.js +88 -7
  53. package/dist/resources/resourceDiscovery.js +2 -2
  54. package/dist/resources/resourceGc.js +7 -4
  55. package/dist/resources/resourceRegistrar.js +18 -11
  56. package/dist/runtime/agentEndpoint.js +8 -0
  57. package/dist/runtime/agentHost.js +170 -3
  58. package/dist/runtime/codexAppServerRuntime.js +1 -1
  59. package/dist/runtime/codexNativeAccess.js +175 -0
  60. package/dist/runtime/controlledCodexTui.js +116 -0
  61. package/dist/runtime/integrationRuntimeIsolation.js +21 -0
  62. package/dist/runtime/publicReply.js +23 -0
  63. package/dist/runtime/runtimeObservation.js +48 -0
  64. package/dist/runtime/structuredProviderHost.js +16 -7
  65. package/dist/runtime/taskCostMetrics.js +133 -0
  66. package/dist/runtime/taskRuntimeIsolation.js +91 -21
  67. package/dist/runtime/taskUsageMetrics.js +11 -2
  68. package/dist/runtime/taskUsageQuery.js +38 -0
  69. package/dist/scheduler/taskExecutionProjection.js +2 -0
  70. package/dist/scheduler/taskObservabilityProjection.js +9 -1
  71. package/dist/storage/homeLayout.js +13 -0
  72. package/dist/storage/sqliteSchema.js +44 -0
  73. package/dist/storage/sqliteStore.js +53 -0
  74. package/dist/storage/storageVersions.js +1 -1
  75. package/dist/storage/storeRpc.js +2 -0
  76. package/dist/storage/taskSearch.js +35 -0
  77. package/dist/storage/upgrade/projectKnowledgeMigration.js +52 -0
  78. package/dist/task/archiveDiagnostics.js +26 -8
  79. package/dist/task/archivePreflight.js +26 -9
  80. package/dist/task/leaderArchive.js +9 -15
  81. package/dist/task/ordinaryArchive.js +42 -0
  82. package/dist/tmux/tmuxManager.js +8 -8
  83. package/dist/web/assets/assetManifest.js +11 -51
  84. package/dist/web/assets/client/app/catalog.js +215 -0
  85. package/dist/web/assets/client/app/main.js +148 -0
  86. package/dist/web/assets/client/app/selection.js +139 -0
  87. package/dist/web/assets/client/app/settings.js +326 -0
  88. package/dist/web/assets/client/app/taskView.js +280 -0
  89. package/dist/web/assets/client/domain/context.js +96 -0
  90. package/dist/web/assets/client/domain/records.js +126 -0
  91. package/dist/web/assets/client/domain/runs.js +119 -0
  92. package/dist/web/assets/client/domain/taskForms.js +197 -0
  93. package/dist/web/assets/client/domain/vocab.js +69 -0
  94. package/dist/web/assets/client/domain/work.js +116 -0
  95. package/dist/web/assets/client/i18n/en.js +900 -0
  96. package/dist/web/assets/client/i18n/zh-CN.js +898 -0
  97. package/dist/web/assets/client/index.js +114 -0
  98. package/dist/web/assets/client/layout/resizer.js +37 -0
  99. package/dist/web/assets/client/layout/router.js +35 -0
  100. package/dist/web/assets/client/layout/shortcuts.js +45 -0
  101. package/dist/web/assets/client/layout/sizing.js +95 -0
  102. package/dist/web/assets/client/layout/workspace.js +247 -0
  103. package/dist/web/assets/client/{api.js → lib/api.js} +28 -4
  104. package/dist/web/assets/client/{dom.js → lib/dom.js} +24 -12
  105. package/dist/web/assets/client/{format.js → lib/format.js} +7 -0
  106. package/dist/web/assets/client/lib/i18n.js +54 -0
  107. package/dist/web/assets/client/lib/markdown.js +167 -0
  108. package/dist/web/assets/client/lib/prefs.js +28 -0
  109. package/dist/web/assets/client/lib/theme.js +68 -0
  110. package/dist/web/assets/client/ui/containers.js +101 -0
  111. package/dist/web/assets/client/ui/controls.js +51 -0
  112. package/dist/web/assets/client/ui/forms.js +48 -0
  113. package/dist/web/assets/client/ui/metrics.js +137 -0
  114. package/dist/web/assets/client/ui/primitives.js +92 -0
  115. package/dist/web/assets/client/ui/text.js +33 -0
  116. package/dist/web/assets/client/ui/toast.js +12 -0
  117. package/dist/web/assets/client/views/bodySearch.js +172 -0
  118. package/dist/web/assets/client/views/createTask.js +85 -0
  119. package/dist/web/assets/client/views/dock/conversation.js +612 -0
  120. package/dist/web/assets/client/views/dock/discussion.js +173 -0
  121. package/dist/web/assets/client/views/dock/preview.js +129 -0
  122. package/dist/web/assets/client/views/dock/terminal.js +199 -0
  123. package/dist/web/assets/client/views/globalInput.js +67 -0
  124. package/dist/web/assets/client/{overview.js → views/overview.js} +62 -56
  125. package/dist/web/assets/client/{sidebar.js → views/sidebar.js} +56 -62
  126. package/dist/web/assets/client/views/skills.js +152 -0
  127. package/dist/web/assets/client/views/task/actions.js +36 -0
  128. package/dist/web/assets/client/views/task/delivery.js +185 -0
  129. package/dist/web/assets/client/views/task/deliveryResults.js +159 -0
  130. package/dist/web/assets/client/views/task/files.js +272 -0
  131. package/dist/web/assets/client/views/task/observation.js +153 -0
  132. package/dist/web/assets/client/views/task/overview.js +161 -0
  133. package/dist/web/assets/client/views/task/page.js +131 -0
  134. package/dist/web/assets/client/views/task/records.js +163 -0
  135. package/dist/web/assets/client/views/task/runtime.js +130 -0
  136. package/dist/web/assets/client/views/task/timeline.js +190 -0
  137. package/dist/web/assets/shared/geometry.js +19 -0
  138. package/dist/web/assets/{icons.js → shared/icons.js} +4 -0
  139. package/dist/web/assets/shared/taskTabs.js +8 -0
  140. package/dist/web/assets/shared/themes.js +93 -0
  141. package/dist/web/assets/shell/dialogs.js +63 -0
  142. package/dist/web/assets/shell/dock.js +40 -0
  143. package/dist/web/assets/shell/index.js +40 -0
  144. package/dist/web/assets/shell/settings.js +34 -0
  145. package/dist/web/assets/shell/sidebar.js +45 -0
  146. package/dist/web/assets/styles/index.js +41 -0
  147. package/dist/web/assets/styles/{responsive.js → layout/responsive.js} +15 -13
  148. package/dist/web/assets/styles/{layout.js → layout/workspace.js} +17 -24
  149. package/dist/web/assets/styles/markdown.js +22 -3
  150. package/dist/web/assets/styles/tokens.js +10 -63
  151. package/dist/web/assets/styles/ui/controls.js +76 -0
  152. package/dist/web/assets/styles/ui/forms.js +46 -0
  153. package/dist/web/assets/styles/ui/surfaces.js +122 -0
  154. package/dist/web/assets/styles/views/delivery.js +29 -0
  155. package/dist/web/assets/styles/views/dock.js +71 -0
  156. package/dist/web/assets/styles/views/page.js +32 -0
  157. package/dist/web/assets/styles/views/records.js +70 -0
  158. package/dist/web/assets/styles/views/settings.js +26 -0
  159. package/dist/web/assets/styles/views/sidebar.js +74 -0
  160. package/dist/web/assets/styles/views/task.js +80 -0
  161. package/dist/web/assets/styles/views/terminal.js +38 -0
  162. package/dist/web/taskPreviews.js +205 -0
  163. package/dist/web/tmuxWebTerminal.js +16 -9
  164. package/dist/web/webConversation.js +373 -0
  165. package/dist/web/webMaterials.js +155 -0
  166. package/dist/web/webServer.js +306 -18
  167. package/dist/web/webSettings.js +331 -0
  168. package/dist/web/webSkills.js +86 -0
  169. package/dist/web/webSnapshot.js +40 -8
  170. package/dist/web/webTaskSurface.js +114 -9
  171. package/dist/workspace/gitChangeSetCapture.js +3 -1
  172. package/docs/managed-turn-and-session-runtime.md +9 -0
  173. package/docs/managed-turn-and-session-runtime.zh-CN.md +7 -0
  174. package/docs/observability/README.md +13 -3
  175. package/docs/observability/README.zh-CN.md +10 -3
  176. package/docs/release-workflow.md +53 -0
  177. package/docs/release-workflow.zh-CN.md +40 -0
  178. package/docs/storage-baseline.md +38 -1
  179. package/docs/storage-baseline.zh-CN.md +22 -0
  180. package/docs/task-delivery.md +36 -8
  181. package/docs/task-delivery.zh-CN.md +24 -7
  182. package/docs/task-discovery.md +28 -0
  183. package/docs/testing/verification-levels.md +2 -2
  184. package/i18n/README.zh-CN.md +4 -3
  185. package/package.json +1 -1
  186. package/skills/yui-leader/references/execution.md +2 -1
  187. package/skills/yui-leader/references/integration.md +20 -0
  188. package/skills/yui-operator/SKILL.md +4 -0
  189. package/skills/yui-reviewer/SKILL.md +3 -0
  190. package/skills/yui-runtime/SKILL.md +4 -0
  191. package/skills/yui-runtime/references/publication.md +20 -4
  192. package/skills/yui-worker/SKILL.md +3 -0
  193. package/dist/web/assets/client/app.js +0 -804
  194. package/dist/web/assets/client/components.js +0 -418
  195. package/dist/web/assets/client/detail.js +0 -333
  196. package/dist/web/assets/client/dock.js +0 -225
  197. package/dist/web/assets/client/evidence.js +0 -172
  198. package/dist/web/assets/client/forms.js +0 -230
  199. package/dist/web/assets/client/i18n.js +0 -1161
  200. package/dist/web/assets/client/markdown.js +0 -114
  201. package/dist/web/assets/client/records.js +0 -63
  202. package/dist/web/assets/client/sections.js +0 -313
  203. package/dist/web/assets/client/theme.js +0 -71
  204. package/dist/web/assets/shell.js +0 -161
  205. package/dist/web/assets/styles/components.js +0 -169
  206. package/dist/web/assets/styles/views.js +0 -292
@@ -1,114 +0,0 @@
1
- export const MARKDOWN_SCRIPT = `
2
- // Minimal, safe Markdown renderer.
3
- //
4
- // Agent-authored prose (focus, outcomes, reviews, messages) arrives as plain
5
- // text with informal Markdown. Rendering structure (headings, lists, code)
6
- // runs walls of text into scannable blocks.
7
- //
8
- // Safety rule: every byte of user text is HTML-escaped BEFORE any tag is
9
- // introduced; the transforms below only ever add our own elements. Links are
10
- // limited to http(s) URLs taken from already-escaped text, so no attribute
11
- // breakout is possible.
12
- export function escapeHtml(text) {
13
- return String(text)
14
- .replace(/&/g, "&")
15
- .replace(/</g, "&lt;")
16
- .replace(/>/g, "&gt;")
17
- .replace(/"/g, "&quot;");
18
- }
19
-
20
- // Inline spans: code, bold, auto-links. Expects HTML-escaped input.
21
- export function inlineMarkdown(escaped) {
22
- const codes = [];
23
- let out = escaped.replace(/\`([^\`\\n]+)\`/g, function (_match, code) {
24
- codes.push(code);
25
- return "\\u0000" + (codes.length - 1) + "\\u0000";
26
- });
27
- out = out.replace(/\\*\\*([^*\\n]+)\\*\\*/g, "<strong>$1</strong>");
28
- out = out.replace(/(https?:\\/\\/[^\\s<]+)/g, function (url) {
29
- return '<a href="' + url + '" target="_blank" rel="noreferrer">' + url + "</a>";
30
- });
31
- out = out.replace(/\\u0000(\\d+)\\u0000/g, function (_match, index) {
32
- return "<code>" + codes[Number(index)] + "</code>";
33
- });
34
- return out;
35
- }
36
-
37
- // Block structure: fenced code, ATX headings, unordered / ordered lists,
38
- // paragraphs with soft line breaks.
39
- export function renderMarkdown(text) {
40
- const lines = String(text).replace(/\\u0000/g, "").replace(/\\r\\n?/g, "\\n").split("\\n");
41
- const html = [];
42
- let paragraph = [];
43
- let list = null;
44
- let code = null;
45
- function flushParagraph() {
46
- if (!paragraph.length) return;
47
- html.push("<p>" + paragraph.map(inlineMarkdown).join("<br>") + "</p>");
48
- paragraph = [];
49
- }
50
- function flushList() {
51
- if (!list) return;
52
- html.push("<" + list.type + ">" + list.items.map(function (item) {
53
- return "<li>" + inlineMarkdown(item) + "</li>";
54
- }).join("") + "</" + list.type + ">");
55
- list = null;
56
- }
57
- lines.forEach(function (line) {
58
- if (code !== null) {
59
- if (/^\\s*\`\`\`/.test(line)) {
60
- html.push("<pre><code>" + code.join("\\n") + "</code></pre>");
61
- code = null;
62
- } else {
63
- code.push(line);
64
- }
65
- return;
66
- }
67
- if (/^\\s*\`\`\`/.test(line)) {
68
- flushParagraph();
69
- flushList();
70
- code = [];
71
- return;
72
- }
73
- const heading = line.match(/^\\s{0,3}(#{1,4})\\s+(.*)$/);
74
- if (heading) {
75
- flushParagraph();
76
- flushList();
77
- const level = Math.min(heading[1].length + 3, 6);
78
- html.push("<h" + level + ">" + inlineMarkdown(escapeHtml(heading[2].trim())) + "</h" + level + ">");
79
- return;
80
- }
81
- const unordered = line.match(/^\\s*[-*•]\\s+(.*)$/);
82
- if (unordered) {
83
- flushParagraph();
84
- if (!list || list.type !== "ul") {
85
- flushList();
86
- list = { type: "ul", items: [] };
87
- }
88
- list.items.push(escapeHtml(unordered[1]));
89
- return;
90
- }
91
- const ordered = line.match(/^\\s*\\d+[.)]\\s+(.*)$/);
92
- if (ordered) {
93
- flushParagraph();
94
- if (!list || list.type !== "ol") {
95
- flushList();
96
- list = { type: "ol", items: [] };
97
- }
98
- list.items.push(escapeHtml(ordered[1]));
99
- return;
100
- }
101
- if (/^\\s*$/.test(line)) {
102
- flushParagraph();
103
- flushList();
104
- return;
105
- }
106
- flushList();
107
- paragraph.push(escapeHtml(line));
108
- });
109
- flushParagraph();
110
- flushList();
111
- if (code !== null) html.push("<pre><code>" + code.join("\\n") + "</code></pre>");
112
- return html.join("");
113
- }
114
- `;
@@ -1,63 +0,0 @@
1
- export const RECORDS_SCRIPT = String.raw `
2
- // Context record access. Every business fact keeps its Context reference; an
3
- // expanded value is a current read, never a mutation of the snapshot.
4
- import { h, icon } from "/assets/js/dom.js";
5
- import { richText, mono, button, note } from "/assets/js/components.js";
6
-
7
- export function entriesOf(core, store) {
8
- return core.records.filter(function (entry) { return entry.ref.store === store; });
9
- }
10
-
11
- export function valuesOf(core, store) {
12
- return entriesOf(core, store).filter(function (entry) { return !entry.omitted; }).map(function (entry) { return entry.value; });
13
- }
14
-
15
- // A generic, honest card for any record: omitted values say so and can be
16
- // read by reference; reading never acknowledges or accepts anything.
17
- export function recordCard(entry, taskId, t, actions, options) {
18
- const opts = options || {};
19
- const element = h("article.record" + (opts.compact ? ".is-compact" : ""));
20
- element.append(h("header.record-head", null,
21
- h("span.record-store", null, t("store." + entry.ref.store, entry.ref.store)),
22
- mono(entry.ref.refId),
23
- h("span.spacer"),
24
- h("span.faint.small", { title: t("record.revision") }, String(entry.ref.revision).slice(0, 24))));
25
- if (!entry.omitted && entry.value) {
26
- const value = entry.value;
27
- const text = value.content || value.summary || value.body || value.objective || value.title || value.leaderSummary;
28
- if (text) element.append(richText(null, text, t, { threshold: 360 }));
29
- if (entry.ref.store === "task-decision" && value.rationale) element.append(richText(t("record.rationale"), value.rationale, t, { muted: true }));
30
- const facts = [value.status, value.roleName].filter(Boolean);
31
- if (facts.length) element.append(h("p.faint.small", null, facts.join(" · ")));
32
- if (entry.ref.store === "job") element.append(note(t("job." + value.status + ".note", t("job.terminal.note")), value.status === "unknown-needs-attention" ? "warn" : ""));
33
- } else {
34
- element.append(h("p.faint", null, entry.summary || t("record.omitted")));
35
- }
36
- element.append(recordReader(entry, taskId, t, actions));
37
- return element;
38
- }
39
-
40
- // Shared source access for cards, history and discussion, including records
41
- // whose compact value is present but does not display every durable field.
42
- export function recordReader(entry, taskId, t, actions) {
43
- const element = h("div.stack");
44
- const expand = button(t("record.read"), { icon: "eye", variant: "link" });
45
- expand.addEventListener("click", async function () {
46
- expand.disabled = true;
47
- element.dataset.reading = "true";
48
- try {
49
- const result = await actions.inspect(taskId, entry.ref);
50
- if (result.result && result.result.output) element.append(richText(t("record.output"), result.result.output, t));
51
- if (result.result && result.result.diagnostic) element.append(richText(t("record.diagnostic"), result.result.diagnostic, t));
52
- element.append(h("pre.code-block", null, JSON.stringify(result.value, null, 2)));
53
- if (result.execution) element.append(h("pre.code-block", null, JSON.stringify(result.execution, null, 2)));
54
- expand.remove();
55
- } catch {
56
- expand.disabled = false;
57
- expand.replaceChildren(icon("refresh"), h("span", null, t("record.changed")));
58
- } finally { element.dataset.reading = "false"; }
59
- });
60
- element.append(h("div.record-actions", null, expand));
61
- return element;
62
- }
63
- `;
@@ -1,313 +0,0 @@
1
- export const SECTIONS_SCRIPT = String.raw `
2
- // Task sections behind the Work, Execution, History and Details tabs.
3
- import { h, icon, clear } from "/assets/js/dom.js";
4
- import { formatDateTime } from "/assets/js/format.js";
5
- import {
6
- sectionTitle, card, disclosure, emptyState, note, button, statusBadge, label, tone, dot, chip, mono,
7
- kv, richText, pagedList, workItemCard, runCard, reviewCard, roleCard, timeTag, observabilityMetricCard
8
- } from "/assets/js/components.js";
9
- import { entriesOf, valuesOf, recordCard, recordReader } from "/assets/js/records.js";
10
- import { renderEvidence } from "/assets/js/evidence.js";
11
- import { controlForm, titleForm } from "/assets/js/forms.js";
12
-
13
- function omittedNote(core, t) {
14
- return core.omitted.records ? t("records.notIncluded") : t("records.none");
15
- }
16
-
17
- // --- Work -------------------------------------------------------------------------
18
- export function renderWork(panel, data, t, locale, ctx) {
19
- const core = data.core;
20
- const items = entriesOf(core, "work-item");
21
- const titles = {};
22
- valuesOf(core, "work-item").forEach(function (item) { titles[item.id] = item.title; });
23
- const rank = function (entry) { return entry.omitted ? 1 : entry.value.status === "open" ? 0 : 2; };
24
- const sorted = items.slice().sort(function (a, b) {
25
- return rank(a) - rank(b) || Date.parse((b.value && b.value.updatedAt) || 0) - Date.parse((a.value && a.value.updatedAt) || 0);
26
- });
27
- const work = h("section.section", { id: "detail-work" }, sectionTitle(t("work.title"), items.length));
28
- if (!sorted.length) work.append(emptyState(omittedNote(core, t), "layers"));
29
- const list = h("div.stack");
30
- sorted.forEach(function (entry) {
31
- list.append(entry.omitted ? recordCard(entry, data.task.id, t, ctx) : workItemCard(entry.value, t, locale, titles));
32
- });
33
- work.append(list);
34
- panel.append(work);
35
-
36
- const results = h("section.section", { id: "detail-results" }, sectionTitle(t("evidence.title")));
37
- const resultsBody = h("div.card-grid.card-grid-1");
38
- renderEvidence(resultsBody, data, t, locale, ctx);
39
- results.append(resultsBody);
40
- panel.append(results);
41
-
42
- const reviews = entriesOf(core, "review-round");
43
- const reviewSection = h("section.section", { id: "detail-reviews" }, sectionTitle(t("reviews.title"), reviews.length));
44
- if (!reviews.length) reviewSection.append(emptyState(omittedNote(core, t)));
45
- else {
46
- reviewSection.append(note(t("reviews.hint")));
47
- const reviewList = h("div.stack");
48
- reviews.forEach(function (entry) {
49
- reviewList.append(entry.omitted ? recordCard(entry, data.task.id, t, ctx) : reviewCard(entry.value, t, locale));
50
- });
51
- reviewSection.append(reviewList);
52
- }
53
- panel.append(reviewSection);
54
- }
55
-
56
- // --- Execution --------------------------------------------------------------------
57
- export function renderExecution(panel, data, t, locale, ctx) {
58
- const core = data.core;
59
- const task = data.task;
60
- const runtimeRoles = (data.runtime && data.runtime.roles) || [];
61
- const runs = valuesOf(core, "run");
62
-
63
- const roleEntries = entriesOf(core, "role");
64
- const roles = h("section.section", { id: "detail-roles" }, sectionTitle(t("roles.title"), roleEntries.length));
65
- const roleGrid = h("div.role-grid");
66
- roleEntries.forEach(function (entry) {
67
- if (entry.omitted) { roleGrid.append(recordCard(entry, task.id, t, ctx)); return; }
68
- const role = entry.value;
69
- const active = runs.find(function (run) { return run.roleName === role.name && run.status === "active"; });
70
- const runtimeRole = runtimeRoles.find(function (item) { return item.name === role.name; });
71
- const element = roleCard(role, t, locale, {
72
- runtimeRole: runtimeRole,
73
- retry: entry.providerRetry,
74
- launchDrift: active && active.effective && active.effective.sourceDesiredRevision !== role.launchRevision,
75
- onOpen: task.status === "archived" ? null : ctx.openSession
76
- });
77
- const statusSlot = h("span", { dataset: { roleStatus: role.name } });
78
- element.querySelector(".role-head").append(statusSlot);
79
- if (!active) element.append(h("p.faint.small", null, t("roles.noActiveRun")));
80
- roleGrid.append(element);
81
- });
82
- if (!roleEntries.length) roleGrid.append(emptyState(omittedNote(core, t)));
83
- roles.append(roleGrid);
84
- panel.append(roles);
85
-
86
- const redirect = disclosure(t("control.title"), "control", { className: "card-disclosure", meta: t("control.meta") });
87
- redirect.body.append(note(t("control.help")), controlForm(task, t, ctx, roleEntries.map(function (entry) { return entry.ref.refId; })));
88
- panel.append(h("section.section", { id: "detail-control" }, redirect));
89
-
90
- const runEntries = entriesOf(core, "run");
91
- const runSection = h("section.section", { id: "detail-exec" });
92
- const filters = ["all", "active", "completed", "failed"];
93
- let filter = "all";
94
- const filterRow = h("div.chip-tabs", { role: "group", "aria-label": t("runs.filter") });
95
- const list = h("div.stack");
96
- function draw() {
97
- clear(list);
98
- const visible = runEntries.filter(function (entry) { return filter === "all" || (!entry.omitted && entry.value.status === filter); });
99
- if (!visible.length) { list.append(emptyState(omittedNote(core, t), "pulse")); return; }
100
- pagedList(list, visible, 12, function (entry) {
101
- return entry.omitted ? recordCard(entry, task.id, t, ctx) : runCard({ ...entry.value, execution: entry.execution }, t, locale);
102
- }, t);
103
- }
104
- filters.forEach(function (status) {
105
- const count = status === "all" ? runEntries.length : runs.filter(function (run) { return run.status === status; }).length;
106
- if (status !== "all" && !count) return;
107
- filterRow.append(h("button.chip-tab", {
108
- type: "button", "aria-pressed": String(status === filter), dataset: { status },
109
- onclick: function () {
110
- filter = status;
111
- filterRow.querySelectorAll(".chip-tab").forEach(function (b) { b.setAttribute("aria-pressed", String(b.dataset.status === status)); });
112
- draw();
113
- }
114
- }, status === "all" ? t("filter.all") : label(t, "run", status), h("span.count", null, String(count))));
115
- });
116
- runSection.append(sectionTitle(t("runs.title"), runEntries.length), note(t("runs.hint")), filterRow, list);
117
- draw();
118
- panel.append(runSection);
119
-
120
- const jobs = entriesOf(core, "job");
121
- const jobSection = h("section.section", { id: "detail-operations" }, sectionTitle(t("jobs.title"), jobs.length));
122
- if (!jobs.length) jobSection.append(emptyState(omittedNote(core, t)));
123
- else {
124
- jobSection.append(note(t("jobs.hint")));
125
- const jobList = h("div.stack");
126
- jobs.forEach(function (entry) {
127
- if (entry.omitted) { jobList.append(recordCard(entry, task.id, t, ctx)); return; }
128
- const job = entry.value;
129
- jobList.append(h("article.record", null,
130
- h("header.record-head", null, dot(tone("job", job.status)), mono(task.id + "/" + job.id), h("span.spacer"),
131
- statusBadge(t, "job", "job", job.status)),
132
- h("p.small", null, t("job." + job.status + ".note", t("job.terminal.note"))),
133
- h("p.faint.small", null, (job.steps || []).map(function (step) { return step.name; }).join(" → ")),
134
- timeTag(job.terminalAt || job.startedAt || job.createdAt, locale, t)));
135
- });
136
- jobSection.append(jobList);
137
- }
138
- panel.append(jobSection);
139
-
140
- const usage = h("section.section", { id: "detail-usage" }, sectionTitle(t("usage.title")));
141
- const usageBody = h("div", { dataset: { slot: "usage" } });
142
- const metrics = data.runtime && observabilityMetricCard(data.runtime.observability, t);
143
- usageBody.append(metrics || emptyState(t("usage.unavailable")));
144
- usage.append(usageBody);
145
- panel.append(usage);
146
-
147
- const observations = disclosure(t("observation.title"), "execution", { className: "card-disclosure" });
148
- observations.body.append(note(t("observation.help")));
149
- (core.observations || []).forEach(function (observation) {
150
- observations.body.append(h("p.small.mono-line", null,
151
- observation.source + " · " + observation.status + " · " + observation.coverage + " · " + observation.observedAt));
152
- });
153
- observations.body.append(h("p.faint.small", { dataset: { slot: "runtime-status" } }), h("pre.code-block", { dataset: { slot: "runtime-raw" } }));
154
- panel.append(h("section.section", null, observations));
155
- }
156
-
157
- // --- History ----------------------------------------------------------------------
158
- export function renderHistory(panel, data, t, locale, ctx) {
159
- const core = data.core;
160
- const task = data.task;
161
- const events = [];
162
- entriesOf(core, "task-decision").forEach(function (entry) { events.push({ kind: "decision", entry }); });
163
- entriesOf(core, "task-milestone").forEach(function (entry) { events.push({ kind: "milestone", entry }); });
164
- entriesOf(core, "task-message").forEach(function (entry) { events.push({ kind: "message", entry }); });
165
- const at = function (event) {
166
- const value = event.entry.value || {};
167
- return Date.parse(value.createdAt || value.updatedAt || 0) || 0;
168
- };
169
- events.sort(function (a, b) { return at(b) - at(a); });
170
- const section = h("section.section", { id: "detail-history" }, sectionTitle(t("history.title"), events.length));
171
- const kinds = ["all", "decision", "milestone", "message"];
172
- let kind = "all";
173
- const filterRow = h("div.chip-tabs", { role: "group", "aria-label": t("history.filter") });
174
- const list = h("ol.timeline");
175
- function draw() {
176
- clear(list);
177
- const visible = events.filter(function (event) { return kind === "all" || event.kind === kind; });
178
- if (!visible.length) { list.append(h("li.timeline-empty", null, emptyState(omittedNote(core, t), "history"))); return; }
179
- pagedList(list, visible, 20, function (event) { return timelineItem(event, task.id, t, locale, ctx); }, t);
180
- }
181
- kinds.forEach(function (value) {
182
- const count = value === "all" ? events.length : events.filter(function (event) { return event.kind === value; }).length;
183
- filterRow.append(h("button.chip-tab", {
184
- type: "button", "aria-pressed": String(value === kind), dataset: { kind: value },
185
- onclick: function () {
186
- kind = value;
187
- filterRow.querySelectorAll(".chip-tab").forEach(function (b) { b.setAttribute("aria-pressed", String(b.dataset.kind === value)); });
188
- draw();
189
- }
190
- }, t("history." + value), h("span.count", null, String(count))));
191
- });
192
- section.append(filterRow, list);
193
- if (core.omitted.records) section.append(note(t("history.omitted")));
194
- draw();
195
- panel.append(section);
196
- }
197
-
198
- function timelineItem(event, taskId, t, locale, ctx) {
199
- const entry = event.entry;
200
- const item = h("li.timeline-item.kind-" + event.kind);
201
- item.append(h("span.timeline-mark", { "aria-hidden": "true" }, icon(event.kind === "decision" ? "check" : event.kind === "milestone" ? "flag" : "chat", "icon-sm")));
202
- if (entry.omitted) { item.append(recordCard(entry, taskId, t, ctx, { compact: true })); return item; }
203
- const value = entry.value;
204
- const body = h("div.timeline-body");
205
- if (event.kind === "message") {
206
- const author = (value.author && value.author.roleName) || label(t, "author", (value.author && value.author.type) || "system");
207
- body.append(h("header.timeline-head", null, h("strong", null, author),
208
- value.kind ? chip(label(t, "messageKind", value.kind)) : null,
209
- value.intent ? chip(label(t, "intent", value.intent)) : null,
210
- h("span.spacer"), timeTag(value.createdAt, locale, t)));
211
- body.append(richText(null, value.body || "", t, { threshold: 480 }));
212
- if (value.resultRef) body.append(h("p.faint.small", null, t("history.resultOf") + " ", mono(value.resultRef.runId)));
213
- } else if (event.kind === "decision") {
214
- body.append(h("header.timeline-head", null, h("strong", null, value.title),
215
- value.status ? statusBadge(t, "decision", "decision", value.status) : null, h("span.spacer"), timeTag(value.createdAt, locale, t)));
216
- if (value.rationale) body.append(richText(null, value.rationale, t, { muted: true }));
217
- if (value.supersededReason) body.append(richText(t("history.superseded"), value.supersededReason, t, { muted: true }));
218
- } else {
219
- body.append(h("header.timeline-head", null, h("strong", null, value.title), h("span.spacer"), timeTag(value.createdAt, locale, t)));
220
- if (value.summary) body.append(richText(null, value.summary, t, { muted: true }));
221
- }
222
- body.append(h("p.faint.small", null, mono(entry.ref.refId)));
223
- body.append(recordReader(entry, taskId, t, ctx));
224
- item.append(body);
225
- return item;
226
- }
227
-
228
- // --- Details ----------------------------------------------------------------------
229
- export function renderDetails(panel, data, t, locale, ctx) {
230
- const task = data.task;
231
- const core = data.core;
232
- const facts = card({ title: t("details.facts"), icon: "file" });
233
- facts.body.append(kv([
234
- [t("details.id"), mono(task.id)],
235
- [t("details.status"), statusBadge(t, "task", "status", task.status)],
236
- [t("details.priority"), task.priority ? label(t, "priority", task.priority) : null],
237
- [t("details.tags"), (task.tags || []).length ? h("span.chip-row", null, task.tags.map(function (tag) { return chip(tag); })) : null],
238
- [t("details.projects"), (task.projectBindings || []).length ? h("span.chip-row", null, task.projectBindings.map(function (b) { return chip(b.projectId); })) : null],
239
- [t("details.created"), formatDateTime(task.createdAt, locale)],
240
- [t("details.updated"), formatDateTime(task.updatedAt, locale)],
241
- [t("details.workspace"), task.cwd ? mono(task.cwd) : null]
242
- ]));
243
- const edit = card({ title: t("details.title"), icon: "sparkle" });
244
- edit.body.append(titleForm(task, t, ctx));
245
- const grid = h("div.card-grid");
246
- grid.append(facts, edit);
247
- panel.append(h("section.section", { id: "detail-facts" }, grid));
248
-
249
- const context = disclosure(t("details.context"), "context", { className: "card-disclosure" });
250
- context.body.append(h("pre.code-block", null, JSON.stringify({
251
- coreCursor: core.coreCursor, throughCursor: core.throughCursor, count: core.count, omitted: core.omitted
252
- }, null, 2)), note(t("details.contextHelp")));
253
- panel.append(h("section.section", null, context));
254
-
255
- const panels = disclosure(t("panels.title"), "panels", { className: "card-disclosure" });
256
- let loading = false;
257
- panels.addEventListener("toggle", async function () {
258
- if (!panels.open || loading) return;
259
- loading = true;
260
- clear(panels.body);
261
- panels.body.append(h("p.faint", null, t("panels.reading")));
262
- try {
263
- const current = await ctx.panels(task.id);
264
- clear(panels.body);
265
- panels.body.append(h("p.faint.small", null, t("panels.observed") + " " + formatDateTime(current.observedAt, locale)));
266
- if (!current.panels.length) panels.body.append(emptyState(t("panels.none")));
267
- current.panels.forEach(function (item) { panels.body.append(panelCard(item, task, t, ctx)); });
268
- } catch (error) {
269
- clear(panels.body);
270
- panels.body.append(note(t("panels.unavailable") + " " + error.message, "bad"));
271
- } finally { loading = false; }
272
- });
273
- panel.append(h("section.section", null, panels));
274
- }
275
-
276
- function panelCard(item, task, t, ctx) {
277
- const panel = item.panel;
278
- const element = h("article.record", null,
279
- h("header.record-head", null, h("strong", null, panel.title), h("span.spacer"), h("span.faint.small", null, item.capability + " · " + item.provider.id)));
280
- if (item.unavailable) { element.append(note(item.unavailable, "warn")); return element; }
281
- if (panel.kind === "text") element.append(h("p.small", null, panel.text));
282
- else if (panel.kind === "link") {
283
- try {
284
- const url = new URL(panel.href);
285
- if (["http:", "https:"].includes(url.protocol) && !url.username && !url.password) {
286
- element.append(h("a.link", { href: url.href, rel: "noopener noreferrer", target: "_blank" }, panel.title));
287
- }
288
- } catch {}
289
- } else if (panel.kind === "data" && panel.renderer === "json") {
290
- const input = h("textarea.mono", { rows: 3 });
291
- input.value = JSON.stringify({ taskId: task.id });
292
- const schema = disclosure(t("panels.schema"), null);
293
- schema.body.append(h("pre.code-block", null, JSON.stringify(item.inputSchema, null, 2)));
294
- const output = h("pre.code-block");
295
- output.hidden = true;
296
- const read = button(t("panels.read"), { icon: "eye", variant: "ghost" });
297
- read.addEventListener("click", async function () {
298
- if (read.disabled) return;
299
- read.disabled = true;
300
- output.hidden = false;
301
- try {
302
- const result = await ctx.readPanel(task.id, {
303
- capability: item.capability, contractVersion: item.contractVersion, provider: item.provider
304
- }, JSON.parse(input.value));
305
- output.textContent = JSON.stringify(result, null, 2);
306
- } catch (error) { output.textContent = t("panels.unavailable") + " " + error.message; }
307
- finally { read.disabled = false; }
308
- });
309
- element.append(h("label.field", null, h("span", null, t("panels.input")), input), schema, h("div.form-actions", null, read), output);
310
- }
311
- return element;
312
- }
313
- `;
@@ -1,71 +0,0 @@
1
- export const THEME_SCRIPT = String.raw `
2
- // Theme preference. "system" follows prefers-color-scheme and resolves to
3
- // sumi (dark) or washi (light); the resolved name is stamped on <html> so the
4
- // token blocks in styles/tokens.ts apply. To add a theme, append it here and
5
- // add its token block.
6
- import { h } from "/assets/js/dom.js";
7
-
8
- export const THEMES = Object.freeze([
9
- { id: "system", swatch: ["#141518", "#fbfaf7", "#ff7a52"] },
10
- { id: "sumi", swatch: ["#0e0f11", "#191a1e", "#ff7a52"] },
11
- { id: "washi", swatch: ["#f4f2ed", "#ffffff", "#d24a26"] },
12
- { id: "ai", swatch: ["#0a0e1a", "#141a2e", "#8fa8ff"] }
13
- ]);
14
- const IDS = THEMES.map(function (theme) { return theme.id; });
15
-
16
- function storedPreference() {
17
- try {
18
- const saved = localStorage.getItem("yui.theme");
19
- return IDS.includes(saved) ? saved : "system";
20
- } catch { return "system"; }
21
- }
22
-
23
- export function createThemeController(container, t) {
24
- const media = window.matchMedia("(prefers-color-scheme: light)");
25
- let preference = storedPreference();
26
- const listeners = new Set();
27
-
28
- function resolved() {
29
- return preference === "system" ? (media.matches ? "washi" : "sumi") : preference;
30
- }
31
- function apply() {
32
- document.documentElement.dataset.theme = resolved();
33
- if (container) container.querySelectorAll("[data-theme-option]").forEach(function (button) {
34
- button.setAttribute("aria-pressed", String(button.dataset.themeOption === preference));
35
- });
36
- listeners.forEach(function (listener) { listener(resolved()); });
37
- }
38
- function render() {
39
- if (!container) return;
40
- container.replaceChildren.apply(container, THEMES.map(function (theme) {
41
- const swatch = h("span.theme-swatch", { "aria-hidden": "true" },
42
- theme.swatch.map(function (color, index) {
43
- const part = h("i");
44
- part.style.background = color;
45
- part.dataset.part = String(index);
46
- return part;
47
- }));
48
- return h("button.theme-option", {
49
- type: "button",
50
- dataset: { themeOption: theme.id },
51
- onclick: function () { set(theme.id); }
52
- }, swatch, h("span", null, t("theme." + theme.id)));
53
- }));
54
- apply();
55
- }
56
- function set(next) {
57
- if (!IDS.includes(next)) return;
58
- preference = next;
59
- try { localStorage.setItem("yui.theme", next); } catch {}
60
- apply();
61
- }
62
- media.addEventListener("change", function () { if (preference === "system") apply(); });
63
- render();
64
- return {
65
- resolved: resolved,
66
- render: render,
67
- set: set,
68
- subscribe: function (listener) { listeners.add(listener); }
69
- };
70
- }
71
- `;