@zq-silk/yui 2.3.0 → 2.5.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 +15 -1
- package/dist/artifacts/artifactCapability.js +39 -10
- package/dist/artifacts/imageMetadata.js +120 -0
- package/dist/artifacts/managedGit.js +7 -4
- package/dist/artifacts/taskArtifactRepository.js +6 -0
- package/dist/cli/commandCatalog.js +18 -9
- package/dist/cli/invocationAuthority.js +1 -1
- package/dist/commands/executionAuditCommands.js +5 -0
- package/dist/commands/globalRoleCommands.js +41 -3
- package/dist/commands/projectCommands.js +89 -94
- package/dist/commands/roleSkillValidation.js +4 -8
- package/dist/commands/taskCommands.js +65 -14
- package/dist/commands/taskUsageCommand.js +38 -0
- package/dist/context/roleSessionContext.js +18 -2
- package/dist/context/runContextPack.js +5 -1
- package/dist/context/sessionBootstrapManifest.js +18 -3
- package/dist/context/skillCatalog.js +108 -0
- package/dist/context/skillPackage.js +161 -0
- package/dist/context/taskContext.js +3 -2
- package/dist/context/taskSearch.js +127 -0
- package/dist/controlPlaneCli.js +25 -20
- package/dist/controller/fileSchedulerStoreAdapter.js +39 -8
- package/dist/controller/globalInputDelivery.js +2 -4
- package/dist/controller/jobControl.js +2 -0
- package/dist/controller/nativeHostInput.js +37 -0
- package/dist/controller/providerRetryDelivery.js +4 -2
- package/dist/controller/runtime.js +93 -2
- package/dist/controller/runtimeEventInbox.js +2 -2
- package/dist/controller/runtimeEventProcessor.js +3 -3
- package/dist/doctor/doctor.js +10 -0
- package/dist/execution/reviewMainRun.js +1 -0
- package/dist/execution/workItemMainRun.js +1 -0
- package/dist/executor/agentAdapter.js +3 -5
- package/dist/executor/codexConfigConflict.js +6 -4
- package/dist/executor/effectiveLaunch.js +24 -1
- package/dist/executor/fileRoleLaunchPlanner.js +15 -7
- package/dist/integration/gitIntegrationService.js +7 -12
- package/dist/integration/integrationSourceApplication.js +4 -2
- package/dist/interaction/notificationPresentation.js +85 -0
- package/dist/interaction/operatorPresentation.js +1 -2
- package/dist/job/httpPreview.js +61 -0
- package/dist/job/jobRunner.js +12 -2
- package/dist/kernel/builtinCapabilities.js +3 -1
- package/dist/message/message.js +15 -1
- package/dist/output/rolePresentation.js +4 -1
- package/dist/repository/executionLaneGitSnapshot.js +2 -1
- package/dist/repository/gitCompatibility.js +62 -0
- package/dist/repository/gitWorkspace.js +48 -71
- package/dist/repository/gitWorktreeInventory.js +121 -0
- package/dist/repository/project.js +74 -25
- package/dist/resources/resourceDiscovery.js +2 -2
- package/dist/resources/resourceGc.js +7 -4
- package/dist/resources/resourceRegistrar.js +2 -1
- package/dist/runtime/agentEndpoint.js +8 -0
- package/dist/runtime/agentHost.js +170 -3
- package/dist/runtime/codexAppServerRuntime.js +1 -1
- package/dist/runtime/codexNativeAccess.js +175 -0
- package/dist/runtime/controlledCodexTui.js +116 -0
- package/dist/runtime/publicReply.js +23 -0
- package/dist/runtime/runtimeObservation.js +48 -0
- package/dist/runtime/structuredProviderHost.js +16 -7
- package/dist/runtime/taskCostMetrics.js +133 -0
- package/dist/runtime/taskUsageMetrics.js +11 -2
- package/dist/runtime/taskUsageQuery.js +38 -0
- package/dist/scheduler/leaderWakeupProcessor.js +1 -9
- package/dist/scheduler/taskExecutionProjection.js +2 -0
- package/dist/scheduler/taskObservabilityProjection.js +9 -1
- package/dist/storage/homeLayout.js +13 -0
- package/dist/storage/sqliteSchema.js +44 -0
- package/dist/storage/sqliteStore.js +53 -0
- package/dist/storage/storageVersions.js +1 -1
- package/dist/storage/storeRpc.js +2 -0
- package/dist/storage/taskSearch.js +35 -0
- package/dist/storage/upgrade/projectKnowledgeMigration.js +52 -0
- package/dist/task/ordinaryArchive.js +42 -0
- package/dist/tmux/tmuxManager.js +8 -8
- package/dist/web/assets/assetManifest.js +11 -51
- package/dist/web/assets/client/app/catalog.js +215 -0
- package/dist/web/assets/client/app/main.js +148 -0
- package/dist/web/assets/client/app/selection.js +139 -0
- package/dist/web/assets/client/app/settings.js +326 -0
- package/dist/web/assets/client/app/taskView.js +280 -0
- package/dist/web/assets/client/domain/context.js +96 -0
- package/dist/web/assets/client/domain/records.js +126 -0
- package/dist/web/assets/client/domain/runs.js +119 -0
- package/dist/web/assets/client/domain/taskForms.js +197 -0
- package/dist/web/assets/client/domain/vocab.js +69 -0
- package/dist/web/assets/client/domain/work.js +116 -0
- package/dist/web/assets/client/i18n/en.js +900 -0
- package/dist/web/assets/client/i18n/zh-CN.js +898 -0
- package/dist/web/assets/client/index.js +114 -0
- package/dist/web/assets/client/layout/resizer.js +37 -0
- package/dist/web/assets/client/layout/router.js +35 -0
- package/dist/web/assets/client/layout/shortcuts.js +45 -0
- package/dist/web/assets/client/layout/sizing.js +95 -0
- package/dist/web/assets/client/layout/workspace.js +247 -0
- package/dist/web/assets/client/{api.js → lib/api.js} +20 -4
- package/dist/web/assets/client/{dom.js → lib/dom.js} +24 -12
- package/dist/web/assets/client/{format.js → lib/format.js} +7 -0
- package/dist/web/assets/client/lib/i18n.js +54 -0
- package/dist/web/assets/client/lib/markdown.js +167 -0
- package/dist/web/assets/client/lib/prefs.js +28 -0
- package/dist/web/assets/client/lib/theme.js +68 -0
- package/dist/web/assets/client/ui/containers.js +101 -0
- package/dist/web/assets/client/ui/controls.js +51 -0
- package/dist/web/assets/client/ui/forms.js +48 -0
- package/dist/web/assets/client/ui/metrics.js +137 -0
- package/dist/web/assets/client/ui/primitives.js +92 -0
- package/dist/web/assets/client/ui/text.js +33 -0
- package/dist/web/assets/client/ui/toast.js +12 -0
- package/dist/web/assets/client/views/bodySearch.js +172 -0
- package/dist/web/assets/client/views/createTask.js +85 -0
- package/dist/web/assets/client/views/dock/conversation.js +612 -0
- package/dist/web/assets/client/views/dock/discussion.js +173 -0
- package/dist/web/assets/client/views/dock/preview.js +129 -0
- package/dist/web/assets/client/views/dock/terminal.js +199 -0
- package/dist/web/assets/client/views/globalInput.js +67 -0
- package/dist/web/assets/client/{overview.js → views/overview.js} +61 -51
- package/dist/web/assets/client/{sidebar.js → views/sidebar.js} +56 -62
- package/dist/web/assets/client/views/skills.js +152 -0
- package/dist/web/assets/client/views/task/actions.js +36 -0
- package/dist/web/assets/client/views/task/delivery.js +185 -0
- package/dist/web/assets/client/views/task/deliveryResults.js +159 -0
- package/dist/web/assets/client/views/task/files.js +272 -0
- package/dist/web/assets/client/views/task/observation.js +153 -0
- package/dist/web/assets/client/views/task/overview.js +161 -0
- package/dist/web/assets/client/views/task/page.js +131 -0
- package/dist/web/assets/client/views/task/records.js +163 -0
- package/dist/web/assets/client/views/task/runtime.js +130 -0
- package/dist/web/assets/client/views/task/timeline.js +190 -0
- package/dist/web/assets/shared/geometry.js +19 -0
- package/dist/web/assets/shared/taskTabs.js +8 -0
- package/dist/web/assets/shared/themes.js +93 -0
- package/dist/web/assets/shell/dialogs.js +63 -0
- package/dist/web/assets/shell/dock.js +40 -0
- package/dist/web/assets/shell/index.js +40 -0
- package/dist/web/assets/shell/settings.js +34 -0
- package/dist/web/assets/shell/sidebar.js +45 -0
- package/dist/web/assets/styles/index.js +41 -0
- package/dist/web/assets/styles/{responsive.js → layout/responsive.js} +10 -10
- package/dist/web/assets/styles/{layout.js → layout/workspace.js} +17 -24
- package/dist/web/assets/styles/markdown.js +22 -3
- package/dist/web/assets/styles/tokens.js +10 -63
- package/dist/web/assets/styles/ui/controls.js +76 -0
- package/dist/web/assets/styles/ui/forms.js +46 -0
- package/dist/web/assets/styles/ui/surfaces.js +122 -0
- package/dist/web/assets/styles/views/delivery.js +29 -0
- package/dist/web/assets/styles/views/dock.js +71 -0
- package/dist/web/assets/styles/views/page.js +32 -0
- package/dist/web/assets/styles/views/records.js +70 -0
- package/dist/web/assets/styles/views/settings.js +26 -0
- package/dist/web/assets/styles/views/sidebar.js +74 -0
- package/dist/web/assets/styles/views/task.js +80 -0
- package/dist/web/assets/styles/views/terminal.js +38 -0
- package/dist/web/taskPreviews.js +205 -0
- package/dist/web/tmuxWebTerminal.js +16 -9
- package/dist/web/webConversation.js +373 -0
- package/dist/web/webMaterials.js +155 -0
- package/dist/web/webServer.js +295 -18
- package/dist/web/webSettings.js +331 -0
- package/dist/web/webSkills.js +86 -0
- package/dist/web/webSnapshot.js +40 -8
- package/dist/web/webTaskSurface.js +106 -8
- package/dist/workspace/gitChangeSetCapture.js +3 -1
- package/docs/cli-information-contract.md +1 -1
- package/docs/cli-information-contract.zh-CN.md +1 -1
- package/docs/managed-turn-and-session-runtime.md +31 -0
- package/docs/managed-turn-and-session-runtime.zh-CN.md +22 -0
- package/docs/release-workflow.md +54 -0
- package/docs/release-workflow.zh-CN.md +39 -0
- package/docs/storage-baseline.md +38 -1
- package/docs/storage-baseline.zh-CN.md +22 -0
- package/docs/task-discovery.md +28 -0
- package/docs/testing/verification-levels.md +2 -2
- package/i18n/README.zh-CN.md +1 -1
- package/package.json +1 -1
- package/skills/yui-leader/SKILL.md +5 -4
- package/skills/yui-leader/references/execution.md +2 -1
- package/skills/yui-operator/SKILL.md +3 -0
- package/skills/yui-reviewer/SKILL.md +4 -2
- package/skills/yui-runtime/SKILL.md +43 -2
- package/skills/yui-worker/SKILL.md +3 -2
- package/dist/web/assets/client/app.js +0 -808
- package/dist/web/assets/client/components.js +0 -477
- package/dist/web/assets/client/detail.js +0 -379
- package/dist/web/assets/client/dock.js +0 -309
- package/dist/web/assets/client/evidence.js +0 -364
- package/dist/web/assets/client/forms.js +0 -230
- package/dist/web/assets/client/i18n.js +0 -1277
- package/dist/web/assets/client/markdown.js +0 -114
- package/dist/web/assets/client/records.js +0 -198
- package/dist/web/assets/client/sections.js +0 -349
- package/dist/web/assets/client/theme.js +0 -71
- package/dist/web/assets/shell.js +0 -161
- package/dist/web/assets/styles/components.js +0 -216
- package/dist/web/assets/styles/views.js +0 -309
- /package/dist/web/assets/{icons.js → shared/icons.js} +0 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { SIDEBAR } from "../shared/geometry.js";
|
|
2
|
+
import { iconSvg } from "../shared/icons.js";
|
|
3
|
+
// The sidebar region and its resize divider: brand and sync state, search,
|
|
4
|
+
// the attention and status filter mounts, the task list, the catalog pager
|
|
5
|
+
// and the footer actions. The client renders the list and filter contents.
|
|
6
|
+
// The string keeps its indentation inside .app and has no trailing newline.
|
|
7
|
+
export const SIDEBAR_HTML = ` <aside class="sidebar" aria-label="Tasks" data-i18n-aria-label="sidebar.label">
|
|
8
|
+
<header class="side-head">
|
|
9
|
+
<div class="brand">
|
|
10
|
+
<span class="brand-mark" aria-hidden="true">結</span>
|
|
11
|
+
<span class="brand-name">Yui</span>
|
|
12
|
+
</div>
|
|
13
|
+
<span class="sync" id="sync-state" title="Last sync" data-i18n-title="sync.label">
|
|
14
|
+
<i aria-hidden="true"></i><time id="last-sync">—</time>
|
|
15
|
+
</span>
|
|
16
|
+
<button id="refresh" class="icon-btn" type="button" aria-label="Refresh" data-i18n-aria-label="actions.refresh" title="Refresh · R">${iconSvg("refresh")}</button>
|
|
17
|
+
</header>
|
|
18
|
+
<button id="create-task" class="btn btn-primary" type="button" data-i18n="create.title">New task</button>
|
|
19
|
+
<label class="search-field">
|
|
20
|
+
${iconSvg("search")}
|
|
21
|
+
<span class="sr-only" data-i18n="search.label">Search tasks</span>
|
|
22
|
+
<input id="search" type="search" autocomplete="off" spellcheck="false" placeholder="Search tasks" data-i18n-placeholder="search.placeholder">
|
|
23
|
+
<kbd>/</kbd>
|
|
24
|
+
</label>
|
|
25
|
+
<button id="body-search-open" class="foot-btn" type="button">${iconSvg("search")}<span data-i18n="bodySearch.title">Search task contents</span></button>
|
|
26
|
+
<div id="attention-bar" class="attention-bar" aria-live="polite"></div>
|
|
27
|
+
<div id="status-filters" class="status-tabs" role="group" aria-label="Filter by status" data-i18n-aria-label="filters.label"></div>
|
|
28
|
+
<div id="task-list" class="task-list" aria-label="Tasks" data-i18n-aria-label="sidebar.label" aria-live="polite"></div>
|
|
29
|
+
<div id="catalog-controls" class="pager" aria-live="polite">
|
|
30
|
+
<button id="catalog-reset" class="pager-btn" type="button" data-i18n="catalog.first">First page</button>
|
|
31
|
+
<span id="catalog-count" class="pager-count"></span>
|
|
32
|
+
<button id="catalog-next" class="pager-btn" type="button" data-i18n="catalog.next" disabled>Next page</button>
|
|
33
|
+
<button id="catalog-attention-reset" class="pager-clear" type="button" data-i18n="catalog.clearAttention" hidden>Clear attention filter</button>
|
|
34
|
+
</div>
|
|
35
|
+
<footer class="side-foot">
|
|
36
|
+
<button id="operator-terminal" class="foot-btn" type="button" title="Operator session · O">
|
|
37
|
+
${iconSvg("terminal")}<span data-i18n="actions.operator">Operator</span><kbd>O</kbd>
|
|
38
|
+
</button>
|
|
39
|
+
<button id="global-input-open" class="foot-btn" type="button" title="Global input" data-i18n-title="global.open">
|
|
40
|
+
${iconSvg("broadcast")}<span data-i18n="global.open">Global input</span>
|
|
41
|
+
</button>
|
|
42
|
+
<button id="settings-open" class="icon-btn" type="button" aria-label="Settings" data-i18n-aria-label="settings.title" title="Settings">${iconSvg("settings")}</button>
|
|
43
|
+
</footer>
|
|
44
|
+
</aside>
|
|
45
|
+
<div id="sidebar-divider" class="sidebar-divider" role="separator" tabindex="0" aria-orientation="vertical" aria-valuemin="${SIDEBAR.min}" aria-valuemax="${SIDEBAR.max}" aria-valuenow="${SIDEBAR.compact}" aria-label="Resize task list" data-i18n-aria-label="sidebar.resize" title="Drag to resize · double-click to reset" data-i18n-title="sidebar.resizeHint"><span aria-hidden="true"></span></div>`;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { FONT_FACE_STYLES } from "../fonts.js";
|
|
2
|
+
import { BASE_STYLES } from "./base.js";
|
|
3
|
+
import { RESPONSIVE_STYLES } from "./layout/responsive.js";
|
|
4
|
+
import { WORKSPACE_STYLES } from "./layout/workspace.js";
|
|
5
|
+
import { MARKDOWN_STYLES } from "./markdown.js";
|
|
6
|
+
import { TOKEN_STYLES } from "./tokens.js";
|
|
7
|
+
import { CONTROL_STYLES } from "./ui/controls.js";
|
|
8
|
+
import { FORM_STYLES } from "./ui/forms.js";
|
|
9
|
+
import { SURFACE_STYLES } from "./ui/surfaces.js";
|
|
10
|
+
import { DELIVERY_STYLES } from "./views/delivery.js";
|
|
11
|
+
import { DOCK_STYLES } from "./views/dock.js";
|
|
12
|
+
import { PAGE_STYLES } from "./views/page.js";
|
|
13
|
+
import { RECORD_STYLES } from "./views/records.js";
|
|
14
|
+
import { SIDEBAR_STYLES } from "./views/sidebar.js";
|
|
15
|
+
import { TASK_STYLES } from "./views/task.js";
|
|
16
|
+
import { TERMINAL_STYLES } from "./views/terminal.js";
|
|
17
|
+
import { SETTINGS_STYLES } from "./views/settings.js";
|
|
18
|
+
// The stylesheet registry, in cascade order: foundations (fonts, tokens,
|
|
19
|
+
// element defaults), the workspace frame, shared UI primitives, then one
|
|
20
|
+
// sheet per view, rendered prose, and breakpoints last so they override
|
|
21
|
+
// everything above. Each entry is served at /assets/css/<name>.css and linked
|
|
22
|
+
// by the shell in this order; later sheets may rely on earlier ones.
|
|
23
|
+
export const STYLESHEETS = Object.freeze([
|
|
24
|
+
{ name: "fonts", body: FONT_FACE_STYLES },
|
|
25
|
+
{ name: "tokens", body: TOKEN_STYLES },
|
|
26
|
+
{ name: "base", body: BASE_STYLES },
|
|
27
|
+
{ name: "layout/workspace", body: WORKSPACE_STYLES },
|
|
28
|
+
{ name: "ui/controls", body: CONTROL_STYLES },
|
|
29
|
+
{ name: "ui/surfaces", body: SURFACE_STYLES },
|
|
30
|
+
{ name: "ui/forms", body: FORM_STYLES },
|
|
31
|
+
{ name: "views/sidebar", body: SIDEBAR_STYLES },
|
|
32
|
+
{ name: "views/page", body: PAGE_STYLES },
|
|
33
|
+
{ name: "views/task", body: TASK_STYLES },
|
|
34
|
+
{ name: "views/records", body: RECORD_STYLES },
|
|
35
|
+
{ name: "views/delivery", body: DELIVERY_STYLES },
|
|
36
|
+
{ name: "views/dock", body: DOCK_STYLES },
|
|
37
|
+
{ name: "views/terminal", body: TERMINAL_STYLES },
|
|
38
|
+
{ name: "views/settings", body: SETTINGS_STYLES },
|
|
39
|
+
{ name: "markdown", body: MARKDOWN_STYLES },
|
|
40
|
+
{ name: "layout/responsive", body: RESPONSIVE_STYLES }
|
|
41
|
+
]);
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
+
import { BREAKPOINTS, SIDEBAR } from "../../shared/geometry.js";
|
|
1
2
|
/*
|
|
2
|
-
* RESPONSIVE — breakpoints only.
|
|
3
|
-
* ≤
|
|
4
|
-
* ≤
|
|
5
|
-
*
|
|
3
|
+
* RESPONSIVE — breakpoints only, from shared/geometry.ts.
|
|
4
|
+
* ≤ wide compact sidebar default and a three-column metric strip
|
|
5
|
+
* ≤ narrow master–detail: task list OR task page; the dock becomes a
|
|
6
|
+
* full-screen sheet over the task page
|
|
7
|
+
* ≤ small phone layout for page content
|
|
6
8
|
* Sidebar container queries adapt its footer to the width the user chose.
|
|
7
9
|
*/
|
|
8
10
|
export const RESPONSIVE_STYLES = `
|
|
9
11
|
@container sidebar (max-width:299px){
|
|
10
12
|
.foot-btn kbd{display:none}
|
|
11
|
-
.lazy-meta{display:none}
|
|
12
|
-
.lazy-body{padding-left:16px}
|
|
13
13
|
}
|
|
14
14
|
@container sidebar (max-width:259px){
|
|
15
15
|
.foot-btn{gap:0;padding:0 9px}
|
|
16
16
|
.foot-btn span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
|
|
17
17
|
}
|
|
18
|
-
@media(max-width
|
|
19
|
-
:root{--sidebar-w
|
|
18
|
+
@media(max-width:${BREAKPOINTS.wide}px){
|
|
19
|
+
:root{--sidebar-w:${SIDEBAR.compact}px}
|
|
20
20
|
.metric-strip{grid-template-columns:repeat(3,minmax(0,1fr))}
|
|
21
21
|
}
|
|
22
|
-
@media(max-width
|
|
22
|
+
@media(max-width:${BREAKPOINTS.narrow}px){
|
|
23
23
|
.app,body.dock-open .app,body.dock-open.dock-center .app{grid-template-areas:"main";grid-template-columns:minmax(0,1fr)}
|
|
24
24
|
.sidebar{grid-area:main;border-right:0}
|
|
25
25
|
.center{grid-area:main;display:none}
|
|
@@ -33,7 +33,7 @@ export const RESPONSIVE_STYLES = `
|
|
|
33
33
|
.dock-toggle span{display:none}
|
|
34
34
|
.dock-toggle{width:32px;padding:0}
|
|
35
35
|
}
|
|
36
|
-
@media(max-width
|
|
36
|
+
@media(max-width:${BREAKPOINTS.small}px){
|
|
37
37
|
.metric-strip{grid-template-columns:repeat(2,minmax(0,1fr))}
|
|
38
38
|
.page-head{padding-top:24px;flex-wrap:wrap}
|
|
39
39
|
.task-title{font-size:var(--fs-xl)}
|
|
@@ -1,28 +1,34 @@
|
|
|
1
1
|
/*
|
|
2
|
-
*
|
|
2
|
+
* WORKSPACE — the three-region application frame.
|
|
3
3
|
* sidebar | center (task details) | divider | dock (session)
|
|
4
4
|
* body.dock-open shows the dock; body.dock-center swaps the dock into the
|
|
5
5
|
* middle so the order becomes sidebar | dock | divider | center. The sidebar's
|
|
6
6
|
* own divider overlays its right edge, so it adds no grid column; --sidebar-w
|
|
7
|
-
* is the default width and a stored preference overrides it inline.
|
|
7
|
+
* is the default width and a stored preference overrides it inline. Region
|
|
8
|
+
* contents are styled by the view stylesheets.
|
|
8
9
|
*/
|
|
9
|
-
export const
|
|
10
|
+
export const WORKSPACE_STYLES = `
|
|
10
11
|
.app{display:grid;height:100vh;height:100dvh;grid-template-rows:minmax(0,1fr);
|
|
11
12
|
grid-template-areas:"sidebar center divider dock";
|
|
12
13
|
grid-template-columns:var(--sidebar-w) minmax(0,1fr) 0 0}
|
|
13
14
|
body.dock-open .app{grid-template-columns:var(--sidebar-w) minmax(0,1fr) var(--divider-w) var(--dock-w)}
|
|
14
15
|
body.dock-open.dock-center .app{grid-template-areas:"sidebar dock divider center";grid-template-columns:var(--sidebar-w) var(--dock-w) var(--divider-w) minmax(0,1fr)}
|
|
15
16
|
|
|
17
|
+
/* Resize dividers: a wide invisible hit area around a 1px rule that lights up
|
|
18
|
+
on hover, focus and while dragging. */
|
|
19
|
+
.sidebar-divider,.dock-divider{position:relative;cursor:col-resize;touch-action:none}
|
|
20
|
+
.sidebar-divider span,.dock-divider span{position:absolute;top:0;bottom:0;width:1px;transition:background var(--t-fast),box-shadow var(--t-fast)}
|
|
21
|
+
.sidebar-divider:hover span,.sidebar-divider:focus-visible span,body.sidebar-resizing .sidebar-divider span,
|
|
22
|
+
.dock-divider:hover span,.dock-divider:focus-visible span,body.dock-resizing .dock-divider span{background:var(--accent);box-shadow:0 0 0 1px var(--accent)}
|
|
23
|
+
.sidebar-divider:focus-visible,.dock-divider:focus-visible{box-shadow:none}
|
|
24
|
+
body.sidebar-resizing,body.dock-resizing{cursor:col-resize;user-select:none}
|
|
25
|
+
|
|
16
26
|
/* Sidebar */
|
|
17
27
|
.sidebar{grid-area:sidebar;display:flex;flex-direction:column;min-width:0;min-height:0;background:var(--surface);border-right:1px solid var(--line);container:sidebar/inline-size}
|
|
18
|
-
.sidebar-divider{grid-area:sidebar;justify-self:end;
|
|
19
|
-
.sidebar-divider span{
|
|
20
|
-
.sidebar-divider:hover span,.sidebar-divider:focus-visible span,body.sidebar-resizing .sidebar-divider span{background:var(--accent);box-shadow:0 0 0 1px var(--accent)}
|
|
21
|
-
.sidebar-divider:focus-visible{box-shadow:none}
|
|
22
|
-
body.sidebar-resizing{cursor:col-resize;user-select:none}
|
|
28
|
+
.sidebar-divider{grid-area:sidebar;justify-self:end;z-index:20;width:var(--divider-w);margin-right:-5px}
|
|
29
|
+
.sidebar-divider span{left:3px;background:transparent}
|
|
23
30
|
.side-head{flex:none;display:flex;align-items:center;gap:10px;height:var(--header-h);padding:0 12px 0 16px;border-bottom:1px solid var(--line)}
|
|
24
31
|
.brand{display:flex;align-items:center;gap:10px;flex:1;min-width:0}
|
|
25
|
-
.search-field{flex:none;margin:12px 12px 0}
|
|
26
32
|
.attention-bar{flex:none;margin:10px 12px 0}
|
|
27
33
|
.status-tabs{flex:none;margin:10px 0 0;padding:0 12px}
|
|
28
34
|
.task-list{flex:1;min-height:0;overflow-y:auto;padding:4px 8px 12px;scrollbar-gutter:stable}
|
|
@@ -34,27 +40,14 @@ body.sidebar-resizing{cursor:col-resize;user-select:none}
|
|
|
34
40
|
.center{grid-area:center;min-width:0;min-height:0;overflow-y:auto;scrollbar-gutter:stable;background:var(--canvas)}
|
|
35
41
|
.center:focus-visible{box-shadow:none}
|
|
36
42
|
.detail{min-height:100%}
|
|
37
|
-
.page{max-width:var(--center-max);margin:0 auto;padding:0 clamp(16px,3vw,40px) 64px}
|
|
38
|
-
|
|
39
|
-
/* Dock divider */
|
|
40
|
-
.dock-divider{grid-area:divider;position:relative;cursor:col-resize;touch-action:none;background:var(--canvas);z-index:5}
|
|
41
|
-
.dock-divider span{position:absolute;top:0;bottom:0;left:4px;width:1px;background:var(--line-2);transition:background var(--t-fast),box-shadow var(--t-fast)}
|
|
42
|
-
.dock-divider:hover span,.dock-divider:focus-visible span,body.dock-resizing .dock-divider span{background:var(--accent);box-shadow:0 0 0 1px var(--accent)}
|
|
43
|
-
.dock-divider:focus-visible{box-shadow:none}
|
|
44
|
-
body.dock-resizing{cursor:col-resize;user-select:none}
|
|
45
43
|
|
|
46
44
|
/* Dock */
|
|
45
|
+
.dock-divider{grid-area:divider;background:var(--canvas);z-index:5}
|
|
46
|
+
.dock-divider span{left:4px;background:var(--line-2)}
|
|
47
47
|
.dock{grid-area:dock;display:flex;flex-direction:column;min-width:0;min-height:0;background:var(--surface)}
|
|
48
48
|
body.dock-open:not(.dock-center) .dock{border-left:0}
|
|
49
49
|
.dock-head{flex:none;display:flex;align-items:center;justify-content:space-between;gap:8px;height:var(--header-h);padding:0 10px 0 12px;border-bottom:1px solid var(--line)}
|
|
50
50
|
.dock-actions{display:flex;gap:2px}
|
|
51
51
|
.dock-pane{flex:1;min-height:0;display:flex;flex-direction:column}
|
|
52
52
|
.dock-discussion{position:relative}
|
|
53
|
-
.dock-session{background:var(--term-bg)}
|
|
54
|
-
.session-bar{flex:none;display:flex;align-items:center;gap:8px;min-height:44px;padding:6px 10px;border-bottom:1px solid rgba(255,255,255,.07)}
|
|
55
|
-
.session-targets{display:flex;gap:4px;flex:1;min-width:0;overflow-x:auto;scrollbar-width:none}
|
|
56
|
-
.terminal-host{flex:1;min-height:0;padding:10px 4px 6px 12px;overflow:hidden}
|
|
57
|
-
.terminal-host:empty{display:none}
|
|
58
|
-
.terminal-empty{flex:1;display:grid;place-content:center;justify-items:center;gap:8px;padding:24px;text-align:center}
|
|
59
|
-
.session-foot{flex:none;display:flex;align-items:center;gap:8px;padding:8px 12px;border-top:1px solid rgba(255,255,255,.07)}
|
|
60
53
|
`;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* MARKDOWN — rendered Agent/user prose. .md is produced by
|
|
3
|
-
* (escaped HTML plus a small set of our own inline and
|
|
2
|
+
* MARKDOWN — rendered Agent/user prose. .md is produced by
|
|
3
|
+
* client/lib/markdown.ts (escaped HTML plus a small set of our own inline and
|
|
4
|
+
* block tags).
|
|
4
5
|
*/
|
|
5
6
|
export const MARKDOWN_STYLES = `
|
|
6
|
-
.md{display:grid;gap:7px;min-width:0;font-size:var(--fs-sm);line-height:1.62;color:var(--ink);overflow-wrap:anywhere}
|
|
7
|
+
.md{display:grid;grid-template-columns:minmax(0,1fr);gap:7px;min-width:0;font-size:var(--fs-sm);line-height:1.62;color:var(--ink);overflow-wrap:anywhere}
|
|
8
|
+
.md>*{min-width:0}
|
|
7
9
|
.md p{margin:0}
|
|
8
10
|
.md h4,.md h5,.md h6{margin:6px 0 0;font-weight:600;line-height:1.35}
|
|
9
11
|
.md h4{font-size:var(--fs-md)}
|
|
@@ -18,4 +20,21 @@ export const MARKDOWN_STYLES = `
|
|
|
18
20
|
.md a:hover{text-decoration-color:currentColor}
|
|
19
21
|
.md strong{font-weight:600}
|
|
20
22
|
.md.muted{color:var(--ink-2)}
|
|
23
|
+
.md blockquote{margin:0;padding:4px 14px;border-left:3px solid var(--line);color:var(--ink-2);display:grid;gap:7px}
|
|
24
|
+
.md hr{width:100%;border:0;border-top:1px solid var(--line)}
|
|
25
|
+
.md-table{max-width:100%;overflow:auto}
|
|
26
|
+
.md table{border-collapse:collapse;width:100%;font-size:inherit}
|
|
27
|
+
.md th,.md td{border:1px solid var(--line);padding:6px 10px;text-align:left}
|
|
28
|
+
.md th{background:var(--surface-3);font-weight:600}
|
|
29
|
+
.md li>p{display:inline}
|
|
30
|
+
.md li>ul,.md li>ol{margin-top:4px}
|
|
31
|
+
.md input[type=checkbox]{width:14px;height:14px;padding:0;margin:0 6px 0 0;vertical-align:middle;accent-color:var(--accent)}
|
|
32
|
+
.artifact-markdown{padding:16px;border:1px solid var(--line);border-radius:var(--r-md);background:var(--surface)}
|
|
33
|
+
.md-image-slot,.image-preview{display:block;min-width:0;max-width:100%;margin:8px 0}
|
|
34
|
+
.image-viewport{display:block;max-width:100%;max-height:70vh;overflow:auto;border:1px solid var(--line);border-radius:var(--r-md);background:var(--sunken)}
|
|
35
|
+
.artifact-image{display:block;max-width:100%;height:auto;margin:auto}
|
|
36
|
+
.artifact-image.is-zoomed{max-width:none;margin:0}
|
|
37
|
+
.image-preview .record-actions{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:8px}
|
|
38
|
+
.image-preview select{width:auto;max-width:100%}
|
|
39
|
+
.md-image-slot>.viewer-ref{display:block;overflow-wrap:anywhere}
|
|
21
40
|
`;
|
|
@@ -1,77 +1,24 @@
|
|
|
1
|
+
import { DIVIDER_WIDTH, DOCK } from "../shared/geometry.js";
|
|
2
|
+
import { themeTokenStyles } from "../shared/themes.js";
|
|
1
3
|
/*
|
|
2
4
|
* DESIGN TOKENS
|
|
3
5
|
* -------------
|
|
4
|
-
* Geometry, type,
|
|
5
|
-
* :root.
|
|
6
|
-
* theme can never move
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* sumi (墨) graphite dark, vermilion accent — default dark
|
|
10
|
-
* washi (和紙) warm paper light, vermilion accent — default light
|
|
11
|
-
* ai (藍) deep indigo dark, periwinkle accent
|
|
12
|
-
* "system" is not a token block: client/theme.ts resolves it to sumi or washi
|
|
13
|
-
* from prefers-color-scheme and stamps the resolved name on <html>.
|
|
14
|
-
*
|
|
15
|
-
* To add a theme: add a [data-theme="name"] block defining every colour token
|
|
16
|
-
* below, then register the name in client/theme.ts and the settings menu.
|
|
6
|
+
* Geometry, type, radii, motion and the focus ring are theme-independent and
|
|
7
|
+
* live once on :root. Colour and effect tokens come from the theme registry
|
|
8
|
+
* (shared/themes.ts), one block per theme, so switching a theme can never move
|
|
9
|
+
* or resize anything. Layout widths come from shared/geometry.ts, the same
|
|
10
|
+
* source the client layout controller clamps against.
|
|
17
11
|
*/
|
|
18
12
|
export const TOKEN_STYLES = `
|
|
19
13
|
:root{
|
|
20
14
|
--font-sans:"Inter",ui-sans-serif,system-ui,-apple-system,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;
|
|
21
15
|
--font-mono:"JetBrains Mono",ui-monospace,"SFMono-Regular",Menlo,Consolas,monospace;
|
|
22
16
|
--fs-2xs:10.5px;--fs-xs:11.5px;--fs-sm:12.5px;--fs-md:13.5px;--fs-lg:15px;--fs-xl:19px;--fs-2xl:24px;
|
|
23
|
-
--sp-1:4px;--sp-2:8px;--sp-3:12px;--sp-4:16px;--sp-5:20px;--sp-6:24px;--sp-8:32px;
|
|
24
17
|
--r-xs:5px;--r-sm:7px;--r-md:10px;--r-lg:14px;--r-pill:999px;
|
|
25
|
-
--sidebar-w:clamp(260px,21vw,312px);--dock-w
|
|
26
|
-
--center-max:880px;--header-h:56px;
|
|
18
|
+
--sidebar-w:clamp(260px,21vw,312px);--dock-w:${DOCK.initial}px;--divider-w:${DIVIDER_WIDTH}px;
|
|
19
|
+
--center-max:880px;--header-h:56px;--gutter:clamp(16px,3vw,40px);
|
|
27
20
|
--t-fast:120ms;--t-med:220ms;--ease:cubic-bezier(.2,.8,.2,1);
|
|
28
|
-
}
|
|
29
|
-
:root,[data-theme="sumi"]{
|
|
30
|
-
color-scheme:dark;
|
|
31
|
-
--canvas:#0e0f11;--surface:#141518;--surface-2:#191a1e;--surface-3:#202126;--sunken:#0b0c0d;
|
|
32
|
-
--line:rgba(255,255,255,.065);--line-2:rgba(255,255,255,.11);--line-3:rgba(255,255,255,.18);
|
|
33
|
-
--ink:#ececee;--ink-2:#b4b5bb;--ink-3:#85868e;--ink-4:#5c5d64;
|
|
34
|
-
--accent:#ff7a52;--accent-ink:#1a0c06;--accent-soft:rgba(255,122,82,.12);--accent-line:rgba(255,122,82,.38);
|
|
35
|
-
--info:#6cb6ff;--info-soft:rgba(108,182,255,.13);
|
|
36
|
-
--ok:#4fd18b;--ok-soft:rgba(79,209,139,.13);
|
|
37
|
-
--warn:#f5c065;--warn-soft:rgba(245,192,101,.14);
|
|
38
|
-
--bad:#ff6b7a;--bad-soft:rgba(255,107,122,.13);
|
|
39
|
-
--idle:#8e8f97;--idle-soft:rgba(142,143,151,.14);
|
|
40
|
-
--shadow-1:0 1px 0 rgba(255,255,255,.03) inset,0 1px 2px rgba(0,0,0,.35);
|
|
41
|
-
--shadow-2:0 12px 40px rgba(0,0,0,.5),0 2px 8px rgba(0,0,0,.35);
|
|
42
|
-
--focus:0 0 0 2px var(--canvas),0 0 0 4px var(--accent-line);
|
|
43
|
-
--term-bg:#0b0c0d;--term-fg:#e6e6e8;--term-cursor:#ff7a52;--term-sel:#3a2a24;
|
|
44
|
-
}
|
|
45
|
-
[data-theme="washi"]{
|
|
46
|
-
color-scheme:light;
|
|
47
|
-
--canvas:#f4f2ed;--surface:#fbfaf7;--surface-2:#ffffff;--surface-3:#f1eee7;--sunken:#ebe8e0;
|
|
48
|
-
--line:rgba(40,32,20,.08);--line-2:rgba(40,32,20,.13);--line-3:rgba(40,32,20,.22);
|
|
49
|
-
--ink:#1d1b18;--ink-2:#45413b;--ink-3:#77726a;--ink-4:#a39e95;
|
|
50
|
-
--accent:#d24a26;--accent-ink:#ffffff;--accent-soft:rgba(210,74,38,.09);--accent-line:rgba(210,74,38,.34);
|
|
51
|
-
--info:#1f6fd1;--info-soft:rgba(31,111,209,.09);
|
|
52
|
-
--ok:#17844f;--ok-soft:rgba(23,132,79,.1);
|
|
53
|
-
--warn:#a86500;--warn-soft:rgba(168,101,0,.1);
|
|
54
|
-
--bad:#c72f45;--bad-soft:rgba(199,47,69,.09);
|
|
55
|
-
--idle:#7a756c;--idle-soft:rgba(122,117,108,.11);
|
|
56
|
-
--shadow-1:0 1px 2px rgba(40,32,20,.06);
|
|
57
|
-
--shadow-2:0 16px 40px rgba(40,32,20,.16),0 2px 8px rgba(40,32,20,.08);
|
|
58
|
-
--focus:0 0 0 2px var(--canvas),0 0 0 4px var(--accent-line);
|
|
59
|
-
--term-bg:#1b1a18;--term-fg:#efece6;--term-cursor:#ff8a63;--term-sel:#4a3a32;
|
|
60
|
-
}
|
|
61
|
-
[data-theme="ai"]{
|
|
62
|
-
color-scheme:dark;
|
|
63
|
-
--canvas:#0a0e1a;--surface:#0f1424;--surface-2:#141a2e;--surface-3:#1a2139;--sunken:#080b15;
|
|
64
|
-
--line:rgba(160,180,255,.08);--line-2:rgba(160,180,255,.13);--line-3:rgba(160,180,255,.22);
|
|
65
|
-
--ink:#e7eaf6;--ink-2:#b0b7d2;--ink-3:#8088a8;--ink-4:#565e7d;
|
|
66
|
-
--accent:#8fa8ff;--accent-ink:#0a0e1a;--accent-soft:rgba(143,168,255,.13);--accent-line:rgba(143,168,255,.4);
|
|
67
|
-
--info:#6fd3ff;--info-soft:rgba(111,211,255,.12);
|
|
68
|
-
--ok:#5ad6a0;--ok-soft:rgba(90,214,160,.12);
|
|
69
|
-
--warn:#f2c46d;--warn-soft:rgba(242,196,109,.13);
|
|
70
|
-
--bad:#ff7d93;--bad-soft:rgba(255,125,147,.13);
|
|
71
|
-
--idle:#8a91ad;--idle-soft:rgba(138,145,173,.14);
|
|
72
|
-
--shadow-1:0 1px 0 rgba(255,255,255,.03) inset,0 1px 2px rgba(0,0,0,.4);
|
|
73
|
-
--shadow-2:0 14px 44px rgba(0,0,0,.55),0 2px 8px rgba(0,0,0,.4);
|
|
74
21
|
--focus:0 0 0 2px var(--canvas),0 0 0 4px var(--accent-line);
|
|
75
|
-
--term-bg:#080b15;--term-fg:#e2e6f5;--term-cursor:#8fa8ff;--term-sel:#26305a;
|
|
76
22
|
}
|
|
23
|
+
${themeTokenStyles()}
|
|
77
24
|
`;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* UI CONTROLS — interactive primitives shared by every view: tones, buttons,
|
|
3
|
+
* segmented controls, badges, dots, chips, chip tabs and the scrollable tab
|
|
4
|
+
* strips. Colour comes only from tokens.
|
|
5
|
+
*/
|
|
6
|
+
export const CONTROL_STYLES = `
|
|
7
|
+
/* Tones: one semantic colour per tone, used by dots, badges and signals */
|
|
8
|
+
.tone-info{--tone:var(--info);--tone-soft:var(--info-soft)}
|
|
9
|
+
.tone-ok{--tone:var(--ok);--tone-soft:var(--ok-soft)}
|
|
10
|
+
.tone-warn{--tone:var(--warn);--tone-soft:var(--warn-soft)}
|
|
11
|
+
.tone-bad{--tone:var(--bad);--tone-soft:var(--bad-soft)}
|
|
12
|
+
.tone-idle{--tone:var(--idle);--tone-soft:var(--idle-soft)}
|
|
13
|
+
.tone-accent{--tone:var(--accent);--tone-soft:var(--accent-soft)}
|
|
14
|
+
|
|
15
|
+
/* Buttons */
|
|
16
|
+
.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:32px;padding:0 12px;border:1px solid var(--line-2);border-radius:var(--r-sm);background:var(--surface-2);color:var(--ink);font-size:var(--fs-sm);font-weight:500;white-space:nowrap;transition:background var(--t-fast),border-color var(--t-fast),color var(--t-fast),transform var(--t-fast)}
|
|
17
|
+
.btn:hover:not(:disabled){border-color:var(--line-3);background:var(--surface-3)}
|
|
18
|
+
.btn:active:not(:disabled){transform:translateY(1px)}
|
|
19
|
+
.btn:disabled{opacity:.45}
|
|
20
|
+
.btn .icon{width:15px;height:15px}
|
|
21
|
+
.btn-primary{background:var(--accent);border-color:transparent;color:var(--accent-ink);font-weight:600}
|
|
22
|
+
.btn-primary:hover:not(:disabled){background:var(--accent);border-color:transparent;filter:brightness(1.08)}
|
|
23
|
+
.btn-ghost{background:transparent;border-color:transparent;color:var(--ink-2)}
|
|
24
|
+
.btn-ghost:hover:not(:disabled){background:var(--surface-3);border-color:transparent;color:var(--ink)}
|
|
25
|
+
.btn-ghost[aria-pressed="true"]{background:var(--accent-soft);color:var(--accent)}
|
|
26
|
+
.btn-link{height:auto;padding:2px 0;border:0;background:transparent;color:var(--accent);font-weight:500}
|
|
27
|
+
.btn-link:hover:not(:disabled){background:transparent;text-decoration:underline;text-underline-offset:3px}
|
|
28
|
+
.link-btn{justify-self:start;padding:0;border:0;background:none;color:var(--accent);font-size:var(--fs-xs);font-weight:500}
|
|
29
|
+
.link-btn:hover{text-decoration:underline;text-underline-offset:3px}
|
|
30
|
+
.icon-btn{display:inline-grid;place-items:center;width:32px;height:32px;flex:none;padding:0;border:0;border-radius:var(--r-sm);background:transparent;color:var(--ink-3);transition:background var(--t-fast),color var(--t-fast)}
|
|
31
|
+
.icon-btn:hover:not(:disabled){background:var(--surface-3);color:var(--ink)}
|
|
32
|
+
.icon-btn[aria-pressed="true"]{background:var(--accent-soft);color:var(--accent)}
|
|
33
|
+
.icon-btn:disabled{opacity:.4}
|
|
34
|
+
.icon-btn .icon{width:17px;height:17px}
|
|
35
|
+
|
|
36
|
+
/* Segmented control */
|
|
37
|
+
.seg{display:inline-flex;gap:2px;padding:3px;border-radius:var(--r-md);background:var(--sunken);border:1px solid var(--line)}
|
|
38
|
+
.seg-btn{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 11px;border:0;border-radius:var(--r-sm);background:transparent;color:var(--ink-3);font-size:var(--fs-sm);font-weight:500;white-space:nowrap;transition:background var(--t-fast),color var(--t-fast),box-shadow var(--t-fast)}
|
|
39
|
+
.seg-btn:hover:not(:disabled){color:var(--ink)}
|
|
40
|
+
.seg-btn[aria-selected="true"],.seg-btn[aria-checked="true"]{background:var(--surface-2);color:var(--ink);box-shadow:var(--shadow-1),0 0 0 1px var(--line-2)}
|
|
41
|
+
.seg-btn:disabled{opacity:.4}
|
|
42
|
+
.seg-btn .icon{width:15px;height:15px}
|
|
43
|
+
.seg-sm .seg-btn{height:24px;padding:0 9px;font-size:var(--fs-xs)}
|
|
44
|
+
|
|
45
|
+
/* Badges, dots, chips and inline text utilities */
|
|
46
|
+
.badge{display:inline-flex;align-items:center;gap:6px;height:22px;padding:0 8px;border-radius:var(--r-pill);background:var(--tone-soft,var(--idle-soft));color:var(--tone,var(--ink-2));font-size:var(--fs-xs);font-weight:600;white-space:nowrap;line-height:1}
|
|
47
|
+
.badge-dot{width:6px;height:6px;border-radius:50%;background:currentColor;flex:none}
|
|
48
|
+
.dot{display:inline-block;width:8px;height:8px;flex:none;border-radius:50%;background:var(--tone,var(--idle));box-shadow:0 0 0 3px var(--tone-soft,transparent)}
|
|
49
|
+
.chip{display:inline-flex;align-items:center;height:20px;padding:0 7px;border-radius:var(--r-xs);background:var(--surface-3);color:var(--ink-2);font-size:var(--fs-2xs);font-weight:500;white-space:nowrap}
|
|
50
|
+
.chip-strong{color:var(--ink);background:var(--line-2)}
|
|
51
|
+
.chip-row{display:inline-flex;flex-wrap:wrap;align-items:center;gap:4px}
|
|
52
|
+
code.id{padding:1px 6px;border-radius:var(--r-xs);background:var(--surface-3);color:var(--ink-2);font-size:var(--fs-2xs);white-space:nowrap}
|
|
53
|
+
.when{color:var(--ink-3);font-size:var(--fs-xs);white-space:nowrap}
|
|
54
|
+
.count{display:inline-grid;place-items:center;min-width:18px;height:18px;padding:0 5px;border-radius:var(--r-pill);background:var(--surface-3);color:var(--ink-3);font-size:10.5px;font-weight:600;line-height:1}
|
|
55
|
+
.spacer{flex:1}
|
|
56
|
+
.small{font-size:var(--fs-xs)}
|
|
57
|
+
.mono-line{font-family:var(--font-mono);font-size:var(--fs-2xs);overflow-wrap:anywhere}
|
|
58
|
+
|
|
59
|
+
/* Chip tabs (local filters) */
|
|
60
|
+
.chip-tabs{display:flex;flex-wrap:wrap;gap:6px}
|
|
61
|
+
.chip-tab{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 10px;border:1px solid var(--line-2);border-radius:var(--r-pill);background:transparent;color:var(--ink-3);font-size:var(--fs-xs);font-weight:500}
|
|
62
|
+
.chip-tab:hover{color:var(--ink);border-color:var(--line-3)}
|
|
63
|
+
.chip-tab[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:var(--canvas)}
|
|
64
|
+
.chip-tab[aria-pressed="true"] .count{background:rgba(127,127,127,.25);color:inherit}
|
|
65
|
+
|
|
66
|
+
/* Scrollable tab strips: task tabs (.tabs) and the sidebar status filters
|
|
67
|
+
(.tabs-row, which fades whichever edge still has more to scroll). The
|
|
68
|
+
selected tab draws an accent underline; each view sets its insets. */
|
|
69
|
+
.tabs,.tabs-row{display:flex;overflow-x:auto;scrollbar-width:none}
|
|
70
|
+
.tabs::-webkit-scrollbar,.tabs-row::-webkit-scrollbar{display:none}
|
|
71
|
+
.tabs-row{position:relative;gap:2px;padding-bottom:2px;border-bottom:1px solid var(--line)}
|
|
72
|
+
.tabs-row[data-fade="end"]{-webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 28px),transparent);mask-image:linear-gradient(90deg,#000 calc(100% - 28px),transparent)}
|
|
73
|
+
.tabs-row[data-fade="start"]{-webkit-mask-image:linear-gradient(90deg,transparent,#000 28px);mask-image:linear-gradient(90deg,transparent,#000 28px)}
|
|
74
|
+
.tabs-row[data-fade="both"]{-webkit-mask-image:linear-gradient(90deg,transparent,#000 28px,#000 calc(100% - 28px),transparent);mask-image:linear-gradient(90deg,transparent,#000 28px,#000 calc(100% - 28px),transparent)}
|
|
75
|
+
.status-tab[aria-pressed="true"]::after,.tab[aria-selected="true"]::after{content:"";position:absolute;height:2px;border-radius:2px;background:var(--accent)}
|
|
76
|
+
`;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* UI FORMS — form fields and rows, modal dialogs (settings with its theme
|
|
3
|
+
* swatches and shortcut list, global input) and the transient toast.
|
|
4
|
+
*/
|
|
5
|
+
export const FORM_STYLES = `
|
|
6
|
+
/* Forms */
|
|
7
|
+
.field{display:grid;gap:6px;min-width:0;margin:0;padding:0;border:0;font-size:var(--fs-sm)}
|
|
8
|
+
.field>span,.field>legend{color:var(--ink-2);font-size:var(--fs-xs);font-weight:500;padding:0}
|
|
9
|
+
.field-row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
|
|
10
|
+
.form-actions{display:flex;gap:8px;justify-content:flex-end}
|
|
11
|
+
.inline-form{display:grid;gap:8px}
|
|
12
|
+
.inline-row{display:flex;gap:8px}
|
|
13
|
+
.inline-row input{flex:1}
|
|
14
|
+
|
|
15
|
+
/* Dialogs */
|
|
16
|
+
.dialog{width:min(560px,calc(100vw - 32px));max-height:calc(100dvh - 48px);padding:0;overflow:auto;border:1px solid var(--line-2);border-radius:var(--r-lg);background:var(--surface);color:var(--ink);box-shadow:var(--shadow-2)}
|
|
17
|
+
.dialog::backdrop{background:rgba(0,0,0,.45);backdrop-filter:blur(2px)}
|
|
18
|
+
.dialog-body{display:grid;gap:16px;padding:20px}
|
|
19
|
+
.dialog-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}
|
|
20
|
+
.dialog-head h2{font-size:var(--fs-lg)}
|
|
21
|
+
.dialog-sub{margin-top:4px;color:var(--ink-3);font-size:var(--fs-xs)}
|
|
22
|
+
.dialog-actions{display:flex;gap:8px;justify-content:flex-end}
|
|
23
|
+
.settings-dialog{width:min(460px,calc(100vw - 32px))}
|
|
24
|
+
.body-search-dialog{width:min(880px,calc(100vw - 32px))}
|
|
25
|
+
.body-search-dialog .card-title{overflow-wrap:anywhere}
|
|
26
|
+
.body-search-dialog .dialog-actions{flex-wrap:wrap}
|
|
27
|
+
.body-search-dialog .card{min-width:0}
|
|
28
|
+
.body-search-dialog .search-source{width:100%;resize:vertical;line-height:1.6;white-space:pre-wrap}
|
|
29
|
+
.body-search-dialog .faint{overflow-wrap:anywhere}
|
|
30
|
+
.body-search-dialog .dialog-sub{overflow-wrap:anywhere}
|
|
31
|
+
.body-search-dialog .search-snippet{max-height:10em;overflow:auto}
|
|
32
|
+
.theme-options{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
|
|
33
|
+
.theme-option{display:grid;gap:8px;padding:8px;border:1px solid var(--line-2);border-radius:var(--r-md);background:var(--surface-2);text-align:left;font-size:var(--fs-sm);font-weight:500}
|
|
34
|
+
.theme-option:hover{border-color:var(--line-3)}
|
|
35
|
+
.theme-option[aria-pressed="true"]{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}
|
|
36
|
+
.theme-swatch{display:flex;height:34px;overflow:hidden;border-radius:var(--r-sm);border:1px solid var(--line)}
|
|
37
|
+
.theme-swatch i{flex:2}
|
|
38
|
+
.theme-swatch i[data-part="2"]{flex:1}
|
|
39
|
+
.shortcut-list{display:grid;grid-template-columns:max-content 1fr;gap:6px 14px;margin:0;font-size:var(--fs-sm);color:var(--ink-2)}
|
|
40
|
+
.shortcut-list dt{display:flex;gap:3px;align-items:center}
|
|
41
|
+
.shortcut-list dd{margin:0}
|
|
42
|
+
|
|
43
|
+
/* Toast */
|
|
44
|
+
.toast{position:fixed;left:50%;bottom:24px;z-index:90;max-width:min(520px,calc(100vw - 32px));padding:10px 16px;border:1px solid var(--line-2);border-radius:var(--r-md);background:var(--surface-2);color:var(--ink);box-shadow:var(--shadow-2);font-size:var(--fs-sm);opacity:0;transform:translate(-50%,8px);pointer-events:none;transition:opacity var(--t-med),transform var(--t-med) var(--ease)}
|
|
45
|
+
.toast.show{opacity:1;transform:translate(-50%,0)}
|
|
46
|
+
`;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* UI SURFACES — the reading column's building blocks: cards, list cards, lazy
|
|
3
|
+
* rows, disclosures, key/value lists, prose, notes, receipts, code, loading
|
|
4
|
+
* states and metrics. A card is a flat panel: a head (icon tile, title, count,
|
|
5
|
+
* hint, actions) above a hairline, then the body; list cards divide their
|
|
6
|
+
* rows with hairlines instead of nesting boxes.
|
|
7
|
+
*/
|
|
8
|
+
export const SURFACE_STYLES = `
|
|
9
|
+
/* Cards: actions wrap below the heading when the column is too narrow. Icon
|
|
10
|
+
tiles (brand mark, avatars, card icons) share one centring base. */
|
|
11
|
+
.brand-mark,.avatar,.msg-avatar,.card-icon{display:grid;place-items:center;flex:none}
|
|
12
|
+
.card{display:flex;flex-direction:column;min-width:0;border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface)}
|
|
13
|
+
.card-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px 16px;padding:12px 16px}
|
|
14
|
+
.card-heading{display:grid;gap:3px;flex:1 1 260px;min-width:0}
|
|
15
|
+
.card-title{display:flex;align-items:center;gap:10px;min-width:0;font-size:var(--fs-md);font-weight:600;color:var(--ink)}
|
|
16
|
+
.card-title>span:not(.card-icon):not(.count){min-width:0;overflow-wrap:anywhere}
|
|
17
|
+
.card-icon{width:24px;height:24px;border-radius:var(--r-sm);background:var(--surface-3);color:var(--ink-3)}
|
|
18
|
+
.card-icon .icon{width:14px;height:14px}
|
|
19
|
+
.card-hint{color:var(--ink-3);font-size:var(--fs-xs);line-height:1.45}
|
|
20
|
+
.card-heading:has(.card-icon) .card-hint{padding-left:34px}
|
|
21
|
+
.card-actions{display:flex;flex-wrap:wrap;align-items:center;gap:6px;min-width:0}
|
|
22
|
+
.card-actions>.btn-ghost:last-child{margin-right:-8px}
|
|
23
|
+
.card-body{display:grid;grid-template-columns:minmax(0,1fr);gap:12px;padding:14px 16px 16px;min-width:0}
|
|
24
|
+
.card-head+.card-body{border-top:1px solid var(--line)}
|
|
25
|
+
.card-body:empty,.card-body:has(> :only-child:empty){display:none}
|
|
26
|
+
.card-body>.btn-link{justify-self:start}
|
|
27
|
+
.card-stack{display:flex;flex-direction:column;gap:16px;min-width:0}
|
|
28
|
+
.stack{display:grid;gap:10px;min-width:0}
|
|
29
|
+
|
|
30
|
+
/* List cards: one row per record, divided by hairlines */
|
|
31
|
+
.list-card{overflow:hidden}
|
|
32
|
+
.list-card>.card-body{padding:0;gap:0}
|
|
33
|
+
.row-stack{display:grid;grid-template-columns:minmax(0,1fr);min-width:0}
|
|
34
|
+
.row-stack>:is(.work-card,.run-card,.review-card,.record,.role-card,.lazy-row){border:0;border-top:1px solid var(--line);border-radius:0;background:transparent;box-shadow:none}
|
|
35
|
+
.row-stack>:is(.work-card,.run-card,.review-card,.record,.role-card,.lazy-row):first-child,
|
|
36
|
+
.row-stack>.row-label+:is(.work-card,.run-card,.review-card,.record,.lazy-row){border-top:0}
|
|
37
|
+
.row-stack>:is(.run-card,.review-card,.record){padding:12px 16px}
|
|
38
|
+
.row-stack>.run-card[data-status="failed"]{box-shadow:inset 3px 0 0 var(--bad)}
|
|
39
|
+
.row-stack>.empty{margin:14px 16px}
|
|
40
|
+
.row-stack>.note{margin:12px 16px}
|
|
41
|
+
.row-stack>.show-more{margin:6px 16px 14px}
|
|
42
|
+
.row-stack>.row-stack{border-top:1px solid var(--line)}
|
|
43
|
+
.row-stack>.row-label{padding:12px 16px 2px;color:var(--ink-4);font-size:var(--fs-2xs);font-weight:600;letter-spacing:.04em}
|
|
44
|
+
.row-stack>.row-label:only-child{padding-bottom:12px}
|
|
45
|
+
.row-stack.boxed{border:1px solid var(--line);border-radius:var(--r-md);background:var(--surface);overflow:hidden}
|
|
46
|
+
.row-stack.boxed>:is(.record){padding:10px 14px}
|
|
47
|
+
.list-foot{display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px;min-width:0}
|
|
48
|
+
.list-foot:empty{display:none}
|
|
49
|
+
.row-stack>.list-foot{padding:8px 16px;border-top:1px solid var(--line)}
|
|
50
|
+
.card-body>.list-foot{padding-top:4px;border-top:1px solid var(--line)}
|
|
51
|
+
.list-foot>.faint{margin-right:auto}
|
|
52
|
+
|
|
53
|
+
/* Lazy rows: a list summary that reads its exact record when opened */
|
|
54
|
+
.lazy-row{min-width:0}
|
|
55
|
+
.lazy-head{display:flex;align-items:center;gap:10px;min-width:0;padding:11px 16px;list-style:none;cursor:pointer;font-size:var(--fs-sm)}
|
|
56
|
+
.lazy-head::-webkit-details-marker{display:none}
|
|
57
|
+
.lazy-head:hover .lazy-title{color:var(--ink)}
|
|
58
|
+
.lazy-head:focus-visible{box-shadow:inset 0 0 0 2px var(--accent-line)}
|
|
59
|
+
.lazy-title{flex:1;min-width:0;color:var(--ink-2);font-weight:500;overflow-wrap:anywhere}
|
|
60
|
+
.lazy-body{display:grid;grid-template-columns:minmax(0,1fr);gap:10px;min-width:0;padding:0 16px 14px 40px}
|
|
61
|
+
.lazy-content{display:grid;grid-template-columns:minmax(0,1fr);gap:12px;min-width:0}
|
|
62
|
+
[data-reading="true"]>.record-actions,.record[data-reading="true"]{opacity:.7}
|
|
63
|
+
|
|
64
|
+
/* Disclosures, inline and card-sized */
|
|
65
|
+
.disclosure{min-width:0;border-top:1px solid var(--line)}
|
|
66
|
+
.disclosure>summary{display:flex;align-items:center;gap:8px;padding:10px 0;list-style:none;cursor:pointer;color:var(--ink-2);font-size:var(--fs-sm);font-weight:500;user-select:none}
|
|
67
|
+
.disclosure>summary::-webkit-details-marker{display:none}
|
|
68
|
+
.disclosure>summary:hover{color:var(--ink)}
|
|
69
|
+
.disclosure-chevron{width:14px;height:14px;color:var(--ink-4);transition:transform var(--t-med) var(--ease)}
|
|
70
|
+
details[open]>summary .disclosure-chevron{transform:rotate(90deg)}
|
|
71
|
+
.disclosure-meta{margin-left:auto;color:var(--ink-4);font-size:var(--fs-xs);font-weight:400}
|
|
72
|
+
.disclosure-body{display:grid;grid-template-columns:minmax(0,1fr);gap:10px;padding:0 0 12px 22px;min-width:0}
|
|
73
|
+
.card-disclosure{border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface)}
|
|
74
|
+
.card-disclosure>summary{gap:10px;padding:12px 16px;border-radius:var(--r-lg);color:var(--ink);font-weight:600;font-size:var(--fs-md)}
|
|
75
|
+
.card-disclosure>summary .disclosure-chevron{box-sizing:content-box;padding:5px;border-radius:var(--r-sm);background:var(--surface-3);color:var(--ink-3)}
|
|
76
|
+
.card-disclosure[open]>summary{border-bottom:1px solid var(--line);border-radius:var(--r-lg) var(--r-lg) 0 0}
|
|
77
|
+
.card-disclosure>.disclosure-body{padding:14px 16px 16px}
|
|
78
|
+
|
|
79
|
+
/* Key/value lists and prose */
|
|
80
|
+
.kv{display:grid;grid-template-columns:minmax(96px,max-content) minmax(0,1fr);gap:7px 16px;margin:0;font-size:var(--fs-sm)}
|
|
81
|
+
.kv dt{color:var(--ink-3)}
|
|
82
|
+
.kv dd{margin:0;min-width:0;color:var(--ink);overflow-wrap:anywhere}
|
|
83
|
+
.kv dd code.id{white-space:normal;overflow-wrap:anywhere;-webkit-box-decoration-break:clone;box-decoration-break:clone}
|
|
84
|
+
.kv-compact{gap:3px 12px;font-size:var(--fs-xs)}
|
|
85
|
+
.prose-block{display:grid;gap:5px;min-width:0}
|
|
86
|
+
.prose-label{color:var(--ink-3);font-size:var(--fs-2xs);font-weight:600;text-transform:uppercase;letter-spacing:.06em}
|
|
87
|
+
.prose-block.is-collapsed .md{max-height:180px;overflow:hidden;-webkit-mask-image:linear-gradient(#000 65%,transparent);mask-image:linear-gradient(#000 65%,transparent)}
|
|
88
|
+
.callout{padding:10px 12px;border-radius:var(--r-md);background:var(--tone-soft,var(--surface-3));border-left:2px solid var(--tone,var(--line-3))}
|
|
89
|
+
.bullets{margin:0;padding-left:18px;display:grid;gap:3px;font-size:var(--fs-sm);color:var(--ink-2)}
|
|
90
|
+
.checklist{list-style:none;margin:0;padding:0;display:grid;gap:5px;font-size:var(--fs-sm)}
|
|
91
|
+
.checklist li{display:flex;gap:8px;align-items:flex-start;color:var(--ink-2)}
|
|
92
|
+
.checklist li .icon{margin-top:3px;color:var(--ink-4)}
|
|
93
|
+
.checklist li.is-done .icon{color:var(--ok)}
|
|
94
|
+
|
|
95
|
+
/* Notes, empty states, receipts, code, dashed "more" buttons, loading */
|
|
96
|
+
.note{padding:8px 11px;border-radius:var(--r-sm);background:var(--tone-soft,var(--surface-3));color:var(--ink-2);font-size:var(--fs-xs);line-height:1.5}
|
|
97
|
+
.note.tone-bad{color:var(--bad)}
|
|
98
|
+
.note.tone-warn{color:var(--ink)}
|
|
99
|
+
.empty{display:flex;align-items:center;gap:10px;padding:14px;border:1px dashed var(--line-2);border-radius:var(--r-md);color:var(--ink-3);font-size:var(--fs-sm)}
|
|
100
|
+
.empty .icon{color:var(--ink-4)}
|
|
101
|
+
.receipt{color:var(--ink-3);font-size:var(--fs-xs);overflow-wrap:anywhere}
|
|
102
|
+
.receipt[data-state="pending"]{color:var(--info)}
|
|
103
|
+
.receipt[data-state="ok"]{color:var(--ok)}
|
|
104
|
+
.receipt[data-state="warn"]{color:var(--warn)}
|
|
105
|
+
.receipt[data-state="bad"]{color:var(--bad)}
|
|
106
|
+
.code-block{margin:0;max-height:360px;overflow:auto;padding:10px 12px;border:1px solid var(--line);border-radius:var(--r-md);background:var(--sunken);color:var(--ink-2);font-size:var(--fs-2xs);line-height:1.55;white-space:pre-wrap;overflow-wrap:anywhere}
|
|
107
|
+
.show-more,.pager-clear{border:1px dashed var(--line-3);border-radius:var(--r-sm);background:transparent;color:var(--ink-3);font-size:var(--fs-xs)}
|
|
108
|
+
.show-more:hover,.pager-clear:hover{color:var(--accent);border-color:var(--accent-line)}
|
|
109
|
+
.show-more{justify-self:start;display:inline-flex;align-items:center;height:30px;padding:0 12px;font-weight:500}
|
|
110
|
+
.loading-block{display:flex;align-items:center;gap:10px;padding:32px 8px;color:var(--ink-3)}
|
|
111
|
+
.spinner{width:14px;height:14px;border-radius:50%;border:2px solid var(--line-3);border-top-color:var(--accent);animation:spin .8s linear infinite}
|
|
112
|
+
@keyframes spin{to{transform:rotate(360deg)}}
|
|
113
|
+
|
|
114
|
+
/* Metrics */
|
|
115
|
+
.metric{display:grid;gap:4px;align-content:start;min-width:0;padding:12px 14px;border:1px solid var(--line);border-radius:var(--r-md);background:var(--surface)}
|
|
116
|
+
.metric-label{color:var(--ink-3);font-size:var(--fs-xs)}
|
|
117
|
+
.metric-value{font-size:var(--fs-xl);font-weight:600;letter-spacing:-.02em;color:var(--tone,var(--ink));font-variant-numeric:tabular-nums;line-height:1.2}
|
|
118
|
+
.metric-note{color:var(--ink-4);font-size:var(--fs-2xs);line-height:1.4}
|
|
119
|
+
.metric-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:8px}
|
|
120
|
+
.usage{display:grid;gap:10px}
|
|
121
|
+
.usage-meta{display:flex;flex-wrap:wrap;gap:4px 16px;color:var(--ink-3);font-size:var(--fs-2xs)}
|
|
122
|
+
`;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* DELIVERY VIEW — the Delivery tab's results: delivery projects and their
|
|
3
|
+
* check lists, plus evidence files and the artifact viewer.
|
|
4
|
+
*/
|
|
5
|
+
export const DELIVERY_STYLES = `
|
|
6
|
+
/* Delivery results */
|
|
7
|
+
.delivery-stack>.sub-head:not(:first-child){margin-top:10px}
|
|
8
|
+
.delivery-project .record-head strong{overflow-wrap:anywhere}
|
|
9
|
+
.check-list{list-style:none;margin:0;padding:0;display:grid;gap:4px;font-size:var(--fs-xs)}
|
|
10
|
+
.check-list li{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:2px 8px;min-width:0}
|
|
11
|
+
.check-details{grid-column:2/-1;white-space:pre-wrap;overflow-wrap:anywhere}
|
|
12
|
+
|
|
13
|
+
/* Evidence files */
|
|
14
|
+
.file-list{display:grid;grid-template-columns:minmax(0,1fr);gap:2px}
|
|
15
|
+
.file-list:empty{display:none}
|
|
16
|
+
.file-row{display:flex;align-items:center;gap:8px;min-height:32px;padding:5px 8px;border:0;border-radius:var(--r-sm);background:transparent;text-align:left;font-size:var(--fs-sm);color:var(--ink-2)}
|
|
17
|
+
.file-row:hover{background:var(--surface-3);color:var(--ink)}
|
|
18
|
+
.file-row[aria-current="true"]{background:var(--accent-soft);color:var(--ink)}
|
|
19
|
+
.file-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--font-mono);font-size:var(--fs-xs)}
|
|
20
|
+
.file-viewer{display:grid;grid-template-columns:minmax(0,1fr);min-width:0;gap:8px}
|
|
21
|
+
.file-viewer:empty{display:none}
|
|
22
|
+
.viewer-head{display:flex;align-items:center;gap:8px;font-size:var(--fs-sm)}
|
|
23
|
+
.viewer-ref code{white-space:normal;overflow-wrap:anywhere}
|
|
24
|
+
.artifact-text{max-height:480px;color:var(--ink)}
|
|
25
|
+
.record-actions{flex-wrap:wrap}
|
|
26
|
+
.record-actions input{min-width:0;max-width:100%;flex:1 1 180px}
|
|
27
|
+
.composer-wrap .row-stack{overflow-wrap:anywhere;max-height:180px;overflow:auto}
|
|
28
|
+
.composer-wrap input[type=file]{max-width:100%}
|
|
29
|
+
`;
|