svharness 0.8.0 → 0.13.2
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 +290 -61
- package/dist/adapters/claude-code.js +1 -0
- package/dist/adapters/codechat.js +1 -0
- package/dist/adapters/cursor.js +1 -0
- package/dist/adapters/generic.js +1 -0
- package/dist/adapters/index.js +2 -0
- package/dist/adapters/opencode.js +17 -0
- package/dist/adapters/qoder.js +1 -0
- package/dist/commands/apply.js +456 -71
- package/dist/commands/convert.js +371 -0
- package/dist/commands/init.js +156 -11
- package/dist/commands/references-apply-skills.js +47 -0
- package/dist/commands/wizard.js +442 -0
- package/dist/config/constants.js +7 -0
- package/dist/config/index.js +18 -0
- package/dist/config/load-config.js +54 -0
- package/dist/config/merge-options.js +115 -0
- package/dist/config/normalize.js +165 -0
- package/dist/config/save-config.js +40 -0
- package/dist/config/types.js +2 -0
- package/dist/core/agent-injector.js +58 -9
- package/dist/core/apply-project-entry.js +66 -0
- package/dist/core/build-project-entry.js +98 -0
- package/dist/core/doc-intake-paths.js +155 -0
- package/dist/core/extra-assets-intake.js +254 -0
- package/dist/core/markitdown-client.js +156 -0
- package/dist/core/next-steps.js +33 -22
- package/dist/core/project-ignore.js +53 -0
- package/dist/core/reference-apply-skills.js +35 -0
- package/dist/core/render-meta.js +2 -1
- package/dist/core/repomix-pack.js +3 -3
- package/dist/core/state.js +44 -24
- package/dist/index.js +211 -140
- package/dist/utils/harness-name.js +41 -0
- package/dist/utils/validate-args.js +147 -6
- package/dist/wiki/wikiTasksWriter.js +5 -6
- package/package.json +2 -1
- package/templates/_shared/apply-skills/harness-apply-skills-main.md +19 -78
- package/templates/_shared/build-rules/harness-build-rule-agent-agnostic.md +5 -5
- package/templates/_shared/build-rules/harness-build-rule-chinese-only.md +5 -5
- package/templates/_shared/build-rules/harness-build-rule-convert-check.md +46 -0
- package/templates/_shared/build-rules/harness-build-rule-memory-write.md +1 -1
- package/templates/_shared/build-rules/harness-build-rule-orchestrator-flow.md +36 -10
- package/templates/_shared/build-rules/harness-build-rule-skills-tasks-output.md +3 -2
- package/templates/_shared/build-rules/harness-build-rule-specs-schema.md +3 -3
- package/templates/_shared/build-rules/harness-build-rule-user-interaction.md +36 -16
- package/templates/_shared/build-skills/harness-build-skill-agent-env-merge.md +75 -0
- package/templates/_shared/build-skills/harness-build-skill-knowledge-builder.md +49 -85
- package/templates/_shared/build-skills/harness-build-skill-orchestrator.md +35 -18
- package/templates/_shared/build-skills/harness-build-skill-references-intake.md +91 -0
- package/templates/_shared/build-skills/harness-build-skill-spec-builder.md +19 -9
- package/templates/_shared/build-skills/harness-build-skill-wiki-writer.md +24 -24
- package/templates/_shared/build-skills/harness-build-skills-main.md +83 -0
- package/templates/_shared/meta/AGENTS_APPLY.md.ejs +139 -0
- package/templates/_shared/meta/{AGENTS.md.ejs → AGENTS_BUILD.md.ejs} +7 -5
- package/templates/_shared/meta/CHANGELOG.md.ejs +3 -3
- package/templates/_shared/meta/README.md.ejs +11 -9
- package/templates/_shared/meta/harness.yaml.ejs +28 -7
- package/templates/_shared/skeleton/baseline/code/.gitkeep +1 -0
- package/templates/_shared/skeleton/baseline/wiki/.gitkeep +1 -0
- package/templates/_shared/skeleton/references/apply-skills-registry.example.yaml +11 -0
- package/templates/_shared/skeleton/references/md/.gitkeep +1 -0
- package/templates/_shared/skeleton/references/raw/.gitkeep +1 -0
- package/templates/_shared/skeleton/references/yaml/.gitkeep +1 -0
- package/templates/_shared/skeleton/requirements/md/.gitkeep +1 -0
- package/templates/_shared/skeleton/requirements/raw/.gitkeep +1 -0
- package/templates/_shared/skeleton/requirements/yaml/.gitkeep +1 -0
- package/templates/android-xml/skeleton/agent-env/skills/harness-android-cli/SKILL.md +88 -0
- package/templates/android-xml/skeleton/agent-env/skills/harness-android-service-patterns/SKILL.md +205 -0
- package/templates/android-xml/skeleton/agent-env/skills/harness-android-xml-architecture/SKILL.md +138 -0
- package/templates/android-xml/skeleton/agent-env/skills/harness-lifecycle-management/SKILL.md +158 -0
- package/templates/android-xml/skeleton/agent-env/skills/harness-xml-ui/SKILL.md +112 -0
- package/templates/cpp/skeleton/agent-env/skills/harness-cmake-build/SKILL.md +163 -0
- package/templates/cpp/skeleton/agent-env/skills/harness-cpp-architecture/SKILL.md +157 -0
- package/templates/cpp/skeleton/agent-env/skills/harness-cpp-concurrency/SKILL.md +180 -0
- package/templates/cpp/skeleton/agent-env/skills/harness-memory-safety/SKILL.md +163 -0
- package/templates/cpp/skeleton/agent-env/skills/harness-modern-cpp/SKILL.md +149 -0
- package/templates/python/skeleton/agent-env/skills/harness-async-patterns/SKILL.md +162 -0
- package/templates/python/skeleton/agent-env/skills/harness-python-architecture/SKILL.md +160 -0
- package/templates/python/skeleton/agent-env/skills/harness-python-package-structure/SKILL.md +210 -0
- package/templates/python/skeleton/agent-env/skills/harness-python-performance/SKILL.md +207 -0
- package/templates/python/skeleton/agent-env/skills/harness-python-testing/SKILL.md +198 -0
- package/templates/svharness.config.example.yaml +40 -0
- package/templates/web-react/skeleton/agent-env/skills/harness-react-architecture/SKILL.md +177 -0
- package/templates/web-react/skeleton/agent-env/skills/harness-react-performance/SKILL.md +177 -0
- package/templates/web-react/skeleton/agent-env/skills/harness-react-testing/SKILL.md +193 -0
- package/templates/web-react/skeleton/agent-env/skills/harness-react-ui-patterns/SKILL.md +257 -0
- package/templates/web-react/skeleton/agent-env/skills/harness-state-management/SKILL.md +189 -0
- package/templates/_shared/skeleton/assets/baseline/code/.gitkeep +0 -1
- package/templates/_shared/skeleton/assets/baseline/wiki/.gitkeep +0 -1
- package/templates/_shared/skeleton/assets/raw/.gitkeep +0 -1
- package/templates/_shared/skeleton/assets/requirements/.gitkeep +0 -1
- /package/templates/_shared/skeleton/{assets/baseline/repomix → agent-env/_incoming/skills}/.gitkeep +0 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: harness-state-management
|
|
3
|
+
description: React 状态管理模式。覆盖 useState/useReducer、Context、Zustand、Redux Toolkit 的选择与使用。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 状态管理
|
|
7
|
+
|
|
8
|
+
## 概述
|
|
9
|
+
|
|
10
|
+
根据状态的作用域与复杂度选择合适的管理方式。避免过度工程,也避免状态混乱。
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 状态分类
|
|
15
|
+
|
|
16
|
+
| 状态类型 | 作用域 | 推荐方案 |
|
|
17
|
+
|----------|--------|---------|
|
|
18
|
+
| **本地 UI 状态** | 单个组件 | `useState` |
|
|
19
|
+
| **跨组件状态** | 组件树局部 | `useReducer` + Context |
|
|
20
|
+
| **全局共享状态** | 全应用 | Zustand / Redux Toolkit |
|
|
21
|
+
| **服务端状态** | 远程数据 | React Query / SWR |
|
|
22
|
+
| **URL 状态** | 路由参数 | React Router / URL SearchParams |
|
|
23
|
+
|
|
24
|
+
## 本地状态:useState
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
function Counter() {
|
|
28
|
+
const [count, setCount] = useState(0);
|
|
29
|
+
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 复杂状态:useReducer
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
type Action =
|
|
37
|
+
| { type: 'INCREMENT'; payload: number }
|
|
38
|
+
| { type: 'DECREMENT'; payload: number }
|
|
39
|
+
| { type: 'RESET' };
|
|
40
|
+
|
|
41
|
+
function counterReducer(state: number, action: Action): number {
|
|
42
|
+
switch (action.type) {
|
|
43
|
+
case 'INCREMENT': return state + action.payload;
|
|
44
|
+
case 'DECREMENT': return state - action.payload;
|
|
45
|
+
case 'RESET': return 0;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function Counter() {
|
|
50
|
+
const [count, dispatch] = useReducer(counterReducer, 0);
|
|
51
|
+
return (
|
|
52
|
+
<>
|
|
53
|
+
<p>{count}</p>
|
|
54
|
+
<button onClick={() => dispatch({ type: 'INCREMENT', payload: 1 })}>+</button>
|
|
55
|
+
<button onClick={() => dispatch({ type: 'RESET' })}>Reset</button>
|
|
56
|
+
</>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## 跨组件状态:Context
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
import { createContext, useContext, useReducer, type ReactNode } from 'react';
|
|
65
|
+
|
|
66
|
+
// 1. 定义状态与 Action
|
|
67
|
+
interface AuthState { user: User | null; token: string | null; }
|
|
68
|
+
type AuthAction =
|
|
69
|
+
| { type: 'LOGIN'; user: User; token: string }
|
|
70
|
+
| { type: 'LOGOUT' };
|
|
71
|
+
|
|
72
|
+
// 2. 创建 Context
|
|
73
|
+
interface AuthContextType {
|
|
74
|
+
state: AuthState;
|
|
75
|
+
login: (user: User, token: string) => void;
|
|
76
|
+
logout: () => void;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const AuthContext = createContext<AuthContextType | null>(null);
|
|
80
|
+
|
|
81
|
+
// 3. Provider
|
|
82
|
+
function AuthProvider({ children }: { children: ReactNode }) {
|
|
83
|
+
const [state, dispatch] = useReducer(authReducer, initialState);
|
|
84
|
+
|
|
85
|
+
const login = (user: User, token: string) =>
|
|
86
|
+
dispatch({ type: 'LOGIN', user, token });
|
|
87
|
+
|
|
88
|
+
const logout = () => dispatch({ type: 'LOGOUT' });
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<AuthContext.Provider value={{ state, login, logout }}>
|
|
92
|
+
{children}
|
|
93
|
+
</AuthContext.Provider>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// 4. 自定义 Hook
|
|
98
|
+
function useAuth(): AuthContextType {
|
|
99
|
+
const ctx = useContext(AuthContext);
|
|
100
|
+
if (!ctx) throw new Error('useAuth must be used within AuthProvider');
|
|
101
|
+
return ctx;
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## 全局状态:Zustand
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
import { create } from 'zustand';
|
|
109
|
+
|
|
110
|
+
interface CartStore {
|
|
111
|
+
items: CartItem[];
|
|
112
|
+
total: number;
|
|
113
|
+
addItem: (item: CartItem) => void;
|
|
114
|
+
removeItem: (id: string) => void;
|
|
115
|
+
clearCart: () => void;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const useCartStore = create<CartStore>((set, get) => ({
|
|
119
|
+
items: [],
|
|
120
|
+
total: 0,
|
|
121
|
+
addItem: (item) => set((state) => ({
|
|
122
|
+
items: [...state.items, item],
|
|
123
|
+
total: state.total + item.price * item.quantity,
|
|
124
|
+
})),
|
|
125
|
+
removeItem: (id) => set((state) => {
|
|
126
|
+
const items = state.items.filter((i) => i.id !== id);
|
|
127
|
+
const total = items.reduce((sum, i) => sum + i.price * i.quantity, 0);
|
|
128
|
+
return { items, total };
|
|
129
|
+
}),
|
|
130
|
+
clearCart: () => set({ items: [], total: 0 }),
|
|
131
|
+
}));
|
|
132
|
+
|
|
133
|
+
// 使用(组件内)
|
|
134
|
+
function CartSummary() {
|
|
135
|
+
const total = useCartStore((state) => state.total);
|
|
136
|
+
const items = useCartStore((state) => state.items);
|
|
137
|
+
const addItem = useCartStore((state) => state.addItem);
|
|
138
|
+
// ...
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## 服务端状态:React Query (TanStack Query)
|
|
143
|
+
|
|
144
|
+
```tsx
|
|
145
|
+
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
146
|
+
|
|
147
|
+
// 获取数据
|
|
148
|
+
function useUsers() {
|
|
149
|
+
return useQuery({
|
|
150
|
+
queryKey: ['users'],
|
|
151
|
+
queryFn: () => fetch('/api/users').then(r => r.json()),
|
|
152
|
+
staleTime: 5 * 60 * 1000, // 5 分钟内不过期
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// 变更数据
|
|
157
|
+
function useCreateUser() {
|
|
158
|
+
const queryClient = useQueryClient();
|
|
159
|
+
|
|
160
|
+
return useMutation({
|
|
161
|
+
mutationFn: (newUser: NewUser) =>
|
|
162
|
+
fetch('/api/users', { method: 'POST', body: JSON.stringify(newUser) }),
|
|
163
|
+
onSuccess: () => {
|
|
164
|
+
queryClient.invalidateQueries({ queryKey: ['users'] });
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## 状态管理决策树
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
这个状态是...
|
|
174
|
+
├── 服务端数据(来自 API)? → React Query / SWR
|
|
175
|
+
├── URL 参数? → React Router / useSearchParams
|
|
176
|
+
├── 仅一个组件使用? → useState
|
|
177
|
+
├── 组件树局部(2-3 层)? → useState + Props
|
|
178
|
+
├── 组件树局部(3+ 层透传)? → useReducer + Context(禁止 prop drilling)
|
|
179
|
+
└── 全局共享(主题、用户、购物车)?
|
|
180
|
+
├── 少量状态,简单逻辑 → Zustand
|
|
181
|
+
└── 大量状态,复杂逻辑 → Redux Toolkit
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## 相关规则
|
|
187
|
+
|
|
188
|
+
- `seed-no-props-drilling` — 禁止超 2 层 props drilling
|
|
189
|
+
- `seed-hook-rules` — Hook 调用铁律
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# placeholder — reference code snapshots (~20 key files), NOT full src copy
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# placeholder — repowiki pages rendered by harness-knowledge-builder skill
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# placeholder — populated during harness build (manual requirement docs)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# placeholder — populated during harness build (parsed/structured requirements)
|
/package/templates/_shared/skeleton/{assets/baseline/repomix → agent-env/_incoming/skills}/.gitkeep
RENAMED
|
File without changes
|