canicode 0.10.1 → 0.10.3
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 +3 -1
- package/dist/cli/index.js +95 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +20 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +57 -2
- package/dist/mcp/server.js.map +1 -1
- package/package.json +2 -2
- package/skills/canicode-roundtrip/SKILL.md +122 -19
- package/skills/canicode-roundtrip/helpers.js +54 -10
package/dist/mcp/server.js
CHANGED
|
@@ -1753,7 +1753,7 @@ function computeApplyContext(violation, instanceContext) {
|
|
|
1753
1753
|
}
|
|
1754
1754
|
|
|
1755
1755
|
// package.json
|
|
1756
|
-
var version = "0.10.
|
|
1756
|
+
var version = "0.10.3";
|
|
1757
1757
|
|
|
1758
1758
|
// src/core/engine/scoring.ts
|
|
1759
1759
|
function computeTotalScorePerCategory(configs) {
|
|
@@ -2093,7 +2093,8 @@ function generateGotchaSurvey(result, scores) {
|
|
|
2093
2093
|
);
|
|
2094
2094
|
const deduped = deduplicateSiblingIssues(relevantIssues);
|
|
2095
2095
|
const sorted = stableSortBySeverity(deduped);
|
|
2096
|
-
const
|
|
2096
|
+
const mapped = sorted.map((issue) => mapToQuestion(issue, result.file)).filter((q) => q !== null);
|
|
2097
|
+
const questions = deduplicateBySourceComponent(mapped);
|
|
2097
2098
|
return {
|
|
2098
2099
|
designGrade: grade,
|
|
2099
2100
|
isReadyForCodeGen: isReadyForCodeGen(grade),
|
|
@@ -2163,6 +2164,50 @@ function mapToQuestion(issue, file) {
|
|
|
2163
2164
|
...applyContext.sourceChildId !== void 0 ? { sourceChildId: applyContext.sourceChildId } : {}
|
|
2164
2165
|
};
|
|
2165
2166
|
}
|
|
2167
|
+
function deduplicateBySourceComponent(questions) {
|
|
2168
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2169
|
+
const order = [];
|
|
2170
|
+
let uniqueCounter = 0;
|
|
2171
|
+
for (const q of questions) {
|
|
2172
|
+
const ic = q.instanceContext;
|
|
2173
|
+
let key;
|
|
2174
|
+
if (ic && ic.sourceComponentId && ic.sourceNodeId) {
|
|
2175
|
+
key = `${ic.sourceComponentId}::${ic.sourceNodeId}::${q.ruleId}`;
|
|
2176
|
+
} else {
|
|
2177
|
+
key = `__unique__${uniqueCounter++}`;
|
|
2178
|
+
}
|
|
2179
|
+
const bucket = groups.get(key);
|
|
2180
|
+
if (bucket) {
|
|
2181
|
+
bucket.push(q);
|
|
2182
|
+
} else {
|
|
2183
|
+
groups.set(key, [q]);
|
|
2184
|
+
order.push(key);
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
return order.map((key) => {
|
|
2188
|
+
const group = groups.get(key);
|
|
2189
|
+
const first = group[0];
|
|
2190
|
+
if (group.length === 1) return first;
|
|
2191
|
+
const otherIds = group.slice(1).map((q) => q.nodeId);
|
|
2192
|
+
const sourceComponentName = first.instanceContext?.sourceComponentName;
|
|
2193
|
+
const template = GOTCHA_QUESTIONS[first.ruleId];
|
|
2194
|
+
const renamed = {
|
|
2195
|
+
...first,
|
|
2196
|
+
replicas: group.length,
|
|
2197
|
+
replicaNodeIds: otherIds
|
|
2198
|
+
};
|
|
2199
|
+
if (sourceComponentName) {
|
|
2200
|
+
renamed.nodeName = sourceComponentName;
|
|
2201
|
+
if (template) {
|
|
2202
|
+
renamed.question = template.question.replace(
|
|
2203
|
+
"{nodeName}",
|
|
2204
|
+
sourceComponentName
|
|
2205
|
+
);
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
return renamed;
|
|
2209
|
+
});
|
|
2210
|
+
}
|
|
2166
2211
|
function buildInstanceContext(nodeId, file) {
|
|
2167
2212
|
const parts = parseInstanceChildNodeId(nodeId);
|
|
2168
2213
|
if (!parts) return null;
|
|
@@ -4695,6 +4740,15 @@ function hasStateInComponentMaster(node, context, statePattern) {
|
|
|
4695
4740
|
if (!master) return false;
|
|
4696
4741
|
return hasStateInVariantProps(master, statePattern);
|
|
4697
4742
|
}
|
|
4743
|
+
function canDetermineVariants(node, context) {
|
|
4744
|
+
if (node.type === "COMPONENT") return true;
|
|
4745
|
+
if (node.componentPropertyDefinitions !== void 0) return true;
|
|
4746
|
+
if (node.componentId !== void 0) {
|
|
4747
|
+
const defs = context.file.componentDefinitions;
|
|
4748
|
+
if (defs && defs[node.componentId] !== void 0) return true;
|
|
4749
|
+
}
|
|
4750
|
+
return false;
|
|
4751
|
+
}
|
|
4698
4752
|
var missingInteractionStateDef = {
|
|
4699
4753
|
id: "missing-interaction-state",
|
|
4700
4754
|
name: "Missing Interaction State",
|
|
@@ -4709,6 +4763,7 @@ var missingInteractionStateCheck = (node, context) => {
|
|
|
4709
4763
|
if (!interactiveType) return null;
|
|
4710
4764
|
const expectedStates = EXPECTED_STATES[interactiveType];
|
|
4711
4765
|
if (!expectedStates) return null;
|
|
4766
|
+
if (!canDetermineVariants(node, context)) return null;
|
|
4712
4767
|
const seen = getSeen(context);
|
|
4713
4768
|
const nodePath = context.path.join(" > ");
|
|
4714
4769
|
for (const state of expectedStates) {
|