ワンクリックで
static-ui
维护和扩展 PSOP 静态前端 UI,遵守本地资源、TailwindCSS v4、Alpine.js 和应用壳约束。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
维护和扩展 PSOP 静态前端 UI,遵守本地资源、TailwindCSS v4、Alpine.js 和应用壳约束。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
当需要把冻结的 PSOP Skill source、manifest snapshot 和 runtime 约束编译为 formal-v5 PSOP-EG candidate 时使用此 Skill。
当 psop.runner 需要在 PSOP Runtime 节点中生成受治理的终端引导、参考图片选择和现场证据评估 observation 时使用此 Skill。
当需要根据用户目标、当前 PSOP Skill source、素材分析结果、参考资产和行业标准引用构建可审阅的 PSOP Skill draft candidate 时使用此 Skill。
Use this skill when designing, generating an MVP blueprint for, auditing, refactoring, or explaining an agentic harness for any domain. Covers provider-neutral agent architecture for OpenAI, Anthropic, and OpenAI-compatible APIs: agent loops, tool design, permissions, system prompts, planning, goals, context compaction, memory, skills, MCP/external connectors, observability, evals, prompt caching, agent-legible environments, feedback loops, and safety.
用于为 PSOP 设计或实现基于数据库的后台任务系统、worker 池、调度器、租约、重试、恢复和后台执行拓扑。
用于重构 PSOP 中基于 FastAPI 和 SQLAlchemy 的后端代码,尤其适用于包边界、领域分层、router/service/repository 分离和长期可维护性。
SOC 職業分類に基づく
| name | static-ui |
| description | 维护和扩展 PSOP 静态前端 UI,遵守本地资源、TailwindCSS v4、Alpine.js 和应用壳约束。 |
| allowed-tools | [] |
你是一个资深前端/全栈工程师,需要在本项目中维护/扩展“静态前端 UI”(位于项目根目录 static/)。要求可私有化部署(禁止外部 CDN),运行时不依赖 Node;但允许在开发/构建阶段使用 Node(安装依赖与编译 Tailwind)。
static/ 目录直接提供(本提示词默认不改后端代码)/ -> static/index.html/assets/*、/pages/*、/node_modules/* -> static/ 下同名目录/dashboard、/tasks、/symbols/... 等路由会 fallback 到 index.htmlh-14),展示当前页面标题、全局状态(例如:同步状态/连接状态)、右侧操作区(例如:用户/设置入口)h-14);侧边栏自身高度必须为 100% / h-dvh,不随着右侧内容滚动;菜单列表在侧边栏内部独立滚动;至少包含 3 个一级菜单项;支持高亮当前项fetch('pages/<route>.html') 动态加载页面片段;注入 DOM 后调用 Alpine.initTree(...) 激活新页面;主体区域必须 flex-1 min-h-0 overflow-hidden,页面片段应自适应充满可视区域static/ 下用 Node + PostCSS 编译 Tailwind 输入样式static/package.json/static/package-lock.json 为唯一事实来源;新增依赖必须同时更新 lockfile(用 npm install),不要手写改 lockfilestatic/package.json 为准)assets/css/material-symbols.css + assets/fonts/material-symbols-*.woff2项目根目录下的 static/ 即前端根目录:
static/ package.json(Node 依赖与脚本入口:CSS 构建、开发静态服务器、Jest) package-lock.json(锁定依赖解析结果;用于可复现安装) tailwind.config.js(Tailwind content 扫描范围与主题扩展) postcss.config.js(PostCSS 插件:@tailwindcss/postcss + autoprefixer) scripts/ build-css.cjs(编译 Tailwind:assets/css/style.css -> assets/css/style.compiled.css;支持 --watch) dev-server.cjs(本地 SPA 静态服务器:支持 History fallback;用于纯前端预览) assets/ css/ style.css(Tailwind 输入文件:@import "tailwindcss" + 少量 base 层修正) style.compiled.css(构建产物:index.html 默认引用该文件) material-symbols.css(Material Symbols 本地字体 @font-face 配置;woff2 位于 assets/fonts/) js/ init-alpine.js(统一注册 Alpine 组件/初始化) alpine.min.js(本地 Alpine 单文件副本;如改为从 /assets/js 引入可使用) utils/ kanban.js(通用工具:querystring/路由等) tests/...(Jest 前端单测) components/ frame.js(App Shell:菜单/路由/动态加载 pages 片段) dashboardPage.js / tasksPage.js / ...(各页面的 Alpine 组件逻辑) vendor/ qlibExprEditor.js(CodeMirror 相关:表达式编辑器等) fonts/(本地图标字体与字体文件) img/(图片资源:logo 等) data/(前端演示/本地数据:如 sample-kline.json) pages/ dashboard.html(页面片段:被 frame.js 动态插入主内容区) tasks.html / symbols.html / ...(其余页面片段,必须是“片段”而非完整 HTML 文档) index.html(入口页:App Shell 布局 + CSS/JS 引用 + importmap) readme.md(前端使用/开发说明) node_modules/(npm install 产物;不会提交 git,但会被后端作为静态文件提供给浏览器) .gitignore(忽略 node_modules)
static/assets/css/style.compiled.css:由 npm run build:css 或 npm run watch:css 生成/更新npm run build:css:执行 node scripts/build-css.cjs(编译一次)npm run watch:css:执行 node scripts/build-css.cjs --watch(监听并增量编译)npm run dev:执行 node scripts/dev-server.cjs(History 模式预览用)npm test:执行 Jest(用于 assets/js/**/__tests__)@tailwindcss/postcss 作为 PostCSS 插件(见 static/postcss.config.js)static/tailwind.config.js 的 content,并且我会额外确保它覆盖到那些“动态拼接 class”的 JS 文件,避免样式被 tree-shake 掉。static/tailwind.config.js 当前 content 覆盖:
./*.html(入口)./pages/**/*.html(页面片段)
若你在 JS 中拼接 Tailwind class(字符串模板),需要把对应 JS 路径加入 content 扫描,否则样式可能不会被生成。pages/*.html 必须是片段:不要包含 <!doctype> / <html> / <head> / <body> / <script>x-data="xxxPage" 并在 assets/js/init-alpine.js 注册对应组件assets/js/components/frame.js 的 menuItems 与路由映射逻辑pages/*.html 是被 static/index.html 动态加载并注入的片段,因此片段内的资源引用(图片/链接等)必须以 index.html 的位置为基准写相对路径(例如 assets/img/...、node_modules/...),不要写成相对于 pages/ 目录的 ../assets/...。static/index.html 作为“Layout Cookbook/风格对齐页”,用于快速复制页面骨架与响应式写法;不承担复杂业务逻辑p-* / mx-auto / max-w-*),用“全高面板”贴边承载border-b、border-r、divide-y、divide-x 等细线分隔,而不是继续包一层带边框/圆角/阴影的面板h-full min-h-0 flex flex-col 链路;内容区使用 flex-1 min-h-0 overflow-auto,确保页面片段自适应吃满剩余可视高度与宽度shrink-0,内容区 flex-1 min-h-0 overflow-auto;避免让 body 或整个右侧区域因局部列表变长而滚动border + divide-y;内部内容用细线分隔;列表用 divide-y;尽量少用大阴影/大圆角做分隔flex-wrap;列表页搜索栏必须优先保持单行;按钮“图标常显、文案按断点隐藏(hidden sm:inline)”;输入控件 max-w-fulltasks / symbols / signals / alerts 等列表页)
border border-slate-800 bg-slate-900/40 overflow-hidden h-full flex flex-col min-h-0 divide-y divide-slate-800;这是该页面的唯一主要面板,内部不要再套同级别 border + rounded + shadow 的面板shrink-0 px-4 py-3 flex items-center gap-2 overflow-x-auto whitespace-nowrap;搜索输入可 flex-1 min-w-48,筛选控件 shrink-0,尽量将所有搜索条件放在同一行@input.debounce.300ms,select/date/tag 用 @change 或对应组件的变更回调)。清空某个控件即视为重置该条件flex-1 min-h-0 overflow-auto divide-y divide-slate-800;行:p-4 hover:bg-slate-900/50;行内:flex-col sm:flex-row 自适应flex flex-wrap gap-2p-4 grid grid-cols-1 min-[640px]:grid-cols-2 min-[1024px]:grid-cols-3 min-[1536px]:grid-cols-4 gap-4dashboard)
p-4 space-y-4;统计 tile:rounded-md border border-slate-800 bg-slate-900/40 p-4rounded-full border px-2 py-0.5 text-[11px])+ text-xs text-slate-400 truncate 错误提示symbol-detail / signal-detail)
h-20),其余区域 flex-1 min-h-0 并独立滚动(避免 body 整页滚动)absolute inset-0 + 半透明遮罩;覆盖层内容可用 max-w-* 居中并加内边距(覆盖层允许有边距)h-32),上方预留图例/筛选(避免图表挤占主列表空间)static/index.html 的现有引用方式保持一致):
static/index.html 的 importmap(将模块映射到 /node_modules/...)+ <script type="module" src="assets/js/vendor/qlibExprEditor.js"></script>;布局上让编辑器容器 flex-1 min-h-0,并确保 .cm-editor 可“吃满剩余高度”(优先配合 h-full/min-h-0)node_modules/lightweight-charts/dist/lightweight-charts.standalone.production.js 加载(当前项目已在 static/index.html 引用)node_modules/plotly.js/dist/plotly-basic.min.js 加载(当前项目已在 static/index.html 引用)/static/... 这种不存在的路径):
<!-- 样式(由 npm 构建产物 + 本地字体) -->
<link href="assets/css/material-symbols.css" rel="stylesheet" />
<link href="assets/css/style.compiled.css" rel="stylesheet" />
<!-- 运行时依赖(全部本地加载,不走外部 CDN) -->
<script src="node_modules/plotly.js/dist/plotly-basic.min.js"></script>
<script src="node_modules/lightweight-charts/dist/lightweight-charts.standalone.production.js"></script>
<script defer src="node_modules/alpinejs/dist/cdn.min.js"></script>
定位:深色优先、现代克制、偏“管理后台 / SaaS 控制台”风格;信息密度中等,强调可读性与状态表达
配色方案:
docs/engineering/ui-theme.md 若存在,则它是当前项目的配色重载事实来源;与本节默认值冲突时,以 docs/engineering/ui-theme.md 为准
本节只提供默认定义,保证该 skill 在脱离当前项目文档时仍可独立使用
后续改色时,项目内优先修改 docs/engineering/ui-theme.md;不要把项目主题差异直接堆回本节默认值
其它地方如出现颜色 class,应优先引用“Base / Primary / Danger / Warning / Info / Overlay”这些语义槽位,而不是分散定义
Base(中性基底 / Neutral Gray):
Primary(Orange,主交互):
Success(Emerald / Green,成功):
Danger(Rose,危险/错误):
Warning(Amber,警告):
Info(Sky,信息):
Overlay(遮罩,默认值):
主题:
字体与排版:
正文使用系统字体栈;图标字体例外:Material Symbols(必须自托管)
页面标题/区块标题层级清晰:标题 text-md/lg,正文 text-sm,辅助信息 text-xs/text-[11px]
行高与间距统一:正文 leading-6;常用内边距以 px-4 py-3(工具条)与 p-4(内容区)为主
元信息排版(必须区分样式):ID/时间/日期/时长/数值等统一使用更“技术化”的排版
布局与层级(无边距 / 面板化):
App Shell:外层使用 h-dvh overflow-hidden flex;顶部栏固定高度(默认 h-14);左侧品牌区高度必须与顶部栏一致(默认同为 h-14);侧边栏固定宽度(展开 w-48,折叠 w-14),并使用 h-full shrink-0 flex flex-col overflow-hidden,其中品牌区 shrink-0、菜单列表 flex-1 min-h-0 overflow-y-auto;主内容区使用 flex-1 min-w-0 min-h-0 overflow-hidden flex flex-col 并独立滚动
主内容区默认“无外边距/无卡片外框”:不要默认使用外层 rounded-/shadow/mx-auto/max-w-;页面主体用一个“全高面板”贴边承载,通过 border/divide-y/半透明背景区分结构
禁止面板套面板:页级全高面板内部默认不再嵌套同视觉重量的面板;需要组织内容时优先使用细线分割(border-b / border-r / divide-y / divide-x)、弱背景条或紧凑 tile,避免“卡片海”和重复圆角边框
全高面板推荐结构(需贯穿各视图一致):
flex flex-wrap;列表页搜索栏应使用单行 flex items-center gap-2 overflow-x-auto whitespace-nowrap)“小卡片/Tile”仅用于面板内部的局部信息块(如统计卡、视频卡、弹窗),圆角更小(优先 rounded-md,必要时 rounded-lg),不作为页面默认外框
组件风格(保持一致即可):
p-*border-b 分隔;编辑器本体优先 block w-full rounded-none border-0,仅保留文本阅读所需的 px-4 py-3p-4;不要同时保留“外层面板边框 + textarea 自身边框 + rounded-lg”;视觉目标是“面板即编辑器表面”,不是“面板里再嵌一张卡片”rounded-md border,大段文本编辑器优先使用贴边编辑器模式,不套用通用 textarea 卡片样式rounded-lg border border-slate-800 bg-slate-950/20 overflow-hidden;头部 px-4 py-3 border-b border-slate-800;错误行 px-4 py-3 text-xs text-rose-200 border-b border-rose-900/60;textarea block w-full h-64 rounded-none border-0 px-4 py-3 text-xs font-mono leading-5 resize-none focus:outline-nonereadonly,不可用 disabled(保留聚焦、选择与复制能力);按钮紧贴文本框右侧,按钮高度必须与文本框一致,图标使用 Material Symbols 的 content_copy / checkflex items-stretch min-w-0;文本框 h-11 flex-1 min-w-0 rounded-l-md rounded-r-none border border-r-0 ... font-mono select-all;按钮 h-11 w-11 shrink-0 rounded-l-none rounded-r-md ...。长 URL/路径仍放入 readonly input 中,通过横向光标/全选处理,不改成多行正文rounded-full border px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em];状态标签必须按状态语义区分 tone,不使用单一主色覆盖所有状态。成功/已发布/启用/已接受等代表成功含义的状态必须用 Emerald / Green,不得用 Primary Orange;运行中/编译中用 Sky,待处理/排队/草稿用 Amber,失败/拒绝/取消/超时用 Rose,归档/跳过/未知用 Slate。状态点同样按语义用对应色交互细节:
可视化区域规范(与本提示词要求的 3 个组件一致):
图标策略:
样式引入(入口页 static/index.html):
<!-- Material Symbols:本地字体图标(禁止外部 CDN) -->
<link href="assets/css/material-symbols.css" rel="stylesheet" />
图标使用方式:
<!-- 空心 Outlined 风格 -->
<span class="material-symbols-outlined">menu</span>
<!-- 实心 Rounded 风格 -->
<span class="material-symbols-rounded">settings</span>
/static/... 这种不存在的路径)assets/css/material-symbols.css + assets/fonts/*.woff2)docs/engineering/ui-theme.md,验收时配色应以该文档为准;本 skill 中的配色表仅作为默认值h-14)h-full / h-dvh,不随右侧主内容滚动;菜单列表只在侧栏内部滚动fetch('pages/<route>.html') 动态加载页面片段Alpine.initTree(...) 激活新页面assets/js/components/frame.js 的路由切换逻辑里:在 innerHTML 赋值后应立即对注入容器执行 Alpine.initTree(container),确保新 DOM 被 Alpine 识别(不要延后到下一次交互才初始化)。h-full min-h-0 flex flex-col 链路,页面内容应自适应充满可视区域h-full min-h-0 flex flex-col,并让页级面板吃满可视区域pages/*.html 必须是片段:不要包含 <!doctype> / <html> / <head> / <body> / <script>x-data="xxxPage" 并在 assets/js/init-alpine.js 注册对应组件assets/js/components/frame.js 的 menuItems 与路由映射逻辑static/index.html:片段里用 assets/...、node_modules/... 等路径;不要写 ../assets/...(因为浏览器解析相对路径时基于当前 document,即 index.html)。使用 @tailwindcss/postcss 作为 PostCSS 插件(见 static/postcss.config.js)
Tailwind v4 默认具备自动扫描能力,但本项目以 static/tailwind.config.js 的 content 为准;若存在动态 class(字符串模板/拼接),必须把对应 JS 文件路径补进 content,避免样式缺失。
static/tailwind.config.js 当前 content 覆盖:
./*.html(入口)./pages/**/*.html(页面片段)
若在 JS 中拼接 Tailwind class(字符串模板),需要把对应 JS 路径加入 content 扫描,否则样式可能不会被生成。static/assets/css/style.compiled.css 由 npm run build:css 或 npm run watch:css 生成/更新,并确保入口页引用正确
static/ 下用 Node + PostCSS 编译 Tailwind 输入样式static/package.json/static/package-lock.json 为唯一事实来源;新增依赖必须同时更新 lockfile(用 npm install),不要手写改 lockfile