@planu/cli 0.80.1 → 0.81.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.
Files changed (96) hide show
  1. package/dist/cli/commands/create.js.map +1 -1
  2. package/dist/cli/commands/list.js.map +1 -1
  3. package/dist/config/ac-gap-keywords.json +144 -0
  4. package/dist/config/challenge-scenarios.json +114 -0
  5. package/dist/config/code-quality-thresholds.json +114 -0
  6. package/dist/config/compliance-frameworks.json +150 -0
  7. package/dist/config/dor-dod-items.json +214 -0
  8. package/dist/config/drift-severity.json +22 -0
  9. package/dist/config/elicitation-questions.json +70 -0
  10. package/dist/config/feasibility-rules.json +91 -0
  11. package/dist/config/rbac-roles.json +27 -0
  12. package/dist/config/readiness-config.json +18 -0
  13. package/dist/config/spec-types.json +42 -0
  14. package/dist/engine/ac-gap-detector/constants.d.ts.map +1 -1
  15. package/dist/engine/ac-gap-detector/constants.js +24 -126
  16. package/dist/engine/ac-gap-detector/constants.js.map +1 -1
  17. package/dist/engine/ac-gap-detector/keyword-loader.d.ts +13 -0
  18. package/dist/engine/ac-gap-detector/keyword-loader.d.ts.map +1 -0
  19. package/dist/engine/ac-gap-detector/keyword-loader.js +35 -0
  20. package/dist/engine/ac-gap-detector/keyword-loader.js.map +1 -0
  21. package/dist/engine/challenge-scenarios-loader.d.ts +46 -0
  22. package/dist/engine/challenge-scenarios-loader.d.ts.map +1 -0
  23. package/dist/engine/challenge-scenarios-loader.js +83 -0
  24. package/dist/engine/challenge-scenarios-loader.js.map +1 -0
  25. package/dist/engine/code-quality-thresholds-loader.d.ts +27 -0
  26. package/dist/engine/code-quality-thresholds-loader.d.ts.map +1 -0
  27. package/dist/engine/code-quality-thresholds-loader.js +88 -0
  28. package/dist/engine/code-quality-thresholds-loader.js.map +1 -0
  29. package/dist/engine/compliance-injector.d.ts +46 -0
  30. package/dist/engine/compliance-injector.d.ts.map +1 -0
  31. package/dist/engine/compliance-injector.js +121 -0
  32. package/dist/engine/compliance-injector.js.map +1 -0
  33. package/dist/engine/dor-dod/dod.d.ts +3 -2
  34. package/dist/engine/dor-dod/dod.d.ts.map +1 -1
  35. package/dist/engine/dor-dod/dod.js +38 -73
  36. package/dist/engine/dor-dod/dod.js.map +1 -1
  37. package/dist/engine/dor-dod/dor.d.ts +3 -2
  38. package/dist/engine/dor-dod/dor.d.ts.map +1 -1
  39. package/dist/engine/dor-dod/dor.js +75 -125
  40. package/dist/engine/dor-dod/dor.js.map +1 -1
  41. package/dist/engine/dor-dod/items-loader.d.ts +18 -0
  42. package/dist/engine/dor-dod/items-loader.d.ts.map +1 -0
  43. package/dist/engine/dor-dod/items-loader.js +55 -0
  44. package/dist/engine/dor-dod/items-loader.js.map +1 -0
  45. package/dist/engine/elicitation/question-generator.d.ts.map +1 -1
  46. package/dist/engine/elicitation/question-generator.js +74 -63
  47. package/dist/engine/elicitation/question-generator.js.map +1 -1
  48. package/dist/engine/feasibility-rules-loader.d.ts +13 -0
  49. package/dist/engine/feasibility-rules-loader.d.ts.map +1 -0
  50. package/dist/engine/feasibility-rules-loader.js +39 -0
  51. package/dist/engine/feasibility-rules-loader.js.map +1 -0
  52. package/dist/engine/feasibility-validator.d.ts +1 -1
  53. package/dist/engine/feasibility-validator.d.ts.map +1 -1
  54. package/dist/engine/feasibility-validator.js +21 -78
  55. package/dist/engine/feasibility-validator.js.map +1 -1
  56. package/dist/engine/rbac/roles.d.ts +13 -5
  57. package/dist/engine/rbac/roles.d.ts.map +1 -1
  58. package/dist/engine/rbac/roles.js +58 -24
  59. package/dist/engine/rbac/roles.js.map +1 -1
  60. package/dist/engine/readiness-checker.d.ts +1 -1
  61. package/dist/engine/readiness-checker.d.ts.map +1 -1
  62. package/dist/engine/readiness-checker.js +10 -12
  63. package/dist/engine/readiness-checker.js.map +1 -1
  64. package/dist/engine/readiness-config-loader.d.ts +8 -0
  65. package/dist/engine/readiness-config-loader.d.ts.map +1 -0
  66. package/dist/engine/readiness-config-loader.js +58 -0
  67. package/dist/engine/readiness-config-loader.js.map +1 -0
  68. package/dist/engine/spec-types-loader.d.ts +22 -0
  69. package/dist/engine/spec-types-loader.d.ts.map +1 -0
  70. package/dist/engine/spec-types-loader.js +50 -0
  71. package/dist/engine/spec-types-loader.js.map +1 -0
  72. package/dist/engine/validator/analyzer.d.ts +1 -0
  73. package/dist/engine/validator/analyzer.d.ts.map +1 -1
  74. package/dist/engine/validator/analyzer.js +31 -8
  75. package/dist/engine/validator/analyzer.js.map +1 -1
  76. package/dist/types/common/primitives.d.ts.map +1 -1
  77. package/dist/types/index.d.ts +1 -0
  78. package/dist/types/index.d.ts.map +1 -1
  79. package/dist/types/index.js +1 -0
  80. package/dist/types/index.js.map +1 -1
  81. package/dist/types/plugin-configs.d.ts +105 -0
  82. package/dist/types/plugin-configs.d.ts.map +1 -0
  83. package/dist/types/plugin-configs.js +6 -0
  84. package/dist/types/plugin-configs.js.map +1 -0
  85. package/package.json +1 -1
  86. package/src/config/ac-gap-keywords.json +144 -0
  87. package/src/config/challenge-scenarios.json +114 -0
  88. package/src/config/code-quality-thresholds.json +114 -0
  89. package/src/config/compliance-frameworks.json +150 -0
  90. package/src/config/dor-dod-items.json +214 -0
  91. package/src/config/drift-severity.json +22 -0
  92. package/src/config/elicitation-questions.json +70 -0
  93. package/src/config/feasibility-rules.json +91 -0
  94. package/src/config/rbac-roles.json +27 -0
  95. package/src/config/readiness-config.json +18 -0
  96. package/src/config/spec-types.json +42 -0
@@ -0,0 +1,13 @@
1
+ import type { AcGapKeywordGroup } from '../../types/index.js';
2
+ import { ConfigLoader } from '../config-loader.js';
3
+ export type { AcGapKeywordGroup };
4
+ /**
5
+ * Load all keyword groups, optionally merging project-level overrides.
6
+ * Results are indexed by domain for O(1) lookup.
7
+ */
8
+ export declare function loadKeywordGroups(projectHash?: string): Map<string, readonly string[]>;
9
+ /**
10
+ * Get the ConfigLoader instance (for testing / inspection).
11
+ */
12
+ export declare function getKeywordLoader(): ConfigLoader<AcGapKeywordGroup>;
13
+ //# sourceMappingURL=keyword-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyword-loader.d.ts","sourceRoot":"","sources":["../../../src/engine/ac-gap-detector/keyword-loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAcnD,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAMlC;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAOtF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,YAAY,CAAC,iBAAiB,CAAC,CAElE"}
@@ -0,0 +1,35 @@
1
+ // engine/ac-gap-detector/keyword-loader.ts — Config-driven keyword sets for AC gap analysis (SPEC-211)
2
+ import { z } from 'zod';
3
+ import { ConfigLoader } from '../config-loader.js';
4
+ /** Schema for a single keyword group (one per domain). */
5
+ const AcGapKeywordGroupSchema = z.object({
6
+ id: z.string().describe('Domain identifier matching the gap category (e.g. "error-handling")'),
7
+ domain: z
8
+ .string()
9
+ .describe('Human-readable domain label used in gap rules (must match gap category names)'),
10
+ language: z.string().describe('BCP-47 language tag for this keyword set (e.g. "en", "es")'),
11
+ keywords: z
12
+ .array(z.string())
13
+ .describe('List of lowercase keyword strings that indicate coverage of this domain'),
14
+ });
15
+ const AcGapKeywordGroupArraySchema = z.array(AcGapKeywordGroupSchema);
16
+ const loader = new ConfigLoader('ac-gap-keywords', AcGapKeywordGroupArraySchema);
17
+ /**
18
+ * Load all keyword groups, optionally merging project-level overrides.
19
+ * Results are indexed by domain for O(1) lookup.
20
+ */
21
+ export function loadKeywordGroups(projectHash) {
22
+ const groups = loader.load(projectHash);
23
+ const map = new Map();
24
+ for (const group of groups) {
25
+ map.set(group.domain, group.keywords);
26
+ }
27
+ return map;
28
+ }
29
+ /**
30
+ * Get the ConfigLoader instance (for testing / inspection).
31
+ */
32
+ export function getKeywordLoader() {
33
+ return loader;
34
+ }
35
+ //# sourceMappingURL=keyword-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyword-loader.js","sourceRoot":"","sources":["../../../src/engine/ac-gap-detector/keyword-loader.ts"],"names":[],"mappings":"AAAA,uGAAuG;AACvG,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,0DAA0D;AAC1D,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qEAAqE,CAAC;IAC9F,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,QAAQ,CAAC,+EAA+E,CAAC;IAC5F,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4DAA4D,CAAC;IAC3F,QAAQ,EAAE,CAAC;SACR,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,CAAC,yEAAyE,CAAC;CACvF,CAAC,CAAC;AAIH,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;AAEtE,MAAM,MAAM,GAAG,IAAI,YAAY,CAAoB,iBAAiB,EAAE,4BAA4B,CAAC,CAAC;AAEpG;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAoB;IACpD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,IAAI,GAAG,EAA6B,CAAC;IACjD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { z } from 'zod';
2
+ import type { ChallengeScenarioPattern } from '../types/index.js';
3
+ export declare const ChallengeScenarioPatternSchema: z.ZodObject<{
4
+ id: z.ZodString;
5
+ category: z.ZodString;
6
+ triggerKeywords: z.ZodArray<z.ZodString>;
7
+ scenario: z.ZodString;
8
+ probability: z.ZodEnum<{
9
+ low: "low";
10
+ medium: "medium";
11
+ high: "high";
12
+ }>;
13
+ impact: z.ZodEnum<{
14
+ low: "low";
15
+ medium: "medium";
16
+ high: "high";
17
+ critical: "critical";
18
+ }>;
19
+ handlingKeywords: z.ZodArray<z.ZodString>;
20
+ handlingFound: z.ZodString;
21
+ handlingMissing: z.ZodString;
22
+ requiredHandling: z.ZodString;
23
+ dataConsistency: z.ZodString;
24
+ userExperience: z.ZodString;
25
+ }, z.core.$strip>;
26
+ export type { ChallengeScenarioPattern };
27
+ /**
28
+ * Load all challenge scenario patterns from the 3-layer config system.
29
+ */
30
+ export declare function loadScenarioPatterns(projectHash?: string): ChallengeScenarioPattern[];
31
+ /**
32
+ * Filter patterns that are triggered by content of the spec.
33
+ * A pattern is triggered if ANY of its triggerKeywords appear in specContent,
34
+ * OR if it has no trigger keywords (always-on scenarios).
35
+ */
36
+ export declare function getTriggeredPatterns(specContent: string, projectHash?: string): ChallengeScenarioPattern[];
37
+ /**
38
+ * Get patterns filtered by category.
39
+ */
40
+ export declare function getPatternsByCategory(category: string, projectHash?: string): ChallengeScenarioPattern[];
41
+ /**
42
+ * Determine currentHandling label based on whether the spec content
43
+ * includes any of the pattern's handlingKeywords.
44
+ */
45
+ export declare function resolveHandlingLabel(pattern: ChallengeScenarioPattern, specContent: string): string;
46
+ //# sourceMappingURL=challenge-scenarios-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"challenge-scenarios-loader.d.ts","sourceRoot":"","sources":["../../src/engine/challenge-scenarios-loader.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAOlE,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;iBAoBzC,CAAC;AAEH,YAAY,EAAE,wBAAwB,EAAE,CAAC;AAsBzC;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,wBAAwB,EAAE,CAErF;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM,GACnB,wBAAwB,EAAE,CAU5B;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,GACnB,wBAAwB,EAAE,CAE5B;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,wBAAwB,EACjC,WAAW,EAAE,MAAM,GAClB,MAAM,CAIR"}
@@ -0,0 +1,83 @@
1
+ // engine/challenge-scenarios-loader.ts — Challenge scenario pattern library (SPEC-214)
2
+ //
3
+ // Loads challenge scenario patterns from the 3-layer config system.
4
+ // Source: src/config/challenge-scenarios.json (system defaults)
5
+ // Override: data/global/challenge-scenarios-custom.json
6
+ // data/projects/{hash}/config/challenge-scenarios-overrides.json
7
+ //
8
+ // Scenarios can be extended via JSON without modifying TypeScript source files.
9
+ import { z } from 'zod';
10
+ import { ConfigLoader } from './config-loader.js';
11
+ // ---------------------------------------------------------------------------
12
+ // Schema
13
+ // ---------------------------------------------------------------------------
14
+ export const ChallengeScenarioPatternSchema = z.object({
15
+ id: z.string().min(1).describe('Unique scenario pattern identifier'),
16
+ category: z
17
+ .string()
18
+ .min(1)
19
+ .describe('Scenario category: data-consistency, security, scale, failure, etc.'),
20
+ triggerKeywords: z
21
+ .array(z.string())
22
+ .describe('Keywords in spec content that activate this scenario'),
23
+ scenario: z.string().min(1).describe('Short description of the failure scenario'),
24
+ probability: z.enum(['low', 'medium', 'high']).describe('Probability of this failure occurring'),
25
+ impact: z.enum(['low', 'medium', 'high', 'critical']).describe('Impact if this failure occurs'),
26
+ handlingKeywords: z
27
+ .array(z.string())
28
+ .describe('Keywords that indicate the spec already addresses this scenario'),
29
+ handlingFound: z.string().describe('Message when handling is detected in spec'),
30
+ handlingMissing: z.string().describe('Message when handling is absent from spec'),
31
+ requiredHandling: z.string().describe('What the spec should implement to handle this scenario'),
32
+ dataConsistency: z.string().describe('Data consistency requirements for this scenario'),
33
+ userExperience: z.string().describe('Expected user experience for this scenario'),
34
+ });
35
+ const patternsArraySchema = z.array(ChallengeScenarioPatternSchema);
36
+ // ---------------------------------------------------------------------------
37
+ // Loader singleton
38
+ // ---------------------------------------------------------------------------
39
+ let _loader = null;
40
+ function getLoader() {
41
+ _loader ??= new ConfigLoader('challenge-scenarios', patternsArraySchema);
42
+ return _loader;
43
+ }
44
+ // ---------------------------------------------------------------------------
45
+ // Public API
46
+ // ---------------------------------------------------------------------------
47
+ /**
48
+ * Load all challenge scenario patterns from the 3-layer config system.
49
+ */
50
+ export function loadScenarioPatterns(projectHash) {
51
+ return getLoader().load(projectHash);
52
+ }
53
+ /**
54
+ * Filter patterns that are triggered by content of the spec.
55
+ * A pattern is triggered if ANY of its triggerKeywords appear in specContent,
56
+ * OR if it has no trigger keywords (always-on scenarios).
57
+ */
58
+ export function getTriggeredPatterns(specContent, projectHash) {
59
+ const lower = specContent.toLowerCase();
60
+ const all = loadScenarioPatterns(projectHash);
61
+ return all.filter((pattern) => {
62
+ if (pattern.triggerKeywords.length === 0) {
63
+ return true; // always-on pattern
64
+ }
65
+ return pattern.triggerKeywords.some((kw) => lower.includes(kw.toLowerCase()));
66
+ });
67
+ }
68
+ /**
69
+ * Get patterns filtered by category.
70
+ */
71
+ export function getPatternsByCategory(category, projectHash) {
72
+ return loadScenarioPatterns(projectHash).filter((p) => p.category === category);
73
+ }
74
+ /**
75
+ * Determine currentHandling label based on whether the spec content
76
+ * includes any of the pattern's handlingKeywords.
77
+ */
78
+ export function resolveHandlingLabel(pattern, specContent) {
79
+ const lower = specContent.toLowerCase();
80
+ const addressed = pattern.handlingKeywords.some((kw) => lower.includes(kw.toLowerCase()));
81
+ return addressed ? pattern.handlingFound : pattern.handlingMissing;
82
+ }
83
+ //# sourceMappingURL=challenge-scenarios-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"challenge-scenarios-loader.js","sourceRoot":"","sources":["../../src/engine/challenge-scenarios-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { z } from 'zod';
2
+ import type { CodeQualityThreshold } from '../types/index.js';
3
+ export declare const CodeQualityThresholdSchema: z.ZodObject<{
4
+ id: z.ZodString;
5
+ language: z.ZodString;
6
+ maxFileLines: z.ZodNumber;
7
+ maxFunctionLines: z.ZodNumber;
8
+ maxParams: z.ZodNumber;
9
+ maxNestingDepth: z.ZodNumber;
10
+ maxCyclomaticComplexity: z.ZodNumber;
11
+ minCoverageStatements: z.ZodNumber;
12
+ minCoverageBranches: z.ZodNumber;
13
+ minCoverageFunctions: z.ZodNumber;
14
+ minCoverageLines: z.ZodNumber;
15
+ duplicateLineThreshold: z.ZodNumber;
16
+ }, z.core.$strip>;
17
+ export type { CodeQualityThreshold };
18
+ /**
19
+ * Load all code quality thresholds, merging system defaults with global/project overrides.
20
+ */
21
+ export declare function loadThresholds(projectHash?: string): CodeQualityThreshold[];
22
+ /**
23
+ * Get thresholds for a specific language. Falls back to 'default' if no exact match.
24
+ * Language comparison is case-insensitive.
25
+ */
26
+ export declare function getThresholds(language: string, projectHash?: string): CodeQualityThreshold;
27
+ //# sourceMappingURL=code-quality-thresholds-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-quality-thresholds-loader.d.ts","sourceRoot":"","sources":["../../src/engine/code-quality-thresholds-loader.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAO9D,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;iBAiBrC,CAAC;AAEH,YAAY,EAAE,oBAAoB,EAAE,CAAC;AAsBrC;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAE3E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,oBAAoB,CAmC1F"}
@@ -0,0 +1,88 @@
1
+ // engine/code-quality-thresholds-loader.ts — Configurable code quality thresholds (SPEC-210)
2
+ //
3
+ // Provides per-language code quality thresholds via the 3-layer ConfigLoader pattern.
4
+ // Source: src/config/code-quality-thresholds.json (system defaults)
5
+ // Override: data/global/code-quality-thresholds-custom.json (global)
6
+ // data/projects/{hash}/config/code-quality-thresholds-overrides.json (project)
7
+ //
8
+ // USAGE:
9
+ // const thresholds = getThresholds('typescript');
10
+ // if (lines.length > thresholds.maxFileLines) { ... }
11
+ import { z } from 'zod';
12
+ import { ConfigLoader } from './config-loader.js';
13
+ // ---------------------------------------------------------------------------
14
+ // Schema
15
+ // ---------------------------------------------------------------------------
16
+ export const CodeQualityThresholdSchema = z.object({
17
+ id: z.string().min(1).describe('Language identifier (e.g. "typescript", "python", "default")'),
18
+ language: z.string().min(1).describe('Human-readable language name'),
19
+ maxFileLines: z.number().int().positive().describe('Maximum lines per file'),
20
+ maxFunctionLines: z.number().int().positive().describe('Maximum lines per function'),
21
+ maxParams: z.number().int().positive().describe('Maximum function parameters'),
22
+ maxNestingDepth: z.number().int().positive().describe('Maximum nesting depth'),
23
+ maxCyclomaticComplexity: z.number().int().positive().describe('Maximum cyclomatic complexity'),
24
+ minCoverageStatements: z.number().min(0).max(100).describe('Minimum statement coverage %'),
25
+ minCoverageBranches: z.number().min(0).max(100).describe('Minimum branch coverage %'),
26
+ minCoverageFunctions: z.number().min(0).max(100).describe('Minimum function coverage %'),
27
+ minCoverageLines: z.number().min(0).max(100).describe('Minimum line coverage %'),
28
+ duplicateLineThreshold: z
29
+ .number()
30
+ .int()
31
+ .positive()
32
+ .describe('Number of identical lines to flag as duplication'),
33
+ });
34
+ const thresholdsArraySchema = z.array(CodeQualityThresholdSchema);
35
+ // ---------------------------------------------------------------------------
36
+ // Loader singleton
37
+ // ---------------------------------------------------------------------------
38
+ let _loader = null;
39
+ function getLoader() {
40
+ _loader ??= new ConfigLoader('code-quality-thresholds', thresholdsArraySchema);
41
+ return _loader;
42
+ }
43
+ // ---------------------------------------------------------------------------
44
+ // Public API
45
+ // ---------------------------------------------------------------------------
46
+ /**
47
+ * Load all code quality thresholds, merging system defaults with global/project overrides.
48
+ */
49
+ export function loadThresholds(projectHash) {
50
+ return getLoader().load(projectHash);
51
+ }
52
+ /**
53
+ * Get thresholds for a specific language. Falls back to 'default' if no exact match.
54
+ * Language comparison is case-insensitive.
55
+ */
56
+ export function getThresholds(language, projectHash) {
57
+ const all = loadThresholds(projectHash);
58
+ const normalized = language.toLowerCase().trim();
59
+ const exact = all.find((t) => t.language.toLowerCase() === normalized);
60
+ if (exact !== undefined) {
61
+ return exact;
62
+ }
63
+ // Try matching by id as well (e.g. "ts" → no match, "typescript" → match)
64
+ const byId = all.find((t) => t.id.toLowerCase() === normalized);
65
+ if (byId !== undefined) {
66
+ return byId;
67
+ }
68
+ const fallback = all.find((t) => t.id === 'default');
69
+ if (fallback !== undefined) {
70
+ return fallback;
71
+ }
72
+ // Should never happen if the config JSON is intact, but be defensive
73
+ return {
74
+ id: 'default',
75
+ language: 'default',
76
+ maxFileLines: 500,
77
+ maxFunctionLines: 60,
78
+ maxParams: 5,
79
+ maxNestingDepth: 5,
80
+ maxCyclomaticComplexity: 15,
81
+ minCoverageStatements: 80,
82
+ minCoverageBranches: 70,
83
+ minCoverageFunctions: 80,
84
+ minCoverageLines: 80,
85
+ duplicateLineThreshold: 4,
86
+ };
87
+ }
88
+ //# sourceMappingURL=code-quality-thresholds-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-quality-thresholds-loader.js","sourceRoot":"","sources":["../../src/engine/code-quality-thresholds-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import { z } from 'zod';
2
+ import type { ComplianceFrameworkDef } from '../types/index.js';
3
+ export declare const ComplianceFrameworkDefSchema: z.ZodObject<{
4
+ id: z.ZodString;
5
+ name: z.ZodString;
6
+ fullName: z.ZodString;
7
+ type: z.ZodEnum<{
8
+ security: "security";
9
+ testing: "testing";
10
+ quality: "quality";
11
+ accessibility: "accessibility";
12
+ privacy: "privacy";
13
+ }>;
14
+ regions: z.ZodArray<z.ZodString>;
15
+ triggerKeywords: z.ZodArray<z.ZodString>;
16
+ dataTypes: z.ZodArray<z.ZodString>;
17
+ criteria: z.ZodArray<z.ZodString>;
18
+ references: z.ZodArray<z.ZodString>;
19
+ }, z.core.$strip>;
20
+ export type { ComplianceFrameworkDef };
21
+ /**
22
+ * Load all compliance framework definitions from the 3-layer config system.
23
+ */
24
+ export declare function loadComplianceFrameworkDefs(projectHash?: string): ComplianceFrameworkDef[];
25
+ /**
26
+ * Detect which compliance frameworks apply to the given context.
27
+ *
28
+ * A framework is applicable when ANY of its triggerKeywords appear in the
29
+ * combined context string (spec description + project stack).
30
+ */
31
+ export declare function detectApplicableFrameworks(context: string, projectHash?: string): ComplianceFrameworkDef[];
32
+ /**
33
+ * Generate acceptance criteria to inject into a spec based on detected frameworks.
34
+ * Deduplicates criteria across frameworks and caps at maxCriteria (default: 8).
35
+ */
36
+ export declare function generateComplianceCriteria(context: string, projectHash?: string, maxCriteria?: number): string[];
37
+ /**
38
+ * Build a markdown compliance section summarizing detected frameworks and their criteria.
39
+ * Intended for injection into technical.md.
40
+ */
41
+ export declare function buildComplianceSection(context: string, projectHash?: string): string;
42
+ /**
43
+ * Get framework by ID. Returns undefined if not found.
44
+ */
45
+ export declare function getFrameworkById(id: string, projectHash?: string): ComplianceFrameworkDef | undefined;
46
+ //# sourceMappingURL=compliance-injector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compliance-injector.d.ts","sourceRoot":"","sources":["../../src/engine/compliance-injector.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAOhE,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;iBAmBvC,CAAC;AAEH,YAAY,EAAE,sBAAsB,EAAE,CAAC;AAsBvC;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,sBAAsB,EAAE,CAE1F;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,GACnB,sBAAsB,EAAE,CAK1B;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,EACpB,WAAW,SAAI,GACd,MAAM,EAAE,CAeV;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAiCpF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,MAAM,EACV,WAAW,CAAC,EAAE,MAAM,GACnB,sBAAsB,GAAG,SAAS,CAEpC"}
@@ -0,0 +1,121 @@
1
+ // engine/compliance-injector.ts — Automatic IEEE/ISO/GDPR compliance injection (SPEC-202)
2
+ //
3
+ // Loads compliance framework definitions from the 3-layer config system and
4
+ // injects relevant criteria into spec content based on context detection.
5
+ //
6
+ // Source: src/config/compliance-frameworks.json (system defaults)
7
+ // Override: data/global/compliance-frameworks-custom.json
8
+ // data/projects/{hash}/config/compliance-frameworks-overrides.json
9
+ import { z } from 'zod';
10
+ import { ConfigLoader } from './config-loader.js';
11
+ // ---------------------------------------------------------------------------
12
+ // Schema
13
+ // ---------------------------------------------------------------------------
14
+ export const ComplianceFrameworkDefSchema = z.object({
15
+ id: z.string().min(1).describe('Framework identifier (e.g. "gdpr", "iso-27001", "hipaa")'),
16
+ name: z.string().min(1).describe('Short framework name (e.g. "GDPR", "ISO 27001")'),
17
+ fullName: z.string().min(1).describe('Full framework name'),
18
+ type: z
19
+ .enum(['privacy', 'security', 'quality', 'testing', 'accessibility'])
20
+ .describe('Framework type'),
21
+ regions: z.array(z.string()).describe('Applicable regions or countries (use "global" for all)'),
22
+ triggerKeywords: z
23
+ .array(z.string())
24
+ .describe('Keywords in spec/project content that suggest this framework applies'),
25
+ dataTypes: z
26
+ .array(z.string())
27
+ .describe('Sensitive data types this framework covers (pii, financial, health, etc.)'),
28
+ criteria: z
29
+ .array(z.string())
30
+ .min(1)
31
+ .describe('Acceptance criteria to inject into specs when framework is detected'),
32
+ references: z.array(z.string()).describe('Official documentation URLs'),
33
+ });
34
+ const frameworksArraySchema = z.array(ComplianceFrameworkDefSchema);
35
+ // ---------------------------------------------------------------------------
36
+ // Loader singleton
37
+ // ---------------------------------------------------------------------------
38
+ let _loader = null;
39
+ function getLoader() {
40
+ _loader ??= new ConfigLoader('compliance-frameworks', frameworksArraySchema);
41
+ return _loader;
42
+ }
43
+ // ---------------------------------------------------------------------------
44
+ // Public API
45
+ // ---------------------------------------------------------------------------
46
+ /**
47
+ * Load all compliance framework definitions from the 3-layer config system.
48
+ */
49
+ export function loadComplianceFrameworkDefs(projectHash) {
50
+ return getLoader().load(projectHash);
51
+ }
52
+ /**
53
+ * Detect which compliance frameworks apply to the given context.
54
+ *
55
+ * A framework is applicable when ANY of its triggerKeywords appear in the
56
+ * combined context string (spec description + project stack).
57
+ */
58
+ export function detectApplicableFrameworks(context, projectHash) {
59
+ const lower = context.toLowerCase();
60
+ const all = loadComplianceFrameworkDefs(projectHash);
61
+ return all.filter((fw) => fw.triggerKeywords.some((kw) => lower.includes(kw.toLowerCase())));
62
+ }
63
+ /**
64
+ * Generate acceptance criteria to inject into a spec based on detected frameworks.
65
+ * Deduplicates criteria across frameworks and caps at maxCriteria (default: 8).
66
+ */
67
+ export function generateComplianceCriteria(context, projectHash, maxCriteria = 8) {
68
+ const frameworks = detectApplicableFrameworks(context, projectHash);
69
+ const seen = new Set();
70
+ const result = [];
71
+ for (const fw of frameworks) {
72
+ for (const criterion of fw.criteria) {
73
+ if (!seen.has(criterion) && result.length < maxCriteria) {
74
+ seen.add(criterion);
75
+ result.push(criterion);
76
+ }
77
+ }
78
+ }
79
+ return result;
80
+ }
81
+ /**
82
+ * Build a markdown compliance section summarizing detected frameworks and their criteria.
83
+ * Intended for injection into technical.md.
84
+ */
85
+ export function buildComplianceSection(context, projectHash) {
86
+ const frameworks = detectApplicableFrameworks(context, projectHash);
87
+ if (frameworks.length === 0) {
88
+ return '';
89
+ }
90
+ const lines = [
91
+ '## Compliance Frameworks',
92
+ '',
93
+ '> **Note**: The following compliance frameworks were automatically detected based on project context.',
94
+ '> Verify applicability with your legal/compliance team.',
95
+ '',
96
+ ];
97
+ for (const fw of frameworks) {
98
+ lines.push(`### ${fw.name} — ${fw.fullName}`);
99
+ lines.push('');
100
+ lines.push(`**Type**: ${fw.type} | **Regions**: ${fw.regions.join(', ')}`);
101
+ lines.push('');
102
+ lines.push('**Required criteria:**');
103
+ lines.push('');
104
+ for (const criterion of fw.criteria) {
105
+ lines.push(`- [ ] ${criterion}`);
106
+ }
107
+ lines.push('');
108
+ if (fw.references.length > 0) {
109
+ lines.push(`**References**: ${fw.references.map((r) => `[${r}](${r})`).join(' | ')}`);
110
+ lines.push('');
111
+ }
112
+ }
113
+ return lines.join('\n');
114
+ }
115
+ /**
116
+ * Get framework by ID. Returns undefined if not found.
117
+ */
118
+ export function getFrameworkById(id, projectHash) {
119
+ return loadComplianceFrameworkDefs(projectHash).find((fw) => fw.id === id);
120
+ }
121
+ //# sourceMappingURL=compliance-injector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compliance-injector.js","sourceRoot":"","sources":["../../src/engine/compliance-injector.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,EAAE;AACF,4EAA4E;AAC5E,0EAA0E;AAC1E,EAAE;AACF,kEAAkE;AAClE,0DAA0D;AAC1D,6EAA6E;AAE7E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,8EAA8E;AAC9E,SAAS;AACT,8EAA8E;AAE9E,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,MAAM,CAAC;IACnD,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,0DAA0D,CAAC;IAC1F,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,iDAAiD,CAAC;IACnF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC;IAC3D,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;SACpE,QAAQ,CAAC,gBAAgB,CAAC;IAC7B,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,wDAAwD,CAAC;IAC/F,eAAe,EAAE,CAAC;SACf,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,CAAC,sEAAsE,CAAC;IACnF,SAAS,EAAE,CAAC;SACT,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,CAAC,2EAA2E,CAAC;IACxF,QAAQ,EAAE,CAAC;SACR,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CAAC,qEAAqE,CAAC;IAClF,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,6BAA6B,CAAC;CACxE,CAAC,CAAC;AAIH,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;AAEpE,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,IAAI,OAAO,GAAgD,IAAI,CAAC;AAEhE,SAAS,SAAS;IAChB,OAAO,KAAK,IAAI,YAAY,CAC1B,uBAAuB,EACvB,qBAAqB,CACtB,CAAC;IACF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;GAEG;AACH,MAAM,UAAU,2BAA2B,CAAC,WAAoB;IAC9D,OAAO,SAAS,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AACvC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CACxC,OAAe,EACf,WAAoB;IAEpB,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACpC,MAAM,GAAG,GAAG,2BAA2B,CAAC,WAAW,CAAC,CAAC;IAErD,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/F,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CACxC,OAAe,EACf,WAAoB,EACpB,WAAW,GAAG,CAAC;IAEf,MAAM,UAAU,GAAG,0BAA0B,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;QAC5B,KAAK,MAAM,SAAS,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,WAAW,EAAE,CAAC;gBACxD,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBACpB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAe,EAAE,WAAoB;IAC1E,MAAM,UAAU,GAAG,0BAA0B,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAEpE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAa;QACtB,0BAA0B;QAC1B,EAAE;QACF,uGAAuG;QACvG,yDAAyD;QACzD,EAAE;KACH,CAAC;IAEF,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC9C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,IAAI,mBAAmB,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,MAAM,SAAS,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC,SAAS,SAAS,EAAE,CAAC,CAAC;QACnC,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACtF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,EAAU,EACV,WAAoB;IAEpB,OAAO,2BAA2B,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAC7E,CAAC"}
@@ -2,13 +2,14 @@ import type { Spec, DefinitionOfDone, DoDItem, DoRDoDValidationResult } from '..
2
2
  /**
3
3
  * Generate a Definition of Done checklist derived from spec metadata.
4
4
  * criteriaCount reflects how many acceptance criteria exist in HU.md.
5
+ * Optionally pass a projectHash to load project-level overrides.
5
6
  */
6
- export declare function generateDoD(spec: Spec, criteriaCount?: number): DefinitionOfDone;
7
+ export declare function generateDoD(spec: Spec, criteriaCount?: number, projectHash?: string): DefinitionOfDone;
7
8
  /**
8
9
  * Validate a spec's DoD.
9
10
  * Both failed AND pending required items are blocking (manual items need explicit confirmation).
10
11
  */
11
- export declare function validateDoD(spec: Spec): DoRDoDValidationResult;
12
+ export declare function validateDoD(spec: Spec, projectHash?: string): DoRDoDValidationResult;
12
13
  /**
13
14
  * Add a custom item to an existing DoD checklist.
14
15
  */
@@ -1 +1 @@
1
- {"version":3,"file":"dod.d.ts","sourceRoot":"","sources":["../../../src/engine/dor-dod/dod.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAyGpG;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,SAAI,GAAG,gBAAgB,CAG3E;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,sBAAsB,CAoB9D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,OAAO,GAAG,gBAAgB,CAGvF"}
1
+ {"version":3,"file":"dod.d.ts","sourceRoot":"","sources":["../../../src/engine/dor-dod/dod.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AA2EpG;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,SAAI,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAGjG;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,sBAAsB,CAoBpF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,OAAO,GAAG,gBAAgB,CAGvF"}