great-cto 2.1.0 → 2.2.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/dist/archetypes.js +213 -5
- package/package.json +1 -1
package/dist/archetypes.js
CHANGED
|
@@ -141,17 +141,20 @@ const RULES = [
|
|
|
141
141
|
archetype: "agent-product",
|
|
142
142
|
score: (d) => {
|
|
143
143
|
const llms = ["anthropic-sdk", "openai-sdk", "google-ai", "aws-bedrock", "cohere"];
|
|
144
|
+
const llmFrameworks = ["langchain", "llamaindex"]; // RAG-capable LLM frameworks
|
|
144
145
|
const vdbs = ["pinecone", "weaviate", "chroma", "qdrant"];
|
|
145
146
|
const agents = ["langgraph", "crewai", "autogen", "mastra", "mcp"];
|
|
146
147
|
const hasLlm = llms.some((s) => d.stack.includes(s));
|
|
148
|
+
const hasLlmFw = llmFrameworks.some((s) => d.stack.includes(s));
|
|
147
149
|
const hasVdb = vdbs.some((s) => d.stack.includes(s));
|
|
148
150
|
const hasAgentFw = agents.some((s) => d.stack.includes(s));
|
|
149
151
|
let s = 0;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
+
// RAG-style agent: any LLM (raw SDK or framework) + vector DB
|
|
153
|
+
if ((hasLlm || hasLlmFw) && hasVdb)
|
|
154
|
+
s += 7;
|
|
152
155
|
if (hasAgentFw)
|
|
153
156
|
s += 6; // explicit agent framework
|
|
154
|
-
if (hasLlm && hasAgentFw)
|
|
157
|
+
if ((hasLlm || hasLlmFw) && hasAgentFw)
|
|
155
158
|
s += 2; // bonus
|
|
156
159
|
// README mining hint
|
|
157
160
|
if (d.readmeKeywords.includes("agent") || d.readmeKeywords.includes("ai"))
|
|
@@ -212,8 +215,17 @@ const RULES = [
|
|
|
212
215
|
if (agents.some((a) => d.stack.includes(a)))
|
|
213
216
|
s = Math.max(0, s - 2);
|
|
214
217
|
const vdbs = ["pinecone", "weaviate", "chroma", "qdrant"];
|
|
215
|
-
|
|
218
|
+
const hasVdb = vdbs.some((v) => d.stack.includes(v));
|
|
219
|
+
if (hasVdb)
|
|
216
220
|
s = Math.max(0, s - 2);
|
|
221
|
+
// Strong RAG signal — LangChain/LlamaIndex + VDB is almost certainly
|
|
222
|
+
// an agent-product (RAG-style), not a generic ai-system. The +5 score
|
|
223
|
+
// these frameworks contribute (above) is appropriate when there's no
|
|
224
|
+
// VDB; with a VDB it overcounts. Apply an additional deduction so
|
|
225
|
+
// agent-product wins the tie. See test "LangChain + Pinecone → agent-product".
|
|
226
|
+
const hasLlmFw = ["langchain", "llamaindex"].some((s) => d.stack.includes(s));
|
|
227
|
+
if (hasVdb && hasLlmFw)
|
|
228
|
+
s = Math.max(0, s - 5);
|
|
217
229
|
return s;
|
|
218
230
|
},
|
|
219
231
|
reason: (d) => {
|
|
@@ -794,12 +806,173 @@ const RULES = [
|
|
|
794
806
|
return "no web/mobile/infra framework detected — looks like a library/SDK";
|
|
795
807
|
},
|
|
796
808
|
},
|
|
809
|
+
// ── edtech (education technology — COPPA / FERPA / WCAG-AA child safety) ──
|
|
810
|
+
// Distinct from cms (general content) and healthcare (PHI). Drives age-gate,
|
|
811
|
+
// parental-consent, and accessibility patterns.
|
|
812
|
+
{
|
|
813
|
+
archetype: "edtech",
|
|
814
|
+
score: (d) => {
|
|
815
|
+
let s = 0;
|
|
816
|
+
const lmsLibs = ["canvas-lms", "moodle-api", "schoology-sdk", "blackboard-rest",
|
|
817
|
+
"google-classroom", "khan-academy-cli", "learnosity",
|
|
818
|
+
"kahoot-api", "h5p", "scorm", "lti", "lti-1.3"];
|
|
819
|
+
lmsLibs.forEach((l) => { if (d.stack.includes(l))
|
|
820
|
+
s += 6; });
|
|
821
|
+
// Auth/identity providers commonly used in edtech
|
|
822
|
+
if (d.stack.includes("clever-sdk"))
|
|
823
|
+
s += 6;
|
|
824
|
+
if (d.stack.includes("classlink-sso"))
|
|
825
|
+
s += 4;
|
|
826
|
+
const kws = d.readmeKeywords;
|
|
827
|
+
const eduKeywords = ["student", "classroom", "teacher", "k-12", "k12",
|
|
828
|
+
"lms", "learning management", "grade book", "gradebook",
|
|
829
|
+
"enrollment", "transcript", "pupil", "tutoring", "edtech"];
|
|
830
|
+
const matchedKws = eduKeywords.filter((k) => kws.includes(k));
|
|
831
|
+
if (matchedKws.length >= 2)
|
|
832
|
+
s += 5;
|
|
833
|
+
else if (matchedKws.length === 1)
|
|
834
|
+
s += 2;
|
|
835
|
+
// Strong signal: COPPA / FERPA explicitly mentioned
|
|
836
|
+
if (kws.includes("coppa") || kws.includes("ferpa"))
|
|
837
|
+
s += 6;
|
|
838
|
+
if (kws.includes("parental consent") || kws.includes("age gate"))
|
|
839
|
+
s += 4;
|
|
840
|
+
return s;
|
|
841
|
+
},
|
|
842
|
+
reason: (d) => {
|
|
843
|
+
const kws = d.readmeKeywords;
|
|
844
|
+
const bits = [];
|
|
845
|
+
const lmsLibs = ["canvas-lms", "moodle-api", "schoology-sdk", "google-classroom", "lti", "scorm"];
|
|
846
|
+
lmsLibs.forEach((l) => { if (d.stack.includes(l))
|
|
847
|
+
bits.push(l); });
|
|
848
|
+
if (kws.includes("coppa"))
|
|
849
|
+
bits.push("COPPA mention");
|
|
850
|
+
if (kws.includes("ferpa"))
|
|
851
|
+
bits.push("FERPA mention");
|
|
852
|
+
if (kws.includes("k-12") || kws.includes("k12"))
|
|
853
|
+
bits.push("K-12 keyword");
|
|
854
|
+
if (kws.includes("student"))
|
|
855
|
+
bits.push("student-data keyword");
|
|
856
|
+
return `edtech detected (${bits.join(", ") || "education domain signals"}) — COPPA/FERPA/WCAG-AA child-safety gates required`;
|
|
857
|
+
},
|
|
858
|
+
},
|
|
859
|
+
// ── gov-public (government / civic-tech — FedRAMP / NIST 800-53 / Section 508) ──
|
|
860
|
+
// Severe regulatory burden. Distinct from regulated (which is more EU-focused
|
|
861
|
+
// DORA/NIS2). gov-public targets US federal/state + UK gov.uk patterns.
|
|
862
|
+
{
|
|
863
|
+
archetype: "gov-public",
|
|
864
|
+
score: (d) => {
|
|
865
|
+
let s = 0;
|
|
866
|
+
const govLibs = ["login-gov-sdk", "id-me-sdk", "idme-sdk",
|
|
867
|
+
"usds-design-system", "uswds", "uk-gov-design-system",
|
|
868
|
+
"gov-uk-frontend", "verify-gov-uk",
|
|
869
|
+
"usajobs-sdk", "data-gov", "irs-modernized-efile"];
|
|
870
|
+
govLibs.forEach((l) => { if (d.stack.includes(l))
|
|
871
|
+
s += 6; });
|
|
872
|
+
const kws = d.readmeKeywords;
|
|
873
|
+
const govKeywords = ["fedramp", "fisma", "nist 800-53", "nist-800-53",
|
|
874
|
+
"section 508", "section-508", "ato", "civic tech",
|
|
875
|
+
"government", "municipal", "federal", "agency",
|
|
876
|
+
"gov.uk", "usds", "data.gov", "usa.gov", "irs", "ssa",
|
|
877
|
+
"department of", "stateramp", "cjis"];
|
|
878
|
+
const matchedKws = govKeywords.filter((k) => kws.includes(k));
|
|
879
|
+
if (matchedKws.length >= 2)
|
|
880
|
+
s += 6;
|
|
881
|
+
else if (matchedKws.length === 1)
|
|
882
|
+
s += 3;
|
|
883
|
+
// Very strong signals
|
|
884
|
+
if (kws.includes("fedramp") || kws.includes("fisma"))
|
|
885
|
+
s += 4;
|
|
886
|
+
if (kws.includes("section 508") || kws.includes("section-508"))
|
|
887
|
+
s += 3;
|
|
888
|
+
if (kws.includes("ato"))
|
|
889
|
+
s += 3;
|
|
890
|
+
return s;
|
|
891
|
+
},
|
|
892
|
+
reason: (d) => {
|
|
893
|
+
const kws = d.readmeKeywords;
|
|
894
|
+
const bits = [];
|
|
895
|
+
if (d.stack.includes("login-gov-sdk"))
|
|
896
|
+
bits.push("login.gov");
|
|
897
|
+
if (d.stack.includes("usds-design-system") || d.stack.includes("uswds"))
|
|
898
|
+
bits.push("USWDS");
|
|
899
|
+
if (d.stack.includes("uk-gov-design-system") || d.stack.includes("gov-uk-frontend"))
|
|
900
|
+
bits.push("gov.uk Design System");
|
|
901
|
+
if (kws.includes("fedramp"))
|
|
902
|
+
bits.push("FedRAMP mention");
|
|
903
|
+
if (kws.includes("nist-800-53") || kws.includes("nist 800-53"))
|
|
904
|
+
bits.push("NIST 800-53 mention");
|
|
905
|
+
if (kws.includes("section 508") || kws.includes("section-508"))
|
|
906
|
+
bits.push("Section 508 mention");
|
|
907
|
+
return `gov-public detected (${bits.join(", ") || "government domain signals"}) — FedRAMP/NIST 800-53/Section 508 gates required`;
|
|
908
|
+
},
|
|
909
|
+
},
|
|
910
|
+
// ── insurance (insurtech — NAIC / Solvency II / actuarial / claims fraud) ──
|
|
911
|
+
// Fintech-adjacent but distinct: multi-state filings, anti-discrimination
|
|
912
|
+
// pricing, actuarial model auditability, claims fraud detection.
|
|
913
|
+
{
|
|
914
|
+
archetype: "insurance",
|
|
915
|
+
score: (d) => {
|
|
916
|
+
let s = 0;
|
|
917
|
+
const insuranceLibs = ["acord-standards", "naic-schemas", "drools-rules",
|
|
918
|
+
"solvency2-calc", "openexposure", "ms-actuarial",
|
|
919
|
+
"lloyds-vendor-api", "verisk-sdk", "ccc-one-sdk",
|
|
920
|
+
"guidewire-cloud", "duck-creek", "majesco-sdk",
|
|
921
|
+
"ebix", "aplus-pas"];
|
|
922
|
+
insuranceLibs.forEach((l) => { if (d.stack.includes(l))
|
|
923
|
+
s += 6; });
|
|
924
|
+
const kws = d.readmeKeywords;
|
|
925
|
+
const insuranceKeywords = ["policy", "underwriting", "premium", "claim",
|
|
926
|
+
"actuarial", "reinsurance", "naic", "solvency",
|
|
927
|
+
"broker", "carrier", "mga", "mgu", "tpa",
|
|
928
|
+
"insurance", "insurtech", "insurer", "insured",
|
|
929
|
+
"deductible", "coverage", "bordereau"];
|
|
930
|
+
const matchedKws = insuranceKeywords.filter((k) => kws.includes(k));
|
|
931
|
+
if (matchedKws.length >= 3)
|
|
932
|
+
s += 6;
|
|
933
|
+
else if (matchedKws.length === 2)
|
|
934
|
+
s += 3;
|
|
935
|
+
else if (matchedKws.length === 1)
|
|
936
|
+
s += 1;
|
|
937
|
+
// Very strong signals — NAIC/Solvency/IFRS 17 explicit
|
|
938
|
+
if (kws.includes("naic") || kws.includes("solvency ii") || kws.includes("solvency-ii"))
|
|
939
|
+
s += 5;
|
|
940
|
+
if (kws.includes("ifrs 17") || kws.includes("ifrs-17"))
|
|
941
|
+
s += 4;
|
|
942
|
+
if (kws.includes("insurtech"))
|
|
943
|
+
s += 4;
|
|
944
|
+
// Don't double-score: if also matches commerce/fintech, subtract
|
|
945
|
+
// since insurance is distinct domain (not generic fintech)
|
|
946
|
+
if (d.stack.includes("stripe") && !insuranceLibs.some((l) => d.stack.includes(l))) {
|
|
947
|
+
s = Math.max(0, s - 2);
|
|
948
|
+
}
|
|
949
|
+
return s;
|
|
950
|
+
},
|
|
951
|
+
reason: (d) => {
|
|
952
|
+
const kws = d.readmeKeywords;
|
|
953
|
+
const bits = [];
|
|
954
|
+
const insuranceLibs = ["acord-standards", "naic-schemas", "guidewire-cloud", "duck-creek", "majesco-sdk"];
|
|
955
|
+
insuranceLibs.forEach((l) => { if (d.stack.includes(l))
|
|
956
|
+
bits.push(l); });
|
|
957
|
+
if (kws.includes("naic"))
|
|
958
|
+
bits.push("NAIC mention");
|
|
959
|
+
if (kws.includes("solvency ii") || kws.includes("solvency-ii"))
|
|
960
|
+
bits.push("Solvency II mention");
|
|
961
|
+
if (kws.includes("actuarial"))
|
|
962
|
+
bits.push("actuarial keyword");
|
|
963
|
+
if (kws.includes("underwriting"))
|
|
964
|
+
bits.push("underwriting keyword");
|
|
965
|
+
if (kws.includes("insurtech"))
|
|
966
|
+
bits.push("insurtech keyword");
|
|
967
|
+
return `insurance detected (${bits.join(", ") || "insurance domain signals"}) — NAIC/Solvency II/actuarial-audit gates required`;
|
|
968
|
+
},
|
|
969
|
+
},
|
|
797
970
|
];
|
|
798
971
|
// Tie-break priority — when two rules score equally, prefer the one
|
|
799
972
|
// higher in this list (more specific / domain-bound first).
|
|
800
973
|
const TIE_BREAK_PRIORITY = [
|
|
801
974
|
"browser-extension", "iot-embedded", "web3", "game",
|
|
802
|
-
"agent-product", "fintech", "healthcare", "marketplace",
|
|
975
|
+
"agent-product", "fintech", "insurance", "healthcare", "edtech", "gov-public", "marketplace",
|
|
803
976
|
"mlops", "streaming",
|
|
804
977
|
"commerce", "enterprise-saas", "ai-system", "devtools",
|
|
805
978
|
"data-platform", "cms", "infra", "mobile-app",
|
|
@@ -944,6 +1117,41 @@ export function suggestCompliance(d, archetype) {
|
|
|
944
1117
|
c.add("gdpr");
|
|
945
1118
|
c.add("dsa-eu");
|
|
946
1119
|
}
|
|
1120
|
+
if (archetype === "edtech") {
|
|
1121
|
+
c.add("coppa");
|
|
1122
|
+
c.add("ferpa");
|
|
1123
|
+
c.add("gdpr-k");
|
|
1124
|
+
c.add("wcag-2.2-aa");
|
|
1125
|
+
c.add("section-508");
|
|
1126
|
+
// State student-privacy laws
|
|
1127
|
+
c.add("sopipa-ca");
|
|
1128
|
+
}
|
|
1129
|
+
if (archetype === "gov-public") {
|
|
1130
|
+
c.add("fedramp");
|
|
1131
|
+
c.add("nist-800-53");
|
|
1132
|
+
c.add("fisma");
|
|
1133
|
+
c.add("section-508");
|
|
1134
|
+
c.add("pia");
|
|
1135
|
+
// CJIS only if law-enforcement keywords present
|
|
1136
|
+
const kws = d.readmeKeywords;
|
|
1137
|
+
if (kws.includes("cjis") || kws.includes("law enforcement") || kws.includes("criminal justice")) {
|
|
1138
|
+
c.add("cjis");
|
|
1139
|
+
}
|
|
1140
|
+
// StateRAMP if state-level
|
|
1141
|
+
if (kws.includes("stateramp") || kws.includes("state government"))
|
|
1142
|
+
c.add("stateramp");
|
|
1143
|
+
c.add("ato"); // Authority to Operate
|
|
1144
|
+
}
|
|
1145
|
+
if (archetype === "insurance") {
|
|
1146
|
+
c.add("naic");
|
|
1147
|
+
c.add("solvency-ii");
|
|
1148
|
+
c.add("ifrs-17");
|
|
1149
|
+
c.add("gdpr");
|
|
1150
|
+
c.add("ccpa");
|
|
1151
|
+
c.add("anti-discrimination-pricing");
|
|
1152
|
+
c.add("actuarial-asops");
|
|
1153
|
+
c.add("state-doi"); // Department of Insurance per US state
|
|
1154
|
+
}
|
|
947
1155
|
// ── stack-derived (cross-archetype) ──────────────
|
|
948
1156
|
if (d.stack.includes("stripe") || d.stack.includes("braintree") ||
|
|
949
1157
|
d.stack.includes("adyen") || d.stack.includes("paddle")) {
|
package/package.json
CHANGED