scip-query 0.10.2 → 0.10.4
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 +9 -8
- package/dist/{chunk-FGCL6NDB.js → chunk-237YUOPK.js} +2 -2
- package/dist/chunk-56UN3DMK.js +2 -0
- package/dist/chunk-5UDFZC4D.js +2 -0
- package/dist/{chunk-MHK7Z53U.js → chunk-6UFMPECA.js} +2 -2
- package/dist/chunk-7JOTOWZO.js +4 -0
- package/dist/chunk-A7RNHUJH.js +20 -0
- package/dist/chunk-AYYIZ4BA.js +4 -0
- package/dist/chunk-BNKE4TT5.js +2 -0
- package/dist/{chunk-CNTEQMHA.js → chunk-EYLXU575.js} +2 -2
- package/dist/chunk-KRGBLZT2.js +7 -0
- package/dist/chunk-MA7OVFHI.js +2 -0
- package/dist/chunk-QUJBXLBY.js +2 -0
- package/dist/chunk-UQJGTVHV.js +5 -0
- package/dist/chunk-WBJZNPUT.js +2 -0
- package/dist/{chunk-UNJG7P2I.js → chunk-YUTRW57I.js} +2 -2
- package/dist/cli.js +209 -197
- package/dist/frontend-behavior-evidence-BxKpKWUu.d.ts +4 -0
- package/dist/postinstall.js +3 -3
- package/dist/queries/co-change.js +1 -1
- package/dist/queries/diff-gate.d.ts +10 -3
- package/dist/queries/diff-gate.js +1 -1
- package/dist/queries/diff-impact.js +1 -1
- package/dist/queries/doc-drift.js +1 -1
- package/dist/queries/health.js +1 -1
- package/dist/queries/incomplete-migration.js +1 -1
- package/dist/queries/index.d.ts +1 -0
- package/dist/queries/index.js +1 -1
- package/dist/queries/plan-context.js +1 -1
- package/dist/queries/react-component-duplicates.js +1 -1
- package/dist/queries/react-hook-candidates.d.ts +3 -2
- package/dist/queries/react-hook-candidates.js +1 -1
- package/dist/queries/recent-duplicates.js +1 -1
- package/dist/queries/similar.d.ts +9 -1
- package/dist/queries/similar.js +1 -1
- package/dist/queries/vue-component-duplicates.js +1 -1
- package/dist/queries/vue-composable-candidates.d.ts +3 -2
- package/dist/queries/vue-composable-candidates.js +1 -1
- package/dist/runtime.js +1 -1
- package/docs/AGENT_GUIDE.md +42 -5
- package/docs/AI_FAILURE_MODES.md +28 -21
- package/docs/COMMAND_REFERENCE.md +4 -2
- package/docs/analyzer-inventory.md +5 -1
- package/docs/analyzer-validation-ledger.md +8 -0
- package/package.json +3 -2
- package/skills/concrete-plan/SKILL.md +3 -5
- package/skills/concrete-plan/agents/openai.yaml +4 -0
- package/skills/scip-adoption/SKILL.md +120 -0
- package/skills/scip-adoption/agents/openai.yaml +4 -0
- package/skills/scip-ai-cleanup/SKILL.md +12 -4
- package/skills/scip-ai-cleanup/agents/openai.yaml +4 -0
- package/skills/scip-api-impact/SKILL.md +147 -0
- package/skills/scip-api-impact/agents/openai.yaml +4 -0
- package/skills/scip-debloat/SKILL.md +15 -13
- package/skills/scip-debloat/agents/openai.yaml +4 -0
- package/skills/scip-debug/SKILL.md +119 -0
- package/skills/scip-debug/agents/openai.yaml +4 -0
- package/skills/scip-diagram/SKILL.md +138 -0
- package/skills/scip-diagram/agents/openai.yaml +4 -0
- package/skills/scip-directory-architecture/SKILL.md +2 -2
- package/skills/scip-directory-architecture/agents/openai.yaml +4 -0
- package/skills/scip-doc-reconcile/SKILL.md +1 -3
- package/skills/scip-doc-reconcile/agents/openai.yaml +4 -0
- package/skills/scip-explore/SKILL.md +8 -2
- package/skills/scip-explore/agents/openai.yaml +4 -0
- package/skills/scip-health-audit/SKILL.md +158 -0
- package/skills/scip-health-audit/agents/openai.yaml +4 -0
- package/skills/scip-health-improve/SKILL.md +151 -0
- package/skills/scip-health-improve/agents/openai.yaml +4 -0
- package/skills/scip-language-playbook/SKILL.md +7 -4
- package/skills/scip-language-playbook/agents/openai.yaml +4 -0
- package/skills/scip-maintainability/SKILL.md +7 -3
- package/skills/scip-maintainability/agents/openai.yaml +4 -0
- package/skills/scip-query/SKILL.md +74 -33
- package/skills/scip-query/agents/openai.yaml +4 -0
- package/skills/scip-query-setup/SKILL.md +65 -18
- package/skills/scip-query-setup/agents/openai.yaml +3 -0
- package/skills/scip-react-maintainability/SKILL.md +2 -2
- package/skills/scip-react-maintainability/agents/openai.yaml +4 -0
- package/skills/scip-triage-issue/SKILL.md +112 -0
- package/skills/scip-triage-issue/agents/openai.yaml +4 -0
- package/skills/scip-verify/SKILL.md +83 -232
- package/skills/scip-verify/agents/openai.yaml +4 -0
- package/skills/scip-vue-maintainability/SKILL.md +2 -3
- package/skills/scip-vue-maintainability/agents/openai.yaml +4 -0
- package/dist/chunk-5B53WB6E.js +0 -4
- package/dist/chunk-DRAZH77R.js +0 -7
- package/dist/chunk-FPMVCDIJ.js +0 -2
- package/dist/chunk-GS33KGAY.js +0 -2
- package/dist/chunk-MHTDOFV7.js +0 -5
- package/dist/chunk-NP5HYVLX.js +0 -20
- package/dist/chunk-O4L4AB3T.js +0 -2
- package/dist/chunk-TO54DY4O.js +0 -2
- package/dist/chunk-UMNENNTX.js +0 -2
- package/dist/chunk-WDUTG2ZR.js +0 -4
|
@@ -1,307 +1,158 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: scip-verify
|
|
3
|
-
description: Post-implementation verification using scip-query
|
|
4
|
-
allowed-tools: [Bash, Write, Edit, Glob, Agent, TaskCreate, TaskUpdate, TaskGet, TaskList]
|
|
5
|
-
keywords: [verify, check, validate, wire, confirm, post-implementation, review, regression, health]
|
|
3
|
+
description: Post-implementation verification using scip-query's modern gate model. Use after making code, docs, config, refactor, cleanup, or setup changes; before committing; when the user asks whether a change is wired correctly, safe, verified, regression-free, or ready to ship.
|
|
6
4
|
---
|
|
7
5
|
|
|
8
6
|
# Post-Implementation Verification with scip-query
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
## When to Use This Skill
|
|
15
|
-
|
|
16
|
-
- "Verify my changes"
|
|
17
|
-
- "Check if everything is wired correctly"
|
|
18
|
-
- "Did I break anything?"
|
|
19
|
-
- "Is it safe to commit?"
|
|
20
|
-
- "Run a post-implementation check"
|
|
21
|
-
- After completing a `/concrete-plan` implementation
|
|
22
|
-
- Before any commit of non-trivial changes
|
|
23
|
-
|
|
24
|
-
---
|
|
8
|
+
Verify the actual diff, not your intention. A verification pass proves that the current workspace has a runnable scip-query environment, a current index, expected blast radius, no diff-gate findings, and no relevant health or config regression.
|
|
25
9
|
|
|
26
10
|
## Hard Rules
|
|
27
11
|
|
|
28
|
-
1.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
4. **Compare against baseline.** If a health score or finding count was recorded before the change, compare against it. A regression is a finding.
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
## Symbol Lookup Tips
|
|
39
|
-
|
|
40
|
-
`scip-query` accepts partial symbol names — you don't need the full SCIP symbol path. These all work:
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
scip-query code processVegaMention # just the function name
|
|
44
|
-
scip-query call-graph ChatService # just the class name
|
|
45
|
-
scip-query trace getActiveInferenceConfig # any unique substring
|
|
46
|
-
```
|
|
12
|
+
1. Run environment checks before trusting graph facts.
|
|
13
|
+
2. Reindex before final verification unless a just-finished command already did so and no files changed afterward.
|
|
14
|
+
3. Treat `scip-query diff-gate --json` as the primary blocker for diff-specific risk. Manual checks are drill-down evidence, not a replacement.
|
|
15
|
+
4. Run the postchecks that match the actual change type.
|
|
16
|
+
5. Prefer fixing findings. Use `scip-query suppress <id> --reason "<specific reason>"` only for intentional design, compatibility shims, framework entry points, or accepted false positives with durable evidence.
|
|
17
|
+
6. If `.scipquery.json` or suppressions changed, run `scip-query config-validate`.
|
|
47
18
|
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
# BAD — shell tries to execute a subshell
|
|
51
|
-
scip-query code processVegaMention()
|
|
19
|
+
## Default Verification Flow
|
|
52
20
|
|
|
53
|
-
|
|
54
|
-
scip-query code processVegaMention
|
|
21
|
+
### 1. Prove the workspace can answer
|
|
55
22
|
|
|
56
|
-
# ALSO GOOD — single quotes protect special characters
|
|
57
|
-
scip-query code 'processVegaMention'
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
**Read source by file + line range** when the symbol name is ambiguous:
|
|
61
23
|
```bash
|
|
62
|
-
scip-query
|
|
24
|
+
scip-query doctor
|
|
25
|
+
scip-query status --capabilities
|
|
63
26
|
```
|
|
64
27
|
|
|
65
|
-
|
|
66
|
-
1. Try a shorter/simpler name — `login` instead of `AuthService:login`
|
|
67
|
-
2. Try `scip-query outline <file>` to see what symbols exist in the file
|
|
68
|
-
3. Try `scip-query trace <name>` which uses a different lookup path
|
|
69
|
-
4. Use the `file:line-line` syntax for `code` if you know the location
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## The 7 Verification Checks
|
|
74
|
-
|
|
75
|
-
Run every one of these. Each catches a different class of implementation error.
|
|
28
|
+
If either command reports missing indexers, stale indexes, invalid config, or unavailable capabilities relevant to the change, resolve that first or report it as a blocker. Unavailable is not clean; it means that signal class was not proven.
|
|
76
29
|
|
|
77
|
-
###
|
|
30
|
+
### 2. Refresh and assess the diff
|
|
78
31
|
|
|
79
32
|
```bash
|
|
80
33
|
scip-query reindex
|
|
81
|
-
scip-query diff-impact
|
|
34
|
+
scip-query diff-impact --json
|
|
82
35
|
```
|
|
83
36
|
|
|
84
|
-
|
|
37
|
+
Use `diff-impact` to check whether the changed files, changed symbols, and downstream consumers match the work you intended to do. Unexpected symbols or a much wider blast radius are findings even if `diff-gate` later passes.
|
|
85
38
|
|
|
86
|
-
|
|
87
|
-
- Every changed symbol is intentional (no accidental modifications)
|
|
88
|
-
- The number of affected consumer files matches expectations
|
|
39
|
+
### 3. Run routed postchecks
|
|
89
40
|
|
|
90
|
-
|
|
41
|
+
Run every row that applies to the work just performed.
|
|
91
42
|
|
|
92
|
-
|
|
43
|
+
| Change type | Required checks |
|
|
44
|
+
|---|---|
|
|
45
|
+
| Extracted a helper or created an abstraction | `scip-query incomplete-migration --json --full` |
|
|
46
|
+
| Added a new helper, module, component, or adapter | `scip-query similar <symbol> --json --full` and `scip-query recent-duplicates --json --full` |
|
|
47
|
+
| Added parameters, options, or config flags | `scip-query unused-params --json --full` |
|
|
48
|
+
| Added a forwarding or wrapper layer | `scip-query wrapper-candidates --json --full` and `scip-query passthrough-candidates --json --full` |
|
|
49
|
+
| Added an interface, base class, adapter contract, or type alias | `scip-query stale-abstractions --json --full` |
|
|
50
|
+
| Changed schema, config, generated artifacts, or public contracts | `scip-query co-change <file> --json --full` |
|
|
51
|
+
| Changed code described by docs or changed docs that cite code | `scip-query doc-drift --json --full` |
|
|
52
|
+
| Deleted code | `scip-query cleanup-plan --verify --json` |
|
|
53
|
+
| Changed React components or hooks | `scip-query react-component-duplicates --json --full`, `scip-query react-hook-candidates --json --full`, and `scip-query react-large-component-pressure --json --full` |
|
|
54
|
+
| Changed Vue SFCs or composables | `scip-query vue-component-duplicates --json --full`, `scip-query vue-composable-candidates --json --full`, and `scip-query vue-large-view-pressure --json --full` |
|
|
55
|
+
|
|
56
|
+
Use focused probes when a finding needs explanation:
|
|
93
57
|
|
|
94
58
|
```bash
|
|
95
|
-
scip-query
|
|
59
|
+
scip-query code <symbol-or-file>
|
|
60
|
+
scip-query refs <symbol>
|
|
61
|
+
scip-query fan-in <symbol>
|
|
62
|
+
scip-query fan-out <symbol>
|
|
63
|
+
scip-query affected <symbol> --json
|
|
64
|
+
scip-query change-surface <file> --json --full
|
|
96
65
|
```
|
|
97
66
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
**Pass criteria:** Zero cycles, OR the same cycles that existed before the change.
|
|
101
|
-
|
|
102
|
-
**Fail if:** New cycle(s) appear. Report the full cycle path.
|
|
103
|
-
|
|
104
|
-
### Check 3: No New Dead Code
|
|
67
|
+
### 4. Run the gate
|
|
105
68
|
|
|
106
69
|
```bash
|
|
107
|
-
scip-query
|
|
70
|
+
scip-query diff-gate --json
|
|
108
71
|
```
|
|
109
72
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
**Pass criteria:** No new dead symbols compared to before the change. Existing dead code doesn't count.
|
|
113
|
-
|
|
114
|
-
**Fail if:** A symbol that was alive before the change is now dead. This means something was disconnected.
|
|
115
|
-
|
|
116
|
-
### Check 4: No New Isolated Symbols
|
|
73
|
+
On any finding, fix it or explicitly accept it with evidence. Do not ignore a nonzero gate. If a suppression is the right outcome, record the reason and validate config:
|
|
117
74
|
|
|
118
75
|
```bash
|
|
119
|
-
scip-query
|
|
76
|
+
scip-query suppress <id> --reason "<specific reason>"
|
|
77
|
+
scip-query config-validate
|
|
120
78
|
```
|
|
121
79
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
**Pass criteria:** No new isolated symbols.
|
|
125
|
-
|
|
126
|
-
**Fail if:** New isolated symbol(s) appear — something got orphaned.
|
|
80
|
+
### 5. Check baseline health when present
|
|
127
81
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
For each symbol that was modified (from diff-impact), verify it's still referenced by the expected consumers:
|
|
82
|
+
Run this when the repository has a committed scip-query baseline:
|
|
131
83
|
|
|
132
84
|
```bash
|
|
133
|
-
scip-query
|
|
134
|
-
scip-query fan-in <changed-symbol>
|
|
85
|
+
scip-query health --baseline
|
|
135
86
|
```
|
|
136
87
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
**Pass criteria:** Fan-in count for each changed symbol is the same or higher than before.
|
|
140
|
-
|
|
141
|
-
**Fail if:** A changed symbol's fan-in dropped — a consumer was disconnected.
|
|
142
|
-
|
|
143
|
-
### Check 6: Change Surface Risk Check
|
|
144
|
-
|
|
145
|
-
For each modified file:
|
|
88
|
+
If no baseline exists and the user asked for broad health verification, run:
|
|
146
89
|
|
|
147
90
|
```bash
|
|
148
|
-
scip-query
|
|
91
|
+
scip-query health --json --full
|
|
149
92
|
```
|
|
150
93
|
|
|
151
|
-
|
|
94
|
+
Health score changes are diagnostic, not the objective. A score drop matters when it corresponds to a real new signal; a score increase does not excuse unverified behavior.
|
|
152
95
|
|
|
153
|
-
|
|
96
|
+
### 6. Validate config and docs when touched
|
|
154
97
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
### Check 7: Health Score
|
|
98
|
+
If `.scipquery.json`, AGENTS.md, CLAUDE.md, command docs, or skill instructions changed, run the relevant check:
|
|
158
99
|
|
|
159
100
|
```bash
|
|
160
|
-
scip-query
|
|
101
|
+
scip-query config-validate
|
|
102
|
+
scip-query doc-drift --json --full
|
|
161
103
|
```
|
|
162
104
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
**Pass criteria:** Health score is the same or higher than before the change. If it dropped, every finding that increased must be explained.
|
|
166
|
-
|
|
167
|
-
**Fail if:** Health score dropped by more than 5 points without explanation.
|
|
168
|
-
|
|
169
|
-
---
|
|
170
|
-
|
|
171
|
-
## Verification Workflow
|
|
105
|
+
For generated command docs, also run the repo's descriptor or docs test if one exists.
|
|
172
106
|
|
|
173
|
-
|
|
107
|
+
If you are maintaining scip-query analyzers or command descriptors inside the scip-query repository itself, add:
|
|
174
108
|
|
|
175
109
|
```bash
|
|
176
|
-
scip-query
|
|
177
|
-
scip-query diff-impact
|
|
110
|
+
scip-query self-audit
|
|
178
111
|
```
|
|
179
112
|
|
|
180
|
-
|
|
113
|
+
This is a maintainer check for analyzer consistency, not a general app-developer verification step.
|
|
181
114
|
|
|
182
|
-
|
|
115
|
+
## Manual Drill-Down Checks
|
|
183
116
|
|
|
184
|
-
|
|
117
|
+
Use these when `diff-impact`, routed postchecks, or `diff-gate` point to a structural risk:
|
|
185
118
|
|
|
186
119
|
```bash
|
|
187
120
|
scip-query cycles
|
|
188
|
-
scip-query dead --
|
|
189
|
-
scip-query isolated --
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
### Phase 3: Per-Symbol Checks
|
|
193
|
-
|
|
194
|
-
For each changed symbol from diff-impact:
|
|
195
|
-
|
|
196
|
-
```bash
|
|
197
|
-
scip-query refs <symbol>
|
|
198
|
-
scip-query fan-in <symbol>
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
### Phase 4: Per-File Checks
|
|
202
|
-
|
|
203
|
-
For each modified file:
|
|
204
|
-
|
|
205
|
-
```bash
|
|
206
|
-
scip-query change-surface <file>
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
### Phase 5: Health Comparison
|
|
210
|
-
|
|
211
|
-
```bash
|
|
212
|
-
scip-query health
|
|
121
|
+
scip-query dead --json --full
|
|
122
|
+
scip-query isolated --json --full
|
|
123
|
+
scip-query coupling
|
|
124
|
+
scip-query bottlenecks
|
|
213
125
|
```
|
|
214
126
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
---
|
|
127
|
+
These commands are not a substitute for `diff-gate`; they explain or bound the finding.
|
|
218
128
|
|
|
219
|
-
##
|
|
129
|
+
## Verification Report
|
|
220
130
|
|
|
221
|
-
|
|
131
|
+
End with a compact report:
|
|
222
132
|
|
|
223
133
|
```markdown
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
**Date:** YYYY-MM-DD
|
|
227
|
-
**Change:** [description]
|
|
228
|
-
**Pre-change health:** N/100
|
|
229
|
-
**Post-change health:** N/100
|
|
230
|
-
|
|
231
|
-
## Diff Impact
|
|
232
|
-
- Changed files: N
|
|
233
|
-
- Changed symbols: N
|
|
234
|
-
- Affected consumer files: N
|
|
235
|
-
- High-risk symbols touched: N
|
|
236
|
-
|
|
237
|
-
## Check Results
|
|
238
|
-
|
|
239
|
-
| # | Check | Result | Evidence |
|
|
240
|
-
|---|---|---|---|
|
|
241
|
-
| 1 | Diff impact | PASS/FAIL | [summary] |
|
|
242
|
-
| 2 | No new cycles | PASS/FAIL | [count] |
|
|
243
|
-
| 3 | No new dead code | PASS/FAIL | [count] |
|
|
244
|
-
| 4 | No new isolated | PASS/FAIL | [count] |
|
|
245
|
-
| 5 | References intact | PASS/FAIL | [fan-in changes] |
|
|
246
|
-
| 6 | Risk assessment | PASS/FAIL | [high-risk symbols] |
|
|
247
|
-
| 7 | Health score | PASS/FAIL | [score delta] |
|
|
248
|
-
|
|
249
|
-
## Failures
|
|
250
|
-
[Detailed explanation of any failures with scip-query output]
|
|
251
|
-
|
|
252
|
-
## Verdict
|
|
253
|
-
PASS — safe to commit
|
|
254
|
-
FAIL — [list what needs fixing before commit]
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
---
|
|
258
|
-
|
|
259
|
-
## Using with /concrete-plan
|
|
260
|
-
|
|
261
|
-
The ideal workflow:
|
|
134
|
+
Verification: PASS/FAIL
|
|
262
135
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
136
|
+
Environment:
|
|
137
|
+
- doctor: PASS/FAIL
|
|
138
|
+
- status capabilities: PASS/FAIL or unavailable checks
|
|
266
139
|
|
|
267
|
-
|
|
140
|
+
Diff:
|
|
141
|
+
- changed files/symbols from `scip-query diff-impact --json`
|
|
142
|
+
- unexpected blast radius, if any
|
|
268
143
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
## Subagent Briefing Template
|
|
272
|
-
|
|
273
|
-
When parallelizing verification checks:
|
|
274
|
-
|
|
275
|
-
```
|
|
276
|
-
## Task: Run verification check [N]
|
|
144
|
+
Postchecks:
|
|
145
|
+
- <command>: PASS/FAIL and finding count
|
|
277
146
|
|
|
278
|
-
|
|
147
|
+
Gate:
|
|
148
|
+
- `scip-query diff-gate --json`: PASS/FAIL
|
|
279
149
|
|
|
280
|
-
|
|
281
|
-
|
|
150
|
+
Health/config:
|
|
151
|
+
- baseline or health result
|
|
152
|
+
- config validation result when applicable
|
|
282
153
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
2. Whether it PASSES or FAILS the criteria: [specific criteria]
|
|
286
|
-
3. If FAIL: exactly what went wrong and which symbols/files are affected
|
|
287
|
-
|
|
288
|
-
Do NOT use grep, rg, or Read. Use only scip-query commands.
|
|
154
|
+
Remaining risk:
|
|
155
|
+
- accepted suppressions, blocked capabilities, or checks not run
|
|
289
156
|
```
|
|
290
157
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
## scip-query Quick Reference
|
|
294
|
-
|
|
295
|
-
| Check | Command |
|
|
296
|
-
|---|---|
|
|
297
|
-
| Reindex | `scip-query reindex` |
|
|
298
|
-
| Diff impact | `scip-query diff-impact` |
|
|
299
|
-
| Cycles | `scip-query cycles` |
|
|
300
|
-
| Dead code | `scip-query dead --min-loc 5` |
|
|
301
|
-
| Isolated | `scip-query isolated --min-loc 3` |
|
|
302
|
-
| References | `scip-query refs <symbol>` |
|
|
303
|
-
| Fan-in | `scip-query fan-in <symbol>` |
|
|
304
|
-
| Change surface | `scip-query change-surface <file>` |
|
|
305
|
-
| Health | `scip-query health` |
|
|
306
|
-
| Full blast radius | `scip-query affected <symbol>` |
|
|
307
|
-
| Read source | `scip-query code <symbol>` |
|
|
158
|
+
Do not claim "safe to commit" unless `scip-query reindex` and `scip-query diff-gate --json` passed after the final file edit.
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: scip-vue-maintainability
|
|
3
3
|
description: Vue frontend maintainability review using scip-query's Vue SFC, template-duplicate, composable-candidate, large-view, and health commands. Use when reviewing Vue or Nuxt codebases, investigating duplicated components or composables, checking frontend health score pressure, or asking whether agents are reusing Vue code correctly.
|
|
4
|
-
allowed-tools: [Bash, Read, Grep, Glob]
|
|
5
4
|
---
|
|
6
5
|
|
|
7
6
|
# SCIP Vue Maintainability Review
|
|
@@ -80,7 +79,7 @@ After implementing a component reuse, composable extraction, or large-view split
|
|
|
80
79
|
Run the checks that match what changed:
|
|
81
80
|
|
|
82
81
|
```bash
|
|
83
|
-
scip-query diff-impact
|
|
82
|
+
scip-query diff-impact --json
|
|
84
83
|
scip-query vue-component-duplicates --scope <vue-source-scope> --full --json
|
|
85
84
|
scip-query vue-composable-candidates --scope <vue-source-scope> --full --json
|
|
86
85
|
scip-query vue-large-view-pressure --scope <vue-source-scope> --full --json
|
|
@@ -90,7 +89,7 @@ scip-query unused-params
|
|
|
90
89
|
scip-query wrapper-candidates --scope <vue-source-scope> --full --json
|
|
91
90
|
scip-query passthrough-candidates --scope <vue-source-scope> --full --json
|
|
92
91
|
scip-query stale-abstractions --scope <vue-source-scope> --include-low-confidence --full --json
|
|
93
|
-
scip-query reindex && scip-query diff-gate
|
|
92
|
+
scip-query reindex && scip-query diff-gate --json
|
|
94
93
|
```
|
|
95
94
|
|
|
96
95
|
Use the results this way:
|
package/dist/chunk-5B53WB6E.js
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{a as ee}from"./chunk-NNDYO2DX.js";import{a as X}from"./chunk-FGCL6NDB.js";import{a as y}from"./chunk-B32FX5KB.js";import{a as Q}from"./chunk-SPE4YCOT.js";import{a as J}from"./chunk-ZFMPHDAT.js";import{a as Z}from"./chunk-C2QSK7E7.js";import{a as W,b as Y}from"./chunk-MHTDOFV7.js";import{a as U}from"./chunk-G3WGZU5Q.js";import{a as V}from"./chunk-DE7MA6OD.js";import{a as q}from"./chunk-7KCSELEV.js";import{b as I,c as P,f as H}from"./chunk-NP5HYVLX.js";import{a as _,d as z}from"./chunk-WDUTG2ZR.js";import{a as O}from"./chunk-AW4N6MGC.js";import{b as E}from"./chunk-C3MZZ2ZN.js";import{a as F,c as N,d as K,e as B}from"./chunk-CNTEQMHA.js";import{f as L}from"./chunk-DRAZH77R.js";import{a as M}from"./chunk-CJJP64OC.js";import{a as j}from"./chunk-3ZYF3ELZ.js";import{f as w,g as D}from"./chunk-ZQLO2SCU.js";import{d as $,e as G}from"./chunk-JM72FNGA.js";import{createHash as ye}from"crypto";import{existsSync as x,readFileSync as oe}from"fs";import{existsSync as se,readFileSync as ae,writeFileSync as ce}from"fs";import{isAbsolute as le,join as fe}from"path";var de=75e3,ue=5e3,he=2500;function ge(e){let i=Z(e);return i.symbols>=de||i.documents>=ue?he:void 0}var me=".scipquery-baseline.json";function k(e,i){return i&&le(i)?i:fe(e.config.projectRoot,i??me)}function ne(e,i={}){let{scope:n}=i,r=ge(e),o=[],s=E(e,{scope:n,...y.dead,scanLimit:r});for(let t of s.symbols)w(e,t.relativePath)||D(e,t.symbol,t.relativePath)||t.kind==="dead-code"&&o.push(`dead:${t.relativePath}:${t.shortName}`);for(let t of U(e,{scope:n,...y.isolated,scanLimit:r}))w(e,t.relativePath)||D(e,t.symbol,t.relativePath)||o.push(`isolated:${t.relativePath}:${t.shortName}`);for(let t of M(e,{scope:n}))t.kind==="real"&&o.push(`cycle:${pe(t.path)}`);for(let t of Y(e,{scope:n,...y.similar,scanLimit:r}))o.push(`similar:${[t.symbolA,t.symbolB].sort().join("|")}`);for(let t of q(e,{scope:n,...y.extract,scanLimit:r}))o.push(`extract:${t.relativePath}:${t.shortName}`);for(let t of Q(e,{scope:n,...y.wrappers,scanLimit:r}))o.push(`wrapper:${t.file}:${t.shortName}`);for(let t of V(e,{scope:n,...y.passthroughs,scanLimit:r}))o.push(`passthrough:${t.file}:${t.shortName}`);for(let t of J(e,{scope:n,...y.stale,scanLimit:r}))o.push(`stale:${t.file}:${t.shortName}`);for(let t of O(e,{scope:n,...y.drift}).results)t.kind!=="pattern-deviation"&&o.push(`drift:${t.kind}:${t.file}:${t.dep}`);return[...new Set(o)].sort()}function pe(e){if(e.length===0)return"";let i=0;for(let n=1;n<e.length;n++)e[n]<e[i]&&(i=n);return[...e.slice(i),...e.slice(0,i)].join(">")}function $n(e,i={}){let n=ne(e,{scope:i.scope}),r=k(e,i.path);return ce(r,JSON.stringify({version:1,findings:n},null,2)+`
|
|
2
|
-
`),{path:r,findingCount:n.length}}function ie(e,i={}){let n=k(e,i.path);if(!se(n))throw new Error(`No baseline found at ${n}. Create one with: scip-query health --write-baseline`);let r=JSON.parse(ae(n,"utf-8")),o=new Set(r.findings??[]),s=ne(e,{scope:i.scope}),t=new Set(s);return{baselinePath:n,baselineCount:o.size,current:s,newFindings:s.filter(c=>!o.has(c)),fixedFindings:[...o].filter(c=>!t.has(c))}}var Bn=["echo","incomplete-migration","co-change-partner","doc-reference","unused-params","new-dead","baseline"];function Mn(e,i={}){let n=i.base??"HEAD",{minTogether:r=6,minConfidence:o=.6,maxEchoChecks:s=Number.POSITIVE_INFINITY,maxHelpers:t=Number.POSITIVE_INFINITY,minSimilarity:c=.8}=i,a=new Set(i.skip??[]),f=P(e,{base:n}),g=I(e,{base:n,plan:f}),u=g.changedFiles,d=new Set(u),l=new Set(f.changedFileLines),p=Xe(e.config.projectRoot,n,f),h={base:n,changedFiles:u,changedSymbols:g.changedSymbols.length,checksRun:[],skipped:[],suppressed:[],findings:[],rootCauseGroups:[],note:g.summary.note};if(u.length===0)return h;let m=(b,S)=>{if(a.has(b)){h.skipped.push({check:b,reason:"skipped via --skip"});return}S()};return m("echo",()=>De(e,g.changedSymbols,d,p,s,c,h)),m("incomplete-migration",()=>je(e,n,f,t,h)),m("co-change-partner",()=>Ee(e,d,r,o,h)),m("doc-reference",()=>Me(e,d,l,f.changedRanges,h)),m("unused-params",()=>Je(e,u,h)),m("new-dead",()=>Ze(e,g.changedSymbols,p,h)),m("baseline",()=>tn(e,h)),$e(h,e.config.suppressions??[]),h.rootCauseGroups=be(h.findings),h}function be(e){let i=new Map;for(let n of e){let r=n.groupKey??`${n.check}:${n.id}`,o=i.get(r);o||(o={groupKey:r,check:n.check,severity:n.severity,actionTier:n.actionTier,sourceAnalyzer:n.sourceAnalyzer,rootCauseKey:n.rootCauseKey,count:0,findingIds:[],files:new Set,relatedFiles:new Set,message:n.message,remediation:n.remediation},i.set(r,o)),o.count+=1,o.findingIds.push(n.id),o.severity=Ce(o.severity,n.severity),o.actionTier=Se(o.actionTier,n.actionTier),n.file&&o.files.add(n.file);for(let s of n.relatedFiles??[])o.relatedFiles.add(s)}return[...i.values()].map(n=>({...n,files:[...n.files].sort(),relatedFiles:[...n.relatedFiles].sort()})).sort((n,r)=>r.count-n.count||T(r.severity)-T(n.severity)||n.groupKey.localeCompare(r.groupKey))}function Ce(e,i){return T(i)>T(e)?i:e}function T(e){return e==="error"?2:e==="warning"?1:0}function Se(e,i){return e?i&&te(i)>te(e)?i:e:i}function te(e){return e==="direct"?2:e==="signal"?1:0}function $e(e,i){if(i.length===0||e.findings.length===0)return;let n=[];for(let r of e.findings){let o=i.find(s=>we(s,r));o?e.suppressed.push({finding:r,suppression:o}):n.push(r)}e.findings=n}function we(e,i){return!e.reason||e.reason.trim()===""||e.expiresAt&&Date.parse(e.expiresAt)<=Date.now()||e.id&&e.id!==i.id||e.check&&e.check!==i.check||e.file&&e.file!==i.file?!1:!!(e.id||e.check)}function De(e,i,n,r,o,s,t){t.checksRun.push("echo");for(let c of i.slice(0,o)){if(r(c))continue;let a=W(e,c.symbol,{minSimilarity:s,limit:5}),f=[];for(let l of a){let p=l.fileA===c.file?l.fileB:l.fileA,h=l.fileA===c.file?l.shortNameB:l.shortNameA,m=l.fileA===c.file?l.symbolB:l.symbolA;n.has(p)||f.push({otherFile:p,otherShort:h,otherSymbol:m,similarity:l.similarity,similarityBasis:l.similarityBasis??"callees",sharedEvidence:l.sharedCallees})}if(f.length===0)continue;let g=f[0],u=C("echo",c.symbol,c.file,...f.map(l=>`${l.otherSymbol}|${l.otherFile}`).sort()),d=ke(c,f);t.findings.push({id:u,groupKey:u,actionTier:d,check:"echo",severity:"warning",evidence:"heuristic",confidence:g.similarity,file:c.file,symbol:c.symbol,relatedFiles:[...new Set(f.map(l=>l.otherFile))].sort(),message:xe(c,f),why:Ae(c,f),remediation:Ge(d,c.shortName,g.otherShort),suppressionHint:`scip-query: ignore echo ${u} -- <reason>`})}i.length>o&&t.skipped.push({check:"echo",reason:`echo check capped at ${o} of ${i.length} changed symbols`})}function ke(e,i){return i.some(r=>Re(e.symbol,r))?"direct":"signal"}function Re(e,i){if(i.similarityBasis!=="source-tokens"||i.similarity<.98||i.sharedEvidence.length>8)return!1;let n=$(e),r=$(i.otherSymbol);return!n||!r?!1:n===r?!0:ve(i.sharedEvidence)?!1:Te(n,r)}function Te(e,i){let n=re(e),r=re(i);if(n.length===0||r.length===0)return!1;let o=new Set(r),s=n.filter(t=>o.has(t)).length;return s>=2&&s/Math.min(n.length,r.length)>=.5}function re(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").split(/[^A-Za-z0-9]+/).map(i=>i.toLowerCase()).filter(i=>i.length>=2)}var Fe=new Set(["bytes","crypto","hex","num","random","secret","to","token"]);function ve(e){return e.length>=3&&e.every(i=>Fe.has(i.toLowerCase()))}function xe(e,i){let n=i[0],r=Math.round(n.similarity*100);return i.length===1?`${e.shortName} (${e.file}) is ${r}% similar to established ${n.otherShort} (${n.otherFile})`:`${e.shortName} (${e.file}) resembles ${i.length} established symbol(s); strongest is ${r}% similar to ${n.otherShort} (${n.otherFile})`}function Ae(e,i){let n=[`${e.shortName} was changed in this diff.`];for(let r of i.slice(0,3))n.push(`${r.otherShort} is outside this diff and scored ${Math.round(r.similarity*100)}% similar by ${r.similarityBasis} evidence.`),n.push(`Shared evidence: ${r.sharedEvidence.slice(0,5).join(", ")||"(none listed)"}.`);return i.length>3&&n.push(`${i.length-3} additional similar match(es) grouped into this finding.`),n}function Ge(e,i,n){return e==="direct"?`Extract or reuse the shared behavior with ${n}, or keep the duplicate with a suppression reason.`:`Review whether ${i} is intentionally parallel to the established implementation(s); extract shared behavior only if the product semantics match.`}function je(e,i,n,r,o){let s=X(e,{base:i,maxHelpers:r,diffPlan:n});if(!s.available){o.skipped.push({check:"incomplete-migration",reason:"no git history"});return}o.checksRun.push("incomplete-migration"),s.note&&o.skipped.push({check:"incomplete-migration",reason:s.note});for(let t of s.findings){let c=t.leftovers.map(l=>`${l.shortName} (${l.file}, ${Math.round(l.containment*100)}% helper / ${Math.round(l.siteCoverage*100)}% site, ${l.migrationScope})`).join(", "),a=t.leftovers.map(l=>`${l.shortName}: ${l.migrationScope} (${l.migrationScopeReasons[0]})`).join("; "),f=[...t.migratedFiles,...t.leftovers.map(l=>l.file)],g=t.leftovers.length===0?void 0:Math.max(...t.leftovers.map(l=>Math.min(l.containment,l.siteCoverage))),u=t.leftovers.some(l=>l.migrationScope==="possible-subtype"),d=C("incomplete-migration",t.helperSymbol,t.helperFile,f.join("|"));o.findings.push({id:d,check:"incomplete-migration",severity:"warning",evidence:"heuristic",confidence:g,file:t.helperFile,symbol:t.helperSymbol,relatedFiles:f,message:`new helper ${t.helperShortName} (${t.helperFile}) is wired into ${t.migratedFiles.length} file(s), but ${t.leftovers.length} similar un-migrated site(s) remain: ${c}`,why:[`${t.helperShortName} is new in this diff and already referenced by ${t.migratedFiles.join(", ")}.`,`Helper shape: ${t.helperShape}; ${t.specificHelperCalleeCount}/${t.helperCalleeCount} helper callees are specific enough to score.`,`Unchanged site(s) still contain the helper's callee pattern: ${c}.`,`Migration scope hints: ${a}.`],remediation:u?`Migrate same-scope sites to ${t.helperShortName}; review possible subtype/variant sites before applying the helper.`:`Migrate the remaining sites to ${t.helperShortName}, or confirm they are intentionally different.`,suppressionHint:`scip-query: ignore incomplete-migration ${d} -- <reason>`})}}function Ee(e,i,n,r,o){let s=L(e,{minTogether:n,minConfidence:0,maxFilesPerCommit:20});if(!s){o.skipped.push({check:"co-change-partner",reason:"no git history"});return}o.checksRun.push("co-change-partner");let t=new Set,c=B(e);for(let a of s){let f=i.has(a.fileA),g=i.has(a.fileB);if(f===g)continue;let u=f?a.fileA:a.fileB,d=f?a.fileB:a.fileA,l=f?a.changesA:a.changesB,p=l>0?a.together/l:0;if(p<r||F(d)||F(u)||!x(`${e.config.projectRoot}/${d}`))continue;let h=`${u}|${d}`;if(t.has(h))continue;t.add(h);let m=C("co-change-partner",u,d,String(a.together)),b=N(u,d),S=K({fileA:u,fileB:d,together:a.together,confidence:p,commitScope:a.commitScope,recency:a.recency,subjectContext:a.subjectContext},b,c(u,d)),A=[u,d].sort().join("|");o.findings.push({id:m,check:"co-change-partner",severity:"warning",evidence:"change-graph",actionTier:"signal",groupKey:`co-change-partner:${A}`,confidence:p,file:u,relatedFiles:[d],sourceAnalyzer:"co-change",rootCauseKey:A,partnerClass:b.partnerClass,partnerClassReasons:b.reasons,commitScope:a.commitScope,recency:a.recency,focusedTogether:a.focusedTogether,broadTogether:a.broadTogether,broadCommitRatio:a.broadCommitRatio,lastTogetherAt:a.lastTogetherAt,recentTogether:a.recentTogether,subjectContext:a.subjectContext,...S?{declaredCouplingSuggestion:S}:{},message:`${u} changed, but ${d} did not \u2014 they change together ${a.together}x (${Math.round(p*100)}% of the time)`,why:[`${u} is in this diff and ${d} is not.`,`Git history shows ${a.together} co-change(s), which is ${Math.round(p*100)}% of changes to the edited side.`,`History context: ${Le(a)}.`,`Subject context: ${Ne(a.subjectContext)}.`,...Ke(a),`Partner class: ${b.partnerClass} (${b.reasons.join("; ")}).`],remediation:S?`Update ${d} alongside this change, declare the coupling "${S.name}", or confirm the coupling no longer holds.`:`Update ${d} alongside this change, or confirm the coupling no longer holds.`,suppressionHint:`scip-query: ignore co-change-partner ${m} -- <reason>`})}}function Le(e){return`${e.commitScope}/${e.recency}; ${e.focusedTogether} focused, ${e.broadTogether} broad-sweep (${Math.round(e.broadCommitRatio*100)}% broad), ${e.recentTogether} recent, last ${Be(e.lastTogetherAt)}`}function Ne(e){let i=e.subjectLabels.length>0?e.subjectLabels.slice(0,5).join(", "):"none inferred",n=e.issueRefs.length>0?e.issueRefs.slice(0,5).join(", "):"none",r=e.sampleSubjects.length>0?e.sampleSubjects.slice(0,3).map(o=>`"${o}"`).join("; "):"none";return`labels ${i}; refs ${n}; samples ${r}; external issue/PR labels ${e.externalIssueLabelStatus}`}function Ke(e){let i=[];return e.commitScope==="broad-sweep"&&i.push("Broad-sweep history is weaker than focused co-edits; confirm this is a real coordination contract."),e.recency==="stale"&&i.push("The pair has no co-change in the recent history window; confirm the coupling still holds."),i}function Be(e){return e<=0?"unknown":new Date(e*1e3).toISOString().slice(0,10)}function Me(e,i,n,r,o){o.checksRun.push("doc-reference");let s=Oe(e,i,r);if(s.size!==0)for(let t of z(e,s)){if(n.has(t.doc))continue;let c=t.citedClaims.length>0?t.citedClaims:Pe(e,t.doc,t.cited),a=Ie(c),f=C("doc-reference",t.doc,t.cited.join("|"));o.findings.push({id:f,check:"doc-reference",severity:"warning",evidence:"change-graph",actionTier:a.actionTier,confidence:1,file:t.doc,relatedFiles:t.cited,citationKind:a.citationKind,citationKindReasons:a.reasons,citedClaims:c,message:`${t.doc} cites ${t.cited.join(", ")} as ${_e(a.citationKind)} \u2014 changed in this diff, doc untouched`,why:[`${t.cited.join(", ")} changed in this diff.`,`${t.doc} cites the changed file(s) but was not updated in the same diff.`,...a.reasons.map(g=>`Citation kind evidence: ${g}`)],remediation:ze(a.citationKind,t.doc),suppressionHint:`scip-query: ignore doc-reference ${f} -- <reason>`})}}function Ie(e){let i=e.join(`
|
|
3
|
-
`).toLowerCase(),n=[],r=v(i,[".scipquery","declaredcouplings","suppression","suppressions","config","configuration","json"]);if(r.length>0)return n.push(`configuration/example terms near citation: ${r.join(", ")}`),{citationKind:"configuration-example",actionTier:"support",reasons:n};let o=v(i,["accepted","intentional","intentionally","retained","historical"]);if(o.length>0)return n.push(`intentional-record terms near citation: ${o.join(", ")}`),{citationKind:"intentional-record",actionTier:"support",reasons:n};let s=v(i,["command","cli","usage","example","run","workflow"]);return s.length>0?(n.push(`guide/reference terms near citation: ${s.join(", ")}`),{citationKind:"guide-reference",actionTier:"signal",reasons:n}):(n.push(e.length>0?"citation appears in prose without config or guide markers":"citation context unavailable"),{citationKind:"behavioral-claim",actionTier:"direct",reasons:n})}function Pe(e,i,n){let r;try{r=oe(`${e.config.projectRoot}/${i}`,"utf-8").split(/\r?\n/)}catch{return[]}let o=n.flatMap(He),s=[];for(let t=0;t<r.length;t+=1){let c=r[t]??"";o.some(a=>c.includes(a))&&s.push(_(r,t))}return s}function He(e){let i=e.split("/");return[e,`./${e}`,i.slice(-3).join("/"),i.slice(-2).join("/")].filter((n,r,o)=>n.length>0&&o.indexOf(n)===r)}function v(e,i){return i.filter(n=>e.includes(n))}function _e(e){switch(e){case"behavioral-claim":return"a behavioral doc claim";case"configuration-example":return"a configuration example";case"guide-reference":return"a guide reference";case"intentional-record":return"an intentional record"}}function ze(e,i){switch(e){case"behavioral-claim":return`Re-read ${i} and update the behavioral claim or citation.`;case"configuration-example":return`Verify the configuration example in ${i} still points at the intended file; update only if the example target changed.`;case"guide-reference":return`Verify the guide reference in ${i} still sends readers to the right implementation or command surface.`;case"intentional-record":return`Verify the intentional citation in ${i} is still meant to name this file.`}}function Oe(e,i,n){let r=qe(n),o=new Set;for(let s of i)Ue(e,s,r.get(s)??[])&&o.add(s);return o}function qe(e){let i=new Map;for(let n of e){let r=i.get(n.file)??[];r.push(n),i.set(n.file,r)}return i}function Ue(e,i,n){if(n.length===0)return!1;if(!Ve.test(i))return!0;let r=`${e.config.projectRoot}/${i}`;if(!x(r))return!0;let o=oe(r,"utf-8").split(/\r?\n/),s=We(o);for(let t of n)for(let c=t.startLine;c<=t.endLine;c+=1)if((o[c]??"").trim()!==""&&!s.has(c))return!0;return!1}var Ve=/\.(?:[cm]?[jt]sx?)$/i;function We(e){let i=new Set,n=!1;for(let r=0;r<e.length;r+=1){let o=e[r].trim();!n&&Ye(o)&&(n=!0),n&&(i.add(r),o.endsWith(";")&&(n=!1))}return i}function Ye(e){return/^import(?:\s|$)/.test(e)||/^export(?:\s+type)?\s+(?:\*|\{)/.test(e)}function Je(e,i,n){n.checksRun.push("unused-params");for(let r of ee(e,{files:i,limit:50})){let o=C("unused-params",r.symbol,r.file,r.unusedTrailing.join("|"));n.findings.push({id:o,check:"unused-params",severity:"warning",evidence:"heuristic",confidence:.85,file:r.file,startLine:r.startLine,endLine:r.endLine,symbol:r.symbol,message:`${r.shortName} (${r.file}) has trailing unused parameter(s): ${r.unusedTrailing.join(", ")}`,why:[`${r.shortName} is in a changed file.`,`The trailing parameter(s) ${r.unusedTrailing.join(", ")} are not referenced in the function body.`],remediation:"Drop the unused trailing parameters and their call-site arguments.",suppressionHint:`scip-query: ignore unused-params ${o} -- <reason>`})}}function Ze(e,i,n,r){r.checksRun.push("new-dead");let o=new j(e);for(let s of i){if(n(s)||s.fanIn>0||o.fileKind(s.file)==="test"||w(e,s.file)||D(e,s.symbol,s.file)||Qe(s.symbol))continue;let t=C("new-dead",s.symbol,s.file);r.findings.push({id:t,check:"new-dead",severity:"warning",evidence:"graph-fact",confidence:.9,file:s.file,symbol:s.symbol,message:`${s.shortName} (${s.file}) was changed but has zero indexed consumers`,why:[`${s.shortName} is a changed production symbol.`,"The index reports zero consumers for this symbol.","The symbol is not in a detected entry surface or configured live root."],remediation:"Wire it up, or remove it before it becomes permanent dead code.",suppressionHint:`scip-query: ignore new-dead ${t} -- <reason>`})}}function Qe(e){if(G(e)!=="type")return!1;let i=$(e);return i.startsWith("_Assert")||i.startsWith("Assert")}function Xe(e,i,n){let r=new Map(n.renamedFiles.map(s=>[s.to,s.from])),o=new Map;return s=>{let t=r.get(s.file);if(!t)return!1;let c=$(s.symbol);if(!c)return!1;let a=o.get(t);return a===void 0&&(a=H(e,i,t),o.set(t,a)),a!==null&&en(a,c)}}function en(e,i){return new RegExp(`\\b${nn(i)}\\b`).test(e)}function nn(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function tn(e,i){if(!x(k(e))){i.skipped.push({check:"baseline",reason:"no .scipquery-baseline.json \u2014 run health --write-baseline to enable"});return}i.checksRun.push("baseline");let n=ie(e);for(let r of n.newFindings){let o=rn(r),s=C("baseline",r);i.findings.push({id:s,groupKey:`baseline:${o.sourceAnalyzer}:${o.rootCauseKey}`,check:"baseline",severity:"error",evidence:"baseline",actionTier:o.actionTier,confidence:1,file:o.file,relatedFiles:o.relatedFiles.length>0?o.relatedFiles:void 0,sourceAnalyzer:o.sourceAnalyzer,rootCauseKey:o.rootCauseKey,message:`new ${o.label} vs committed baseline: ${r}`,why:["A committed health baseline exists.","The current health result contains a finding not present in that baseline.",`Underlying analyzer: ${o.sourceAnalyzer}.`,`Inherited action tier: ${o.actionTier}.`,`Root cause key: ${o.rootCauseKey}.`,...o.why],remediation:o.remediation,suppressionHint:`scip-query: ignore baseline ${s} -- <reason>`})}}function rn(e){let[i,n]=R(e,":"),r=i||"unknown",o=(s={})=>{let t=s.actionTier??on(r);return{sourceAnalyzer:r,actionTier:t,rootCauseKey:s.rootCauseKey??(n||e),label:s.label??`${r} finding`,relatedFiles:s.relatedFiles??[],why:s.why??[],remediation:s.remediation??sn(t,r),file:s.file}};if(!n)return o({rootCauseKey:e,why:["Baseline identity did not include analyzer payload."]});if(["dead","isolated","extract","wrapper","passthrough","stale"].includes(r)){let[s,t]=R(n,":");return o({file:s,relatedFiles:s?[s]:[],rootCauseKey:t?`${s}:${t}`:n,label:`${r} finding`,why:t?[`Baseline subject: ${t}.`]:[]})}if(r==="cycle"){let s=n.split(">").filter(Boolean);return o({relatedFiles:s,rootCauseKey:n,label:"cycle finding",why:s.length>0?[`Cycle path: ${s.join(" > ")}.`]:[]})}if(r==="similar"){let s=n.split("|").filter(Boolean);return o({relatedFiles:[],rootCauseKey:n,label:"similarity finding",why:s.length>0?[`Similar symbols: ${s.join(" | ")}.`]:[]})}if(r==="drift"){let[s,t]=R(n,":"),[c,a]=R(t,":");return o({actionTier:s==="unused-import"?"direct":"signal",file:c,relatedFiles:[...new Set([c,a].filter(Boolean))],rootCauseKey:n,label:`${s||"drift"} finding`,why:[...s?[`Drift kind: ${s}.`]:[],...a?[`Related dependency: ${a}.`]:[]]})}return o({why:["Baseline analyzer prefix is not recognized by this diff-gate version."]})}function on(e){switch(e){case"dead":case"isolated":case"cycle":case"passthrough":return"direct";case"similar":case"extract":case"wrapper":case"stale":return"signal";default:return"signal"}}function sn(e,i){return e==="direct"?`Fix the new ${i} baseline finding, or knowingly accept it via health --write-baseline.`:`Review the new ${i} baseline signal; fix it if it reflects real debt, or knowingly accept it via health --write-baseline.`}function R(e,i){let n=e.indexOf(i);return n<0?[e,""]:[e.slice(0,n),e.slice(n+i.length)]}function C(e,...i){return`SQ${ye("sha256").update([e,...i].join("\0")).digest("hex").slice(0,12).toUpperCase()}`}export{ne as a,$n as b,ie as c,Bn as d,Mn as e};
|
|
4
|
-
//# sourceMappingURL=chunk-5B53WB6E.js.map
|
package/dist/chunk-DRAZH77R.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import{d as y}from"./chunk-7S5E7KWT.js";import{execFileSync as j}from"child_process";var F=2e3,E=50,H=8,M=3,L=2160*60*60,P=/\b(?:fix(?:es|ed)?|bug|regression|hotfix)\b/i,D=3,O=/#\d+|\b[A-Z][A-Z0-9]+-\d+\b/g,B=/^([a-z][a-z0-9-]+)(?:\([^)]+\))?!?:/i;function x(e){let t=y(e,{clearGroups:["whole-project"]});return(n,o)=>{let i=N(n.config.projectRoot);if(!i)return null;let r=t.has(n)?t.get(n,()=>({head:"",value:null})):null;return r&&r.head===i?r.value:(t.invalidate(n),t.get(n,()=>({head:i,value:o(n.config.projectRoot,i)})).value)}}var I=x("git-commit-history");function A(e){return I(e,v)}function N(e){try{return C(e,["rev-parse","HEAD"]).trim()||null}catch{return null}}function C(e,t){return j("git",["-C",e,...t],{encoding:"utf-8",maxBuffer:64*1024*1024,stdio:["ignore","pipe","ignore"]})}function v(e,t){let n;try{n=C(e,["log","--no-merges","--name-only","-n",String(F),"--pretty=format:%x01%H%x00%ct%x00%s"])}catch{return null}let o=[],i=0;for(let r of n.split("")){if(r.trim()==="")continue;let a=r.indexOf(`
|
|
2
|
-
`),d=a>=0?r.slice(0,a):r,[f,g,h]=d.split("\0");if(!f||!g)continue;let c=a>=0?r.slice(a+1).split(`
|
|
3
|
-
`).map(s=>s.trim()).filter(s=>s!==""):[];if(c.length>E){i+=1;continue}o.push({hash:f,timestamp:Number(g)||0,subject:h??"",files:c})}return{head:t,commits:o,skippedBulkCommits:i}}function k(e){return P.test(e.subject)}function Q(e){let t=A(e);if(!t)return null;let n=new Map;for(let o of t.commits){let i=k(o);for(let r of o.files){let a=n.get(r)??{changes:0,fixChanges:0,lastChangedAt:0};a.changes+=1,i&&(a.fixChanges+=1),o.timestamp>a.lastChangedAt&&(a.lastChangedAt=o.timestamp),n.set(r,a)}}return n}function Y(e){let t=A(e);if(!t||t.commits.length===0)return null;let n=t.commits.map(o=>o.files.length).filter(o=>o>0).sort((o,i)=>o-i);return n.length===0?null:{medianFilesPerCommit:R(n,.5),p90FilesPerCommit:R(n,.9),commitsAnalyzed:n.length}}function R(e,t){let n=Math.min(e.length-1,Math.floor(e.length*t));return e[n]}var z=x("git-tracked-files");function ee(e){return z(e,t=>{try{let n=C(t,["ls-files"]);return new Set(n.split(`
|
|
4
|
-
`).map(o=>o.trim()).filter(o=>o!==""))}catch{return null}})}var G=x("git-file-adds");function te(e){return G(e,t=>U(t))}function U(e){let t;try{t=C(e,["log","--no-merges","--diff-filter=A","--name-only","-n",String(F),"--pretty=format:%x01%H%x00%ct%x00%s"])}catch{return null}let n=new Map,o=-1;for(let i of t.split("")){if(i.trim()==="")continue;o+=1;let r=i.indexOf(`
|
|
5
|
-
`),a=r>=0?i.slice(0,r):i,[,d]=a.split("\0"),f=Number(d)||0;if(!(r<0))for(let g of i.slice(r+1).split(`
|
|
6
|
-
`)){let h=g.trim();h!==""&&n.set(h,{commitsAgo:o,addedAt:f})}}return n}function ne(e,t={}){let{minTogether:n=4,minConfidence:o=.6,maxFilesPerCommit:i=E}=t,r=A(e);if(!r)return null;let a=new Map,d=new Map,f=0;for(let c of r.commits){let s=[...new Set(c.files)].sort();if(s.length>i)continue;c.timestamp>f&&(f=c.timestamp);let m=J(s);for(let u of s)a.set(u,(a.get(u)??0)+1);for(let u=0;u<s.length;u++)for(let b=u+1;b<s.length;b++){let p=`${s[u]}\0${s[b]}`,l=d.get(p)??{together:0,focusedTogether:0,broadTogether:0,lastTogetherAt:0,timestamps:[],subjects:[]};l.together+=1,m?l.broadTogether+=1:l.focusedTogether+=1,c.timestamp>l.lastTogetherAt&&(l.lastTogetherAt=c.timestamp),l.timestamps.push(c.timestamp),l.subjects.push(c.subject),d.set(p,l)}}let g=[],h=f-L;for(let[c,s]of d){let m=s.together;if(m<n)continue;let[u,b]=c.split("\0"),p=a.get(u)??m,l=a.get(b)??m,S=Math.max(m/p,m/l);if(S<o)continue;let _=s.broadTogether/m,T=s.timestamps.filter(w=>w>=h).length;g.push({fileA:u,fileB:b,together:m,confidence:S,changesA:p,changesB:l,focusedTogether:s.focusedTogether,broadTogether:s.broadTogether,broadCommitRatio:_,lastTogetherAt:s.lastTogetherAt,recentTogether:T,commitScope:K(s.broadTogether,m),recency:T>0?"recent":"stale",subjectContext:W(s.subjects)})}return g.sort((c,s)=>s.together-c.together||s.confidence-c.confidence||c.fileA.localeCompare(s.fileA)),g}function J(e){return e.length>=H?!0:V(e).size>=M}function V(e){let t=new Set;for(let n of e){let o=n.indexOf("/");t.add(o>=0?n.slice(0,o):".")}return t}function K(e,t){return e===0?"focused":e/t>=.5?"broad-sweep":"mixed"}function W(e){let t=new Set,n=[],o=[];for(let i of e){!o.includes(i)&&o.length<D&&o.push(i);for(let r of X(i))t.add(r);for(let r of i.match(O)??[])n.includes(r)||n.push(r)}return{subjectLabels:[...t].sort(),issueRefs:n,sampleSubjects:o,externalIssueLabelStatus:"unavailable"}}function X(e){let t=new Set,n=B.exec(e)?.[1]?.toLowerCase();return n&&t.add(Z(n)),/\b(?:feat|feature)\b/i.test(e)&&t.add("feature"),/\b(?:fix(?:es|ed)?|bug|regression|hotfix)\b/i.test(e)&&t.add("fix"),/\b(?:docs?|documentation|guide|readme)\b/i.test(e)&&t.add("docs"),/\brefactor(?:ing|ed)?\b/i.test(e)&&t.add("refactor"),/\btests?\b/i.test(e)&&t.add("test"),/\b(?:release|version|v\d+\.\d+)\b/i.test(e)&&t.add("release"),/\bchore\b/i.test(e)&&t.add("chore"),/\bbuild\b/i.test(e)&&t.add("build"),/\bci\b/i.test(e)&&t.add("ci"),/\bperf(?:ormance)?\b/i.test(e)&&t.add("perf"),[...t]}function Z(e){return e==="feat"?"feature":e}export{A as a,Q as b,Y as c,ee as d,te as e,ne as f};
|
|
7
|
-
//# sourceMappingURL=chunk-DRAZH77R.js.map
|
package/dist/chunk-FPMVCDIJ.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as S}from"./chunk-O4L4AB3T.js";import{a as g}from"./chunk-GS33KGAY.js";import{a as f}from"./chunk-UMNENNTX.js";import{a as p}from"./chunk-TO54DY4O.js";import{b as y}from"./chunk-MHTDOFV7.js";import{e as h}from"./chunk-DRAZH77R.js";var v=.7,C=.62,R=.45;function H(i,t={}){let{windowCommits:e=100,limit:n=30,scope:a,scanLimit:l}=t,s=h(i);if(!s)return{available:!1,windowCommits:e,findings:[]};if(n<=0)return{available:!0,windowCommits:e,findings:[]};let d=A(i,{limit:n,minSimilarity:t.minSimilarity,scanLimit:l,scope:a,semantic:t.semantic}).map(o=>I(o,s,e)).filter(o=>o!==null);d.sort((o,r)=>(o.kind===r.kind?0:o.kind==="echo"?-1:1)||r.similarity-o.similarity||o.echoFile.localeCompare(r.echoFile)||o.echoSymbol.localeCompare(r.echoSymbol)||o.domain.localeCompare(r.domain));let b=d.slice(0,n).map(x);return{available:!0,windowCommits:e,findings:b,rootCauseGroups:w(b)}}function A(i,t){let e=K(t.limit);return[...F(i,{scope:t.scope,minSimilarity:t.minSimilarity??v,limit:e,scanLimit:t.scanLimit,semantic:t.semantic}),...B(i,{scope:t.scope,minSimilarity:t.minSimilarity??C,limit:e,scanLimit:t.scanLimit}),...L(i,{scope:t.scope,minSimilarity:t.minSimilarity??R,limit:e,scanLimit:t.scanLimit}),...E(i,{scope:t.scope,minSimilarity:t.minSimilarity??C,limit:e,scanLimit:t.scanLimit}),...k(i,{scope:t.scope,minSimilarity:t.minSimilarity??R,limit:e,scanLimit:t.scanLimit})]}function F(i,t){return y(i,{scope:t.scope,minSimilarity:t.minSimilarity,limit:t.limit,crossFileOnly:!0,scanLimit:t.scanLimit,semantic:t.semantic}).map(e=>({domain:"callable",basis:e.similarityBasis??"callees",symbolA:e.shortNameA,fileA:e.fileA,symbolB:e.shortNameB,fileB:e.fileB,similarity:e.similarity,sharedEvidence:e.sharedCallees,sharedCallees:e.sharedCallees}))}function B(i,t){return f(i,{scope:t.scope,minSimilarity:t.minSimilarity,limit:t.limit,scanLimit:t.scanLimit}).filter(e=>e.fileA!==e.fileB).map(e=>({domain:"react-component",basis:"jsx-structure",symbolA:e.componentA,fileA:e.fileA,symbolB:e.componentB,fileB:e.fileB,similarity:e.similarity,sharedEvidence:u(["component",e.sharedComponents],["tag",e.sharedNativeTags],["prop",e.sharedProps],["event",e.sharedEvents],["binding",e.sharedBindings]),sharedCallees:[]}))}function L(i,t){return p(i,{scope:t.scope,minSimilarity:t.minSimilarity,limit:t.limit,scanLimit:t.scanLimit}).filter(e=>e.fileA!==e.fileB).map(e=>({domain:"react-hook",basis:"react-behavior",symbolA:e.componentA,fileA:e.fileA,symbolB:e.componentB,fileB:e.fileB,similarity:e.similarity,sharedEvidence:u(["hook",e.sharedHooks],["react-hook",e.sharedReactHooks],["effect",e.sharedEffects],["state",e.sharedState],["request",e.sharedRequests],["handler",e.sharedHandlers],["action",e.sharedHandlerVerbs]),sharedCallees:[]}))}function E(i,t){return g(i,{scope:t.scope,minSimilarity:t.minSimilarity,limit:t.limit,scanLimit:t.scanLimit}).filter(e=>e.fileA!==e.fileB).map(e=>({domain:"vue-component",basis:"vue-template",symbolA:c(e.fileA),fileA:e.fileA,symbolB:c(e.fileB),fileB:e.fileB,similarity:e.similarity,sharedEvidence:u(["component",e.sharedComponents],["prop",e.sharedProps],["event",e.sharedEvents],["directive",e.sharedDirectives],["slot",e.sharedSlots],["identifier",e.sharedIdentifiers]),sharedCallees:[]}))}function k(i,t){return S(i,{scope:t.scope,minSimilarity:t.minSimilarity,limit:t.limit,scanLimit:t.scanLimit}).filter(e=>e.fileA!==e.fileB).map(e=>({domain:"vue-composable",basis:"vue-behavior",symbolA:c(e.fileA),fileA:e.fileA,symbolB:c(e.fileB),fileB:e.fileB,similarity:e.similarity,sharedEvidence:u(["composable",e.sharedComposables],["store",e.sharedStores],["reactivity",e.sharedReactivity],["lifecycle",e.sharedLifecycle],["request",e.sharedRequests],["function",e.sharedFunctions],["action",e.sharedFunctionVerbs],["binding",e.sharedBindings],["template-event",e.sharedTemplateEvents]),sharedCallees:[]}))}function I(i,t,e){let n=t.get(i.fileA)?.commitsAgo??null,a=t.get(i.fileB)?.commitsAgo??null,l=n!==null&&n<=e,s=a!==null&&a<=e;if(!l&&!s)return null;if(l&&s){let m=(n??0)<=(a??0);return{kind:"twin",domain:i.domain,basis:i.basis,echoSymbol:m?i.symbolA:i.symbolB,echoFile:m?i.fileA:i.fileB,echoAgeCommits:(m?n:a)??0,establishedSymbol:m?i.symbolB:i.symbolA,establishedFile:m?i.fileB:i.fileA,establishedAgeCommits:m?a:n,similarity:i.similarity,sharedEvidence:i.sharedEvidence,sharedCallees:i.sharedCallees}}return{kind:"echo",domain:i.domain,basis:i.basis,echoSymbol:l?i.symbolA:i.symbolB,echoFile:l?i.fileA:i.fileB,echoAgeCommits:(l?n:a)??0,establishedSymbol:l?i.symbolB:i.symbolA,establishedFile:l?i.fileB:i.fileA,establishedAgeCommits:l?a:n,similarity:i.similarity,sharedEvidence:i.sharedEvidence,sharedCallees:i.sharedCallees}}function x(i){let t=D(i);return{...i,rootCauseKey:t,groupKey:`recent-duplicate:${t}`}}function D(i){if(i.kind==="echo")return["echo",i.domain,i.basis,i.establishedSymbol].join(":");let t=i.sharedEvidence.slice().sort().join("|"),e=[i.echoSymbol,i.establishedSymbol].sort().join("|");return["twin",i.domain,i.basis,t||e].join(":")}function w(i){let t=new Map;for(let[e,n]of i.entries()){let a=n.rootCauseKey??D(n),l=n.groupKey??`recent-duplicate:${a}`,s=t.get(l);s||(s={groupKey:l,rootCauseKey:a,kind:n.kind,domain:n.domain,basis:n.basis,count:0,maxSimilarity:n.similarity,findingIndexes:[],echoFiles:new Set,establishedFile:n.kind==="echo"?n.establishedFile:void 0,establishedSymbol:n.kind==="echo"?n.establishedSymbol:void 0,relatedFiles:new Set,sharedEvidence:new Set,recommendation:N(n)},t.set(l,s)),s.count+=1,s.maxSimilarity=Math.max(s.maxSimilarity,n.similarity),s.findingIndexes.push(e),s.echoFiles.add(n.echoFile),s.relatedFiles.add(n.echoFile),s.relatedFiles.add(n.establishedFile);for(let m of n.sharedEvidence)s.sharedEvidence.add(m)}return[...t.values()].map(e=>({...e,echoFiles:[...e.echoFiles].sort(),relatedFiles:[...e.relatedFiles].sort(),sharedEvidence:[...e.sharedEvidence].sort().slice(0,16)})).sort((e,n)=>n.count-e.count||n.maxSimilarity-e.maxSimilarity||e.groupKey.localeCompare(n.groupKey))}function N(i){return i.kind==="echo"?"Review the established side once, then migrate or delete every echo in this group.":"Pick one owner for the new twins and consolidate the group before the copies diverge."}function K(i){return Number.isFinite(i)?i*5:Number.POSITIVE_INFINITY}function u(...i){let t=[],e=new Set;for(let[n,a]of i)for(let l of a){let s=`${n}:${l}`;e.has(s)||(e.add(s),t.push(s))}return t}function c(i){return(i.split("/").pop()??i).replace(/\.[^.]+$/,"")}export{H as a};
|
|
2
|
-
//# sourceMappingURL=chunk-FPMVCDIJ.js.map
|
package/dist/chunk-GS33KGAY.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as p}from"./chunk-PVZMPG5I.js";import{a as c,b as a,c as f}from"./chunk-3UVJJ6Z7.js";import{c as m}from"./chunk-ERHOS6AW.js";function B(e,t={}){let{minSimilarity:n=.62,minTokens:i=8,limit:l=20,scope:d,scanLimit:h,filePattern:g}=t,k=P(e,{scope:d,minTokens:i,scanLimit:h});return p({profiles:k,limit:l,filePattern:g,compare:(o,s)=>v(o,s,n),sort:(o,s)=>s.similarity-o.similarity||o.fileA.localeCompare(s.fileA)||o.fileB.localeCompare(s.fileB)})}function P(e,t){return m(e,{scope:t.scope,minTemplateTokens:t.minTokens,scanLimit:t.scanLimit}).map(n=>({file:n.file,tokens:n.templateTokens,loc:C(n)}))}function C(e){return e.totalLines}function v(e,t,n){let i=c(e.tokens,t.tokens);if(i.size<6||!T(i))return null;let l=f(e.tokens,t.tokens);return l<n?null:{fileA:e.file,fileB:t.file,similarity:l,sharedTokens:u(i),sharedComponents:r(i,"component:"),sharedProps:r(i,"prop:"),sharedEvents:r(i,"event:"),sharedDirectives:r(i,"directive:"),sharedSlots:r(i,"slot:"),sharedIdentifiers:r(i,"id:"),uniqueToA:u(a(e.tokens,t.tokens)).slice(0,25),uniqueToB:u(a(t.tokens,e.tokens)).slice(0,25),locA:e.loc,locB:t.loc}}function T(e){let t=0,n=0;for(let i of e)i.startsWith("component:")&&(t+=1),(i.startsWith("prop:")||i.startsWith("event:")||i.startsWith("directive:")||i.startsWith("slot:"))&&(n+=1);return t>=1||n>=3}function r(e,t){return[...e].filter(n=>n.startsWith(t)).map(n=>n.slice(t.length)).sort()}function u(e){return[...e].sort()}export{B as a};
|
|
2
|
-
//# sourceMappingURL=chunk-GS33KGAY.js.map
|
package/dist/chunk-MHTDOFV7.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import{a as F,b as w,e as N,f as O}from"./chunk-3UVJJ6Z7.js";import{b as M}from"./chunk-B75HZHUP.js";import{a as R}from"./chunk-3ZYF3ELZ.js";import{a as I}from"./chunk-YTR4CO5S.js";import{a as T}from"./chunk-MZ7APUFN.js";import{c as d,d as E,g as A}from"./chunk-JM72FNGA.js";import{b as B}from"./chunk-D322LMSA.js";import{d as D}from"./chunk-7S5E7KWT.js";function Fe(e,i,n={}){let{minSimilarity:t=.4,limit:r=20}=n,l=ne(e,i,{semantic:n.semantic!==!1});if(!l)return[];if(!A(l.symbol))return[];let a=J(e,l,t,{scanLimit:n.scanLimit,semantic:n.semantic!==!1});return a.length>0?a.slice(0,r):ae(e,i,{minSimilarity:t,limit:r})}function J(e,i,n,t){let r=G(e,{minCallees:3,excludeSymbol:i.symbol,scanLimit:t.scanLimit,semantic:t.semantic}),l=N([i,...r].map(c=>c.callees)),a=[];for(let c of r){if(c.callees.size<3)continue;let s=j(i,c,l,{minSimilarity:n,requireSignificantShared:1,requireSharedCount:0});s&&a.push(s)}return a.sort((c,s)=>s.similarity-c.similarity),a}function j(e,i,n,t){let{similarity:r,significantShared:l}=O(e.callees,i.callees,n);if(r<t.minSimilarity)return null;let a=F(e.callees,i.callees).size;if(l.length<t.requireSignificantShared&&a<t.requireSharedCount)return null;let c=l.length>0?l:[...F(e.callees,i.callees)],s=K(c,"callees");return{symbolA:e.symbol,shortNameA:d(e.symbol),fileA:e.file,symbolB:i.symbol,shortNameB:d(i.symbol),fileB:i.file,similarity:r,similarityBasis:"callees",sharedCallees:c.map(d),uniqueToA:[...w(e.callees,i.callees)].map(d),uniqueToB:[...w(i.callees,e.callees)].map(d),...s}}function De(e,i={}){let{minSimilarity:n=.5,limit:t=20,scope:r,minCallees:l=4,crossFileOnly:a=!1,scanLimit:c}=i,s=G(e,{minCallees:l,scope:r,scanLimit:c,semantic:i.semantic!==!1}),o=N(s.map(m=>m.callees)),f=new Map;for(let m of s)for(let u of m.callees)f.set(u,(f.get(u)??0)+1);let b=Math.max(8,Math.ceil(Math.sqrt(s.length))),y=new Map;for(let m=0;m<s.length;m+=1)for(let u of s[m].callees){if((f.get(u)??0)>b)continue;let g=y.get(u);g||(g=[],y.set(u,g)),g.push(m)}let h=[],S=0,C=new Set;for(let m=0;m<s.length;m+=1){let u=s[m],g=new Set;for(let v of u.callees){let k=y.get(v);if(k)for(let p of k)p>m&&g.add(p)}for(let v of g){let k=`${m}|${v}`;if(C.has(k))continue;C.add(k);let p=s[v];if(a&&u.file===p.file)continue;if(u.paramCount>=0&&p.paramCount>=0){let X=Math.abs(u.paramCount-p.paramCount),Y=Math.max(2,Math.ceil(Math.max(u.paramCount,p.paramCount)*.5));if(X>Y)continue}let q=j(u,p,o,{minSimilarity:n,requireSignificantShared:2,requireSharedCount:4});q&&(ee(h,q,t,S),S+=1)}}return h.sort((m,u)=>u.result.similarity-m.result.similarity||m.order-u.order),h.map(m=>m.result)}function ee(e,i,n,t){if(n<=0)return;if(e.length<n){e.push({result:i,order:t});return}let r=0;for(let a=1;a<e.length;a+=1){let c=e[a],s=e[r];(c.result.similarity<s.result.similarity||c.result.similarity===s.result.similarity&&c.order>s.order)&&(r=a)}let l=e[r];i.similarity<=l.result.similarity||(e[r]={result:i,order:t})}var ie=["ScipDatabase#all","ScipDatabase#get","ScipDatabase#prepare","ScipDatabase#pathExclusionsFor","ScipDatabase#isIgnored","ScipDatabase#symbolNoiseFor","PerDbValue#get","PerDbValue#has",":storage:db:ScipDatabase:all",":storage:db:ScipDatabase:get",":storage:db:ScipDatabase:prepare",":storage:db:ScipDatabase:pathExclusionsFor",":storage:db:ScipDatabase:isIgnored",":storage:db:ScipDatabase:symbolNoiseFor",":storage:per-db-cache:PerDbValue:get",":storage:per-db-cache:PerDbValue:has"];function ne(e,i,n){let t=T(e,i),r=new R(e);if(!t)return null;let l=I(e,t,{semantic:n.semantic});return{symbol:t.symbol,file:t.relativePath,callees:U(l.map(a=>a.symbol)),paramCount:r.callableSignature(t)?.paramCount??-1}}var te=D("callee-fingerprint-corpus",{clearGroups:["whole-project","definition-catalog"]});function G(e,i){let{minCallees:n,scope:t,excludeSymbol:r,scanLimit:l}=i,a=i.semantic!==!1,c=te.get(e,()=>new Map),s=`${n}|${t??""}|${l??""}|${a}`,o=c.get(s);return o||(o=re(e,{minCallees:n,scope:t,scanLimit:l,semantic:a}),c.set(s,o)),r===void 0?o:o.filter(f=>f.symbol!==r)}function re(e,i){let{minCallees:n,scope:t,scanLimit:r,semantic:l}=i,a=new R(e),c=M(a.productionCallableDefinitions({scope:t,minLoc:5,sortByLocDesc:typeof r=="number"&&r>0}),r),s=a.calleeMap(c,{semantic:l});return c.map(o=>({symbol:o.symbol,file:o.relativePath,callees:U((s.get(o.symbolId)??[]).map(f=>f.symbol)),paramCount:a.callableSignature(o)?.paramCount??-1})).filter(o=>o.callees.size>=n)}function U(e){return new Set([...e].filter(i=>!se(i)))}function se(e){return ie.some(i=>e.includes(i))}function ae(e,i,n){let t=me(e,i);if(!t||t.tokens.size<3)return[];let r=n.minSimilarity>=.5?n.minSimilarity:.3,l=[],a=new Set,c=pe(ge(e));for(let s of t.tokens)for(let o of c.get(s)??[])a.add(o);for(let s of a){if(s.symbol===t.symbol||s.tokens.size<3)continue;let o=F(t.tokens,s.tokens);if(o.size<2)continue;let f=new Set([...t.tokens,...s.tokens]),b=f.size>0?o.size/f.size:0;b<r||l.push({symbolA:t.symbol,shortNameA:d(t.symbol),fileA:t.file,symbolB:s.symbol,shortNameB:d(s.symbol),fileB:s.file,similarity:b,similarityBasis:"source-tokens",sharedCallees:[...o].sort(),uniqueToA:[...w(t.tokens,s.tokens)].sort(),uniqueToB:[...w(s.tokens,t.tokens)].sort(),...K([...o],"source-tokens")})}return l.sort((s,o)=>o.similarity-s.similarity||s.shortNameB.localeCompare(o.shortNameB)),l.slice(0,n.limit)}function K(e,i){let n=e.flatMap(z),t=e.flatMap(m=>_(m,i)),r=L(n,V),l=L(n,Z),a=L(t,$),c=[...new Set(t.filter(P))],s=e.filter(m=>{let u=_(m,i);return u.some(g=>$.has(g))&&u.some(P)}).length,o=[];r.length>0&&o.push(`access/query scaffolding: ${r.slice(0,5).join(", ")}`),l.length>0&&o.push(`framework/generic scaffolding: ${l.slice(0,5).join(", ")}`),a.length>0&&o.push(`domain behavior verbs: ${a.slice(0,5).join(", ")}`),a.length>0&&c.length>0&&o.push(`domain-specific terms: ${c.slice(0,5).join(", ")}`);let f=i==="source-tokens"&&n.length>0&&n.every(m=>H.has(m));f&&o.push("shared source tokens are generic scaffolding");let b=a.length>0&&c.length>0,y=r.length+l.length>0,h=i==="callees"&&b&&e.length>=4&&c.length>=4&&s>=2,S=h?"domain-behavior":b?y?"mixed":"domain-behavior":r.length>0?"access-query-scaffolding":l.length>0||f?"framework-scaffolding":"structural-overlap";S==="structural-overlap"&&e.length>0&&o.push(`shared ${i} overlap has no recognized domain or scaffolding category`);let C=S==="domain-behavior"&&(e.length>=3||h)?"direct":"signal";return{evidenceClass:S,actionTier:C,evidenceClassReasons:o,recommendation:oe(S,C)}}function oe(e,i){return i==="direct"?"Shared domain behavior looks concrete; review for an extract/reuse opportunity.":e==="mixed"?"Shared evidence mixes domain behavior with scaffolding; review semantics before extracting anything.":e==="access-query-scaffolding"?"Shared evidence is mostly access/query scaffolding; compare product semantics before reusing code.":e==="structural-overlap"?"Shared structure has no domain or scaffolding classification; inspect names and behavior before reusing code.":"Shared evidence is mostly framework or generic scaffolding; treat as a contextual signal."}function L(e,i){return[...new Set(e.filter(n=>i.has(n)))]}function z(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").toLowerCase().split(/[^a-z0-9]+/).filter(i=>i.length>1)}function _(e,i){if(i==="source-tokens")return z(e);let n=E(e);return z(n.length>0?n:le(e))}function le(e){return e.replace(/[()`]/g," ").replace(/\.[a-z][a-z0-9]+(?=\s|$)/gi," ").split(/[:/\\\s]+/).map(t=>t.trim()).filter(t=>/[A-Za-z]/.test(t)).at(-1)?.replace(/\.$/,"")??e}function P(e){return e.length>3&&!$.has(e)&&!V.has(e)&&!Z.has(e)&&!H.has(e)&&!ce.has(e)}var $=new Set(["archive","assign","book","cancel","create","delete","ensure","export","import","notify","persist","publish","restore","schedule","send","set","submit","sync","update","upload","validate","write"]),V=new Set(["access","auth","authorize","cache","context","db","find","get","guard","list","permission","permissions","prisma","query","request","response","role","route","session","sql","where"]),Z=new Set(["bytes","computed","crypto","describe","effect","expect","fetch","filter","hex","hook","json","map","mounted","on","promise","random","react","reduce","ref","render","state","test","token","trim","uuid","vue","watch"]),H=new Set(["bytes","crypto","data","false","get","hex","id","key","map","name","num","random","result","secret","set","string","to","token","true","type","value"]),ce=new Set(["best","backend","conflict","database","effect","effects","error","errors","frontend","found","helpers","javascript","module","modules","scip","shared","source","typescript","utils","with","workflow","workflows"]);function me(e,i){let n=T(e,i);if(!n||!A(n.symbol))return null;let t=ue(e,n);return t?{symbol:n.symbol,file:n.relativePath,tokens:t}:null}function ue(e,i){let n=E(i.symbol),t=W(e,i.relativePath,i.startLine,i.endLine,n),r=Q(t,n);return r.size>0?r:null}var fe=D("source-fingerprint-corpus",{clearGroups:["whole-project","definition-catalog"]});function ge(e){return fe.get(e,()=>de(e))}function pe(e){let i=new Map;for(let n of e)for(let t of n.tokens){let r=i.get(t);r||(r=[],i.set(t,r)),r.push(n)}return i}function de(e){return new R(e).productionCallableDefinitions().map(n=>({symbol:n.symbol,file:n.relativePath,tokens:Q(W(e,n.relativePath,n.startLine,n.endLine,n.leaf),n.leaf)})).filter(n=>n.tokens.size>0)}function W(e,i,n,t,r){let l=B(e,i);if(l.length===0)return"";if(t>=n&&t-n<=12)return l.slice(n,t+1).join(`
|
|
2
|
-
`);let a=[new RegExp(`\\bdef\\s+${x(r)}\\b`),new RegExp(`\\bfun\\s+${x(r)}\\b`),new RegExp(`\\bfn\\s+${x(r)}\\b`),new RegExp(`\\bfunction\\s+${x(r)}\\b`),new RegExp(`\\b${x(r)}\\s*\\(`)],c=l.findIndex(s=>a.some(o=>o.test(s)));if(c>=0){let s=c;for(let o=c+1;o<l.length&&o<=c+8;o++){let f=l[o]??"";if(o>c&&Se(f)||(s=o,f.trim()===""&&o>c+1))break}return l.slice(c,s+1).join(`
|
|
3
|
-
`)}return l.slice(n,Math.min(l.length,n+8)).join(`
|
|
4
|
-
`)}function Q(e,i){if(!e)return new Set;let n=new Set(["public","private","protected","final","static","class","def","fun","fn","function","return","string","bool","boolean","void","unit","self","this","new","const","let","var","end","pub"]),t=be(i),l=e.replace(/["'`]/g," ").replace(/\b\d+\b/g," NUM ").replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/[^A-Za-z0-9_]+/g," ").replace(/_/g," ").toLowerCase().split(/\s+/).map(a=>a.trim()).filter(a=>a.length>1).filter(a=>!n.has(a)).filter(a=>!t.has(a));return new Set(l)}function be(e){return new Set(e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").split(/[^A-Za-z0-9_]+|_/).map(i=>i.toLowerCase()).filter(i=>i.length>1))}function Se(e){return/^\s*(?:def|fun|fn|function|class|trait|module|object|enum|interface|public|private|protected)\b/.test(e)}function x(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}export{Fe as a,De as b,ee as c,G as d,U as e,K as f};
|
|
5
|
-
//# sourceMappingURL=chunk-MHTDOFV7.js.map
|
package/dist/chunk-NP5HYVLX.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import{a as S}from"./chunk-3ZYF3ELZ.js";import{e as b}from"./chunk-FUPDW5AC.js";import{c as p,f as h,h as y}from"./chunk-JM72FNGA.js";import{execFileSync as d}from"child_process";import{existsSync as x,readFileSync as N}from"fs";import{basename as C}from"path";var v="Unable to compute git diff.";function le(e,n={}){let t=n.plan??P(e,n);return t.note?A(t.note,t.changedFileLines):t.changedFiles.length===0?O(t.changedFileLines):T(t.changedFiles,[E(e,t.changedFiles,t.changedFiles,t.changedRanges)])}function P(e,n={}){let{base:t="HEAD"}=n;try{let i=$(e.config.projectRoot,t),r=J(e,i),s=G(e,k(e.config.projectRoot,t));return{changedFileLines:i,changedFiles:r,changedRanges:s,renamedFiles:B(e.config.projectRoot,t,r),note:i.length===0?"No changed files found.":void 0}}catch{return{changedFileLines:[],changedFiles:[],changedRanges:[],renamedFiles:[],note:v}}}function E(e,n,t,i=[]){let r=new S(e),s=new Set(t),a=q(i),l=[],m=new Map,f=n.flatMap(o=>r.definitionsForFile(o)).filter(ee).filter(o=>V(o,a)).sort((o,u)=>o.relativePath.localeCompare(u.relativePath)||o.startLine-u.startLine),c=f.map(o=>o.symbolId),g=K(e,c),w=Q(e,c,t),M=b(e,f.filter(o=>g.get(o.symbolId)===0));for(let o of f)j(e,o,s,l,m,M.get(o.symbolId)??new Set,g.get(o.symbolId)??0,w.get(o.symbolId)??new Set);return{changedSymbols:l,consumerEntries:[...m.entries()].map(([o,u])=>({file:o,symbols:[...u].sort()}))}}function T(e,n){let t=new Map,i=n.flatMap(s=>s.changedSymbols);for(let s of n)for(let a of s.consumerEntries){let l=t.get(a.file);l||(l=new Set,t.set(a.file,l));for(let m of a.symbols)l.add(m)}let r=X(t);return{changedFiles:[...e],changedSymbols:i,affectedConsumers:r,summary:{totalChangedFiles:e.length,totalChangedSymbols:i.length,totalAffectedFiles:r.length}}}function A(e,n=[]){return{changedFiles:n,changedSymbols:[],affectedConsumers:[],summary:{totalChangedFiles:n.length,totalChangedSymbols:0,totalAffectedFiles:0,note:e}}}function O(e){return{changedFiles:e,changedSymbols:[],affectedConsumers:[],summary:{totalChangedFiles:e.length,totalChangedSymbols:0,totalAffectedFiles:0,note:"Changed files are not present in the current SCIP index."}}}function $(e,n){let t=d("git",["diff","--name-only",n],{encoding:"utf-8",cwd:e,timeout:1e4}),i=d("git",["diff","--name-only","--cached",n],{encoding:"utf-8",cwd:e,timeout:1e4}),r=d("git",["ls-files","--others","--exclude-standard"],{encoding:"utf-8",cwd:e,timeout:1e4});return[...new Set([t,i,r].flatMap(s=>s.split(`
|
|
2
|
-
`)).map(s=>s.trim()).filter(s=>s.length>0))]}function k(e,n){let t=d("git",["diff","--unified=0",n],{encoding:"utf-8",cwd:e,timeout:1e4}),i=d("git",["diff","--unified=0","--cached",n],{encoding:"utf-8",cwd:e,timeout:1e4});return _([...L(t),...L(i)])}function z(e,n,t){try{return d("git",["show",`${n}:./${t}`],{encoding:"utf-8",cwd:e,timeout:1e4,stdio:["ignore","pipe","ignore"]})}catch{return null}}function B(e,n,t){if(t.length===0)return[];let i=new Map,r=new Set;for(let a of U(e,n))t.includes(a.to)&&(i.set(a.to,a),r.add(a.from));let s=W(e,n);if(s.length===0)return[...i.values()].sort((a,l)=>a.to.localeCompare(l.to));for(let a of t){if(i.has(a)||!x(`${e}/${a}`))continue;let l=s.filter(c=>!r.has(c)).filter(c=>C(c)===C(a));if(l.length===0)continue;let m=N(`${e}/${a}`,"utf-8"),f=l.map(c=>({from:c,to:a,similarity:H(z(e,n,c)??"",m)})).sort((c,g)=>g.similarity-c.similarity)[0];f&&f.similarity>=.45&&(i.set(a,f),r.add(f.from))}return[...i.values()].sort((a,l)=>a.to.localeCompare(l.to))}function W(e,n){let t=d("git",["diff","--name-only","--diff-filter=D",n],{encoding:"utf-8",cwd:e,timeout:1e4}),i=d("git",["diff","--name-only","--diff-filter=D","--cached",n],{encoding:"utf-8",cwd:e,timeout:1e4});return[...new Set([...R(t),...R(i)])]}function U(e,n){let t=d("git",["diff","--name-status","--find-renames",n],{encoding:"utf-8",cwd:e,timeout:1e4}),i=d("git",["diff","--name-status","--find-renames","--cached",n],{encoding:"utf-8",cwd:e,timeout:1e4});return[...t.split(`
|
|
3
|
-
`),...i.split(`
|
|
4
|
-
`)].map(r=>r.trim()).filter(r=>r.startsWith("R")).map(r=>r.split(" ")).filter(r=>r.length>=3).map(([r,s,a])=>({from:s,to:a,similarity:Number(r.slice(1))/100}))}function H(e,n){let t=new Set(I(e)),i=new Set(I(n));if(t.size===0&&i.size===0)return 1;if(t.size===0||i.size===0)return 0;let r=0;for(let s of t)i.has(s)&&(r+=1);return 2*r/(t.size+i.size)}function I(e){return e.match(/[A-Za-z_$][\w$]*|[{}()[\].,]/g)??[]}function R(e){return e.split(`
|
|
5
|
-
`).map(n=>n.trim()).filter(n=>n.length>0)}function J(e,n){let t=F(e),i=[];for(let r of n){let s=t(r);s&&!e.isIgnored(s)&&i.push(s)}return i}function G(e,n){let t=F(e),i=[];for(let r of n){let s=t(r.file);s&&!e.isIgnored(s)&&i.push({...r,file:s})}return _(i)}function F(e){let n=e.all(`SELECT relative_path FROM documents
|
|
6
|
-
ORDER BY id`).map(i=>i.relative_path),t=new Map(n.map(i=>[i,i]));return i=>{let r=i.replace(/\\/g,"/"),s=t.get(r);return s||(n.find(a=>a.endsWith(r))??null)}}function L(e){let n=[],t=null;for(let i of e.split(`
|
|
7
|
-
`)){if(i.startsWith("+++ ")){t=Y(i.slice(4).trim());continue}if(!t||!i.startsWith("@@ "))continue;let r=/@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/.exec(i);if(!r)continue;let s=Math.max(0,Number(r[1])-1),a=r[2]===void 0?1:Number(r[2]);n.push({file:t,startLine:s,endLine:Math.max(s,s+Math.max(a,1)-1)})}return n}function Y(e){return e==="/dev/null"?null:e.startsWith("a/")||e.startsWith("b/")?e.slice(2):e}function _(e){let n=new Set,t=[];for(let i of e){let r=`${i.file}:${i.startLine}:${i.endLine}`;n.has(r)||(n.add(r),t.push(i))}return t}function q(e){let n=new Map;for(let t of e){let i=n.get(t.file);i||(i=[],n.set(t.file,i)),i.push(t)}return n}function V(e,n){let t=n.get(e.relativePath);return!t||t.length===0?!0:t.some(i=>Z(e.startLine,e.endLine,i.startLine,i.endLine))}function Z(e,n,t,i){return e<=i&&t<=n}function j(e,n,t,i,r,s,a,l){let m=Math.max(a,s.size);if(!ne(n,m))return;let f=p(n.symbol);i.push({symbol:n.symbol,shortName:f,file:n.relativePath,startLine:n.startLine,endLine:n.endLine,fanIn:m});for(let c of l)D(e,t,r,c,f);for(let c of s)D(e,t,r,c,f)}function K(e,n){if(n.length===0)return new Map;let t=e.all(`SELECT m.symbol_id, COUNT(DISTINCT c.document_id) AS fan_in
|
|
8
|
-
FROM mentions m
|
|
9
|
-
JOIN chunks c ON m.chunk_id = c.id
|
|
10
|
-
WHERE m.symbol_id IN (${n.map(()=>"?").join(",")})
|
|
11
|
-
AND m.role != 1
|
|
12
|
-
GROUP BY m.symbol_id`,...n);return new Map(t.map(i=>[i.symbol_id,i.fan_in]))}function Q(e,n,t){if(n.length===0||t.length===0)return new Map;let i=e.all(`SELECT DISTINCT m.symbol_id, ref_d.relative_path
|
|
13
|
-
FROM mentions m
|
|
14
|
-
JOIN chunks c ON m.chunk_id = c.id
|
|
15
|
-
JOIN documents ref_d ON c.document_id = ref_d.id
|
|
16
|
-
WHERE m.symbol_id IN (${n.map(()=>"?").join(",")})
|
|
17
|
-
AND m.role != 1
|
|
18
|
-
AND ref_d.relative_path NOT IN (${t.map(()=>"?").join(",")})
|
|
19
|
-
${e.pathExclusionsFor("ref_d")}`,...n,...t),r=new Map;for(let s of i){let a=r.get(s.symbol_id);a||(a=new Set,r.set(s.symbol_id,a)),a.add(s.relative_path)}return r}function D(e,n,t,i,r){if(e.isIgnored(i)||n.has(i))return;let s=t.get(i);s||(s=new Set,t.set(i,s)),s.add(r)}function X(e){return[...e.entries()].map(([n,t])=>({file:n,consumedSymbols:t.size})).sort((n,t)=>t.consumedSymbols-n.consumedSymbols)}function ee(e){return!(y(e.symbol)||e.parentTypeName!==null&&!h(e.symbol))}function ne(e,n){return h(e.symbol)||e.isTypeLike?!0:e.parentTypeName===null&&n>0}export{v as a,le as b,P as c,E as d,T as e,z as f};
|
|
20
|
-
//# sourceMappingURL=chunk-NP5HYVLX.js.map
|
package/dist/chunk-O4L4AB3T.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as V}from"./chunk-PVZMPG5I.js";import{a as v,b,c as R}from"./chunk-3UVJJ6Z7.js";import{c as B}from"./chunk-ERHOS6AW.js";function L(e,s={}){let{minSimilarity:i=.45,minSharedBehaviors:t=6,limit:n=20,scope:a,scanLimit:l,filePattern:c}=s,h=B(e,{scope:a,minBehaviorTokens:Math.max(3,t),scanLimit:l}).map(o=>({file:o.file,tokens:o.behaviorTokens,profile:o}));return V({profiles:h,limit:n,filePattern:c,compare:(o,r)=>w(o,r,i,t),sort:(o,r)=>r.similarity-o.similarity||o.fileA.localeCompare(r.fileA)||o.fileB.localeCompare(r.fileB)})}function w(e,s,i,t){let n=v(e.tokens,s.tokens);if(n.size<t||!q(n))return null;let a=P(e.tokens,s.tokens);if(a<i)return null;let l=d(n,"composable:"),c=d(n,"store:"),h=d(n,"reactivity:"),o=d(n,"lifecycle:"),r=d(n,"request:"),f=d(n,"function:"),g=d(n,"function-verb:"),p=d(n,"template-binding:"),C=d(n,"template-event:"),m=k({sharedComposables:l,sharedStores:c,sharedReactivity:h,sharedLifecycle:o,sharedRequests:r,sharedFunctions:f,sharedFunctionVerbs:g,sharedBindings:p,sharedTemplateEvents:C});return{fileA:e.file,fileB:s.file,similarity:a,sharedTokens:y(n),sharedComposables:l,sharedStores:c,sharedReactivity:h,sharedLifecycle:o,sharedRequests:r,sharedFunctions:f,sharedFunctionVerbs:g,sharedBindings:p,sharedTemplateEvents:C,evidenceClass:m.evidenceClass,actionTier:m.actionTier,evidenceClassReasons:m.reasons,recommendation:m.recommendation,uniqueToA:y(b(e.tokens,s.tokens)).slice(0,25),uniqueToB:y(b(s.tokens,e.tokens)).slice(0,25),reason:$({sharedComposables:l,sharedStores:c,sharedRequests:r,sharedLifecycle:o,sharedFunctions:f,sharedFunctionVerbs:g,sharedBindings:p}),locA:e.profile.totalLines,locB:s.profile.totalLines}}function k(e){let s=[],i=[],t=[];e.sharedReactivity.length&&i.push(`shared reactivity primitive: ${e.sharedReactivity.join(", ")}`),e.sharedLifecycle.length&&i.push(`shared lifecycle primitive: ${e.sharedLifecycle.join(", ")}`),u(e.sharedComposables,"shared composable",s,t),u(e.sharedStores,"shared store",s,t),u(e.sharedRequests,"shared request",s,i),u(e.sharedFunctions,"shared function",s,i),u(e.sharedFunctionVerbs,"shared action verb",s,i),u(e.sharedBindings,"shared binding",s,i),u(e.sharedTemplateEvents,"shared template event",s,i);let n=s.length>0,a=i.length>0,l=t.length>0,c=n?a||l?"mixed":"domain-behavior":l?"shared-abstraction":"generic-workflow-scaffolding";return{actionTier:c==="domain-behavior"||c==="mixed"?"signal":"support",evidenceClass:c,reasons:[...s,...t,...i].slice(0,6),recommendation:A(c)}}function u(e,s,i,t){let n=[],a=[];for(let l of e)S(l)?n.push(l):a.push(l);n.length&&i.push(`${s} has domain term(s): ${n.slice(0,6).join(", ")}`),a.length&&t.push(`${s} is generic workflow: ${a.slice(0,6).join(", ")}`)}function S(e){return T(e).filter(i=>!F.has(i)).length>0}function T(e){return e.replace(/([A-Z])([A-Z][a-z])/g,"$1 $2").replace(/([a-z0-9])([A-Z])/g,"$1 $2").toLowerCase().split(/[^a-z0-9]+/).filter(Boolean)}function A(e){switch(e){case"domain-behavior":return"Review for a shared composable, store, or feature module around the named domain behavior.";case"mixed":return"Separate generic Vue mechanics from domain-specific behavior before extracting a composable.";case"shared-abstraction":return"Review the existing composable/store usage first; extract only if duplicated behavior remains outside it.";case"generic-workflow-scaffolding":return"Treat as support evidence for a repeated workflow shape, not direct composable-extraction evidence."}}function P(e,s){if(e.size===0||s.size===0)return 0;let t=v(e,s).size/Math.min(e.size,s.size);return Math.max(R(e,s),t)}function q(e){let s=0,i=0,t=0,n=0,a=0,l=0,c=0;for(let r of e)r.startsWith("composable:")?s+=1:r.startsWith("store:")?i+=1:r.startsWith("request:")?t+=1:r.startsWith("lifecycle:")?n+=1:r.startsWith("function:")?a+=1:r.startsWith("reactivity:")?l+=1:(r.startsWith("function-verb:")||r.startsWith("template-binding:")||r.startsWith("template-event:"))&&(c+=1);let h=s+i,o=h+t+n+a+c;return t>=1&&o>=4||n>=1&&a>=2&&o>=4||h>=2&&(t>=1||a>=2)&&o>=5||a>=2&&l>=1&&o>=4}function $(e){let s=[];return e.sharedComposables.length&&s.push(`shared composables: ${e.sharedComposables.join(", ")}`),e.sharedStores.length&&s.push(`shared stores: ${e.sharedStores.join(", ")}`),e.sharedRequests.length&&s.push(`shared request helpers: ${e.sharedRequests.join(", ")}`),e.sharedLifecycle.length&&s.push(`shared lifecycle: ${e.sharedLifecycle.join(", ")}`),e.sharedFunctions.length&&s.push(`shared functions: ${e.sharedFunctions.slice(0,6).join(", ")}`),e.sharedFunctionVerbs.length&&s.push(`shared action verbs: ${e.sharedFunctionVerbs.slice(0,6).join(", ")}`),e.sharedBindings.length&&s.push(`shared template bindings: ${e.sharedBindings.slice(0,6).join(", ")}`),s.join("; ")||"shared Vue behavior profile"}function d(e,s){return[...e].filter(i=>i.startsWith(s)).map(i=>i.slice(s.length)).sort()}function y(e){return[...e].sort()}var F=new Set(["add","apply","cancel","change","clear","close","composable","create","data","delete","draft","edit","error","fetch","filter","form","item","items","load","loading","name","open","reactive","ref","refresh","remove","request","reset","resource","row","rows","save","saving","search","select","selected","store","submit","toggle","update","use","value","watch"]);export{L as a};
|
|
2
|
-
//# sourceMappingURL=chunk-O4L4AB3T.js.map
|