@mingfuyun/star-allinone 0.1.6 → 0.1.8
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 +111 -1
- package/dist/components/BaseModal/index.d.ts +6 -6
- package/dist/components/BaseModal/index.d.ts.map +1 -1
- package/dist/components/CustomDrawer/index.d.ts +5 -5
- package/dist/components/CustomDrawer/index.d.ts.map +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +9 -2
- package/scripts/cli.js +179 -0
- package/skills/README.md +297 -0
- package/skills/shared/ai-review/SKILL.md +29 -0
- package/skills/shared/api-mock/SKILL.md +23 -0
- package/skills/shared/api-mock/references/mock-conventions.md +90 -0
- package/skills/shared/api-to-service/SKILL.md +51 -0
- package/skills/shared/api-to-service/references/api-artifact-generation.md +70 -0
- package/skills/shared/api-to-service/references/service-conventions.md +89 -0
- package/skills/shared/commit-current-changes/SKILL.md +63 -0
- package/skills/shared/design-to-page/SKILL.md +48 -0
- package/skills/shared/design-to-page/references/overlays.md +73 -0
- package/skills/shared/design-to-page/references/page-conventions.md +85 -0
- package/skills/shared/impact-analysis/SKILL.md +30 -0
- package/skills/shared/project-conventions/SKILL.md +30 -0
- package/skills/shared/project-conventions/references/architecture.md +43 -0
- package/skills/shared/project-conventions/references/quality-checklist.md +19 -0
- package/skills/shared/project-conventions/references/review-checklist.md +42 -0
- package/skills/shared/publish-test/SKILL.md +46 -0
- package/skills/shared/publish-test/scripts/publish-current-branch.sh +174 -0
- package/skills/shared/review-and-submit/SKILL.md +75 -0
- package/skills/shared/verify/SKILL.md +44 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: {{sharedSkillName}}
|
|
3
|
+
description: Review the active frontend project's changes and prepare a confirmation-gated Conventional Commit and optional push. Use when the user asks to review current changes, submit code, or commit and push. Never commit before explicit confirmation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Commit Current Changes
|
|
7
|
+
|
|
8
|
+
This skill is fully shared. Review user-authorized working-tree changes, report findings and a commit proposal, and mutate Git only after explicit confirmation.
|
|
9
|
+
|
|
10
|
+
## Write-operation gate
|
|
11
|
+
|
|
12
|
+
Git writes are forbidden until both gates are complete in the current turn:
|
|
13
|
+
|
|
14
|
+
1. **Review gate**: deliver a report with findings or `No issues found.`
|
|
15
|
+
2. **Confirmation gate**: present exact file paths and the exact commit subject, then receive affirmative confirmation of that proposal. “提交代码” is not confirmation before the proposal exists.
|
|
16
|
+
|
|
17
|
+
Before `git add`, `git commit`, or `git push`, re-check status and diff. If scope changed, stop and issue a new proposal. Never infer confirmation from urgency or a previous turn.
|
|
18
|
+
|
|
19
|
+
## Workflow
|
|
20
|
+
|
|
21
|
+
### 1. Scope
|
|
22
|
+
|
|
23
|
+
Run `git status --short --branch`, `git diff --stat`, and `git diff`. Inspect cached diffs when staged changes exist. Do not include unrelated user-owned files. Follow recent `git log` language and naming.
|
|
24
|
+
|
|
25
|
+
### 2. Review
|
|
26
|
+
|
|
27
|
+
Read:
|
|
28
|
+
|
|
29
|
+
1. `.agents/skills/shared-project-conventions/references/review-checklist.md`
|
|
30
|
+
2. `.agents/skills/shared-project-conventions/references/quality-checklist.md`
|
|
31
|
+
3. `.agents/skills/shared-project-conventions/references/architecture.md`
|
|
32
|
+
|
|
33
|
+
This skill is fully shared. If `.agents/project/review-rules.md` exists, apply extra domain checks only; do not weaken shared hard rules.
|
|
34
|
+
|
|
35
|
+
Classify only concrete security, data-loss, runtime, contract, validation, performance, accessibility, or maintainability risks as P0–P2.
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
[P1] Short finding title — src/path/file.tsx:42
|
|
39
|
+
Impact and reproduction/contract evidence.
|
|
40
|
+
Fix: focused direction, without unrelated redesign.
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 3. Validate
|
|
44
|
+
|
|
45
|
+
Always run `git diff --check`. Then run focused Prettier, ESLint, TypeScript, and the project's documented build in proportion to risk. Do not auto-fix. Do not propose commit while an unresolved P0/P1 or a current-change validation failure remains.
|
|
46
|
+
|
|
47
|
+
### 4. Proposal
|
|
48
|
+
|
|
49
|
+
Lead with findings. Then present optional improvements, validation results, change summary, exact files, branch/remote, and a concise Chinese Conventional Commit message (`feat` / `fix` / `refactor` / `chore` / `docs` / `test` / `style` / `perf` / `build` / `ci`). Stop and wait.
|
|
50
|
+
|
|
51
|
+
### 5. After confirmation
|
|
52
|
+
|
|
53
|
+
1. Re-inspect the working tree. If the diff changed, propose again.
|
|
54
|
+
2. Stage only confirmed paths.
|
|
55
|
+
3. Commit without `--no-verify` unless the user explicitly authorizes it. Do not amend unless requested.
|
|
56
|
+
4. Push to upstream, or `git push -u origin HEAD` when none exists. Never force-push.
|
|
57
|
+
5. Report hash, subject, files, validation, and remote branch.
|
|
58
|
+
|
|
59
|
+
## Safety
|
|
60
|
+
|
|
61
|
+
- Never expose credentials from diffs; stop if secrets are present.
|
|
62
|
+
- Never use destructive Git commands to clean the working tree.
|
|
63
|
+
- If push is rejected, report the reason and do not rewrite history without separate authorization.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: {{sharedSkillName}}
|
|
3
|
+
description: Implement frontend pages from designs using the active project's React, Umi, Ant Design Pro, service, permission, routing, and component conventions. Use when translating Figma, screenshots, wireframes, or UI specs into page code.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Design to Page
|
|
7
|
+
|
|
8
|
+
Translate a design into repository-native code. Reuse existing architecture; do not invent a parallel stack.
|
|
9
|
+
|
|
10
|
+
Before implementation, read:
|
|
11
|
+
|
|
12
|
+
1. `.star-allinone.json`
|
|
13
|
+
2. [references/page-conventions.md](references/page-conventions.md)
|
|
14
|
+
3. [references/overlays.md](references/overlays.md) for any modal, drawer, or confirmation
|
|
15
|
+
4. `.agents/skills/shared-project-conventions/references/architecture.md`
|
|
16
|
+
|
|
17
|
+
If `.agents/project/conventions.md` exists, use it only for extra paths.
|
|
18
|
+
|
|
19
|
+
Inspect the nearest existing page of the same type before proposing files.
|
|
20
|
+
|
|
21
|
+
## Workflow
|
|
22
|
+
|
|
23
|
+
1. List visible states: default, loading, empty, error, disabled, overflow, permission, and narrow-screen.
|
|
24
|
+
2. Resolve ambiguities that affect APIs, route ownership, permissions, or component boundaries. For minor visual gaps, follow the closest precedent and state the assumption.
|
|
25
|
+
3. Write a short implementation contract: route, sections, query fields, columns, actions, APIs, permissions, states, and files.
|
|
26
|
+
4. Implement the smallest complete vertical slice. Keep columns and actions outside render. Keep overlay concerns in focused components.
|
|
27
|
+
5. API-backed pages include types, `MFRequest` methods, aggregate exports, and page consumption in the same change. Use `.agents/skills/shared-api-to-service/SKILL.md` for missing services. Use `.agents/skills/shared-api-mock/SKILL.md` for deterministic data. Do not embed production fake data.
|
|
28
|
+
6. Compare desktop and narrow layouts against the design. Fix structure and spacing before decoration.
|
|
29
|
+
7. Run focused verification. Do not claim visual fidelity without inspecting the rendered page.
|
|
30
|
+
|
|
31
|
+
## Hard rules
|
|
32
|
+
|
|
33
|
+
- React function components, TypeScript, Ant Design 5, Pro Components, Less.
|
|
34
|
+
- `ProForm` for business forms. `MFProTable` for management lists.
|
|
35
|
+
- Overlays from `@mingfuyun/star-allinone`: `CustomDrawer`, `BaseModal`, `HocModal`.
|
|
36
|
+
- Every `await` uses `try-catch`; loading restores in `finally`; `validateFields()` failures are logged and stop the request.
|
|
37
|
+
- Mutations guard duplicate submit, show feedback, and reload affected lists.
|
|
38
|
+
- Do not add a UI library, state library, or CSS-in-JS system without approval.
|
|
39
|
+
- Do not refactor unrelated code.
|
|
40
|
+
|
|
41
|
+
## Verification
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pnpm exec prettier --check <changed-files>
|
|
45
|
+
pnpm exec tsc --noEmit
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Run `pnpm lint` for broad or shared changes. Run the project's documented build command when routes, entry, or multiple pages change.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Overlays
|
|
2
|
+
|
|
3
|
+
Use this reference for every modal, confirmation dialog, and drawer. Import `@mingfuyun/star-allinone/dist/styles.css` once from the application entry, not from feature components.
|
|
4
|
+
|
|
5
|
+
## Required components
|
|
6
|
+
|
|
7
|
+
- `CustomDrawer` for create, edit, detail, or configuration drawers.
|
|
8
|
+
- `BaseModal` for forms, selections, confirmations, previews, and other dialogs.
|
|
9
|
+
- Wrap feature overlays with `HocModal` so pages open them through a ref.
|
|
10
|
+
- Keep Ant Design and Pro Components for overlay content.
|
|
11
|
+
- Use `ProForm` for every editable overlay form.
|
|
12
|
+
|
|
13
|
+
Do not add new direct feature-level imports of Ant Design `Drawer`, `Modal`, or `Modal.confirm`.
|
|
14
|
+
|
|
15
|
+
## Ref contract
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
export interface ItemDrawerRef {
|
|
19
|
+
show: (args?: { record?: DOMAIN_API.Item }) => void;
|
|
20
|
+
hide: () => void;
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The wrapped component receives `visible`, `handleCancel`, and the args passed to `show`. Render the overlay once and open it from the page:
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
const drawerRef = useRef<ItemDrawerRef>(null);
|
|
28
|
+
drawerRef.current?.show({ record });
|
|
29
|
+
<ItemDrawer ref={drawerRef} reload={() => tableRef.current?.reload()} />;
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Do not duplicate open/visible, selected-record, and close state in the page when `HocModal` can own it.
|
|
33
|
+
|
|
34
|
+
## Drawer pattern
|
|
35
|
+
|
|
36
|
+
Use `CustomDrawer` confirmation controls and disable the ProForm submitter. Reset or initialize fields whenever the overlay becomes visible.
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
const handleConfirm = async () => {
|
|
40
|
+
try {
|
|
41
|
+
const values = await formRef.current?.validateFields();
|
|
42
|
+
setLoading(true);
|
|
43
|
+
await saveItem(values);
|
|
44
|
+
message.success('操作成功');
|
|
45
|
+
reload();
|
|
46
|
+
handleCancel();
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error('提交失败:', error);
|
|
49
|
+
} finally {
|
|
50
|
+
setLoading(false);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Validation failure must stop the request. Restore confirmation loading in `finally`. Never leave an empty `catch`.
|
|
56
|
+
|
|
57
|
+
## Modal pattern
|
|
58
|
+
|
|
59
|
+
Use `BaseModal` with `visible`, `onOk`, `onCancel`, and `confirmLoading`. Use `footer={null}` for read-only dialogs. Use `destroyOnClose` when stale internal state would leak across openings.
|
|
60
|
+
|
|
61
|
+
## Responsibilities
|
|
62
|
+
|
|
63
|
+
- Page: table refs, business entry points, and opening an overlay.
|
|
64
|
+
- Overlay: visibility, selected record, form initialization, validation, submitting state, feedback, close, and reload callback.
|
|
65
|
+
- Service: requests and API types.
|
|
66
|
+
- Feature constants: columns and action definitions; never overlay state.
|
|
67
|
+
|
|
68
|
+
## Verification
|
|
69
|
+
|
|
70
|
+
- Open the same overlay for create, edit, close, and reopen; confirm no stale values remain.
|
|
71
|
+
- Confirm validation prevents closing and duplicate submission.
|
|
72
|
+
- Confirm async failure leaves the overlay open and restores the action button.
|
|
73
|
+
- Check long content, narrow screens, footer visibility, mask behavior, and keyboard closing.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Page Conventions
|
|
2
|
+
|
|
3
|
+
Read `.star-allinone.json` first. Use extra component paths or permission helpers from `.agents/project/conventions.md` only when that file exists.
|
|
4
|
+
|
|
5
|
+
## Stack and locations
|
|
6
|
+
|
|
7
|
+
- Umi Max, React function components, TypeScript, Ant Design 5, Ant Design Pro Components, Less.
|
|
8
|
+
- Pages: `src/pages/<Feature>/`.
|
|
9
|
+
- Shared components: `src/components/`.
|
|
10
|
+
- Shared hooks: `src/hooks/`.
|
|
11
|
+
- Routes: `config/route.ts`.
|
|
12
|
+
- Services: `src/services/index.ts` via `import Service from '@/services'`.
|
|
13
|
+
- Import application modules through `@/`; use relative imports inside the same feature.
|
|
14
|
+
|
|
15
|
+
## File split
|
|
16
|
+
|
|
17
|
+
Keep the smallest complete vertical slice. A standard query-form plus table page usually looks like:
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
src/pages/<Feature>/
|
|
21
|
+
├── index.tsx
|
|
22
|
+
├── index.less
|
|
23
|
+
└── components/ or sibling files
|
|
24
|
+
├── List.tsx # optional when the page is large
|
|
25
|
+
└── const.tsx # columns, actions, toolbar, maps
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Put substantial columns, action builders, status maps, and select options outside render functions. Do not create a second `const.tsx` inside a child component when the page already has one.
|
|
29
|
+
|
|
30
|
+
Styles live in the current page directory. Reuse shared mixins such as `@/styles/proTable.less`; do not import another feature's Less file.
|
|
31
|
+
|
|
32
|
+
## Tables
|
|
33
|
+
|
|
34
|
+
- Prefer `MFProTable` for management lists. Use Ant Design `Table` only for a deliberately simple static shell.
|
|
35
|
+
- Extract `fetchData` as an `async` method. Do not inline request logic in JSX props.
|
|
36
|
+
- Wrap `await` in `try-catch` and return a table-safe empty shape on failure.
|
|
37
|
+
- Adapt backend pagination to the table contract. Common backend shapes are `{ results, count }` or `{ list, total }`; the table adapter is typically `{ code, data: { list, total } }`. Follow the nearest page.
|
|
38
|
+
- Use a stable `rowKey`. Wide tables use `scroll` with `x: 'max-content'`.
|
|
39
|
+
- Render missing display values as `'-'` unless the design requires another empty state.
|
|
40
|
+
- Keep the latest normalized query values available when export or secondary actions reuse them.
|
|
41
|
+
- Watch falsy bugs such as `value || fallback` when `0`, `false`, or `''` is valid.
|
|
42
|
+
|
|
43
|
+
If the table persists column visibility, order, or fixed state, use the project's column-state hook. Do not read or write `localStorage` in page code. Register new storage keys in the project's cache-reset UI when one exists.
|
|
44
|
+
|
|
45
|
+
## Forms
|
|
46
|
+
|
|
47
|
+
- Use `ProForm` as the business form container in pages, drawers, and modals.
|
|
48
|
+
- Prefer `ProFormText`, `ProFormSelect`, `ProFormTextArea`, and related fields.
|
|
49
|
+
- Ant Design `Form` may provide `useForm`, `useWatch`, or `ProForm.Item` integration. Do not introduce a rendered `<Form>` container.
|
|
50
|
+
- Default overlay forms to `layout="horizontal"` with a stable label width. Toolbar query forms stay `layout="inline"`.
|
|
51
|
+
- Normalize submitted values before calling services. Do not send empty strings, `undefined`, or presentation-only fields unless the API requires them.
|
|
52
|
+
- Reset both form controls and the active query state.
|
|
53
|
+
|
|
54
|
+
## Overlays
|
|
55
|
+
|
|
56
|
+
Follow [overlays.md](overlays.md). Use `CustomDrawer`, `BaseModal`, and `HocModal` from `@mingfuyun/star-allinone`. Do not add new feature-level Ant Design `Modal` or `Drawer` shells.
|
|
57
|
+
|
|
58
|
+
## Permissions and routes
|
|
59
|
+
|
|
60
|
+
- Preserve runtime menu and button permissions with the project's wrappers (`WithPermission`, `TablePermissionActions`, `withAuth`, `actionColumn.permission`, or the equivalent named in project conventions).
|
|
61
|
+
- Do not treat hidden buttons as authorization. Backend enforcement must remain.
|
|
62
|
+
- Add explicit routes in `config/route.ts` when the page needs navigation. Preserve `/403`, `/404`, and nested menu behavior.
|
|
63
|
+
|
|
64
|
+
## Async behavior
|
|
65
|
+
|
|
66
|
+
- Every `await` lives in `try-catch`, including handlers, loaders, and submissions.
|
|
67
|
+
- Put `validateFields()` inside the `try`. Log the caught error with `console.error` and do not continue to the request.
|
|
68
|
+
- Restore loading in `finally`. Never use an empty `catch`.
|
|
69
|
+
- Mutations disable or guard duplicate submission, show user-facing feedback, and reload affected lists.
|
|
70
|
+
- Destructive actions require confirmation. Use `BaseModal` + `HocModal`. Do not use `Modal.confirm`.
|
|
71
|
+
- Close overlays must clear form values, loading, selected records, and other async state.
|
|
72
|
+
|
|
73
|
+
## Service integration
|
|
74
|
+
|
|
75
|
+
- API-backed pages include types, service methods, aggregate exports, and page consumption in the same change.
|
|
76
|
+
- Do not embed production fake data or invented response fields.
|
|
77
|
+
- If the backend contract is unavailable, label proposed methods, paths, and fields as proposed.
|
|
78
|
+
- Pair missing services with `.agents/skills/shared-api-to-service/SKILL.md`. Pair missing deterministic data with `.agents/skills/shared-api-mock/SKILL.md`.
|
|
79
|
+
|
|
80
|
+
## Styling and fidelity
|
|
81
|
+
|
|
82
|
+
- Scope Less below a feature class. Use `:global` only for library internals.
|
|
83
|
+
- Do not add a UI library, state library, or CSS-in-JS system without approval.
|
|
84
|
+
- Cover loading, empty, error, disabled, permission, overflow, duplicate-submit, and narrow-screen behavior.
|
|
85
|
+
- Do not claim visual fidelity without inspecting the rendered page; otherwise say verification was static only.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: {{sharedSkillName}}
|
|
3
|
+
description: Analyze frontend Git changes and trace affected routes, pages, services, permissions, shared components, mocks, and regression checks. Read-only. Use for PR or pre-submit impact analysis.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Impact Analysis
|
|
7
|
+
|
|
8
|
+
This skill does not modify files.
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
1. Read `git status`, `git diff --stat`, `git diff`, and changed files. Include staged diffs when present.
|
|
13
|
+
2. For each changed file, trace static imports, service calls, route references (`config/route.ts`), and permission references.
|
|
14
|
+
3. Expand shared files: `MFProTable`, `src/services/request.tsx`, permission components, column-state hooks, overlay shells, and app bootstrap.
|
|
15
|
+
4. Check matching `typings.d.ts`, mocks, drawers/modals, table columns, and menu/route config.
|
|
16
|
+
5. Classify impact: direct callers, indirect pages, API/permission contracts, build/release risk.
|
|
17
|
+
6. Give a minimal automated and manual regression path for each item. An import is not proof of runtime impact.
|
|
18
|
+
|
|
19
|
+
Read `.agents/skills/shared-project-conventions/references/review-checklist.md` for shared files that must be expanded. If `.agents/project/review-rules.md` exists, also expand any extra domain files it names.
|
|
20
|
+
|
|
21
|
+
## Output
|
|
22
|
+
|
|
23
|
+
- Change summary
|
|
24
|
+
- Direct files and pages
|
|
25
|
+
- Possibly affected APIs, permissions, and mocks
|
|
26
|
+
- High-risk shared components and their callers
|
|
27
|
+
- Recommended automated checks and manual paths
|
|
28
|
+
- Risks that cannot be confirmed statically, with why
|
|
29
|
+
|
|
30
|
+
Use repository facts only. Do not invent backend behavior.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: {{sharedSkillName}}
|
|
3
|
+
description: Apply the active frontend project's architecture, API, business, permission, performance, testing, and naming conventions to generated or reviewed code.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Project Conventions
|
|
7
|
+
|
|
8
|
+
Use this skill for every non-trivial change. Preserve existing patterns and make the smallest scoped change.
|
|
9
|
+
|
|
10
|
+
Read in this order:
|
|
11
|
+
|
|
12
|
+
1. `.star-allinone.json`
|
|
13
|
+
2. [references/architecture.md](references/architecture.md)
|
|
14
|
+
3. [references/review-checklist.md](references/review-checklist.md)
|
|
15
|
+
|
|
16
|
+
Shared rules are complete for review, commit, mock, and service generation. If `.agents/project/conventions.md` exists, use it only for extra paths or domain invariants. It must not weaken the shared hard rules below.
|
|
17
|
+
|
|
18
|
+
## Hard rules
|
|
19
|
+
|
|
20
|
+
- Pages consume `import Service from '@/services'`. No direct axios or request-helper calls from pages.
|
|
21
|
+
- DTOs live in `src/services/<Domain>/typings.d.ts`. Pages do not redefine them.
|
|
22
|
+
- Reuse `MFProTable`, `ProForm`, `CustomDrawer`, `BaseModal`, `HocModal`, and existing permission wrappers.
|
|
23
|
+
- Backend field names stay in service types. Convert only at an adapter boundary.
|
|
24
|
+
- Async surfaces handle loading, empty, error, retry, unauthorized, and duplicate-submit.
|
|
25
|
+
- No unexplained `any`, `as any`, `@ts-ignore`, or `Record<string, any>` when the contract is known.
|
|
26
|
+
- No new UI/state library without approval.
|
|
27
|
+
|
|
28
|
+
## Completion
|
|
29
|
+
|
|
30
|
+
Report changed files, API operations used, states covered, validation commands and results, and remaining gaps.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
Apply these rules to every non-trivial frontend change. Shared review, commit, mock, and service generation do not require a project-local conventions file.
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
- Use React function components and TypeScript.
|
|
8
|
+
- Put transport code in `src/services`. Pages must not call axios or the request helper directly.
|
|
9
|
+
- Keep API DTOs in the domain `typings.d.ts`. Use named types and adapters instead of `any`.
|
|
10
|
+
- Reuse `MFProTable`, `BaseModal`, `CustomDrawer`, `HocModal`, permission wrappers, table cells, hooks, and shared styles before adding abstractions.
|
|
11
|
+
- Use `@/` imports for application modules and keep feature-local imports relative.
|
|
12
|
+
- Do not add a UI/state library or duplicate an existing component without explicit approval.
|
|
13
|
+
- Prefer feature-level code splitting for Excel, editors, charts, drag-and-drop, and other heavy modules.
|
|
14
|
+
|
|
15
|
+
## Business behavior
|
|
16
|
+
|
|
17
|
+
- Every async page handles loading, empty, error, retry, and unauthorized states where applicable.
|
|
18
|
+
- Mutations disable or guard duplicate submission, show a user-facing result, and refresh affected data.
|
|
19
|
+
- Destructive actions require confirmation and must not silently discard edits.
|
|
20
|
+
- Preserve backend field names in service types; convert only at a clear adapter boundary.
|
|
21
|
+
- Permission checks exist in the UI and remain enforced by the backend. Never infer permission from button visibility alone.
|
|
22
|
+
- Tables that persist columns use the project's column-state hook and register the key in the project's cache-reset UI when one exists.
|
|
23
|
+
|
|
24
|
+
## Type and quality
|
|
25
|
+
|
|
26
|
+
- Do not introduce new `Record<string, any>`, `Promise<any>`, or unexplained `any` / `as any` / `@ts-ignore` when the contract is known.
|
|
27
|
+
- Do not leave `console.log` or sensitive payloads in production paths.
|
|
28
|
+
- Keep constants, columns, schemas, and render adapters outside large render functions.
|
|
29
|
+
- Make the smallest scoped change. Do not refactor unrelated code.
|
|
30
|
+
|
|
31
|
+
## Validation
|
|
32
|
+
|
|
33
|
+
Identify commands that prove the changed surface is valid. At minimum:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
git diff --check
|
|
37
|
+
pnpm exec prettier --check <changed-files>
|
|
38
|
+
pnpm exec tsc --noEmit
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Run `pnpm lint` for broad or shared changes. Run `pnpm run build` when routes, entry behavior, shared runtime, or multiple page modules change. If `.star-allinone.json` documents a TypeScript `baseUrl` or build script, use that command.
|
|
42
|
+
|
|
43
|
+
Distinguish failures introduced by the current change from pre-existing or environment failures.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Quality Checklist
|
|
2
|
+
|
|
3
|
+
## Correctness and TypeScript
|
|
4
|
+
|
|
5
|
+
Check null/undefined access, partial responses, pagination, truthiness errors, enum drift, stale field names, state mutation, date/timezone handling, number/string ID comparison, and unsafe non-null assertions. Flag `any`, `@ts-ignore`, broad records, and repeated casts when a project or API type can express the boundary.
|
|
6
|
+
|
|
7
|
+
## Resilience, accessibility, styling, and security
|
|
8
|
+
|
|
9
|
+
Review loading, empty, partial, error, retry, permissions, network failure, and malformed responses. Avoid duplicate error toasts when `MFRequest` already reports the same failure.
|
|
10
|
+
|
|
11
|
+
Check semantic controls, keyboard access, focus return, labels, disabled/loading behavior, color-only status, tooltip-only information, and destructive confirmations. Prefer Ant Design primitives over clickable `div` or `span`.
|
|
12
|
+
|
|
13
|
+
Follow scoped Less and nearby conventions. Flag global leakage, arbitrary z-index escalation, long-text breakage, missing overflow, and hardcoded values where theme constants exist.
|
|
14
|
+
|
|
15
|
+
Check unsafe HTML, URL construction, upload/download names, sensitive logs/storage, visual-only permissions, redirects, and dynamic scripts.
|
|
16
|
+
|
|
17
|
+
## Testing
|
|
18
|
+
|
|
19
|
+
Request tests for concrete regression boundaries such as transformations, races, conditional validation, reusable hooks, complex transitions, or likely recurring bugs. Run focused Prettier, TypeScript, lint, `git diff --check`, and a production build in proportion to risk.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Review Checklist
|
|
2
|
+
|
|
3
|
+
This checklist is complete for shared review and commit. If `.agents/project/review-rules.md` exists, apply extra domain checks only; do not weaken the rules below.
|
|
4
|
+
|
|
5
|
+
## Permissions
|
|
6
|
+
|
|
7
|
+
- New routes, menus, and action buttons must stay in sync with the project's permission source.
|
|
8
|
+
- Destructive actions (delete, disable, export, assign, recycle) go through the project's permission wrappers.
|
|
9
|
+
- Do not treat hidden buttons as authorization. Review both the request and the UI permission.
|
|
10
|
+
|
|
11
|
+
## API and types
|
|
12
|
+
|
|
13
|
+
- Production requests go through `MFRequest` in `src/services/request.tsx`.
|
|
14
|
+
- Types live in `src/services/<Domain>/typings.d.ts`. Pages must not redefine DTOs.
|
|
15
|
+
- Changing a service or type requires checking `src/services/index.ts`, callers, and mocks.
|
|
16
|
+
- Do not invent fields, HTTP methods, or response shapes when OpenAPI/Swagger is unclear.
|
|
17
|
+
- Do not add unexplained `any`, `as any`, or `@ts-ignore`.
|
|
18
|
+
- Service callers are typed against unwrapped `data`. Mock JSON keeps the full `{ code, message, data }` envelope unless the project documents another envelope.
|
|
19
|
+
|
|
20
|
+
## Pages and forms
|
|
21
|
+
|
|
22
|
+
- Management lists prefer `MFProTable`. Column and toolbar configuration belong outside the render function.
|
|
23
|
+
- Business forms use `ProForm`. Drawers use `CustomDrawer`. Dialogs use `BaseModal` / `HocModal`.
|
|
24
|
+
- Successful mutations refresh the parent list. Closing an overlay clears form, loading, selected record, and other async state.
|
|
25
|
+
- Every `await` has error handling. Loading restores in `finally`.
|
|
26
|
+
- Check loading, empty, error, disabled, long content, and narrow-screen layout.
|
|
27
|
+
- Table empty values render `'-'` unless the design requires another value.
|
|
28
|
+
|
|
29
|
+
## Shared components and regression
|
|
30
|
+
|
|
31
|
+
- Changes to `MFProTable`, permission components, the request wrapper, or shared hooks must list direct callers.
|
|
32
|
+
- A shared-component change must not be verified on a single page. Cover at least two unrelated features.
|
|
33
|
+
- Separate correctness issues from optional refactors. Report P0/P1/P2 with reproduction or contract evidence.
|
|
34
|
+
|
|
35
|
+
## Severity
|
|
36
|
+
|
|
37
|
+
- **P0**: security/privacy breach, data loss, critical crash, or destructive behavior.
|
|
38
|
+
- **P1**: user-visible regression, broken primary workflow, invalid API/auth contract, stale submitted data, or reliable runtime exception.
|
|
39
|
+
- **P2**: credible performance, accessibility, type-safety, lifecycle, race, or maintainability defect.
|
|
40
|
+
- **P3**: minor actionable cleanup; include only when useful.
|
|
41
|
+
|
|
42
|
+
Do not inflate style preferences or speculative memoization into bugs.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: {{sharedSkillName}}
|
|
3
|
+
description: Publish the current frontend Git branch to the project's Yunxiao test pipeline. Use when the user asks to publish, deploy, release, or run the test environment pipeline, especially 发布测试环境, 发布测试云效流水线, or 以当前分支发布.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Publish Test Environment
|
|
7
|
+
|
|
8
|
+
This skill is fully shared. The only project-specific value is `publishPipelineId` in `.star-allinone.json`.
|
|
9
|
+
|
|
10
|
+
From the business repository root, run:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
bash .agents/skills/{{sharedSkillName}}/scripts/publish-current-branch.sh
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Do not look for a project-local deploy script under `scripts/`. Do not substitute another pipeline. Do not use or merge `rancher-test`.
|
|
17
|
+
|
|
18
|
+
## Config
|
|
19
|
+
|
|
20
|
+
Read `.star-allinone.json` before running. `publishPipelineId` is required:
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"project": "starscope-frontend",
|
|
25
|
+
"publishPipelineId": "5108336"
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Never ask the user to repeat the pipeline ID. Never copy another project's pipeline ID.
|
|
30
|
+
|
|
31
|
+
## Preconditions
|
|
32
|
+
|
|
33
|
+
- Current HEAD is a named branch, not detached.
|
|
34
|
+
- `origin/<branch>` exists and matches local `HEAD`. Push first when it does not.
|
|
35
|
+
- `YUNXIAO_ACCESS_TOKEN` is available. Request approval for the external Yunxiao CLI call.
|
|
36
|
+
- Never print access tokens.
|
|
37
|
+
|
|
38
|
+
## After the run
|
|
39
|
+
|
|
40
|
+
Report branch, commit subject, pipeline ID, run ID, status, and commit verification. Do not expose the full commit SHA in the dashboard comment or final report.
|
|
41
|
+
|
|
42
|
+
If Yunxiao selected a different branch or commit, the script stops the run. That is a failure; do not claim publication succeeded.
|
|
43
|
+
|
|
44
|
+
A missing current-commit field is not a failure. `commit_verification=unavailable` is acceptable when Yunxiao has not yet returned a commit.
|
|
45
|
+
|
|
46
|
+
The dashboard comment is `BUILD_REMARK` and contains branch, commit subject, and `来源: Codex`. A missing top-level `comment` field is not a publication failure.
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
DEFAULT_ORG_ID="61762c5110204867ecfd5ca4"
|
|
5
|
+
|
|
6
|
+
root="$(git rev-parse --show-toplevel)"
|
|
7
|
+
config_file="$root/.star-allinone.json"
|
|
8
|
+
if [[ ! -f "$config_file" ]]; then
|
|
9
|
+
echo "error: missing project config: $config_file" >&2
|
|
10
|
+
exit 1
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
pipeline_id="$(python3 - "$config_file" <<'PY'
|
|
14
|
+
import json
|
|
15
|
+
import sys
|
|
16
|
+
|
|
17
|
+
cfg = json.load(open(sys.argv[1]))
|
|
18
|
+
variables = cfg.get("variables") or {}
|
|
19
|
+
value = cfg.get("publishPipelineId") or variables.get("publishPipelineId") or ""
|
|
20
|
+
print(str(value).strip())
|
|
21
|
+
PY
|
|
22
|
+
)"
|
|
23
|
+
if [[ -z "$pipeline_id" ]]; then
|
|
24
|
+
echo "error: .star-allinone.json is missing publishPipelineId" >&2
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
organization_id="$(python3 - "$config_file" "$DEFAULT_ORG_ID" <<'PY'
|
|
29
|
+
import json
|
|
30
|
+
import sys
|
|
31
|
+
|
|
32
|
+
cfg = json.load(open(sys.argv[1]))
|
|
33
|
+
variables = cfg.get("variables") or {}
|
|
34
|
+
value = cfg.get("yunxiaoOrganizationId") or variables.get("yunxiaoOrganizationId") or sys.argv[2]
|
|
35
|
+
print(str(value).strip())
|
|
36
|
+
PY
|
|
37
|
+
)"
|
|
38
|
+
|
|
39
|
+
repository_url="$(python3 - "$(git remote get-url origin)" <<'PY'
|
|
40
|
+
import sys
|
|
41
|
+
|
|
42
|
+
url = sys.argv[1].strip()
|
|
43
|
+
if url.startswith("git@"):
|
|
44
|
+
host, path = url.split(":", 1)
|
|
45
|
+
host = host.split("@", 1)[1]
|
|
46
|
+
print(f"https://{host}/{path}")
|
|
47
|
+
else:
|
|
48
|
+
print(url)
|
|
49
|
+
PY
|
|
50
|
+
)"
|
|
51
|
+
|
|
52
|
+
branch="${1:-$(git branch --show-current)}"
|
|
53
|
+
if [[ -z "$branch" ]]; then
|
|
54
|
+
echo "error: detached HEAD; check out the branch to publish" >&2
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
local_commit="$(git rev-parse HEAD)"
|
|
59
|
+
if ! remote_commit="$(git ls-remote origin "refs/heads/$branch" | awk 'NR == 1 { print $1 }')"; then
|
|
60
|
+
echo "error: failed to query origin/$branch" >&2
|
|
61
|
+
exit 1
|
|
62
|
+
fi
|
|
63
|
+
if [[ -z "$remote_commit" ]]; then
|
|
64
|
+
echo "error: origin/$branch is unavailable; push it before publishing" >&2
|
|
65
|
+
exit 1
|
|
66
|
+
fi
|
|
67
|
+
if [[ "$local_commit" != "$remote_commit" ]]; then
|
|
68
|
+
echo "error: branch '$branch' is not synchronized with 'origin/$branch'" >&2
|
|
69
|
+
exit 1
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
if [[ -z "${YUNXIAO_ACCESS_TOKEN:-}" ]]; then
|
|
73
|
+
echo "error: YUNXIAO_ACCESS_TOKEN is unavailable" >&2
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
commit_message="$(git log -1 --format='%s')"
|
|
78
|
+
run_comment="发布分支: $branch | 提交内容: $commit_message | 来源: Codex"
|
|
79
|
+
params="$(python3 -c 'import json,sys; print(json.dumps({"runningBranchs": {sys.argv[1]: sys.argv[2]}, "branchModeBranchs": sys.argv[2], "comment": sys.argv[3]}))' "$repository_url" "$branch" "$run_comment")"
|
|
80
|
+
|
|
81
|
+
export ALIBABA_CLOUD_YUNXIAO_ACCESS_TOKEN="$YUNXIAO_ACCESS_TOKEN"
|
|
82
|
+
export ALIBABA_CLOUD_YUNXIAO_ORGANIZATION_ID="$organization_id"
|
|
83
|
+
|
|
84
|
+
run_id="$(aliyun devops flow-create-pipeline-run \
|
|
85
|
+
--pipeline-id "$pipeline_id" \
|
|
86
|
+
--params "$params")"
|
|
87
|
+
run_id="$(printf '%s' "$run_id" | tr -d '[:space:]')"
|
|
88
|
+
|
|
89
|
+
details=""
|
|
90
|
+
for _ in {1..20}; do
|
|
91
|
+
details="$(aliyun devops flow-get-pipeline-run \
|
|
92
|
+
--pipeline-id "$pipeline_id" \
|
|
93
|
+
--pipeline-run-id "$run_id")"
|
|
94
|
+
has_source="$(DETAILS="$details" python3 - <<'PY'
|
|
95
|
+
import json
|
|
96
|
+
import os
|
|
97
|
+
|
|
98
|
+
details = json.loads(os.environ["DETAILS"])
|
|
99
|
+
params = {item.get("key"): item.get("value") for item in details.get("globalParams", [])}
|
|
100
|
+
if params.get("CI_SOURCE_BRANCHES"):
|
|
101
|
+
print("yes")
|
|
102
|
+
elif details.get("sources"):
|
|
103
|
+
print("yes")
|
|
104
|
+
else:
|
|
105
|
+
print("no")
|
|
106
|
+
PY
|
|
107
|
+
)"
|
|
108
|
+
[[ "$has_source" == "yes" ]] && break
|
|
109
|
+
sleep 3
|
|
110
|
+
done
|
|
111
|
+
|
|
112
|
+
source_result="$(DETAILS="$details" python3 - "$branch" <<'PY'
|
|
113
|
+
import json
|
|
114
|
+
import os
|
|
115
|
+
import sys
|
|
116
|
+
|
|
117
|
+
details = json.loads(os.environ["DETAILS"])
|
|
118
|
+
wanted = sys.argv[1]
|
|
119
|
+
params = {item.get("key"): item.get("value") for item in details.get("globalParams", [])}
|
|
120
|
+
branches_raw = params.get("CI_SOURCE_BRANCHES") or "[]"
|
|
121
|
+
try:
|
|
122
|
+
branches = json.loads(branches_raw)
|
|
123
|
+
except json.JSONDecodeError:
|
|
124
|
+
branches = []
|
|
125
|
+
item = branches[0] if branches else {}
|
|
126
|
+
actual_branch = item.get("CI_COMMIT_REF_NAME") or ""
|
|
127
|
+
actual_commit = str(item.get("CI_COMMIT_ID") or "")
|
|
128
|
+
|
|
129
|
+
if not actual_branch:
|
|
130
|
+
sources = details.get("sources") or []
|
|
131
|
+
source = next((entry for entry in sources if (entry.get("data") or {}).get("branch") == wanted), sources[0] if sources else None)
|
|
132
|
+
data = (source or {}).get("data") or {}
|
|
133
|
+
actual_branch = str(data.get("branch") or "")
|
|
134
|
+
actual_commit = next(
|
|
135
|
+
(str(data[key]) for key in ("commit", "commitId", "revision", "checkoutCommit", "checkoutCommitId") if data.get(key)),
|
|
136
|
+
"",
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
print(f"{actual_branch}\t{actual_commit}")
|
|
140
|
+
PY
|
|
141
|
+
)"
|
|
142
|
+
IFS=$'\t' read -r actual_branch actual_commit <<<"$source_result"
|
|
143
|
+
|
|
144
|
+
stop_run() {
|
|
145
|
+
aliyun devops flow-update-pipeline-run \
|
|
146
|
+
--pipeline-id "$pipeline_id" \
|
|
147
|
+
--pipeline-run-id "$run_id" >/dev/null || true
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if [[ -n "$actual_branch" && "$actual_branch" != "$branch" ]]; then
|
|
151
|
+
stop_run
|
|
152
|
+
echo "error: stopped run $run_id because Yunxiao selected '${actual_branch}' instead of '$branch'" >&2
|
|
153
|
+
exit 2
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
commit_verification="unavailable"
|
|
157
|
+
short_commit="$(git rev-parse --short=8 HEAD)"
|
|
158
|
+
if [[ -n "$actual_commit" ]]; then
|
|
159
|
+
if [[ "$actual_commit" == "$local_commit" || "$actual_commit" == "$short_commit"* ]]; then
|
|
160
|
+
commit_verification="verified"
|
|
161
|
+
else
|
|
162
|
+
stop_run
|
|
163
|
+
echo "error: stopped run $run_id because Yunxiao selected a different commit" >&2
|
|
164
|
+
exit 4
|
|
165
|
+
fi
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
status="$(aliyun devops flow-get-pipeline-run \
|
|
169
|
+
--pipeline-id "$pipeline_id" \
|
|
170
|
+
--pipeline-run-id "$run_id" \
|
|
171
|
+
--cli-query 'status' | tr -d '"[:space:]')"
|
|
172
|
+
|
|
173
|
+
printf 'branch=%s\ncommit_message=%s\ncomment=%s\npipeline_id=%s\nrun_id=%s\nstatus=%s\ncommit_verification=%s\n' \
|
|
174
|
+
"$branch" "$commit_message" "$run_comment" "$pipeline_id" "$run_id" "$status" "$commit_verification"
|