great-cto 1.0.124 → 1.0.125

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.
@@ -1,7 +1,80 @@
1
1
  // Archetype decision: detected stack → archetype recommendation.
2
- // Mirrors great_cto's 10 archetypes in skills/great_cto/ARCHETYPES.md.
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"].includes(t));
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "great-cto",
3
- "version": "1.0.124",
3
+ "version": "1.0.125",
4
4
  "description": "One command install for the great_cto Claude Code plugin. Auto-detects your stack, picks the right archetype, bootstraps PROJECT.md.",
5
5
  "keywords": [
6
6
  "claude-code",