canicode 0.10.5 → 0.11.0
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 -2
- package/dist/cli/index.js +546 -138
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +254 -19
- package/dist/index.js +243 -70
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +229 -78
- package/dist/mcp/server.js.map +1 -1
- package/docs/CUSTOMIZATION.md +39 -3
- package/package.json +1 -1
- package/skills/canicode-gotchas/SKILL.md +17 -14
- package/skills/canicode-roundtrip/SKILL.md +12 -11
- package/skills/canicode-roundtrip/helpers.js +1 -1
- package/skills/cursor/canicode/SKILL.md +76 -0
- package/skills/cursor/canicode-gotchas/SKILL.md +199 -0
- package/skills/cursor/canicode-roundtrip/SKILL.md +618 -0
- package/skills/cursor/canicode-roundtrip/helpers.js +523 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { GetFileResponse, Node } from '@figma/rest-api-spec';
|
|
3
3
|
|
|
4
|
-
var version = "0.
|
|
4
|
+
var version = "0.11.0";
|
|
5
5
|
|
|
6
6
|
declare const SeveritySchema: z.ZodEnum<{
|
|
7
7
|
blocking: "blocking";
|
|
@@ -13,17 +13,40 @@ type Severity = z.infer<typeof SeveritySchema>;
|
|
|
13
13
|
declare const SEVERITY_WEIGHT: Record<Severity, number>;
|
|
14
14
|
declare const SEVERITY_LABELS: Record<Severity, string>;
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
/**
|
|
17
|
+
* #402 shared output-channel vocabulary.
|
|
18
|
+
* Detection stays rule-based; output channel and persistence intent vary by
|
|
19
|
+
* consumer payload (score/transient vs annotation/durable).
|
|
20
|
+
*/
|
|
21
|
+
declare const DetectionSchema: z.ZodLiteral<"rule-based">;
|
|
22
|
+
declare const OutputChannelSchema: z.ZodEnum<{
|
|
23
|
+
score: "score";
|
|
24
|
+
annotation: "annotation";
|
|
23
25
|
}>;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
declare const PersistenceIntentSchema: z.ZodEnum<{
|
|
27
|
+
transient: "transient";
|
|
28
|
+
durable: "durable";
|
|
29
|
+
}>;
|
|
30
|
+
type Detection = z.infer<typeof DetectionSchema>;
|
|
31
|
+
type OutputChannel = z.infer<typeof OutputChannelSchema>;
|
|
32
|
+
type PersistenceIntent = z.infer<typeof PersistenceIntentSchema>;
|
|
33
|
+
/**
|
|
34
|
+
* #406 rule purpose classification.
|
|
35
|
+
* - `violation`: score-primary. Node is violating a best-practice expectation;
|
|
36
|
+
* fixing the violation removes the rule fire. Gotcha question is secondary
|
|
37
|
+
* context about how to resolve the violation.
|
|
38
|
+
* - `info-collection`: annotation-primary. Node is not necessarily "wrong,"
|
|
39
|
+
* but implementation-critical context is absent from Figma (e.g. click
|
|
40
|
+
* target, interaction states). Gotcha question is the primary output;
|
|
41
|
+
* score impact is intentionally minimal (typically -1 or 0).
|
|
42
|
+
*
|
|
43
|
+
* Detection stays `rule-based` in both cases — see ADR-017.
|
|
44
|
+
*/
|
|
45
|
+
declare const RulePurposeSchema: z.ZodEnum<{
|
|
46
|
+
violation: "violation";
|
|
47
|
+
"info-collection": "info-collection";
|
|
48
|
+
}>;
|
|
49
|
+
type RulePurpose = z.infer<typeof RulePurposeSchema>;
|
|
27
50
|
|
|
28
51
|
/**
|
|
29
52
|
* Figma node types required for analysis
|
|
@@ -308,6 +331,51 @@ declare const AnalysisFileSchema: z.ZodObject<{
|
|
|
308
331
|
}, z.core.$strip>;
|
|
309
332
|
type AnalysisFile = z.infer<typeof AnalysisFileSchema>;
|
|
310
333
|
|
|
334
|
+
/**
|
|
335
|
+
* #404: Analysis scope — what the user is asking canicode to reason about.
|
|
336
|
+
*
|
|
337
|
+
* - `page`: full screen / section / layout. Container frames are
|
|
338
|
+
* responsible for bounds; repetition detection is meaningful; rules
|
|
339
|
+
* that assume "this is a self-contained screen" apply.
|
|
340
|
+
* - `component`: standalone reusable UI unit (COMPONENT / COMPONENT_SET
|
|
341
|
+
* / INSTANCE analyzed in isolation). Root FILL is the design contract
|
|
342
|
+
* rather than a missing bound; repetition detection is generally a
|
|
343
|
+
* false signal because a component is itself the unit of reuse.
|
|
344
|
+
*
|
|
345
|
+
* The enum is intentionally two-valued; multi-scope analysis (analyzing
|
|
346
|
+
* a page and its inner components in one run) is explicitly out of scope
|
|
347
|
+
* per the issue. Each rule decides how (or whether) to switch on `scope`;
|
|
348
|
+
* this PR only carries the context. Rule-level consumption lands in
|
|
349
|
+
* follow-up PRs (e.g. #403 for `missing-size-constraint`).
|
|
350
|
+
*/
|
|
351
|
+
declare const AnalysisScopeSchema: z.ZodEnum<{
|
|
352
|
+
page: "page";
|
|
353
|
+
component: "component";
|
|
354
|
+
}>;
|
|
355
|
+
type AnalysisScope = z.infer<typeof AnalysisScopeSchema>;
|
|
356
|
+
/**
|
|
357
|
+
* Deterministically detect analysis scope from the root node type. Returns
|
|
358
|
+
* `"component"` for `COMPONENT` / `COMPONENT_SET` / `INSTANCE` roots, and
|
|
359
|
+
* `"page"` for everything else.
|
|
360
|
+
*
|
|
361
|
+
* The CLI / MCP layer may override this with an explicit `scope` flag when
|
|
362
|
+
* the user knows the heuristic mis-detects (e.g. analyzing a FRAME that
|
|
363
|
+
* ships as a standalone design-system example rather than a screen).
|
|
364
|
+
*/
|
|
365
|
+
declare function detectAnalysisScope(rootNode: AnalysisNode): AnalysisScope;
|
|
366
|
+
|
|
367
|
+
declare const CategorySchema: z.ZodEnum<{
|
|
368
|
+
"pixel-critical": "pixel-critical";
|
|
369
|
+
"responsive-critical": "responsive-critical";
|
|
370
|
+
"code-quality": "code-quality";
|
|
371
|
+
"token-management": "token-management";
|
|
372
|
+
semantic: "semantic";
|
|
373
|
+
interaction: "interaction";
|
|
374
|
+
}>;
|
|
375
|
+
type Category = z.infer<typeof CategorySchema>;
|
|
376
|
+
declare const CATEGORIES: ("pixel-critical" | "responsive-critical" | "code-quality" | "token-management" | "semantic" | "interaction")[];
|
|
377
|
+
declare const CATEGORY_LABELS: Record<Category, string>;
|
|
378
|
+
|
|
311
379
|
/**
|
|
312
380
|
* Rule definition - static metadata (does not change)
|
|
313
381
|
*/
|
|
@@ -359,6 +427,28 @@ interface RuleContext {
|
|
|
359
427
|
siblings?: AnalysisNode[] | undefined;
|
|
360
428
|
/** Per-analysis shared state. Created fresh for each analysis run, eliminating module-level mutable state. */
|
|
361
429
|
analysisState: Map<string, unknown>;
|
|
430
|
+
/**
|
|
431
|
+
* #404: Scope of the analysis root (`page` vs `component`). Rules use
|
|
432
|
+
* this to decide whether expectations like "container must define
|
|
433
|
+
* bounds" or "repetition should become a component" apply. Constant for
|
|
434
|
+
* all nodes in a single analysis — whether the CURRENT node happens to
|
|
435
|
+
* be a `COMPONENT` descendant of a page root is already signalled by
|
|
436
|
+
* `componentDepth`, not by re-deriving scope per node.
|
|
437
|
+
*/
|
|
438
|
+
scope: AnalysisScope;
|
|
439
|
+
/**
|
|
440
|
+
* #403: Figma node type of the analysis root, captured once in
|
|
441
|
+
* `RuleEngine.analyze`. This is an *axis orthogonal to* `scope`:
|
|
442
|
+
* `scope === "component"` does not tell a rule whether the root is a
|
|
443
|
+
* `COMPONENT`/`COMPONENT_SET` (component being audited) or an
|
|
444
|
+
* `INSTANCE` (component being used, possibly with overrides). The
|
|
445
|
+
* `missing-size-constraint` redesign needs that distinction so the
|
|
446
|
+
* gotcha question can ask the right thing — "intentionally
|
|
447
|
+
* non-responsive?" vs "override intended? original may be FILL". The
|
|
448
|
+
* value is the raw Figma node type string (no new enum) so it stays in
|
|
449
|
+
* sync with `AnalysisNode.type` without a translation layer.
|
|
450
|
+
*/
|
|
451
|
+
rootNodeType: string;
|
|
362
452
|
}
|
|
363
453
|
/**
|
|
364
454
|
* Get or initialize per-analysis state for a rule.
|
|
@@ -522,6 +612,10 @@ declare const McpAnalyzeResponseSchema: z.ZodObject<{
|
|
|
522
612
|
fileName: z.ZodString;
|
|
523
613
|
nodeCount: z.ZodNumber;
|
|
524
614
|
maxDepth: z.ZodNumber;
|
|
615
|
+
scope: z.ZodEnum<{
|
|
616
|
+
page: "page";
|
|
617
|
+
component: "component";
|
|
618
|
+
}>;
|
|
525
619
|
issueCount: z.ZodNumber;
|
|
526
620
|
isReadyForCodeGen: z.ZodBoolean;
|
|
527
621
|
blockingIssueCount: z.ZodNumber;
|
|
@@ -577,6 +671,17 @@ declare const McpAnalyzeResponseSchema: z.ZodObject<{
|
|
|
577
671
|
issuesByRule: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
578
672
|
issues: z.ZodArray<z.ZodObject<{
|
|
579
673
|
ruleId: z.ZodString;
|
|
674
|
+
detection: z.ZodLiteral<"rule-based">;
|
|
675
|
+
outputChannel: z.ZodEnum<{
|
|
676
|
+
score: "score";
|
|
677
|
+
}>;
|
|
678
|
+
persistenceIntent: z.ZodEnum<{
|
|
679
|
+
transient: "transient";
|
|
680
|
+
}>;
|
|
681
|
+
purpose: z.ZodEnum<{
|
|
682
|
+
violation: "violation";
|
|
683
|
+
"info-collection": "info-collection";
|
|
684
|
+
}>;
|
|
580
685
|
subType: z.ZodOptional<z.ZodString>;
|
|
581
686
|
severity: z.ZodEnum<{
|
|
582
687
|
blocking: "blocking";
|
|
@@ -606,9 +711,9 @@ type InstanceContext = z.infer<typeof InstanceContextSchema>;
|
|
|
606
711
|
* declared as a Zod enum here so MCP responses validate end-to-end.
|
|
607
712
|
*/
|
|
608
713
|
declare const RuleApplyStrategySchema: z.ZodEnum<{
|
|
714
|
+
annotation: "annotation";
|
|
609
715
|
"property-mod": "property-mod";
|
|
610
716
|
"structural-mod": "structural-mod";
|
|
611
|
-
annotation: "annotation";
|
|
612
717
|
"auto-fix": "auto-fix";
|
|
613
718
|
}>;
|
|
614
719
|
type RuleApplyStrategy = z.infer<typeof RuleApplyStrategySchema>;
|
|
@@ -620,10 +725,33 @@ type RuleApplyStrategy = z.infer<typeof RuleApplyStrategySchema>;
|
|
|
620
725
|
declare const AnnotationPropertySchema: z.ZodObject<{
|
|
621
726
|
type: z.ZodString;
|
|
622
727
|
}, z.core.$strip>;
|
|
728
|
+
/**
|
|
729
|
+
* #402: Gotcha output is generated by a rule-based detection pass but flows
|
|
730
|
+
* to the annotation channel (not the score channel). Answers are durable
|
|
731
|
+
* context intended to survive beyond a single re-analysis cycle.
|
|
732
|
+
*/
|
|
733
|
+
declare const GotchaDetectionSchema: z.ZodLiteral<"rule-based">;
|
|
734
|
+
declare const GotchaOutputChannelSchema: z.ZodEnum<{
|
|
735
|
+
annotation: "annotation";
|
|
736
|
+
}>;
|
|
737
|
+
declare const GotchaPersistenceIntentSchema: z.ZodEnum<{
|
|
738
|
+
durable: "durable";
|
|
739
|
+
}>;
|
|
623
740
|
declare const GotchaSurveyQuestionSchema: z.ZodObject<{
|
|
624
741
|
nodeId: z.ZodString;
|
|
625
742
|
nodeName: z.ZodString;
|
|
626
743
|
ruleId: z.ZodString;
|
|
744
|
+
detection: z.ZodLiteral<"rule-based">;
|
|
745
|
+
outputChannel: z.ZodEnum<{
|
|
746
|
+
annotation: "annotation";
|
|
747
|
+
}>;
|
|
748
|
+
persistenceIntent: z.ZodEnum<{
|
|
749
|
+
durable: "durable";
|
|
750
|
+
}>;
|
|
751
|
+
purpose: z.ZodEnum<{
|
|
752
|
+
violation: "violation";
|
|
753
|
+
"info-collection": "info-collection";
|
|
754
|
+
}>;
|
|
627
755
|
severity: z.ZodEnum<{
|
|
628
756
|
blocking: "blocking";
|
|
629
757
|
risk: "risk";
|
|
@@ -640,9 +768,9 @@ declare const GotchaSurveyQuestionSchema: z.ZodObject<{
|
|
|
640
768
|
sourceComponentName: z.ZodOptional<z.ZodString>;
|
|
641
769
|
}, z.core.$strip>>;
|
|
642
770
|
applyStrategy: z.ZodEnum<{
|
|
771
|
+
annotation: "annotation";
|
|
643
772
|
"property-mod": "property-mod";
|
|
644
773
|
"structural-mod": "structural-mod";
|
|
645
|
-
annotation: "annotation";
|
|
646
774
|
"auto-fix": "auto-fix";
|
|
647
775
|
}>;
|
|
648
776
|
targetProperty: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
@@ -675,6 +803,17 @@ declare const SurveyQuestionBatchSchema: z.ZodObject<{
|
|
|
675
803
|
nodeId: z.ZodString;
|
|
676
804
|
nodeName: z.ZodString;
|
|
677
805
|
ruleId: z.ZodString;
|
|
806
|
+
detection: z.ZodLiteral<"rule-based">;
|
|
807
|
+
outputChannel: z.ZodEnum<{
|
|
808
|
+
annotation: "annotation";
|
|
809
|
+
}>;
|
|
810
|
+
persistenceIntent: z.ZodEnum<{
|
|
811
|
+
durable: "durable";
|
|
812
|
+
}>;
|
|
813
|
+
purpose: z.ZodEnum<{
|
|
814
|
+
violation: "violation";
|
|
815
|
+
"info-collection": "info-collection";
|
|
816
|
+
}>;
|
|
678
817
|
severity: z.ZodEnum<{
|
|
679
818
|
blocking: "blocking";
|
|
680
819
|
risk: "risk";
|
|
@@ -691,9 +830,9 @@ declare const SurveyQuestionBatchSchema: z.ZodObject<{
|
|
|
691
830
|
sourceComponentName: z.ZodOptional<z.ZodString>;
|
|
692
831
|
}, z.core.$strip>>;
|
|
693
832
|
applyStrategy: z.ZodEnum<{
|
|
833
|
+
annotation: "annotation";
|
|
694
834
|
"property-mod": "property-mod";
|
|
695
835
|
"structural-mod": "structural-mod";
|
|
696
|
-
annotation: "annotation";
|
|
697
836
|
"auto-fix": "auto-fix";
|
|
698
837
|
}>;
|
|
699
838
|
targetProperty: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
@@ -723,6 +862,17 @@ declare const SurveyQuestionGroupSchema: z.ZodObject<{
|
|
|
723
862
|
nodeId: z.ZodString;
|
|
724
863
|
nodeName: z.ZodString;
|
|
725
864
|
ruleId: z.ZodString;
|
|
865
|
+
detection: z.ZodLiteral<"rule-based">;
|
|
866
|
+
outputChannel: z.ZodEnum<{
|
|
867
|
+
annotation: "annotation";
|
|
868
|
+
}>;
|
|
869
|
+
persistenceIntent: z.ZodEnum<{
|
|
870
|
+
durable: "durable";
|
|
871
|
+
}>;
|
|
872
|
+
purpose: z.ZodEnum<{
|
|
873
|
+
violation: "violation";
|
|
874
|
+
"info-collection": "info-collection";
|
|
875
|
+
}>;
|
|
726
876
|
severity: z.ZodEnum<{
|
|
727
877
|
blocking: "blocking";
|
|
728
878
|
risk: "risk";
|
|
@@ -739,9 +889,9 @@ declare const SurveyQuestionGroupSchema: z.ZodObject<{
|
|
|
739
889
|
sourceComponentName: z.ZodOptional<z.ZodString>;
|
|
740
890
|
}, z.core.$strip>>;
|
|
741
891
|
applyStrategy: z.ZodEnum<{
|
|
892
|
+
annotation: "annotation";
|
|
742
893
|
"property-mod": "property-mod";
|
|
743
894
|
"structural-mod": "structural-mod";
|
|
744
|
-
annotation: "annotation";
|
|
745
895
|
"auto-fix": "auto-fix";
|
|
746
896
|
}>;
|
|
747
897
|
targetProperty: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
@@ -773,6 +923,17 @@ declare const GroupedSurveySchema: z.ZodObject<{
|
|
|
773
923
|
nodeId: z.ZodString;
|
|
774
924
|
nodeName: z.ZodString;
|
|
775
925
|
ruleId: z.ZodString;
|
|
926
|
+
detection: z.ZodLiteral<"rule-based">;
|
|
927
|
+
outputChannel: z.ZodEnum<{
|
|
928
|
+
annotation: "annotation";
|
|
929
|
+
}>;
|
|
930
|
+
persistenceIntent: z.ZodEnum<{
|
|
931
|
+
durable: "durable";
|
|
932
|
+
}>;
|
|
933
|
+
purpose: z.ZodEnum<{
|
|
934
|
+
violation: "violation";
|
|
935
|
+
"info-collection": "info-collection";
|
|
936
|
+
}>;
|
|
776
937
|
severity: z.ZodEnum<{
|
|
777
938
|
blocking: "blocking";
|
|
778
939
|
risk: "risk";
|
|
@@ -789,9 +950,9 @@ declare const GroupedSurveySchema: z.ZodObject<{
|
|
|
789
950
|
sourceComponentName: z.ZodOptional<z.ZodString>;
|
|
790
951
|
}, z.core.$strip>>;
|
|
791
952
|
applyStrategy: z.ZodEnum<{
|
|
953
|
+
annotation: "annotation";
|
|
792
954
|
"property-mod": "property-mod";
|
|
793
955
|
"structural-mod": "structural-mod";
|
|
794
|
-
annotation: "annotation";
|
|
795
956
|
"auto-fix": "auto-fix";
|
|
796
957
|
}>;
|
|
797
958
|
targetProperty: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
@@ -826,6 +987,17 @@ declare const GotchaSurveySchema: z.ZodObject<{
|
|
|
826
987
|
nodeId: z.ZodString;
|
|
827
988
|
nodeName: z.ZodString;
|
|
828
989
|
ruleId: z.ZodString;
|
|
990
|
+
detection: z.ZodLiteral<"rule-based">;
|
|
991
|
+
outputChannel: z.ZodEnum<{
|
|
992
|
+
annotation: "annotation";
|
|
993
|
+
}>;
|
|
994
|
+
persistenceIntent: z.ZodEnum<{
|
|
995
|
+
durable: "durable";
|
|
996
|
+
}>;
|
|
997
|
+
purpose: z.ZodEnum<{
|
|
998
|
+
violation: "violation";
|
|
999
|
+
"info-collection": "info-collection";
|
|
1000
|
+
}>;
|
|
829
1001
|
severity: z.ZodEnum<{
|
|
830
1002
|
blocking: "blocking";
|
|
831
1003
|
risk: "risk";
|
|
@@ -842,9 +1014,9 @@ declare const GotchaSurveySchema: z.ZodObject<{
|
|
|
842
1014
|
sourceComponentName: z.ZodOptional<z.ZodString>;
|
|
843
1015
|
}, z.core.$strip>>;
|
|
844
1016
|
applyStrategy: z.ZodEnum<{
|
|
1017
|
+
annotation: "annotation";
|
|
845
1018
|
"property-mod": "property-mod";
|
|
846
1019
|
"structural-mod": "structural-mod";
|
|
847
|
-
annotation: "annotation";
|
|
848
1020
|
"auto-fix": "auto-fix";
|
|
849
1021
|
}>;
|
|
850
1022
|
targetProperty: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
@@ -872,6 +1044,17 @@ declare const GotchaSurveySchema: z.ZodObject<{
|
|
|
872
1044
|
nodeId: z.ZodString;
|
|
873
1045
|
nodeName: z.ZodString;
|
|
874
1046
|
ruleId: z.ZodString;
|
|
1047
|
+
detection: z.ZodLiteral<"rule-based">;
|
|
1048
|
+
outputChannel: z.ZodEnum<{
|
|
1049
|
+
annotation: "annotation";
|
|
1050
|
+
}>;
|
|
1051
|
+
persistenceIntent: z.ZodEnum<{
|
|
1052
|
+
durable: "durable";
|
|
1053
|
+
}>;
|
|
1054
|
+
purpose: z.ZodEnum<{
|
|
1055
|
+
violation: "violation";
|
|
1056
|
+
"info-collection": "info-collection";
|
|
1057
|
+
}>;
|
|
875
1058
|
severity: z.ZodEnum<{
|
|
876
1059
|
blocking: "blocking";
|
|
877
1060
|
risk: "risk";
|
|
@@ -888,9 +1071,9 @@ declare const GotchaSurveySchema: z.ZodObject<{
|
|
|
888
1071
|
sourceComponentName: z.ZodOptional<z.ZodString>;
|
|
889
1072
|
}, z.core.$strip>>;
|
|
890
1073
|
applyStrategy: z.ZodEnum<{
|
|
1074
|
+
annotation: "annotation";
|
|
891
1075
|
"property-mod": "property-mod";
|
|
892
1076
|
"structural-mod": "structural-mod";
|
|
893
|
-
annotation: "annotation";
|
|
894
1077
|
"auto-fix": "auto-fix";
|
|
895
1078
|
}>;
|
|
896
1079
|
targetProperty: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
@@ -972,6 +1155,13 @@ interface AnalysisResult {
|
|
|
972
1155
|
maxDepth: number;
|
|
973
1156
|
nodeCount: number;
|
|
974
1157
|
analyzedAt: string;
|
|
1158
|
+
/**
|
|
1159
|
+
* #404: Resolved analysis scope (`page` vs `component`). Either detected
|
|
1160
|
+
* from the root node type or taken from the caller's explicit override.
|
|
1161
|
+
* Propagated to MCP / JSON output so downstream consumers (code-gen,
|
|
1162
|
+
* reports) can branch the same way rules do.
|
|
1163
|
+
*/
|
|
1164
|
+
scope: AnalysisScope;
|
|
975
1165
|
}
|
|
976
1166
|
/**
|
|
977
1167
|
* Options for the rule engine
|
|
@@ -991,6 +1181,15 @@ interface RuleEngineOptions {
|
|
|
991
1181
|
* (`123-456`) or Plugin-API form (`123:456`) — both normalize to `:`.
|
|
992
1182
|
*/
|
|
993
1183
|
acknowledgments?: Acknowledgment[];
|
|
1184
|
+
/**
|
|
1185
|
+
* #404: Explicit scope override. When omitted, the engine auto-detects
|
|
1186
|
+
* from the analysis root's node type via `detectAnalysisScope`. Supply
|
|
1187
|
+
* this when the caller knows the heuristic would mis-detect — e.g. a
|
|
1188
|
+
* FRAME that happens to be a design-system demo (component scope) or a
|
|
1189
|
+
* COMPONENT_SET being audited as part of a full page inventory (page
|
|
1190
|
+
* scope).
|
|
1191
|
+
*/
|
|
1192
|
+
scope?: AnalysisScope;
|
|
994
1193
|
}
|
|
995
1194
|
/**
|
|
996
1195
|
* Rule engine for analyzing Figma files
|
|
@@ -1003,6 +1202,7 @@ declare class RuleEngine {
|
|
|
1003
1202
|
private excludeNamePattern;
|
|
1004
1203
|
private excludeNodeTypes;
|
|
1005
1204
|
private acknowledgments;
|
|
1205
|
+
private scopeOverride;
|
|
1006
1206
|
constructor(options?: RuleEngineOptions);
|
|
1007
1207
|
/**
|
|
1008
1208
|
* Analyze a Figma file and return issues
|
|
@@ -1430,6 +1630,12 @@ declare class RuleRegistry {
|
|
|
1430
1630
|
* Register a rule
|
|
1431
1631
|
*/
|
|
1432
1632
|
register(rule: Rule): void;
|
|
1633
|
+
/**
|
|
1634
|
+
* Remove a rule by ID. Primarily used by tests that register a
|
|
1635
|
+
* throwaway rule and need to restore the registry afterwards. Returns
|
|
1636
|
+
* `true` if the rule was present.
|
|
1637
|
+
*/
|
|
1638
|
+
unregister(id: RuleId): boolean;
|
|
1433
1639
|
/**
|
|
1434
1640
|
* Get a rule by ID
|
|
1435
1641
|
*/
|
|
@@ -1482,6 +1688,31 @@ interface AnnotationProperty {
|
|
|
1482
1688
|
* - semantic: ΔV < 2%, negligible code difference — naming and semantic issues
|
|
1483
1689
|
*/
|
|
1484
1690
|
declare const RULE_ID_CATEGORY: Record<RuleId, Category>;
|
|
1691
|
+
/**
|
|
1692
|
+
* #406: Classifies each rule by primary output channel.
|
|
1693
|
+
*
|
|
1694
|
+
* - `violation` (default): score-primary. Rule fires when a best-practice
|
|
1695
|
+
* expectation is broken; the score penalty is the main signal, gotcha
|
|
1696
|
+
* questions are secondary context on how to resolve the violation.
|
|
1697
|
+
* - `info-collection`: annotation-primary. Rule fires on nodes that need
|
|
1698
|
+
* implementation context Figma cannot encode natively (click target,
|
|
1699
|
+
* state variants). The gotcha annotation IS the output; score impact is
|
|
1700
|
+
* kept minimal (-1 range) so presence/absence of the annotation — not
|
|
1701
|
+
* the penalty — differentiates designs.
|
|
1702
|
+
*
|
|
1703
|
+
* Sibling map (mirrors `RULE_ID_CATEGORY`) so existing `RuleDefinition`
|
|
1704
|
+
* call sites don't need to be touched. Look up via `getRulePurpose`.
|
|
1705
|
+
*/
|
|
1706
|
+
declare const RULE_PURPOSE: Record<RuleId, RulePurpose>;
|
|
1707
|
+
/**
|
|
1708
|
+
* Resolve a rule's purpose. Accepts `string` (not `RuleId`) because the
|
|
1709
|
+
* purpose concept must work for out-of-tree custom rules added via the
|
|
1710
|
+
* config loader — callers pass `issue.violation.ruleId` which is a plain
|
|
1711
|
+
* string. Defaults to `"violation"` for unknown ids. Keeping the cast
|
|
1712
|
+
* inside this helper (rather than forcing every caller to do `as RuleId`)
|
|
1713
|
+
* makes the fallback semantically honest.
|
|
1714
|
+
*/
|
|
1715
|
+
declare function getRulePurpose(ruleId: string): RulePurpose;
|
|
1485
1716
|
/**
|
|
1486
1717
|
* Central configuration for all rules.
|
|
1487
1718
|
* Scores based on ablation experiment + AI implementation interview (#200):
|
|
@@ -1718,6 +1949,10 @@ declare const CalibrationConfigSchema: z.ZodObject<{
|
|
|
1718
1949
|
}>>;
|
|
1719
1950
|
outputPath: z.ZodDefault<z.ZodString>;
|
|
1720
1951
|
runDir: z.ZodOptional<z.ZodString>;
|
|
1952
|
+
scope: z.ZodOptional<z.ZodEnum<{
|
|
1953
|
+
page: "page";
|
|
1954
|
+
component: "component";
|
|
1955
|
+
}>>;
|
|
1721
1956
|
}, z.core.$strip>;
|
|
1722
1957
|
type CalibrationConfig = z.infer<typeof CalibrationConfigSchema>;
|
|
1723
1958
|
type CalibrationConfigInput = z.input<typeof CalibrationConfigSchema>;
|
|
@@ -2107,4 +2342,4 @@ declare class ActivityLogger {
|
|
|
2107
2342
|
getLogPath(): string;
|
|
2108
2343
|
}
|
|
2109
2344
|
|
|
2110
|
-
export { ALL_STRIP_TYPES, ActivityLogger, type AnalysisAgentInput, type AnalysisAgentOutput, type AnalysisFile, AnalysisFileSchema, type AnalysisIssue, type AnalysisNode, AnalysisNodeSchema, type AnalysisNodeType, AnalysisNodeTypeSchema, type AnalysisResult, AnnotationPropertySchema, CATEGORIES, CATEGORY_LABELS, type CalibrationConfig, type CalibrationConfigInput, CalibrationConfigSchema, type CalibrationRun, type CalibrationStatus, CalibrationStatusSchema, type Category, CategorySchema, type CategoryScore, type CategoryScoreResult, CategoryScoreSchema, type Confidence, ConfidenceSchema, type ConversionRecord, ConversionRecordSchema, DEPTH_WEIGHT_CATEGORIES, DESIGN_TREE_INFO_TYPES, type DesignTreeInfoType, type DesignTreeOptions, type DesignTreeResult, type DesignTreeStripType, type Difficulty, DifficultySchema, type EvaluationAgentInput, type EvaluationAgentOutput, FigmaClient, FigmaClientError, type FigmaClientOptions, FigmaFileLoadError, type FigmaUrlInfo, FigmaUrlInfoSchema, FigmaUrlParseError, type GapAnalyzerOutput, GapAnalyzerOutputSchema, type GapEntry, GapEntrySchema, type GetFileNodesResponse, type GotchaApplyResolution, type GotchaApplyStrategy, type GotchaSurvey, type GotchaSurveyQuestion, GotchaSurveyQuestionSchema, GotchaSurveySchema, type Grade, type GridChildAlign, GridChildAlignSchema, type GroupedSurvey, GroupedSurveySchema, type InstanceChildIdParts, type InstanceContext, InstanceContextSchema, type Issue, IssueSchema, type LayoutAlign, LayoutAlignSchema, type LayoutConstraint, LayoutConstraintSchema, type LayoutMode, LayoutModeSchema, type LayoutPositioning, LayoutPositioningSchema, type LayoutWrap, LayoutWrapSchema, type McpAnalyzeResponse, McpAnalyzeResponseSchema, type MismatchCase, MismatchCaseSchema, type MismatchType, MismatchTypeSchema, type NewRuleProposal, NewRuleProposalSchema, type NodeIssueDetail, type NodeIssueSummary, NodeIssueSummarySchema, type OverflowDirection, OverflowDirectionSchema, type Preset, RULE_ANNOTATION_PROPERTIES, RULE_CONFIGS, RULE_ID_CATEGORY, type Report, type ReportMetadata, ReportMetadataSchema, ReportSchema, type Rule, type RuleApplyStrategy, RuleApplyStrategySchema, type RuleCheckFn, type RuleConfig, RuleConfigSchema, type RuleContext, type RuleDefinition, RuleDefinitionSchema, RuleEngine, type RuleEngineOptions, type RuleFailure, type RuleId, RuleImpactAssessmentSchema, type RuleRelatedStruggle, RuleRelatedStruggleSchema, type RuleViolation, SEVERITY_LABELS, SEVERITY_WEIGHT, type SamplingStrategy, SamplingStrategySchema, type ScoreAdjustment, ScoreAdjustmentSchema, type ScoreReport, type Severity, SeveritySchema, type StripDeltaForEval, type StripDeltaResult, StripDeltaResultSchema, StripDeltasArraySchema, StripTypeEnum, type SurveyQuestionBatch, SurveyQuestionBatchSchema, type SurveyQuestionGroup, SurveyQuestionGroupSchema, type TuningAgentInput, type TuningAgentOutput, type UncoveredStruggle, UncoveredStruggleSchema, UncoveredStrugglesInputSchema, version as VERSION, type VisualCompareCliOptions, VisualCompareCliOptionsSchema, absolutePositionInAutoLayout, analyzeFile, buildFigmaDeepLink, buildResultJson, calculateScores, collectComponentIds, collectInteractionDestinationIds, createRuleEngine, deepNesting, defineRule, detachedInstance, extractRuleScores, fixedSizeInAutoLayout, formatScoreSummary, generateCalibrationReport, generateDesignTree, generateDesignTreeWithStats, getAnalysisState, getAnnotationProperties, getCategoryLabel, getConfigsWithPreset, getRuleOption, getSeverityLabel, gradeToClassName, inconsistentNamingConvention, irregularSpacing, isInstanceChildNodeId, isReadyForCodeGen, loadFigmaFileFromJson, missingComponent, missingInteractionState, missingPrototype, missingSizeConstraint, noAutoLayout, nonLayoutContainer, nonSemanticName, nonStandardNaming, parseFigmaJson, parseFigmaUrl, parseInstanceChildNodeId, rawValue, resolveComponentDefinitions, resolveGotchaApplyTarget, resolveInteractionDestinations, ruleRegistry, runAnalysisAgent, runCalibrationAnalyze, runCalibrationEvaluate, runEvaluationAgent, runTuningAgent, stripDeltaToDifficulty, stripDesignTree, supportsDepthWeight, toCommentableNodeId, tokenDeltaToDifficulty, transformComponentMasterNodes, transformFigmaResponse, transformFileNodesResponse, variantStructureMismatch };
|
|
2345
|
+
export { ALL_STRIP_TYPES, ActivityLogger, type AnalysisAgentInput, type AnalysisAgentOutput, type AnalysisFile, AnalysisFileSchema, type AnalysisIssue, type AnalysisNode, AnalysisNodeSchema, type AnalysisNodeType, AnalysisNodeTypeSchema, type AnalysisResult, type AnalysisScope, AnalysisScopeSchema, AnnotationPropertySchema, CATEGORIES, CATEGORY_LABELS, type CalibrationConfig, type CalibrationConfigInput, CalibrationConfigSchema, type CalibrationRun, type CalibrationStatus, CalibrationStatusSchema, type Category, CategorySchema, type CategoryScore, type CategoryScoreResult, CategoryScoreSchema, type Confidence, ConfidenceSchema, type ConversionRecord, ConversionRecordSchema, DEPTH_WEIGHT_CATEGORIES, DESIGN_TREE_INFO_TYPES, type DesignTreeInfoType, type DesignTreeOptions, type DesignTreeResult, type DesignTreeStripType, type Detection, DetectionSchema, type Difficulty, DifficultySchema, type EvaluationAgentInput, type EvaluationAgentOutput, FigmaClient, FigmaClientError, type FigmaClientOptions, FigmaFileLoadError, type FigmaUrlInfo, FigmaUrlInfoSchema, FigmaUrlParseError, type GapAnalyzerOutput, GapAnalyzerOutputSchema, type GapEntry, GapEntrySchema, type GetFileNodesResponse, type GotchaApplyResolution, type GotchaApplyStrategy, GotchaDetectionSchema, GotchaOutputChannelSchema, GotchaPersistenceIntentSchema, type GotchaSurvey, type GotchaSurveyQuestion, GotchaSurveyQuestionSchema, GotchaSurveySchema, type Grade, type GridChildAlign, GridChildAlignSchema, type GroupedSurvey, GroupedSurveySchema, type InstanceChildIdParts, type InstanceContext, InstanceContextSchema, type Issue, IssueSchema, type LayoutAlign, LayoutAlignSchema, type LayoutConstraint, LayoutConstraintSchema, type LayoutMode, LayoutModeSchema, type LayoutPositioning, LayoutPositioningSchema, type LayoutWrap, LayoutWrapSchema, type McpAnalyzeResponse, McpAnalyzeResponseSchema, type MismatchCase, MismatchCaseSchema, type MismatchType, MismatchTypeSchema, type NewRuleProposal, NewRuleProposalSchema, type NodeIssueDetail, type NodeIssueSummary, NodeIssueSummarySchema, type OutputChannel, OutputChannelSchema, type OverflowDirection, OverflowDirectionSchema, type PersistenceIntent, PersistenceIntentSchema, type Preset, RULE_ANNOTATION_PROPERTIES, RULE_CONFIGS, RULE_ID_CATEGORY, RULE_PURPOSE, type Report, type ReportMetadata, ReportMetadataSchema, ReportSchema, type Rule, type RuleApplyStrategy, RuleApplyStrategySchema, type RuleCheckFn, type RuleConfig, RuleConfigSchema, type RuleContext, type RuleDefinition, RuleDefinitionSchema, RuleEngine, type RuleEngineOptions, type RuleFailure, type RuleId, RuleImpactAssessmentSchema, type RulePurpose, RulePurposeSchema, type RuleRelatedStruggle, RuleRelatedStruggleSchema, type RuleViolation, SEVERITY_LABELS, SEVERITY_WEIGHT, type SamplingStrategy, SamplingStrategySchema, type ScoreAdjustment, ScoreAdjustmentSchema, type ScoreReport, type Severity, SeveritySchema, type StripDeltaForEval, type StripDeltaResult, StripDeltaResultSchema, StripDeltasArraySchema, StripTypeEnum, type SurveyQuestionBatch, SurveyQuestionBatchSchema, type SurveyQuestionGroup, SurveyQuestionGroupSchema, type TuningAgentInput, type TuningAgentOutput, type UncoveredStruggle, UncoveredStruggleSchema, UncoveredStrugglesInputSchema, version as VERSION, type VisualCompareCliOptions, VisualCompareCliOptionsSchema, absolutePositionInAutoLayout, analyzeFile, buildFigmaDeepLink, buildResultJson, calculateScores, collectComponentIds, collectInteractionDestinationIds, createRuleEngine, deepNesting, defineRule, detachedInstance, detectAnalysisScope, extractRuleScores, fixedSizeInAutoLayout, formatScoreSummary, generateCalibrationReport, generateDesignTree, generateDesignTreeWithStats, getAnalysisState, getAnnotationProperties, getCategoryLabel, getConfigsWithPreset, getRuleOption, getRulePurpose, getSeverityLabel, gradeToClassName, inconsistentNamingConvention, irregularSpacing, isInstanceChildNodeId, isReadyForCodeGen, loadFigmaFileFromJson, missingComponent, missingInteractionState, missingPrototype, missingSizeConstraint, noAutoLayout, nonLayoutContainer, nonSemanticName, nonStandardNaming, parseFigmaJson, parseFigmaUrl, parseInstanceChildNodeId, rawValue, resolveComponentDefinitions, resolveGotchaApplyTarget, resolveInteractionDestinations, ruleRegistry, runAnalysisAgent, runCalibrationAnalyze, runCalibrationEvaluate, runEvaluationAgent, runTuningAgent, stripDeltaToDifficulty, stripDesignTree, supportsDepthWeight, toCommentableNodeId, tokenDeltaToDifficulty, transformComponentMasterNodes, transformFigmaResponse, transformFileNodesResponse, variantStructureMismatch };
|