Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8e569b83a7 | |||
| 0f05385995 | |||
| fc22300937 | |||
| 4a0c5c4921 |
+16
-9
@@ -16,12 +16,19 @@ on:
|
|||||||
branches: [main]
|
branches: [main]
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
# runner 分配:
|
||||||
|
# · runs-on: ubuntu-latest —— 在 catthehacker 容器里跑,仅用于纯 bash 扫描
|
||||||
|
# (redline/cleartext/portable-sql);容器内**不能**嵌套 `docker run`(DinD 挂载
|
||||||
|
# 失败,$PWD 在宿主不存在),故套 docker 的 job 不能用它。
|
||||||
|
# · runs-on: nas —— host 模式(mac-pangolin-2 直接在宿主跑),`docker run` 是宿主
|
||||||
|
# 真 docker(非嵌套),可正常拉/跑 node/golang/flutter/python/shellcheck 镜像。
|
||||||
|
# golden 保留 ghcr.io/cirruslabs/flutter Linux 容器 → 与入库基线渲染一致。
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
# ── Job 1: Lint (shellcheck) ─────────────────────────────────────────────
|
# ── Job 1: Lint (shellcheck) ─────────────────────────────────────────────
|
||||||
lint:
|
lint:
|
||||||
name: Lint — shellcheck
|
name: Lint — shellcheck
|
||||||
runs-on: ubuntu-latest
|
runs-on: nas
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -74,7 +81,7 @@ jobs:
|
|||||||
# ── Job 2: OpenAPI Sync Check ────────────────────────────────────────────
|
# ── Job 2: OpenAPI Sync Check ────────────────────────────────────────────
|
||||||
openapi-check:
|
openapi-check:
|
||||||
name: OpenAPI Sync Check
|
name: OpenAPI Sync Check
|
||||||
runs-on: ubuntu-latest
|
runs-on: nas
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -113,7 +120,7 @@ jobs:
|
|||||||
# ── Job 4: Flutter 客户端(分析 + 单测/组件测试)────────────────────────
|
# ── Job 4: Flutter 客户端(分析 + 单测/组件测试)────────────────────────
|
||||||
flutter-client:
|
flutter-client:
|
||||||
name: Flutter — analyze + test
|
name: Flutter — analyze + test
|
||||||
runs-on: ubuntu-latest
|
runs-on: nas
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -149,7 +156,7 @@ jobs:
|
|||||||
# (改了 design/colors_and_type.css 没重生成,或手改了生成物)。
|
# (改了 design/colors_and_type.css 没重生成,或手改了生成物)。
|
||||||
codegen-drift:
|
codegen-drift:
|
||||||
name: Codegen Drift — token 生成物未漂移
|
name: Codegen Drift — token 生成物未漂移
|
||||||
runs-on: ubuntu-latest
|
runs-on: nas
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -163,7 +170,7 @@ jobs:
|
|||||||
|
|
||||||
ds-flow:
|
ds-flow:
|
||||||
name: DS-flow — 原型/跨端同源/代码色单源闸
|
name: DS-flow — 原型/跨端同源/代码色单源闸
|
||||||
runs-on: ubuntu-latest
|
runs-on: nas
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -182,7 +189,7 @@ jobs:
|
|||||||
# -tags integration(需 docker 起 mysql/redis),见 go-integration job。
|
# -tags integration(需 docker 起 mysql/redis),见 go-integration job。
|
||||||
go-server:
|
go-server:
|
||||||
name: Go — build + test
|
name: Go — build + test
|
||||||
runs-on: ubuntu-latest
|
runs-on: nas
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -208,7 +215,7 @@ jobs:
|
|||||||
# 详见 scripts/e2e-smoke.sh + server/test/e2e/。
|
# 详见 scripts/e2e-smoke.sh + server/test/e2e/。
|
||||||
e2e-smoke:
|
e2e-smoke:
|
||||||
name: E2E Smoke — L4 进程级端到端
|
name: E2E Smoke — L4 进程级端到端
|
||||||
runs-on: ubuntu-latest
|
runs-on: nas
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -232,7 +239,7 @@ jobs:
|
|||||||
# · -p 1 串行:一次只起一个 mysql 容器,避免并发把 Docker Desktop 压垮/端口资源争用。
|
# · -p 1 串行:一次只起一个 mysql 容器,避免并发把 Docker Desktop 压垮/端口资源争用。
|
||||||
go-integration:
|
go-integration:
|
||||||
name: Go — integration (mysql/redis testcontainers)
|
name: Go — integration (mysql/redis testcontainers)
|
||||||
runs-on: ubuntu-latest
|
runs-on: nas
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -247,7 +254,7 @@ jobs:
|
|||||||
# tablet/desktop-stats golden 与 stats-overhaul 工作区耦合,待其合并后并入本 job。
|
# tablet/desktop-stats golden 与 stats-overhaul 工作区耦合,待其合并后并入本 job。
|
||||||
golden:
|
golden:
|
||||||
name: Golden — 视觉回归 (全量:components/auth/desktop/tablet)
|
name: Golden — 视觉回归 (全量:components/auth/desktop/tablet)
|
||||||
runs-on: ubuntu-latest
|
runs-on: nas
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|||||||
@@ -8,14 +8,23 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:pangolin_vpn/bridge/vpn_bridge.dart';
|
import 'package:pangolin_vpn/bridge/vpn_bridge.dart';
|
||||||
import 'package:pangolin_vpn/bridge/vpn_bridge_provider.dart';
|
import 'package:pangolin_vpn/bridge/vpn_bridge_provider.dart';
|
||||||
|
import 'package:pangolin_vpn/l10n/app_text.dart';
|
||||||
import 'package:pangolin_vpn/l10n/strings_zh.dart';
|
import 'package:pangolin_vpn/l10n/strings_zh.dart';
|
||||||
import 'package:pangolin_vpn/models/node.dart';
|
import 'package:pangolin_vpn/models/node.dart';
|
||||||
import 'package:pangolin_vpn/services/connect_api.dart';
|
import 'package:pangolin_vpn/services/connect_api.dart';
|
||||||
import 'package:pangolin_vpn/services/device_identity.dart';
|
import 'package:pangolin_vpn/services/device_identity.dart';
|
||||||
|
import 'package:pangolin_vpn/state/app_providers.dart';
|
||||||
import 'package:pangolin_vpn/state/connection_provider.dart';
|
import 'package:pangolin_vpn/state/connection_provider.dart';
|
||||||
import 'package:pangolin_vpn/state/nodes_provider.dart';
|
import 'package:pangolin_vpn/state/nodes_provider.dart';
|
||||||
import 'package:pangolin_vpn/state/quota_provider.dart';
|
import 'package:pangolin_vpn/state/quota_provider.dart';
|
||||||
|
|
||||||
|
// localeProvider 现默认英文;测试硬编码 StringsZh 预期 → 钉死中文 locale。
|
||||||
|
class _FixedLocale extends LocaleNotifier {
|
||||||
|
_FixedLocale(AppLang lang) {
|
||||||
|
state = lang;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 可控假桥:能手动推 VpnStatus,无内部计时器(避免 pending timer)。
|
// 可控假桥:能手动推 VpnStatus,无内部计时器(避免 pending timer)。
|
||||||
class _FakeBridge implements VpnBridge {
|
class _FakeBridge implements VpnBridge {
|
||||||
final _status = StreamController<VpnStatus>.broadcast();
|
final _status = StreamController<VpnStatus>.broadcast();
|
||||||
@@ -94,6 +103,7 @@ void main() {
|
|||||||
ProviderContainer makeContainer(_FakeBridge bridge,
|
ProviderContainer makeContainer(_FakeBridge bridge,
|
||||||
{NodesNotifier Function()? nodes, DateTime Function()? now}) =>
|
{NodesNotifier Function()? nodes, DateTime Function()? now}) =>
|
||||||
ProviderContainer(overrides: [
|
ProviderContainer(overrides: [
|
||||||
|
localeProvider.overrideWith((ref) => _FixedLocale(AppLang.zh)),
|
||||||
vpnBridgeProvider.overrideWithValue(bridge),
|
vpnBridgeProvider.overrideWithValue(bridge),
|
||||||
nodesProvider.overrideWith(nodes ?? _StubNodes.new),
|
nodesProvider.overrideWith(nodes ?? _StubNodes.new),
|
||||||
deviceIdentityProvider.overrideWithValue(DeviceIdentity(store: _MemKV())),
|
deviceIdentityProvider.overrideWithValue(DeviceIdentity(store: _MemKV())),
|
||||||
|
|||||||
@@ -8,10 +8,12 @@ import 'package:flutter_test/flutter_test.dart';
|
|||||||
import 'package:pangolin_vpn/bridge/vpn_bridge.dart';
|
import 'package:pangolin_vpn/bridge/vpn_bridge.dart';
|
||||||
import 'package:pangolin_vpn/bridge/vpn_bridge_mock.dart';
|
import 'package:pangolin_vpn/bridge/vpn_bridge_mock.dart';
|
||||||
import 'package:pangolin_vpn/bridge/vpn_bridge_provider.dart';
|
import 'package:pangolin_vpn/bridge/vpn_bridge_provider.dart';
|
||||||
|
import 'package:pangolin_vpn/l10n/app_text.dart';
|
||||||
import 'package:pangolin_vpn/l10n/strings_zh.dart';
|
import 'package:pangolin_vpn/l10n/strings_zh.dart';
|
||||||
import 'package:pangolin_vpn/models/node.dart';
|
import 'package:pangolin_vpn/models/node.dart';
|
||||||
import 'package:pangolin_vpn/pangolin_theme.dart';
|
import 'package:pangolin_vpn/pangolin_theme.dart';
|
||||||
import 'package:pangolin_vpn/screens/nodes_page.dart';
|
import 'package:pangolin_vpn/screens/nodes_page.dart';
|
||||||
|
import 'package:pangolin_vpn/state/app_providers.dart';
|
||||||
import 'package:pangolin_vpn/state/connection_provider.dart';
|
import 'package:pangolin_vpn/state/connection_provider.dart';
|
||||||
import 'package:pangolin_vpn/state/nodes_provider.dart';
|
import 'package:pangolin_vpn/state/nodes_provider.dart';
|
||||||
import 'package:pangolin_vpn/widgets/smart_select_card.dart';
|
import 'package:pangolin_vpn/widgets/smart_select_card.dart';
|
||||||
@@ -31,11 +33,19 @@ const _nodes = [
|
|||||||
Node(code: 'JP', nameZh: '东京', nameEn: 'Tokyo', ping: 35, uuid: 'jp-uuid', host: 'jp', port: 443),
|
Node(code: 'JP', nameZh: '东京', nameEn: 'Tokyo', ping: 35, uuid: 'jp-uuid', host: 'jp', port: 443),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// localeProvider 现默认英文;测试硬编码 StringsZh 预期 → 钉死中文 locale。
|
||||||
|
class _FixedLocale extends LocaleNotifier {
|
||||||
|
_FixedLocale(AppLang lang) {
|
||||||
|
state = lang;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
setUpAll(disableGoogleFontsFetching);
|
setUpAll(disableGoogleFontsFetching);
|
||||||
const t = StringsZh();
|
const t = StringsZh();
|
||||||
|
|
||||||
ProviderContainer makeContainer(VpnBridge bridge) => ProviderContainer(overrides: [
|
ProviderContainer makeContainer(VpnBridge bridge) => ProviderContainer(overrides: [
|
||||||
|
localeProvider.overrideWith((ref) => _FixedLocale(AppLang.zh)),
|
||||||
nodesProvider.overrideWith(_StubNodes.new),
|
nodesProvider.overrideWith(_StubNodes.new),
|
||||||
vpnBridgeProvider.overrideWithValue(bridge),
|
vpnBridgeProvider.overrideWithValue(bridge),
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import 'package:http/http.dart' as http;
|
|||||||
import 'package:http/testing.dart';
|
import 'package:http/testing.dart';
|
||||||
import 'package:pangolin_vpn/bridge/vpn_bridge_mock.dart';
|
import 'package:pangolin_vpn/bridge/vpn_bridge_mock.dart';
|
||||||
import 'package:pangolin_vpn/bridge/vpn_bridge_provider.dart';
|
import 'package:pangolin_vpn/bridge/vpn_bridge_provider.dart';
|
||||||
|
import 'package:pangolin_vpn/l10n/app_text.dart';
|
||||||
import 'package:pangolin_vpn/l10n/strings_zh.dart';
|
import 'package:pangolin_vpn/l10n/strings_zh.dart';
|
||||||
import 'package:pangolin_vpn/models/node.dart';
|
import 'package:pangolin_vpn/models/node.dart';
|
||||||
import 'package:pangolin_vpn/pangolin_theme.dart';
|
import 'package:pangolin_vpn/pangolin_theme.dart';
|
||||||
@@ -20,6 +21,7 @@ import 'package:pangolin_vpn/screens/stats_page.dart';
|
|||||||
import 'package:pangolin_vpn/services/api_client.dart';
|
import 'package:pangolin_vpn/services/api_client.dart';
|
||||||
import 'package:pangolin_vpn/services/token_store.dart';
|
import 'package:pangolin_vpn/services/token_store.dart';
|
||||||
import 'package:pangolin_vpn/state/account_providers.dart';
|
import 'package:pangolin_vpn/state/account_providers.dart';
|
||||||
|
import 'package:pangolin_vpn/state/app_providers.dart';
|
||||||
import 'package:pangolin_vpn/state/auth_provider.dart';
|
import 'package:pangolin_vpn/state/auth_provider.dart';
|
||||||
import 'package:pangolin_vpn/state/nodes_provider.dart';
|
import 'package:pangolin_vpn/state/nodes_provider.dart';
|
||||||
import 'package:pangolin_vpn/widgets/period_card.dart';
|
import 'package:pangolin_vpn/widgets/period_card.dart';
|
||||||
@@ -101,6 +103,13 @@ Finder _metric(String period, int i, String value, String unit) => find.byWidget
|
|||||||
w.metrics[i].unit == unit,
|
w.metrics[i].unit == unit,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// localeProvider 现默认英文;测试硬编码 StringsZh 预期 → 钉死中文 locale。
|
||||||
|
class _FixedLocale extends LocaleNotifier {
|
||||||
|
_FixedLocale(AppLang lang) {
|
||||||
|
state = lang;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
setUpAll(disableGoogleFontsFetching);
|
setUpAll(disableGoogleFontsFetching);
|
||||||
const t = StringsZh();
|
const t = StringsZh();
|
||||||
@@ -111,6 +120,7 @@ void main() {
|
|||||||
|
|
||||||
await tester.pumpWidget(ProviderScope(
|
await tester.pumpWidget(ProviderScope(
|
||||||
overrides: [
|
overrides: [
|
||||||
|
localeProvider.overrideWith((ref) => _FixedLocale(AppLang.zh)),
|
||||||
tokenStoreProvider.overrideWithValue(const _LoggedInTokenStore()),
|
tokenStoreProvider.overrideWithValue(const _LoggedInTokenStore()),
|
||||||
apiClientProvider.overrideWithValue(ApiClient(
|
apiClientProvider.overrideWithValue(ApiClient(
|
||||||
baseUrl: 'http://test.local',
|
baseUrl: 'http://test.local',
|
||||||
|
|||||||
+42
-41
@@ -327,12 +327,12 @@ header .header-meta{color:var(--fg-soft)}
|
|||||||
<header>
|
<header>
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
<h1>feature+windows — 项目 TODO</h1>
|
<h1>feature+windows — 项目 TODO</h1>
|
||||||
<div class="header-meta">生成于 2026-07-07 · 真相源 todo/todo.json</div>
|
<div class="header-meta">生成于 2026-07-08 · 真相源 todo/todo.json</div>
|
||||||
<div class="stats">
|
<div class="stats">
|
||||||
<div class="stat-pill"><strong>18</strong>全部</div>
|
<div class="stat-pill"><strong>18</strong>全部</div>
|
||||||
<div class="stat-pill"><strong>8</strong>待开始</div>
|
<div class="stat-pill"><strong>8</strong>待开始</div>
|
||||||
<div class="stat-pill"><strong>1</strong>开发中</div>
|
<div class="stat-pill"><strong>0</strong>开发中</div>
|
||||||
<div class="stat-pill"><strong>1</strong>待验收</div>
|
<div class="stat-pill"><strong>2</strong>待验收</div>
|
||||||
<div class="stat-pill"><strong>8</strong>已验收</div>
|
<div class="stat-pill"><strong>8</strong>已验收</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -634,53 +634,18 @@ header .header-meta{color:var(--fg-soft)}
|
|||||||
</div>
|
</div>
|
||||||
<div class="section-block" id="section-doing">
|
<div class="section-block" id="section-doing">
|
||||||
<div class="section-title st-doing" data-toggle="doing">
|
<div class="section-title st-doing" data-toggle="doing">
|
||||||
🔨 开发中 <span class="s-count">1</span>
|
🔨 开发中 <span class="s-count">0</span>
|
||||||
<span class="s-arrow">▴ 收起</span>
|
<span class="s-arrow">▴ 收起</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="section-list-wrap " id="list-wrap-doing">
|
<div class="section-list-wrap " id="list-wrap-doing">
|
||||||
<ul class="todo-list" id="list-doing">
|
<ul class="todo-list" id="list-doing">
|
||||||
|
<p class="empty-tip">暂无条目</p>
|
||||||
<li class="todo-card s-doing"
|
|
||||||
data-id="19"
|
|
||||||
data-level="mid"
|
|
||||||
data-status="doing"
|
|
||||||
data-tier="1"
|
|
||||||
data-tags="前端,Web,mac,iOS,Android,Windows,CI/CD">
|
|
||||||
<div class="card-header">
|
|
||||||
<span class="item-id">#19</span>
|
|
||||||
<span class="item-title">前端设计系统治理重构(ds-flow 全端)</span>
|
|
||||||
<div class="card-badges">
|
|
||||||
<span class="tag status-badge s-doing">开发中</span>
|
|
||||||
<span class="tag t-high">重要</span>
|
|
||||||
<span class="tag tier-1">一级</span>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="item-desc">用 ds-flow 把 Flutter 五端+官网+用户中心收口到设计单源。补原型三件套(atoms.css/icons.js/index.html)+Web共享原子层去重(各自实现+同源闸)+硬编码色/fidelity闸+启用pre-commit。6阶段。计划见 docs/superpowers/plans/2026-07-07-frontend-ds-refactor.md</div>
|
|
||||||
<div class="gate-block gate-granted">
|
|
||||||
<div class="gate-head"><span class="gate-badge granted">✓ 已确认</span>
|
|
||||||
<span class="gate-kind">一级方案规划</span>
|
|
||||||
<span class="gate-date">2026-07-07</span></div>
|
|
||||||
<div class="gate-note">6 阶段 ds-flow 治理重构:Phase0 CLAUDE.md+计划落库 / Phase1 原型三件套(atoms.css/icons.js/index.html,收敛ui_kits) / Phase2 Web token同源闸 / Phase3 Web共享原子层去重(各自实现+同源闸,★工作量最大) / Phase4 Flutter收尾+golden补齐 / Phase5 静态闸挂满+启用pre-commit+fidelity体检。已定决策:Web各自实现+同源闸、ui_kits收敛纯HTML、先定稿再逐刀。主题保持light/dark。</div><div class="gate-ref">📄 详见 <code>docs/superpowers/plans/2026-07-07-frontend-ds-refactor.md</code></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-footer">
|
|
||||||
<div class="tag-row"><span class="tag t-tag" data-tag="前端">前端</span> <span class="tag t-tag" data-tag="Web">Web</span> <span class="tag t-tag" data-tag="mac">mac</span> <span class="tag t-tag" data-tag="iOS">iOS</span> <span class="tag t-tag" data-tag="Android">Android</span> <span class="tag t-tag" data-tag="Windows">Windows</span> <span class="tag t-tag" data-tag="CI/CD">CI/CD</span></div>
|
|
||||||
<div class="item-meta">
|
|
||||||
<span class="tag owner-agent">🤖 agent</span>
|
|
||||||
<span class="meta-date">🕐 2026-07-07</span>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section-block" id="section-done">
|
<div class="section-block" id="section-done">
|
||||||
<div class="section-title st-done" data-toggle="done">
|
<div class="section-title st-done" data-toggle="done">
|
||||||
🔍 待验收 <span class="s-count">1</span>
|
🔍 待验收 <span class="s-count">2</span>
|
||||||
<span class="s-arrow">▴ 收起</span>
|
<span class="s-arrow">▴ 收起</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="section-list-wrap " id="list-wrap-done">
|
<div class="section-list-wrap " id="list-wrap-done">
|
||||||
@@ -713,6 +678,42 @@ header .header-meta{color:var(--fg-soft)}
|
|||||||
<span class="tag owner-agent">🤖 agent</span>
|
<span class="tag owner-agent">🤖 agent</span>
|
||||||
<span class="meta-date">🕐 2026-07-01</span>
|
<span class="meta-date">🕐 2026-07-01</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="todo-card s-done"
|
||||||
|
data-id="19"
|
||||||
|
data-level="mid"
|
||||||
|
data-status="done"
|
||||||
|
data-tier="1"
|
||||||
|
data-tags="前端,Web,mac,iOS,Android,Windows,CI/CD">
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="item-id">#19</span>
|
||||||
|
<span class="item-title">前端设计系统治理重构(ds-flow 全端)</span>
|
||||||
|
<div class="card-badges">
|
||||||
|
<span class="tag status-badge s-done">待验收</span>
|
||||||
|
<span class="tag t-high">重要</span>
|
||||||
|
<span class="tag tier-1">一级</span>
|
||||||
|
|
||||||
|
<button class="reject-btn" data-id="19" data-title="前端设计系统治理重构(ds-flow 全端)">拒绝验收</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="item-desc">用 ds-flow 把 Flutter 五端+官网+用户中心收口到设计单源。补原型三件套(atoms.css/icons.js/index.html)+Web共享原子层去重(各自实现+同源闸)+硬编码色/fidelity闸+启用pre-commit。6阶段。计划见 docs/superpowers/plans/2026-07-07-frontend-ds-refactor.md</div>
|
||||||
|
<div class="gate-block gate-granted">
|
||||||
|
<div class="gate-head"><span class="gate-badge granted">✓ 已确认</span>
|
||||||
|
<span class="gate-kind">一级方案规划</span>
|
||||||
|
<span class="gate-date">2026-07-07</span></div>
|
||||||
|
<div class="gate-note">6 阶段 ds-flow 治理重构:Phase0 CLAUDE.md+计划落库 / Phase1 原型三件套(atoms.css/icons.js/index.html,收敛ui_kits) / Phase2 Web token同源闸 / Phase3 Web共享原子层去重(各自实现+同源闸,★工作量最大) / Phase4 Flutter收尾+golden补齐 / Phase5 静态闸挂满+启用pre-commit+fidelity体检。已定决策:Web各自实现+同源闸、ui_kits收敛纯HTML、先定稿再逐刀。主题保持light/dark。</div><div class="gate-ref">📄 详见 <code>docs/superpowers/plans/2026-07-07-frontend-ds-refactor.md</code></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-footer">
|
||||||
|
<div class="tag-row"><span class="tag t-tag" data-tag="前端">前端</span> <span class="tag t-tag" data-tag="Web">Web</span> <span class="tag t-tag" data-tag="mac">mac</span> <span class="tag t-tag" data-tag="iOS">iOS</span> <span class="tag t-tag" data-tag="Android">Android</span> <span class="tag t-tag" data-tag="Windows">Windows</span> <span class="tag t-tag" data-tag="CI/CD">CI/CD</span></div>
|
||||||
|
<div class="item-meta">
|
||||||
|
<span class="tag owner-agent">🤖 agent</span>
|
||||||
|
<span class="meta-date">🕐 2026-07-07</span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"meta": {
|
"meta": {
|
||||||
"title": "feature+windows — 项目 TODO",
|
"title": "feature+windows — 项目 TODO",
|
||||||
"updated_at": "2026-07-07T15:54:54.457Z"
|
"updated_at": "2026-07-07T17:45:18.036Z"
|
||||||
},
|
},
|
||||||
"seq": 19,
|
"seq": 19,
|
||||||
"items": [
|
"items": [
|
||||||
@@ -304,7 +304,7 @@
|
|||||||
"CI/CD"
|
"CI/CD"
|
||||||
],
|
],
|
||||||
"owner": "agent",
|
"owner": "agent",
|
||||||
"status": "doing",
|
"status": "done",
|
||||||
"created_at": "2026-07-07T15:41:25.760Z",
|
"created_at": "2026-07-07T15:41:25.760Z",
|
||||||
"done": false,
|
"done": false,
|
||||||
"completed_at": null,
|
"completed_at": null,
|
||||||
|
|||||||
Reference in New Issue
Block a user