great-cto 1.0.124 → 1.0.126
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 +92 -2
- package/dist/detect.js +128 -0
- package/dist/main.js +4 -3
- package/package.json +1 -1
package/dist/archetypes.js
CHANGED
|
@@ -1,7 +1,80 @@
|
|
|
1
1
|
// Archetype decision: detected stack → archetype recommendation.
|
|
2
|
-
// Mirrors great_cto's
|
|
2
|
+
// Mirrors great_cto's 13 archetypes in skills/great_cto/ARCHETYPES.md.
|
|
3
3
|
// Rules are evaluated; highest score wins.
|
|
4
4
|
const RULES = [
|
|
5
|
+
// ── browser-extension ─────────────────────────────
|
|
6
|
+
// High priority: explicit MV3 manifest signal beats web-service / library
|
|
7
|
+
{
|
|
8
|
+
archetype: "browser-extension",
|
|
9
|
+
score: (d) => (d.stack.includes("browser-extension") ? 8 : 0),
|
|
10
|
+
reason: (_d) => "manifest.json with manifest_version detected — Chrome/Firefox/Edge extension",
|
|
11
|
+
},
|
|
12
|
+
// ── game ─────────────────────────────────────────
|
|
13
|
+
// High priority: Unity / Unreal / Godot signals beat library
|
|
14
|
+
{
|
|
15
|
+
archetype: "game",
|
|
16
|
+
score: (d) => {
|
|
17
|
+
let s = 0;
|
|
18
|
+
if (d.stack.includes("unity"))
|
|
19
|
+
s += 8;
|
|
20
|
+
if (d.stack.includes("unreal"))
|
|
21
|
+
s += 8;
|
|
22
|
+
if (d.stack.includes("godot"))
|
|
23
|
+
s += 8;
|
|
24
|
+
if (d.stack.includes("phaser"))
|
|
25
|
+
s += 6;
|
|
26
|
+
if (d.stack.includes("cocos"))
|
|
27
|
+
s += 6;
|
|
28
|
+
return s;
|
|
29
|
+
},
|
|
30
|
+
reason: (d) => {
|
|
31
|
+
const bits = [];
|
|
32
|
+
if (d.stack.includes("unity"))
|
|
33
|
+
bits.push("Unity");
|
|
34
|
+
if (d.stack.includes("unreal"))
|
|
35
|
+
bits.push("Unreal");
|
|
36
|
+
if (d.stack.includes("godot"))
|
|
37
|
+
bits.push("Godot");
|
|
38
|
+
if (d.stack.includes("phaser"))
|
|
39
|
+
bits.push("Phaser");
|
|
40
|
+
if (d.stack.includes("cocos"))
|
|
41
|
+
bits.push("Cocos");
|
|
42
|
+
return `game engine detected: ${bits.join(", ")} — netcode/anti-cheat/age-rating gates`;
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
// ── devtools ─────────────────────────────────────
|
|
46
|
+
// High priority: OpenAPI + multi-language SDK presence beats library
|
|
47
|
+
{
|
|
48
|
+
archetype: "devtools",
|
|
49
|
+
score: (d) => {
|
|
50
|
+
let s = 0;
|
|
51
|
+
if (d.stack.includes("devtools-api"))
|
|
52
|
+
s += 7;
|
|
53
|
+
if (d.stack.includes("openapi-spec"))
|
|
54
|
+
s += 4;
|
|
55
|
+
if (d.stack.includes("graphql-schema"))
|
|
56
|
+
s += 3;
|
|
57
|
+
if (d.stack.includes("multi-sdk"))
|
|
58
|
+
s += 4;
|
|
59
|
+
if (d.stack.includes("stainless"))
|
|
60
|
+
s += 4;
|
|
61
|
+
if (d.stack.includes("docs-platform"))
|
|
62
|
+
s += 2;
|
|
63
|
+
return s;
|
|
64
|
+
},
|
|
65
|
+
reason: (d) => {
|
|
66
|
+
const bits = [];
|
|
67
|
+
if (d.stack.includes("openapi-spec"))
|
|
68
|
+
bits.push("OpenAPI spec");
|
|
69
|
+
if (d.stack.includes("graphql-schema"))
|
|
70
|
+
bits.push("GraphQL schema");
|
|
71
|
+
if (d.stack.includes("multi-sdk"))
|
|
72
|
+
bits.push("multi-language SDKs");
|
|
73
|
+
if (d.stack.includes("stainless"))
|
|
74
|
+
bits.push("Stainless");
|
|
75
|
+
return `developer-tools platform detected (${bits.join(", ")}) — API stability + SDK quality gates`;
|
|
76
|
+
},
|
|
77
|
+
},
|
|
5
78
|
// ── commerce ─────────────────────────────────────
|
|
6
79
|
{
|
|
7
80
|
archetype: "commerce",
|
|
@@ -182,7 +255,8 @@ const RULES = [
|
|
|
182
255
|
const hasApp = d.stack.some((t) => ["next.js", "django", "fastapi", "flask", "express", "fastify", "nestjs", "hono",
|
|
183
256
|
"react-native", "expo", "tauri", "capacitor", "flutter",
|
|
184
257
|
"terraform", "pulumi", "aws-cdk", "helm",
|
|
185
|
-
"embedded", "zephyr", "esp-idf"
|
|
258
|
+
"embedded", "zephyr", "esp-idf",
|
|
259
|
+
"browser-extension", "unity", "unreal", "godot", "phaser", "cocos"].includes(t));
|
|
186
260
|
if (hasApp)
|
|
187
261
|
return 0;
|
|
188
262
|
if (d.stack.includes("nodejs") || d.stack.includes("python") || d.stack.includes("go") || d.stack.includes("rust")) {
|
|
@@ -239,6 +313,22 @@ export function suggestCompliance(d, archetype) {
|
|
|
239
313
|
if (archetype === "iot-embedded") {
|
|
240
314
|
c.add("iso27001");
|
|
241
315
|
}
|
|
316
|
+
if (archetype === "browser-extension") {
|
|
317
|
+
c.add("csp");
|
|
318
|
+
c.add("mv3-security");
|
|
319
|
+
c.add("gdpr");
|
|
320
|
+
}
|
|
321
|
+
if (archetype === "game") {
|
|
322
|
+
c.add("coppa");
|
|
323
|
+
c.add("age-rating");
|
|
324
|
+
c.add("accessibility");
|
|
325
|
+
}
|
|
326
|
+
if (archetype === "devtools") {
|
|
327
|
+
c.add("openssf");
|
|
328
|
+
c.add("api-stability");
|
|
329
|
+
c.add("soc2-type-2");
|
|
330
|
+
c.add("gdpr");
|
|
331
|
+
}
|
|
242
332
|
if (d.stack.includes("stripe"))
|
|
243
333
|
c.add("pci-dss");
|
|
244
334
|
// Reasonable default for any web service storing user data
|
package/dist/detect.js
CHANGED
|
@@ -467,6 +467,134 @@ export function detect(dir) {
|
|
|
467
467
|
sig("web3", "solidity-files");
|
|
468
468
|
stack.add("solidity");
|
|
469
469
|
}
|
|
470
|
+
// ── Browser extension (MV2/MV3) ──────────────────────────
|
|
471
|
+
// manifest.json at repo root with "manifest_version" → Chrome/Firefox/Edge extension
|
|
472
|
+
const manifestPath = join(dir, "manifest.json");
|
|
473
|
+
if (existsSync(manifestPath)) {
|
|
474
|
+
try {
|
|
475
|
+
const m = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
476
|
+
if (m.manifest_version === 2 || m.manifest_version === 3) {
|
|
477
|
+
sig("browser-extension", `manifest_version=${m.manifest_version}`);
|
|
478
|
+
stack.add("browser-extension");
|
|
479
|
+
if (m.manifest_version === 3)
|
|
480
|
+
stack.add("mv3");
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
catch { /* not a browser-ext manifest */ }
|
|
484
|
+
}
|
|
485
|
+
// WXT framework signal
|
|
486
|
+
if (existsSync(join(dir, "wxt.config.ts")) || existsSync(join(dir, "wxt.config.js"))) {
|
|
487
|
+
sig("browser-extension", "wxt");
|
|
488
|
+
stack.add("browser-extension");
|
|
489
|
+
stack.add("wxt");
|
|
490
|
+
}
|
|
491
|
+
// Plasmo framework signal
|
|
492
|
+
if (existsSync(join(dir, ".plasmo"))) {
|
|
493
|
+
sig("browser-extension", "plasmo");
|
|
494
|
+
stack.add("browser-extension");
|
|
495
|
+
stack.add("plasmo");
|
|
496
|
+
}
|
|
497
|
+
// ── Game engines ─────────────────────────────────────────
|
|
498
|
+
// Unity: ProjectSettings/ + Assets/
|
|
499
|
+
if (existsSync(join(dir, "ProjectSettings")) && existsSync(join(dir, "Assets"))) {
|
|
500
|
+
sig("game", "unity");
|
|
501
|
+
stack.add("unity");
|
|
502
|
+
stack.add("game");
|
|
503
|
+
languages.add("csharp");
|
|
504
|
+
}
|
|
505
|
+
// Unreal: any .uproject file
|
|
506
|
+
if (safeGlob(dir, /\.uproject$/)) {
|
|
507
|
+
sig("game", "unreal");
|
|
508
|
+
stack.add("unreal");
|
|
509
|
+
stack.add("game");
|
|
510
|
+
languages.add("cpp");
|
|
511
|
+
}
|
|
512
|
+
// Godot: project.godot
|
|
513
|
+
if (existsSync(join(dir, "project.godot"))) {
|
|
514
|
+
sig("game", "godot");
|
|
515
|
+
stack.add("godot");
|
|
516
|
+
stack.add("game");
|
|
517
|
+
languages.add("gdscript");
|
|
518
|
+
}
|
|
519
|
+
// Phaser / Cocos / PlayCanvas (web-game frameworks via package.json deps)
|
|
520
|
+
{
|
|
521
|
+
const allDeps = {
|
|
522
|
+
...(pkg.dependencies ?? {}),
|
|
523
|
+
...(pkg.devDependencies ?? {}),
|
|
524
|
+
};
|
|
525
|
+
if ("phaser" in allDeps) {
|
|
526
|
+
stack.add("phaser");
|
|
527
|
+
stack.add("game");
|
|
528
|
+
sig("game", "phaser");
|
|
529
|
+
}
|
|
530
|
+
if ("cocos2d" in allDeps) {
|
|
531
|
+
stack.add("cocos");
|
|
532
|
+
stack.add("game");
|
|
533
|
+
sig("game", "cocos");
|
|
534
|
+
}
|
|
535
|
+
if ("playcanvas" in allDeps) {
|
|
536
|
+
stack.add("playcanvas");
|
|
537
|
+
stack.add("game");
|
|
538
|
+
sig("game", "playcanvas");
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
// ── DevTools / API platform ──────────────────────────────
|
|
542
|
+
// OpenAPI / Swagger spec at root or in api/ dir
|
|
543
|
+
const openapiPaths = ["openapi.yaml", "openapi.yml", "openapi.json", "swagger.yaml", "swagger.json",
|
|
544
|
+
"api/openapi.yaml", "api/openapi.yml", "api/openapi.json"];
|
|
545
|
+
for (const p of openapiPaths) {
|
|
546
|
+
if (existsSync(join(dir, p))) {
|
|
547
|
+
sig("devtools", `openapi:${p}`);
|
|
548
|
+
stack.add("openapi-spec");
|
|
549
|
+
break;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
// GraphQL schema at root
|
|
553
|
+
if (existsSync(join(dir, "schema.graphql")) || existsSync(join(dir, "schema.gql"))) {
|
|
554
|
+
sig("devtools", "graphql-schema");
|
|
555
|
+
stack.add("graphql-schema");
|
|
556
|
+
}
|
|
557
|
+
// Stainless config (multi-SDK generation)
|
|
558
|
+
if (existsSync(join(dir, "stainless.yml")) || existsSync(join(dir, "stainless.yaml"))) {
|
|
559
|
+
sig("devtools", "stainless");
|
|
560
|
+
stack.add("stainless");
|
|
561
|
+
stack.add("multi-sdk");
|
|
562
|
+
}
|
|
563
|
+
// Multi-language SDK presence: sdks/ or clients/ with multiple language sub-dirs
|
|
564
|
+
const sdkRoots = ["sdks", "clients", "packages/sdk", "packages/clients"];
|
|
565
|
+
for (const root of sdkRoots) {
|
|
566
|
+
const rootPath = join(dir, root);
|
|
567
|
+
if (existsSync(rootPath)) {
|
|
568
|
+
try {
|
|
569
|
+
const sub = readdirSync(rootPath).filter((e) => {
|
|
570
|
+
try {
|
|
571
|
+
return statSync(join(rootPath, e)).isDirectory();
|
|
572
|
+
}
|
|
573
|
+
catch {
|
|
574
|
+
return false;
|
|
575
|
+
}
|
|
576
|
+
});
|
|
577
|
+
// ≥3 sub-dirs that look like language names → multi-SDK platform
|
|
578
|
+
const langPattern = /^(python|node|typescript|javascript|go|ruby|java|kotlin|php|rust|csharp|dotnet|swift|elixir)$/i;
|
|
579
|
+
const hits = sub.filter((s) => langPattern.test(s));
|
|
580
|
+
if (hits.length >= 3) {
|
|
581
|
+
sig("devtools", `multi-sdk:${root}:${hits.join(",")}`);
|
|
582
|
+
stack.add("multi-sdk");
|
|
583
|
+
break;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
catch { /* ignore */ }
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
// Mintlify docs (signal of devtools / API platform docs-as-product)
|
|
590
|
+
if (existsSync(join(dir, "mint.json")) || existsSync(join(dir, "docs.json"))) {
|
|
591
|
+
sig("devtools", "mintlify");
|
|
592
|
+
stack.add("docs-platform");
|
|
593
|
+
}
|
|
594
|
+
// Aggregate signal: OpenAPI + multi-SDK ⇒ explicit devtools-api flag
|
|
595
|
+
if (stack.has("openapi-spec") && stack.has("multi-sdk")) {
|
|
596
|
+
stack.add("devtools-api");
|
|
597
|
+
}
|
|
470
598
|
// ── Embedded ─────────────────────────────────────────────
|
|
471
599
|
if (existsSync(join(dir, "platformio.ini")) ||
|
|
472
600
|
existsSync(join(dir, "sdkconfig")) ||
|
package/dist/main.js
CHANGED
|
@@ -69,8 +69,9 @@ ${bold("Options:")}
|
|
|
69
69
|
--dry-run Show what would be done without doing it
|
|
70
70
|
--force Reinstall even if already present
|
|
71
71
|
--archetype NAME Override detected archetype
|
|
72
|
-
(${cyan("web-service|mobile-app|ai-system|commerce|web3|")}
|
|
73
|
-
${cyan("data-platform|infra|library|iot-embedded|regulated")}
|
|
72
|
+
(${cyan("web-service|mobile-app|ai-system|agent-product|commerce|web3|")}
|
|
73
|
+
${cyan("data-platform|infra|library|iot-embedded|regulated|")}
|
|
74
|
+
${cyan("devtools|browser-extension|game")})
|
|
74
75
|
--version-tag VER Pin to specific great_cto version (default: latest)
|
|
75
76
|
--dir PATH Run against a different directory (default: cwd)
|
|
76
77
|
-h, --help Show this help
|
|
@@ -78,7 +79,7 @@ ${bold("Options:")}
|
|
|
78
79
|
|
|
79
80
|
${bold("What it does:")}
|
|
80
81
|
1. Scans your project for stack signals (package.json, Cargo.toml, go.mod, etc.)
|
|
81
|
-
2. Picks the matching great_cto archetype (web-service, commerce, ai-system, ...)
|
|
82
|
+
2. Picks the matching great_cto archetype (web-service, commerce, ai-system, devtools, browser-extension, game, ...)
|
|
82
83
|
3. Clones the plugin into ~/.claude/plugins/cache/local/great_cto/<version>/
|
|
83
84
|
4. Enables the plugin in ~/.claude/settings.json
|
|
84
85
|
5. Creates .great_cto/PROJECT.md pre-filled with archetype + detected stack
|
package/package.json
CHANGED