@ibotor/smart-trellis 0.5.22 → 0.5.24
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 +176 -153
- package/dist/cli/smart.js +3 -1
- package/dist/cli/smart.js.map +1 -1
- package/dist/commands/smart-init.d.ts +4 -1
- package/dist/commands/smart-init.d.ts.map +1 -1
- package/dist/commands/smart-init.js +96 -1
- package/dist/commands/smart-init.js.map +1 -1
- package/dist/configurators/shared.d.ts.map +1 -1
- package/dist/configurators/shared.js +2 -0
- package/dist/configurators/shared.js.map +1 -1
- package/dist/migrations/manifests/0.5.23.json +9 -0
- package/dist/templates/common/bundled-skills/trellis-dev-preflight/SKILL.md +162 -0
- package/dist/templates/common/bundled-skills/trellis-quality-review/SKILL.md +82 -0
- package/dist/templates/common/bundled-skills/trellis-quality-review/docs/overview.md +331 -0
- package/dist/templates/common/bundled-skills/trellis-quality-review/evals/evals.json +50 -0
- package/dist/templates/common/bundled-skills/trellis-quality-review/references/copy-fidelity.md +56 -0
- package/dist/templates/common/bundled-skills/trellis-quality-review/references/decision-tree.md +102 -0
- package/dist/templates/common/bundled-skills/trellis-quality-review/references/formatting-fidelity.md +37 -0
- package/dist/templates/common/bundled-skills/trellis-quality-review/references/framework-rules.md +59 -0
- package/dist/templates/common/bundled-skills/trellis-quality-review/references/report-format.md +23 -0
- package/dist/templates/common/bundled-skills/trellis-quality-review/references/safe-refactor-boundaries.md +158 -0
- package/dist/templates/common/bundled-skills/trellis-quality-review/references/scope-control.md +49 -0
- package/dist/templates/common/bundled-skills/trellis-quality-review/references/severity.md +105 -0
- package/dist/templates/common/bundled-skills/trellis-quality-review/references/small-change-fast-path.md +51 -0
- package/dist/templates/common/bundled-skills/trellis-quality-review/references/verification-selection.md +81 -0
- package/dist/templates/common/bundled-skills/trellis-quality-review/scripts/diff_scans.sh +145 -0
- package/dist/templates/common/bundled-skills/verification-before-completion/SKILL.md +139 -0
- package/dist/templates/common/commands/micro-task.md +33 -0
- package/dist/templates/trellis/workflow.md +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# Safe Refactor Boundaries
|
|
2
|
+
|
|
3
|
+
Use this reference before splitting components, extracting composables/hooks, moving helpers, or changing ownership. The goal is to reduce responsibility pile-up without creating abstraction churn or expanding beyond the current diff.
|
|
4
|
+
|
|
5
|
+
## Core Rule
|
|
6
|
+
|
|
7
|
+
Refactor only when it improves the current requirement's clarity, correctness, or maintainability inside the review boundary. File size alone is not enough.
|
|
8
|
+
|
|
9
|
+
A safe refactor has all of these properties:
|
|
10
|
+
|
|
11
|
+
- The problematic responsibility is touched by the current diff.
|
|
12
|
+
- The target boundary is obvious and nameable.
|
|
13
|
+
- The extracted interface is smaller than the code it hides.
|
|
14
|
+
- The move does not require unrelated callers, routes, stores, styles, or tests to change.
|
|
15
|
+
- Behavior, copy, layout, and public contracts remain unchanged unless required.
|
|
16
|
+
- Verification can cover the moved logic or affected render path.
|
|
17
|
+
|
|
18
|
+
## Strong Signals to Split or Extract
|
|
19
|
+
|
|
20
|
+
Consider a targeted split when at least one is true:
|
|
21
|
+
|
|
22
|
+
- A page/container now owns orchestration plus multiple changed UI sections.
|
|
23
|
+
- A component now mixes rendering with request orchestration, validation, mapping, and modal/table/form state touched by this requirement.
|
|
24
|
+
- The current diff duplicates non-trivial logic in two or more places.
|
|
25
|
+
- Newly added side effects make the render component hard to follow.
|
|
26
|
+
- Newly added pure mapping/formatting/validation logic obscures the UI path.
|
|
27
|
+
- A modal/drawer/wizard section has its own state, validation, and actions that can be named independently.
|
|
28
|
+
- A hook/composable would isolate stateful behavior used by the current feature without becoming a generic utility.
|
|
29
|
+
|
|
30
|
+
## Strong Signals Not to Refactor
|
|
31
|
+
|
|
32
|
+
Avoid structural refactor when any is true:
|
|
33
|
+
|
|
34
|
+
- The file is merely large, but the current change touches a small localized area.
|
|
35
|
+
- The split would require moving unrelated markup, styles, tests, or callers.
|
|
36
|
+
- The extracted function/component would have many props or return values just to keep behavior working.
|
|
37
|
+
- The new abstraction would be used once and does not hide meaningful complexity.
|
|
38
|
+
- Naming the boundary requires vague words like `Common`, `Base`, `Manager`, `Handler`, or `Utils`.
|
|
39
|
+
- The refactor would change user-visible copy, layout, option order, focus behavior, or event timing.
|
|
40
|
+
- The user requested a micro-change or explicitly asked to avoid broad cleanup.
|
|
41
|
+
|
|
42
|
+
## Boundary Heuristics
|
|
43
|
+
|
|
44
|
+
### Page / Route / Container
|
|
45
|
+
|
|
46
|
+
Should own:
|
|
47
|
+
|
|
48
|
+
- route params and navigation glue
|
|
49
|
+
- top-level data loading orchestration
|
|
50
|
+
- composition of feature sections
|
|
51
|
+
- passing typed props and event handlers to children
|
|
52
|
+
|
|
53
|
+
Should not accumulate:
|
|
54
|
+
|
|
55
|
+
- multiple independent UI sections with detailed markup
|
|
56
|
+
- modal internals
|
|
57
|
+
- table cell formatting details
|
|
58
|
+
- form field validation internals
|
|
59
|
+
- low-level API payload mapping when it obscures orchestration
|
|
60
|
+
|
|
61
|
+
### Component
|
|
62
|
+
|
|
63
|
+
Should own:
|
|
64
|
+
|
|
65
|
+
- one nameable UI section
|
|
66
|
+
- local UI state for that section
|
|
67
|
+
- typed props/events or callbacks
|
|
68
|
+
- minimal formatting needed for display
|
|
69
|
+
|
|
70
|
+
Extract when the component contains multiple independently nameable regions touched by this requirement, such as search form + table + edit modal + upload drawer.
|
|
71
|
+
|
|
72
|
+
Do not extract when the child would only wrap a few lines and add prop plumbing without hiding complexity.
|
|
73
|
+
|
|
74
|
+
### Composable / Hook
|
|
75
|
+
|
|
76
|
+
Should own:
|
|
77
|
+
|
|
78
|
+
- stateful logic and side effects
|
|
79
|
+
- async request lifecycle
|
|
80
|
+
- derived state tied to the feature
|
|
81
|
+
- event handlers whose behavior is not just presentational
|
|
82
|
+
|
|
83
|
+
Good candidates:
|
|
84
|
+
|
|
85
|
+
- `useUserTableData`
|
|
86
|
+
- `useDomainForm`
|
|
87
|
+
- `useUploadDialog`
|
|
88
|
+
|
|
89
|
+
Weak candidates:
|
|
90
|
+
|
|
91
|
+
- `useHelpers`
|
|
92
|
+
- `useCommon`
|
|
93
|
+
- `usePageLogic`
|
|
94
|
+
- a hook returning 15 unrelated values
|
|
95
|
+
|
|
96
|
+
### Helper
|
|
97
|
+
|
|
98
|
+
Should own pure logic:
|
|
99
|
+
|
|
100
|
+
- formatters
|
|
101
|
+
- mappers
|
|
102
|
+
- validators
|
|
103
|
+
- sort/filter predicates
|
|
104
|
+
- small calculations
|
|
105
|
+
|
|
106
|
+
Keep helpers local when used only by one component/composable. Move to a separate file only when the helper is non-trivial, reused by current-work code, or makes the owning file materially clearer.
|
|
107
|
+
|
|
108
|
+
### Types
|
|
109
|
+
|
|
110
|
+
Keep feature-local types near the owning component/composable when they are not reused.
|
|
111
|
+
|
|
112
|
+
Move types to shared files only when:
|
|
113
|
+
|
|
114
|
+
- multiple current-work files consume them
|
|
115
|
+
- they represent API or route/store boundaries
|
|
116
|
+
- colocating them would create import cycles or unclear ownership
|
|
117
|
+
|
|
118
|
+
## Vue-Specific Guidance
|
|
119
|
+
|
|
120
|
+
- Prefer `<script setup>` and typed props/emits when the project uses that style.
|
|
121
|
+
- Keep section-local refs in the section component unless parent orchestration needs them.
|
|
122
|
+
- Extract a composable when state transitions, async effects, watchers, or derived state dominate the component.
|
|
123
|
+
- Avoid Pinia for one-off UI state; use Pinia when state is shared across routes/features or must outlive the component.
|
|
124
|
+
- Avoid composables that return large bags of unrelated refs; split by feature behavior instead.
|
|
125
|
+
|
|
126
|
+
## React / Next-Specific Guidance
|
|
127
|
+
|
|
128
|
+
- Keep route/page components focused on orchestration and server/client boundary correctness.
|
|
129
|
+
- Do not add `use client` broadly just to support a small interactive child; prefer isolating the client component when feasible and in scope.
|
|
130
|
+
- Extract a hook when stateful behavior or side effects obscure the component body.
|
|
131
|
+
- Extract a component when a nameable UI section has its own props and events.
|
|
132
|
+
- Do not add `useMemo`/`useCallback` as a refactor unless identity stability or render cost is a real current-diff concern.
|
|
133
|
+
|
|
134
|
+
## Safe Refactor Procedure
|
|
135
|
+
|
|
136
|
+
1. Name the responsibility that is piled up.
|
|
137
|
+
2. Confirm it is touched by the current requirement.
|
|
138
|
+
3. Choose the smallest boundary that hides complexity without leaking many props/returns.
|
|
139
|
+
4. Preserve public behavior, copy, layout, and event timing.
|
|
140
|
+
5. Move only the directly related code.
|
|
141
|
+
6. Re-run the smallest relevant verification from `verification-selection.md`.
|
|
142
|
+
7. If any step requires broad unrelated edits, stop and record the idea as Note Only.
|
|
143
|
+
|
|
144
|
+
## Reporting
|
|
145
|
+
|
|
146
|
+
When you refactor, report why the boundary was safe:
|
|
147
|
+
|
|
148
|
+
```text
|
|
149
|
+
Changed:
|
|
150
|
+
- Extracted EditDomainModal because the current diff added independent modal state, validation, and submit handling; parent now only orchestrates open/close and refresh.
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
When you do not refactor, report why not when relevant:
|
|
154
|
+
|
|
155
|
+
```text
|
|
156
|
+
Severity:
|
|
157
|
+
- Should Fix: did not split SettingsPage because the large table section was pre-existing and untouched by this request.
|
|
158
|
+
```
|
package/dist/templates/common/bundled-skills/trellis-quality-review/references/scope-control.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Scope Control
|
|
2
|
+
|
|
3
|
+
Use this gate before any cleanup or refactor. The purpose is to protect the user's requested change from scope creep.
|
|
4
|
+
|
|
5
|
+
## Default Rule
|
|
6
|
+
|
|
7
|
+
Change only what the requirement asks for, plus the smallest necessary adjacent code to keep it correct, typed, lint-clean, or buildable.
|
|
8
|
+
|
|
9
|
+
Do not opportunistically optimize, polish, reorder, refactor, rename, reformat, or clean up code the requirement does not touch.
|
|
10
|
+
|
|
11
|
+
Preserve existing user-visible text, helper descriptions, option order, placeholders, tooltips, validation messages, comments, and layout unless the requirement explicitly asks to change them or the feature cannot work without the change.
|
|
12
|
+
|
|
13
|
+
If the user says “do not change anything not mentioned”, treat all non-required UI/text changes as high-risk and list them explicitly in the review.
|
|
14
|
+
|
|
15
|
+
## Gate Steps
|
|
16
|
+
|
|
17
|
+
1. Restate the current requirement in one sentence.
|
|
18
|
+
2. Inspect `git status` and `git diff HEAD` before editing.
|
|
19
|
+
3. Classify each changed block:
|
|
20
|
+
- **In requirement:** directly implements or verifies the requested change.
|
|
21
|
+
- **Necessary adjacent:** required to keep the requested change correct, typed, lint-clean, or buildable.
|
|
22
|
+
- **Out of scope:** opportunistic old-code optimization, unrelated formatting, broad refactor, unrelated dead-code cleanup, renamed abstractions, style changes, user-visible copy changes, helper-description changes, or option-order changes not needed by the requirement.
|
|
23
|
+
4. Only edit **In requirement** and **Necessary adjacent** blocks.
|
|
24
|
+
5. For **Out of scope** blocks, do not extend the change.
|
|
25
|
+
6. Revert your own out-of-scope edits when safe.
|
|
26
|
+
7. If an out-of-scope edit predates the session or ownership is unclear, leave it untouched and mention it in Notes.
|
|
27
|
+
8. If classification is unclear and would change more code, ask the user instead of deciding silently.
|
|
28
|
+
|
|
29
|
+
## Responsibility Map
|
|
30
|
+
|
|
31
|
+
Use this map to decide whether structure changes are justified:
|
|
32
|
+
|
|
33
|
+
- **route/page/container:** orchestration, data loading, high-level composition
|
|
34
|
+
- **component:** one UI section with typed props/emits or typed component props/callbacks
|
|
35
|
+
- **composable/hook:** stateful logic, side effects, derived state, lifecycle coordination
|
|
36
|
+
- **helper:** pure feature-local logic
|
|
37
|
+
- **api/types:** external boundary and shared contracts
|
|
38
|
+
|
|
39
|
+
Split only when the current requirement created unclear ownership or repeated logic. Keep feature-local types/helpers near the owning unit unless reused broadly.
|
|
40
|
+
|
|
41
|
+
## Common Scope Mistakes
|
|
42
|
+
|
|
43
|
+
| Mistake | Correction |
|
|
44
|
+
| --- | --- |
|
|
45
|
+
| Optimizing old code during requirement review | Record it in Notes unless it blocks the current requirement |
|
|
46
|
+
| Splitting every type/helper into standalone files | Keep local helpers local unless reused |
|
|
47
|
+
| Moving UI state into parent unnecessarily | Keep section-local state near the section |
|
|
48
|
+
| Letting old violations expand scope | Fix only newly introduced violations unless adjacent legacy code blocks correctness |
|
|
49
|
+
| Trusting visual refactor | Preserve behavior and verify with commands |
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Severity
|
|
2
|
+
|
|
3
|
+
Classify findings before fixing them. Severity applies to the current review boundary: default to `git diff HEAD` unless the user requested staged-only or a specific base ref. Historical or untouched issues are usually Note Only unless they block the current requirement.
|
|
4
|
+
|
|
5
|
+
## Levels
|
|
6
|
+
|
|
7
|
+
### Blocker
|
|
8
|
+
|
|
9
|
+
Must be fixed before handoff. The current diff introduces or exposes a problem that can break build, typecheck, runtime behavior, critical user flow, permissions, data integrity, or security.
|
|
10
|
+
|
|
11
|
+
Frontend examples:
|
|
12
|
+
|
|
13
|
+
- current diff causes build, typecheck, or required test failure
|
|
14
|
+
- key page crashes or fails to render
|
|
15
|
+
- form cannot submit, primary action cannot be clicked, or required user flow is broken
|
|
16
|
+
- API payload or response mapping is wrong for the changed feature
|
|
17
|
+
- permission/auth guard is loosened or bypassed
|
|
18
|
+
- Next.js server/client boundary error prevents render or build
|
|
19
|
+
- changed props/types break touched consumers
|
|
20
|
+
- unsanitized user-controlled `dangerouslySetInnerHTML` or equivalent XSS risk
|
|
21
|
+
- production-executed `debugger`
|
|
22
|
+
|
|
23
|
+
Action: fix in the current review if possible, rerun relevant verification, and report as blocking if not resolved.
|
|
24
|
+
|
|
25
|
+
### Must Fix Before Handoff
|
|
26
|
+
|
|
27
|
+
Should be fixed before delivery when introduced by the current diff, even if it does not immediately fail build.
|
|
28
|
+
|
|
29
|
+
Frontend examples:
|
|
30
|
+
|
|
31
|
+
- added `console.log`, `debugger`, unexplained `@ts-ignore`, `@ts-expect-error`, or broad `eslint-disable`
|
|
32
|
+
- current-work dead code: unused props, emits, refs, state, imports, branches, mock fields
|
|
33
|
+
- out-of-scope user-visible copy, helper text, placeholder, validation message, or option-order changes
|
|
34
|
+
- out-of-scope formatting churn mixed into the diff
|
|
35
|
+
- current diff introduces obvious duplicated logic that can be removed locally
|
|
36
|
+
- local UI state was lifted or globalized without requirement support
|
|
37
|
+
- newly added loading/error state is never rendered or consumed
|
|
38
|
+
- temporary mock/demo data is scattered in production components
|
|
39
|
+
|
|
40
|
+
Action: fix when ownership is clear and the fix stays inside the requirement boundary. If ownership is unclear, record in Notes instead of expanding scope.
|
|
41
|
+
|
|
42
|
+
### Should Fix If In Scope
|
|
43
|
+
|
|
44
|
+
Real issue, but fix only when it is clearly within the current requirement and the change is small.
|
|
45
|
+
|
|
46
|
+
Frontend examples:
|
|
47
|
+
|
|
48
|
+
- unclear name in newly added function, prop, event, or variable
|
|
49
|
+
- newly added condition is hard to read but safe
|
|
50
|
+
- new component is somewhat large but not yet clearly multi-responsibility
|
|
51
|
+
- duplicated new snippet appears twice and a local helper would clarify it
|
|
52
|
+
- type could be narrower, but current type is safe
|
|
53
|
+
- composable/hook return shape is slightly broad but still understandable
|
|
54
|
+
- helper extraction would improve clarity but requires moving files or touching callers
|
|
55
|
+
- tests are not ideal, but selected verification covers the main changed path
|
|
56
|
+
|
|
57
|
+
Action: fix only if the edit is small and does not expand scope. Otherwise mention as a follow-up Note.
|
|
58
|
+
|
|
59
|
+
### Note Only
|
|
60
|
+
|
|
61
|
+
Do not fix during this review. The issue is historical, untouched, unclear ownership, or not needed for the current requirement.
|
|
62
|
+
|
|
63
|
+
Frontend examples:
|
|
64
|
+
|
|
65
|
+
- old component is large but this task touched only a tiny unrelated line
|
|
66
|
+
- historical lint/typecheck/test failures
|
|
67
|
+
- old copy inconsistency
|
|
68
|
+
- legacy form validation pattern
|
|
69
|
+
- old API layer or directory structure concerns
|
|
70
|
+
- untouched hook/composable design issue
|
|
71
|
+
- existing `any`, formatter churn, or test gap not introduced by the current diff
|
|
72
|
+
|
|
73
|
+
Action: record briefly in Notes when useful. Do not mark the current task failed unless it blocks the current requirement.
|
|
74
|
+
|
|
75
|
+
## Classification Flow
|
|
76
|
+
|
|
77
|
+
1. **Was it introduced or exposed by the current review diff?**
|
|
78
|
+
- No: Note Only, unless it blocks the current requirement.
|
|
79
|
+
- Yes: continue.
|
|
80
|
+
|
|
81
|
+
2. **Can it break build, typecheck, runtime behavior, critical flow, permissions, data integrity, or security?**
|
|
82
|
+
- Yes: Blocker.
|
|
83
|
+
- No: continue.
|
|
84
|
+
|
|
85
|
+
3. **Is it current-work debug code, unexplained suppression, dead code, out-of-scope copy, or out-of-scope formatting?**
|
|
86
|
+
- Yes: Must Fix Before Handoff.
|
|
87
|
+
- No: continue.
|
|
88
|
+
|
|
89
|
+
4. **Is the fix small, local, and inside the current requirement boundary?**
|
|
90
|
+
- Yes: Should Fix If In Scope.
|
|
91
|
+
- No: Note Only.
|
|
92
|
+
|
|
93
|
+
## Reporting
|
|
94
|
+
|
|
95
|
+
Keep severity concise. Prefer counts and high-signal examples over long lists.
|
|
96
|
+
|
|
97
|
+
Example:
|
|
98
|
+
|
|
99
|
+
```text
|
|
100
|
+
Severity:
|
|
101
|
+
- Blocker: none
|
|
102
|
+
- Must Fix: removed added console.log; restored out-of-scope placeholder change
|
|
103
|
+
- Should Fix: did not split SettingsPanel because it would touch unrelated sections
|
|
104
|
+
- Note Only: pre-existing vue-tsc errors in src/legacy/* are unrelated to touched files
|
|
105
|
+
```
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Small-Change Fast Path
|
|
2
|
+
|
|
3
|
+
Use this path for tiny, low-risk frontend changes where full quality review would create more churn than value.
|
|
4
|
+
|
|
5
|
+
## Qualifying Changes
|
|
6
|
+
|
|
7
|
+
A change qualifies only when all are true:
|
|
8
|
+
|
|
9
|
+
- The user's request is narrow and explicit.
|
|
10
|
+
- The diff is limited to one file or a very small localized area.
|
|
11
|
+
- The change does not affect API shape, routing, permissions, state flow, data transformation, validation behavior, dependency configuration, or shared types.
|
|
12
|
+
- The change is easy to verify by reading the diff.
|
|
13
|
+
- No suspicious added lines appear, such as `console.log`, `debugger`, `@ts-ignore`, `eslint-disable`, `TODO`, or `FIXME`.
|
|
14
|
+
|
|
15
|
+
Common qualifying examples:
|
|
16
|
+
|
|
17
|
+
- UI spacing, width, color, or alignment constants
|
|
18
|
+
- single label/copy change explicitly requested by the user
|
|
19
|
+
- table column width/order requested by the user
|
|
20
|
+
- small style/class adjustment
|
|
21
|
+
- single local config flag with no behavior cascade
|
|
22
|
+
|
|
23
|
+
## Disqualifiers
|
|
24
|
+
|
|
25
|
+
Do not use the fast path if any are true:
|
|
26
|
+
|
|
27
|
+
- The change affects component boundaries, composables/hooks, stores, route logic, API calls, form validation, permissions, upload/download behavior, or data mapping.
|
|
28
|
+
- The diff spans multiple modules or shared abstractions.
|
|
29
|
+
- The change introduces or edits TypeScript types used outside the local file.
|
|
30
|
+
- The diff includes unrelated formatting or copy churn.
|
|
31
|
+
- The user asks for a full review, cleanup, refactor, verification, or confidence before handoff.
|
|
32
|
+
- The project currently has failing diagnostics that may be related to the touched code.
|
|
33
|
+
|
|
34
|
+
## Fast Path Procedure
|
|
35
|
+
|
|
36
|
+
1. Restate the small requirement in one sentence.
|
|
37
|
+
2. Inspect the relevant diff only.
|
|
38
|
+
3. Confirm the diff contains only the requested localized change.
|
|
39
|
+
4. Do not run broad lint, typecheck, unit tests, or build by default.
|
|
40
|
+
5. If a minimal targeted command is obvious and cheap, run it only when it directly validates the change.
|
|
41
|
+
6. Report that the fast path was used and whether verification was limited to diff inspection.
|
|
42
|
+
|
|
43
|
+
## Required Final Note
|
|
44
|
+
|
|
45
|
+
When using this path, include a short note like:
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
Used small-change fast path: skipped lint/typecheck/test/build because the diff is a localized UI/copy/config change and diff inspection confirmed scope.
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
If the diff inspection finds scope expansion, leave the fast path and return to the normal decision tree.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Verification Selection
|
|
2
|
+
|
|
3
|
+
Use this reference before reporting completion or correctness. The goal is to choose the smallest verification set that gives confidence for the current frontend diff without expanding into unrelated legacy cleanup.
|
|
4
|
+
|
|
5
|
+
## Core Rule
|
|
6
|
+
|
|
7
|
+
Verification should match the risk introduced by the current diff:
|
|
8
|
+
|
|
9
|
+
- Tiny localized UI/copy/style/config changes can use the small-change fast path and diff inspection only.
|
|
10
|
+
- Type, data, state, validation, routing, API, component-boundary, or framework-boundary changes need targeted commands.
|
|
11
|
+
- Full build is reserved for changes that affect bundling, routes/pages, framework config, server/client boundaries, or when lighter checks cannot cover the risk.
|
|
12
|
+
|
|
13
|
+
Always inspect project scripts and nearby docs/config before inventing commands.
|
|
14
|
+
|
|
15
|
+
## Command Discovery Order
|
|
16
|
+
|
|
17
|
+
Prefer project-defined scripts over raw tool invocations:
|
|
18
|
+
|
|
19
|
+
1. Read `package.json` scripts.
|
|
20
|
+
2. Check project docs or local agent instructions if already relevant to the task.
|
|
21
|
+
3. Check framework config only when needed: `vite.config.*`, `next.config.*`, `tsconfig*.json`, `eslint.config.*`, `.eslintrc*`, `vitest.config.*`, `jest.config.*`, `playwright.config.*`.
|
|
22
|
+
4. Prefer the package manager already used by the project: lockfiles and scripts reveal `pnpm`, `npm`, `yarn`, or `bun`.
|
|
23
|
+
|
|
24
|
+
Do not add dependencies or modify configs just to run verification.
|
|
25
|
+
|
|
26
|
+
## Selection Matrix
|
|
27
|
+
|
|
28
|
+
| Diff signal | Verification default |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| Small-change fast path | Diff inspection only; no broad lint/typecheck/test/build by default |
|
|
31
|
+
| `.vue` template/script/style changes | Project lint plus Vue/typecheck script when available, such as `vue-tsc` or `typecheck` |
|
|
32
|
+
| Vue props/emits/composable/store changes | Typecheck plus targeted tests if present |
|
|
33
|
+
| React/TSX component changes | Project lint plus TypeScript check when available |
|
|
34
|
+
| Next.js route/page/server-client boundary changes | Lint/typecheck plus build when boundary or route behavior risk is meaningful |
|
|
35
|
+
| Type definitions or shared contracts changed | Typecheck; targeted tests for consumers when present |
|
|
36
|
+
| Form validation, data mapping, formatter, parser, permission logic | Targeted unit tests; typecheck if TypeScript is involved |
|
|
37
|
+
| API call shape or request/response mapping changed | Typecheck plus targeted integration/unit tests if available |
|
|
38
|
+
| Styling-only but not fast-path | Scoped lint/style check if project has one; otherwise diff inspection plus optional visual/manual note |
|
|
39
|
+
| Suspicious added debug/type-suppression lines fixed | Re-run the scan or scoped lint that would catch the issue |
|
|
40
|
+
| Formatter conflict | Prefer scoped lint with formatting rules disabled when preserving scope; report the conflict |
|
|
41
|
+
|
|
42
|
+
## Running Strategy
|
|
43
|
+
|
|
44
|
+
1. Start with the narrowest command that covers the changed files or feature.
|
|
45
|
+
2. Prefer targeted tests over full test suites when a clear target exists.
|
|
46
|
+
3. Run full lint/typecheck/build only when the diff risk justifies it or project scripts are fast and standard.
|
|
47
|
+
4. If a command is unavailable, do not invent a replacement blindly; report that no matching script was found.
|
|
48
|
+
5. If the user explicitly asked to skip verification, skip it and report that instruction.
|
|
49
|
+
|
|
50
|
+
## Failure Handling
|
|
51
|
+
|
|
52
|
+
When a command fails:
|
|
53
|
+
|
|
54
|
+
1. Read the output and identify the failing file or test.
|
|
55
|
+
2. Decide whether the failure is related to the current diff.
|
|
56
|
+
3. If related, fix within scope and rerun the relevant command.
|
|
57
|
+
4. If unrelated or historical, do not expand scope; report it under Notes with evidence.
|
|
58
|
+
5. Do not claim verification passed if any required command failed.
|
|
59
|
+
6. If partial verification passed, say exactly which commands passed and which failed.
|
|
60
|
+
|
|
61
|
+
## Final Report Evidence
|
|
62
|
+
|
|
63
|
+
In the `Verified` section, include:
|
|
64
|
+
|
|
65
|
+
- exact command
|
|
66
|
+
- exit status
|
|
67
|
+
- short result summary
|
|
68
|
+
- if skipped, the explicit reason
|
|
69
|
+
|
|
70
|
+
Examples:
|
|
71
|
+
|
|
72
|
+
```text
|
|
73
|
+
Verified:
|
|
74
|
+
- `pnpm lint -- src/pages/Settings.vue` exited 0.
|
|
75
|
+
- `pnpm vue-tsc --noEmit` exited 1 due to pre-existing errors in src/legacy/*; no errors referenced the touched files.
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
```text
|
|
79
|
+
Verified:
|
|
80
|
+
- Used small-change fast path: skipped lint/typecheck/test/build because only one table column width changed and diff inspection confirmed scope.
|
|
81
|
+
```
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
mode="base"
|
|
5
|
+
base_ref="HEAD"
|
|
6
|
+
json=0
|
|
7
|
+
files_only=0
|
|
8
|
+
|
|
9
|
+
usage() {
|
|
10
|
+
cat <<'EOF'
|
|
11
|
+
Usage: diff_scans.sh [--base REF] [--cached] [--files] [--json]
|
|
12
|
+
|
|
13
|
+
Modes:
|
|
14
|
+
--base REF Scan git diff against REF. Defaults to HEAD.
|
|
15
|
+
--cached Scan staged changes.
|
|
16
|
+
--files Only print changed frontend files.
|
|
17
|
+
--json Print a JSON summary instead of sectioned text.
|
|
18
|
+
-h, --help Show this help.
|
|
19
|
+
EOF
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
while [[ $# -gt 0 ]]; do
|
|
23
|
+
case "$1" in
|
|
24
|
+
--base)
|
|
25
|
+
mode="base"
|
|
26
|
+
base_ref="${2:?--base requires a ref}"
|
|
27
|
+
shift 2
|
|
28
|
+
;;
|
|
29
|
+
--cached|--staged)
|
|
30
|
+
mode="cached"
|
|
31
|
+
shift
|
|
32
|
+
;;
|
|
33
|
+
--files)
|
|
34
|
+
files_only=1
|
|
35
|
+
shift
|
|
36
|
+
;;
|
|
37
|
+
--json)
|
|
38
|
+
json=1
|
|
39
|
+
shift
|
|
40
|
+
;;
|
|
41
|
+
-h|--help)
|
|
42
|
+
usage
|
|
43
|
+
exit 0
|
|
44
|
+
;;
|
|
45
|
+
*)
|
|
46
|
+
mode="base"
|
|
47
|
+
base_ref="$1"
|
|
48
|
+
shift
|
|
49
|
+
;;
|
|
50
|
+
esac
|
|
51
|
+
done
|
|
52
|
+
|
|
53
|
+
frontend_globs=(-- '*.vue' '*.ts' '*.tsx' '*.jsx' '*.js' '*.css' '*.scss')
|
|
54
|
+
code_globs=(-- '*.vue' '*.ts' '*.tsx' '*.jsx' '*.js')
|
|
55
|
+
|
|
56
|
+
git_diff() {
|
|
57
|
+
if [[ "$mode" == "cached" ]]; then
|
|
58
|
+
git diff --cached "$@"
|
|
59
|
+
else
|
|
60
|
+
git diff "$base_ref" "$@"
|
|
61
|
+
fi
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
diff_label() {
|
|
65
|
+
if [[ "$mode" == "cached" ]]; then
|
|
66
|
+
echo "--cached"
|
|
67
|
+
else
|
|
68
|
+
echo "$base_ref"
|
|
69
|
+
fi
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
json_array() {
|
|
73
|
+
python3 -c 'import json,sys; print(json.dumps(sys.stdin.read().splitlines()))'
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
json_string() {
|
|
77
|
+
python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))'
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
changed_files() {
|
|
81
|
+
git_diff --name-only --diff-filter=ACMRTUXB "${frontend_globs[@]}" || true
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
scan() {
|
|
85
|
+
local title="$1"
|
|
86
|
+
local pattern="$2"
|
|
87
|
+
shift 2
|
|
88
|
+
echo
|
|
89
|
+
echo "== $title =="
|
|
90
|
+
git_diff -U0 "$@" | rg "$pattern" || true
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if [[ "$files_only" -eq 1 && "$json" -eq 0 ]]; then
|
|
94
|
+
changed_files
|
|
95
|
+
exit 0
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
if [[ "$json" -eq 1 ]]; then
|
|
99
|
+
files="$(changed_files)"
|
|
100
|
+
suspicious="$(git_diff -U0 "${code_globs[@]}" | rg '^\+[^+].*(eslint-disable|@ts-ignore|@ts-expect-error|console\.log|debugger|TODO|FIXME)' || true)"
|
|
101
|
+
ts_risks="$(git_diff -U0 "${code_globs[@]}" | rg '^\+[^+].*(:\s*any\b|as\s+any\b|as\s+unknown\s+as|!\.|\w!\b)' || true)"
|
|
102
|
+
vue_risks="$(git_diff -U0 -- '*.vue' | rg '^\+[^+].*(v-model:|watch\s*\([^\n]*deep\s*:\s*true|defineProps\([^\n]*\)\.[A-Za-z_$][\w$]*\s*=)' || true)"
|
|
103
|
+
react_next_risks="$(git_diff -U0 "${code_globs[@]}" | rg '^\+[^+].*(use client|dangerouslySetInnerHTML|window\.|document\.|localStorage\.|sessionStorage\.)' || true)"
|
|
104
|
+
copy_changes="$(git_diff -U0 "${code_globs[@]}" | rg '^[+-][^+-].*(label|title|placeholder|help|message|Radio|Checkbox|Button|Tooltip|content|confirmText|cancelText|text-|aria-label|alt=|请选择|请输入|验证|账户|服务商|域名|说明|提示)' || true)"
|
|
105
|
+
|
|
106
|
+
printf '{\n'
|
|
107
|
+
printf ' "mode": %s,\n' "$(printf '%s' "$(diff_label)" | json_string)"
|
|
108
|
+
printf ' "changed_files": %s,\n' "$(printf '%s' "$files" | json_array)"
|
|
109
|
+
printf ' "suspicious_patterns": %s,\n' "$(printf '%s' "$suspicious" | json_array)"
|
|
110
|
+
printf ' "typescript_risks": %s,\n' "$(printf '%s' "$ts_risks" | json_array)"
|
|
111
|
+
printf ' "vue_risks": %s,\n' "$(printf '%s' "$vue_risks" | json_array)"
|
|
112
|
+
printf ' "react_next_risks": %s,\n' "$(printf '%s' "$react_next_risks" | json_array)"
|
|
113
|
+
printf ' "potential_copy_changes": %s\n' "$(printf '%s' "$copy_changes" | json_array)"
|
|
114
|
+
printf '}\n'
|
|
115
|
+
exit 0
|
|
116
|
+
fi
|
|
117
|
+
|
|
118
|
+
label="$(diff_label)"
|
|
119
|
+
|
|
120
|
+
echo "== Diff scan mode =="
|
|
121
|
+
echo "$label"
|
|
122
|
+
|
|
123
|
+
echo
|
|
124
|
+
echo "== Changed frontend files =="
|
|
125
|
+
changed_files
|
|
126
|
+
|
|
127
|
+
scan "Added-line suspicious patterns" '^\+[^+].*(eslint-disable|@ts-ignore|@ts-expect-error|console\.log|debugger|TODO|FIXME)' "${code_globs[@]}"
|
|
128
|
+
|
|
129
|
+
scan "TypeScript risk patterns on added lines" '^\+[^+].*(:\s*any\b|as\s+any\b|as\s+unknown\s+as|!\.|\w!\b)' "${code_globs[@]}"
|
|
130
|
+
|
|
131
|
+
scan "Vue risk patterns on added lines" '^\+[^+].*(v-model:|watch\s*\([^\n]*deep\s*:\s*true|defineProps\([^\n]*\)\.[A-Za-z_$][\w$]*\s*=)' -- '*.vue'
|
|
132
|
+
|
|
133
|
+
scan "React/Next/browser-boundary risk patterns on added lines" '^\+[^+].*(use client|dangerouslySetInnerHTML|window\.|document\.|localStorage\.|sessionStorage\.)' "${code_globs[@]}"
|
|
134
|
+
|
|
135
|
+
scan "Potential copy/accessibility text changes" '^[+-][^+-].*(label|title|placeholder|help|message|Radio|Checkbox|Button|Tooltip|content|confirmText|cancelText|text-|aria-label|alt=|请选择|请输入|验证|账户|服务商|域名|说明|提示)' "${code_globs[@]}"
|
|
136
|
+
|
|
137
|
+
echo
|
|
138
|
+
echo "== Formatting check hint =="
|
|
139
|
+
echo "For each modified existing file, compare:"
|
|
140
|
+
echo " git diff $label -- path/to/file"
|
|
141
|
+
if [[ "$mode" == "cached" ]]; then
|
|
142
|
+
echo " git diff --cached -w -- path/to/file"
|
|
143
|
+
else
|
|
144
|
+
echo " git diff -w $base_ref -- path/to/file"
|
|
145
|
+
fi
|