@omerrgocmen/crewctl 1.1.1 → 1.3.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 (91) hide show
  1. package/README.md +193 -193
  2. package/orchestrator/README.md +473 -462
  3. package/orchestrator/config.default.json +79 -71
  4. package/orchestrator/roles/executor.md +57 -57
  5. package/orchestrator/roles/operator.md +77 -77
  6. package/orchestrator/roles/planner.md +58 -58
  7. package/orchestrator/roles/reviewer.md +63 -63
  8. package/orchestrator/skills/acceptance-criteria.md +18 -18
  9. package/orchestrator/skills/accessibility-audit.md +16 -16
  10. package/orchestrator/skills/accessible-forms.md +16 -16
  11. package/orchestrator/skills/api-design.md +27 -27
  12. package/orchestrator/skills/api-documentation.md +16 -16
  13. package/orchestrator/skills/architecture-decision-record.md +18 -18
  14. package/orchestrator/skills/authentication-design.md +16 -16
  15. package/orchestrator/skills/authorization-review.md +16 -16
  16. package/orchestrator/skills/backward-compatibility.md +17 -17
  17. package/orchestrator/skills/changelog-writing.md +16 -16
  18. package/orchestrator/skills/ci-pipeline-design.md +16 -16
  19. package/orchestrator/skills/cli-design.md +16 -16
  20. package/orchestrator/skills/code-review.md +27 -27
  21. package/orchestrator/skills/configuration-management.md +16 -16
  22. package/orchestrator/skills/container-review.md +16 -16
  23. package/orchestrator/skills/contract-testing.md +16 -16
  24. package/orchestrator/skills/dashboard-design.md +16 -16
  25. package/orchestrator/skills/database-migration.md +16 -16
  26. package/orchestrator/skills/database-schema-design.md +16 -16
  27. package/orchestrator/skills/debugging.md +26 -26
  28. package/orchestrator/skills/dependency-review.md +16 -16
  29. package/orchestrator/skills/design-review.md +29 -29
  30. package/orchestrator/skills/design-system.md +16 -16
  31. package/orchestrator/skills/docs-api-reference.md +16 -16
  32. package/orchestrator/skills/docs-troubleshooting.md +16 -16
  33. package/orchestrator/skills/docs-tutorial.md +16 -16
  34. package/orchestrator/skills/docs-writing.md +25 -25
  35. package/orchestrator/skills/empty-error-loading-states.md +16 -16
  36. package/orchestrator/skills/end-to-end-testing.md +16 -16
  37. package/orchestrator/skills/error-handling.md +16 -16
  38. package/orchestrator/skills/frontend-design.md +28 -28
  39. package/orchestrator/skills/git-commit-writing.md +16 -16
  40. package/orchestrator/skills/graphql-design.md +16 -16
  41. package/orchestrator/skills/incident-runbook.md +18 -18
  42. package/orchestrator/skills/input-validation.md +16 -16
  43. package/orchestrator/skills/integration-testing.md +16 -16
  44. package/orchestrator/skills/interaction-design.md +16 -16
  45. package/orchestrator/skills/landing-page-design.md +16 -16
  46. package/orchestrator/skills/observability-design.md +16 -16
  47. package/orchestrator/skills/openapi-contract.md +16 -16
  48. package/orchestrator/skills/performance-profiling.md +16 -16
  49. package/orchestrator/skills/privacy-review.md +16 -16
  50. package/orchestrator/skills/property-based-testing.md +16 -16
  51. package/orchestrator/skills/pull-request-writing.md +16 -16
  52. package/orchestrator/skills/refactoring.md +16 -16
  53. package/orchestrator/skills/release-readiness.md +16 -16
  54. package/orchestrator/skills/responsive-design.md +16 -16
  55. package/orchestrator/skills/secrets-management.md +16 -16
  56. package/orchestrator/skills/secure-file-upload.md +16 -16
  57. package/orchestrator/skills/security-review.md +26 -26
  58. package/orchestrator/skills/semantic-versioning.md +17 -17
  59. package/orchestrator/skills/seo-on-page.md +16 -16
  60. package/orchestrator/skills/seo-structured-data.md +16 -16
  61. package/orchestrator/skills/seo-technical-audit.md +16 -16
  62. package/orchestrator/skills/sql-query-review.md +16 -16
  63. package/orchestrator/skills/supply-chain-security.md +16 -16
  64. package/orchestrator/skills/test-strategy.md +16 -16
  65. package/orchestrator/skills/threat-modeling.md +16 -16
  66. package/orchestrator/skills/unit-testing.md +16 -16
  67. package/orchestrator/skills/write-tests.md +28 -28
  68. package/orchestrator/src/cli-registry.js +740 -682
  69. package/orchestrator/src/cli.js +140 -135
  70. package/orchestrator/src/doctor.js +64 -64
  71. package/orchestrator/src/engine.js +1735 -1630
  72. package/orchestrator/src/schedule.js +126 -126
  73. package/orchestrator/src/server.js +818 -795
  74. package/orchestrator/src/skill-registry.js +272 -272
  75. package/orchestrator/src/store.js +470 -426
  76. package/orchestrator/web/OrbitControls.js +1417 -1417
  77. package/orchestrator/web/board.html +146 -146
  78. package/orchestrator/web/code.html +213 -213
  79. package/orchestrator/web/flow.html +741 -741
  80. package/orchestrator/web/index.html +602 -602
  81. package/orchestrator/web/jsm/postprocessing/EffectComposer.js +231 -231
  82. package/orchestrator/web/jsm/postprocessing/MaskPass.js +104 -104
  83. package/orchestrator/web/jsm/postprocessing/Pass.js +95 -95
  84. package/orchestrator/web/jsm/postprocessing/RenderPass.js +99 -99
  85. package/orchestrator/web/jsm/postprocessing/ShaderPass.js +77 -77
  86. package/orchestrator/web/jsm/postprocessing/UnrealBloomPass.js +415 -415
  87. package/orchestrator/web/jsm/shaders/CopyShader.js +45 -45
  88. package/orchestrator/web/jsm/shaders/LuminosityHighPassShader.js +66 -66
  89. package/orchestrator/web/site.webmanifest +12 -12
  90. package/orchestrator/web/three.module.min.js +6 -6
  91. package/package.json +51 -51
@@ -1,135 +1,140 @@
1
- #!/usr/bin/env node
2
- const path = require("path");
3
- const store = require("./store");
4
-
5
- const VERSION = require("../../package.json").version;
6
- const VALID_MODES = new Set(["auto", "fast", "balanced", "deep"]);
7
-
8
- function help() {
9
- console.log(`CrewCtl ${VERSION}
10
-
11
- Kurulu kodlama CLI'larini tek kuyrukta yonetin.
12
-
13
- Hizli baslangic:
14
- npx @omerrgocmen/crewctl Paneli aninda baslat (kurulum gerektirmez)
15
- npm i -g @omerrgocmen/crewctl Global kur, ardindan: crewctl
16
-
17
- Kullanim:
18
- crewctl [start] Web panelini baslat (komutsuz = start)
19
- crewctl doctor [--fix] Ortami kontrol et (varsayilan salt okunur)
20
- crewctl run [--once] [--approval mod] Kuyrugu panelsiz calistir
21
- crewctl status [--json] Kuyruk ve butce ozetini goster
22
- crewctl task <hedef> [secenekler] Kuyruga gorev ekle
23
- crewctl approvals Onay bekleyen planlari listele
24
- crewctl approve <id> Plani onayla
25
- crewctl reject <id> Plani reddet
26
-
27
- Task secenekleri:
28
- --dir <klasor> Calisma klasoru
29
- --operator <cli> codex | claude | gemini | opencode
30
- --mode <mod> auto | fast | balanced | deep
31
-
32
- Ornek:
33
- crewctl task "Testleri duzelt" --dir . --mode balanced
34
- crewctl status
35
-
36
- Veri (config, kuyruk, gecmis) ~/.crewctl altinda tutulur (CREWCTL_HOME ile degistirilebilir).
37
- Calisma klasoru varsayilan olarak komutun calistirildigi dizindir; panelden degistirilebilir.
38
- `);
39
- }
40
-
41
- function takeOption(args, name) {
42
- const i = args.indexOf(name);
43
- if (i < 0) return undefined;
44
- if (!args[i + 1] || args[i + 1].startsWith("--")) throw new Error(`${name} icin deger gerekli.`);
45
- return args.splice(i, 2)[1];
46
- }
47
-
48
- function status(asJson) {
49
- store.ensureDirs();
50
- const cfg = store.loadConfig();
51
- const data = {
52
- operator: cfg.operator?.cli || null,
53
- approvalMode: cfg.approvalMode || "auto",
54
- callsToday: store.getCallCount(),
55
- dailyCallBudget: Number(cfg.dailyCallBudget || 0),
56
- queue: Object.fromEntries(["pending", "approval", "done", "failed"].map((s) => [s, store.listTasks(s).length])),
57
- activeAgents: Object.values(cfg.agents || {}).filter((a) => a.enabled !== false).length,
58
- };
59
- if (asJson) return console.log(JSON.stringify(data, null, 2));
60
- console.log(`Operator: ${data.operator || "yok"} | Mod: ${data.approvalMode} | Agent: ${data.activeAgents}`);
61
- console.log(`Kuyruk: ${data.queue.pending} bekleyen, ${data.queue.approval} onay, ${data.queue.done} tamam, ${data.queue.failed} basarisiz`);
62
- console.log(`Butce: ${data.callsToday}/${data.dailyCallBudget} cagri (bugun)`);
63
- }
64
-
65
- function addTask(args) {
66
- const targetDir = takeOption(args, "--dir");
67
- const operator = takeOption(args, "--operator");
68
- const mode = takeOption(args, "--mode") || "auto";
69
- if (!VALID_MODES.has(mode)) throw new Error(`Gecersiz mod: ${mode}`);
70
- const unknown = args.find((arg) => arg.startsWith("--"));
71
- if (unknown) throw new Error(`Bilinmeyen secenek: ${unknown}`);
72
- const prompt = args.join(" ").trim();
73
- if (!prompt) throw new Error("Gorev metni gerekli.");
74
- const cfg = store.loadConfig();
75
- const selectedOperator = operator || cfg.operator?.cli;
76
- const resolvedDir = targetDir ? path.resolve(targetDir) : undefined;
77
- const task = store.addTask(prompt, resolvedDir, selectedOperator, mode);
78
- console.log(`Eklendi: ${task.id}`);
79
- console.log(`Mod: ${mode} | Operator: ${selectedOperator || "varsayilan"}`);
80
- }
81
-
82
- function approvals() {
83
- const tasks = store.listTasks("approval");
84
- if (!tasks.length) return console.log("Onay bekleyen gorev yok.");
85
- for (const task of tasks) {
86
- console.log(`\n${task.id} ${task.prompt}`);
87
- if (task.planPreview) console.log(String(task.planPreview).slice(0, 1200));
88
- }
89
- }
90
-
91
- function decide(id, action) {
92
- if (!id) throw new Error(`${action} icin gorev id'si gerekli.`);
93
- const task = action === "approve" ? store.approveTask(id) : store.rejectTask(id);
94
- console.log(`${action === "approve" ? "Onaylandi" : "Reddedildi"}: ${task.id}`);
95
- }
96
-
97
- async function run(args) {
98
- const approval = takeOption(args, "--approval");
99
- if (approval && !["ask", "auto"].includes(approval)) throw new Error("--approval ask veya auto olmali.");
100
- const once = args.includes("--once");
101
- if (approval) require("./engine").setMode(approval);
102
- const engine = require("./engine");
103
- if (once) {
104
- const task = store.nextPending();
105
- if (!task) return console.log("Kuyruk bos.");
106
- engine.running = true;
107
- try { await engine.runTask(task); }
108
- finally { engine.running = false; }
109
- return;
110
- }
111
- engine.start();
112
- console.log("Motor calisiyor. Durdurmak icin Ctrl+C.");
113
- }
114
-
115
- async function main(argv = process.argv.slice(2)) {
116
- store.ensureDirs();
117
- // Komutsuz cagri (or. `npx @omerrgocmen/crewctl`) dogrudan web panelini baslatir.
118
- const [command = "start", ...args] = argv;
119
- if (["help", "--help", "-h"].includes(command)) return help();
120
- if (["--version", "-v", "version"].includes(command)) return console.log(VERSION);
121
- if (command === "start") return require("./server");
122
- if (command === "doctor") return require("./doctor").main({ fix: args.includes("--fix") });
123
- if (command === "run") return run(args);
124
- if (command === "status") return status(args.includes("--json"));
125
- if (command === "task") return addTask(args);
126
- if (command === "approvals") return approvals();
127
- if (command === "approve" || command === "reject") return decide(args[0], command);
128
- throw new Error(`Bilinmeyen komut: ${command}. Yardim icin: crewctl help`);
129
- }
130
-
131
- if (require.main === module) {
132
- main().catch((error) => { console.error(`Hata: ${error.message}`); process.exitCode = 1; });
133
- }
134
-
135
- module.exports = { main, takeOption };
1
+ #!/usr/bin/env node
2
+ const path = require("path");
3
+ const store = require("./store");
4
+
5
+ const VERSION = require("../../package.json").version;
6
+ const VALID_MODES = new Set(["auto", "fast", "balanced", "deep"]);
7
+
8
+ function help() {
9
+ console.log(`CrewCtl ${VERSION}
10
+
11
+ Kurulu kodlama CLI'larini tek kuyrukta yonetin.
12
+
13
+ Hizli baslangic:
14
+ npx @omerrgocmen/crewctl Paneli aninda baslat (kurulum gerektirmez)
15
+ npm i -g @omerrgocmen/crewctl Global kur, ardindan: crewctl
16
+
17
+ Kullanim:
18
+ crewctl [start] Web panelini baslat (komutsuz = start)
19
+ crewctl doctor [--fix] Ortami kontrol et (varsayilan salt okunur)
20
+ crewctl run [--once] [--approval mod] Kuyrugu panelsiz calistir
21
+ crewctl status [--json] Kuyruk ve butce ozetini goster
22
+ crewctl task <hedef> [secenekler] Kuyruga gorev ekle
23
+ crewctl approvals Onay bekleyen planlari listele
24
+ crewctl approve <id> Plani onayla
25
+ crewctl reject <id> Plani reddet
26
+
27
+ Task secenekleri:
28
+ --dir <klasor> Calisma klasoru
29
+ --operator <cli> codex | claude | gemini | opencode
30
+ --mode <mod> auto | fast | balanced | deep
31
+ --fresh Proje profilini yukleme; temiz sayfadan basla
32
+
33
+ Ornek:
34
+ crewctl task "Testleri duzelt" --dir . --mode balanced
35
+ crewctl status
36
+
37
+ Veri (config, kuyruk, gecmis) ~/.crewctl altinda tutulur (CREWCTL_HOME ile degistirilebilir).
38
+ Calisma klasoru varsayilan olarak komutun calistirildigi dizindir; panelden degistirilebilir.
39
+ `);
40
+ }
41
+
42
+ function takeOption(args, name) {
43
+ const i = args.indexOf(name);
44
+ if (i < 0) return undefined;
45
+ if (!args[i + 1] || args[i + 1].startsWith("--")) throw new Error(`${name} icin deger gerekli.`);
46
+ return args.splice(i, 2)[1];
47
+ }
48
+
49
+ function status(asJson) {
50
+ store.ensureDirs();
51
+ const cfg = store.loadConfig();
52
+ const data = {
53
+ operator: cfg.operator?.cli || null,
54
+ approvalMode: cfg.approvalMode || "auto",
55
+ callsToday: store.getCallCount(),
56
+ dailyCallBudget: Number(cfg.dailyCallBudget || 0),
57
+ queue: Object.fromEntries(["pending", "approval", "done", "failed"].map((s) => [s, store.listTasks(s).length])),
58
+ activeAgents: Object.values(cfg.agents || {}).filter((a) => a.enabled !== false).length,
59
+ };
60
+ if (asJson) return console.log(JSON.stringify(data, null, 2));
61
+ console.log(`Operator: ${data.operator || "yok"} | Mod: ${data.approvalMode} | Agent: ${data.activeAgents}`);
62
+ console.log(`Kuyruk: ${data.queue.pending} bekleyen, ${data.queue.approval} onay, ${data.queue.done} tamam, ${data.queue.failed} basarisiz`);
63
+ console.log(`Butce: ${data.callsToday}/${data.dailyCallBudget} cagri (bugun)`);
64
+ }
65
+
66
+ function addTask(args) {
67
+ const targetDir = takeOption(args, "--dir");
68
+ const operator = takeOption(args, "--operator");
69
+ const mode = takeOption(args, "--mode") || "auto";
70
+ // --fresh: bu gorevde proje profilini (.crewctl/CONTEXT.md) yukleme; temiz sayfadan basla.
71
+ const fresh = args.includes("--fresh");
72
+ if (fresh) args.splice(args.indexOf("--fresh"), 1);
73
+ if (!VALID_MODES.has(mode)) throw new Error(`Gecersiz mod: ${mode}`);
74
+ const unknown = args.find((arg) => arg.startsWith("--"));
75
+ if (unknown) throw new Error(`Bilinmeyen secenek: ${unknown}`);
76
+ const prompt = args.join(" ").trim();
77
+ if (!prompt) throw new Error("Gorev metni gerekli.");
78
+ const cfg = store.loadConfig();
79
+ const selectedOperator = operator || cfg.operator?.cli;
80
+ const resolvedDir = targetDir ? path.resolve(targetDir) : undefined;
81
+ const task = store.addTask(prompt, resolvedDir, selectedOperator, mode);
82
+ if (fresh) { task.freshContext = true; store.saveTask("pending", task); }
83
+ console.log(`Eklendi: ${task.id}`);
84
+ console.log(`Mod: ${mode} | Operator: ${selectedOperator || "varsayilan"}${fresh ? " | Temiz sayfa (--fresh)" : ""}`);
85
+ }
86
+
87
+ function approvals() {
88
+ const tasks = store.listTasks("approval");
89
+ if (!tasks.length) return console.log("Onay bekleyen gorev yok.");
90
+ for (const task of tasks) {
91
+ console.log(`\n${task.id} ${task.prompt}`);
92
+ if (task.planPreview) console.log(String(task.planPreview).slice(0, 1200));
93
+ }
94
+ }
95
+
96
+ function decide(id, action) {
97
+ if (!id) throw new Error(`${action} icin gorev id'si gerekli.`);
98
+ const task = action === "approve" ? store.approveTask(id) : store.rejectTask(id);
99
+ console.log(`${action === "approve" ? "Onaylandi" : "Reddedildi"}: ${task.id}`);
100
+ }
101
+
102
+ async function run(args) {
103
+ const approval = takeOption(args, "--approval");
104
+ if (approval && !["ask", "auto"].includes(approval)) throw new Error("--approval ask veya auto olmali.");
105
+ const once = args.includes("--once");
106
+ if (approval) require("./engine").setMode(approval);
107
+ const engine = require("./engine");
108
+ if (once) {
109
+ const task = store.nextPending();
110
+ if (!task) return console.log("Kuyruk bos.");
111
+ engine.running = true;
112
+ try { await engine.runTask(task); }
113
+ finally { engine.running = false; }
114
+ return;
115
+ }
116
+ engine.start();
117
+ console.log("Motor calisiyor. Durdurmak icin Ctrl+C.");
118
+ }
119
+
120
+ async function main(argv = process.argv.slice(2)) {
121
+ store.ensureDirs();
122
+ // Komutsuz cagri (or. `npx @omerrgocmen/crewctl`) dogrudan web panelini baslatir.
123
+ const [command = "start", ...args] = argv;
124
+ if (["help", "--help", "-h"].includes(command)) return help();
125
+ if (["--version", "-v", "version"].includes(command)) return console.log(VERSION);
126
+ if (command === "start") return require("./server");
127
+ if (command === "doctor") return require("./doctor").main({ fix: args.includes("--fix") });
128
+ if (command === "run") return run(args);
129
+ if (command === "status") return status(args.includes("--json"));
130
+ if (command === "task") return addTask(args);
131
+ if (command === "approvals") return approvals();
132
+ if (command === "approve" || command === "reject") return decide(args[0], command);
133
+ throw new Error(`Bilinmeyen komut: ${command}. Yardim icin: crewctl help`);
134
+ }
135
+
136
+ if (require.main === module) {
137
+ main().catch((error) => { console.error(`Hata: ${error.message}`); process.exitCode = 1; });
138
+ }
139
+
140
+ module.exports = { main, takeOption };
@@ -1,64 +1,64 @@
1
- // doctor.js — ortam teşhisi: Node sürümü, kurulu CLI'lar ve yapılandırma özeti.
2
- // Kullanım: npm run doctor
3
- const store = require("./store");
4
- const cliRegistry = require("./cli-registry");
5
-
6
- const G = "\x1b[32m", R = "\x1b[31m", Y = "\x1b[33m", DIM = "\x1b[90m", B = "\x1b[1m", X = "\x1b[0m";
7
- const ok = (s) => `${G}✓${X} ${s}`;
8
- const no = (s) => `${R}✗${X} ${s}`;
9
-
10
- function nodeOk() {
11
- const major = Number(process.versions.node.split(".")[0]);
12
- return { major, ok: major >= 18 };
13
- }
14
-
15
- function main(options = {}) {
16
- store.ensureDirs();
17
- const n = nodeOk();
18
- console.log(`\n${B}CrewCtl — Ortam Teşhisi${X}\n`);
19
- console.log(n.ok ? ok(`Node.js ${process.versions.node} (>=18 gerekli)`) : no(`Node.js ${process.versions.node} — 18+ gerekli!`));
20
-
21
- const clis = cliRegistry.discoverInstalled();
22
- const installed = clis.filter((c) => c.installed);
23
- console.log(`\n${B}CLI araçları${X}`);
24
- const platform = process.platform === "win32" ? "windows" : process.platform === "darwin" ? "macos" : "linux";
25
- for (const c of clis) {
26
- if (c.installed) console.log(" " + ok(`${c.id}${DIM} — ${c.version}${X}`));
27
- else {
28
- const hint = c.install && (c.install[platform] || c.install.linux);
29
- console.log(" " + no(`${c.id}${DIM} — kurulu değil${X}`) + (hint ? `\n ${DIM}kurulum: ${hint}${X}` : ""));
30
- }
31
- }
32
-
33
- const cfg = store.loadConfig();
34
- // Varsayilan teshis salt okunurdur. Farkli bir PATH ile calisan doctor komutu
35
- // kullanicinin mevcut agent'larini sessizce devre disi birakmamalidir.
36
- let changed = false;
37
- if (options.fix) {
38
- changed = Boolean(cliRegistry.addMissingAgents(cfg, clis) | cliRegistry.ensureValidOperator(cfg, clis));
39
- if (changed) store.saveConfig(cfg);
40
- }
41
- const agents = Object.entries(cfg.agents).filter(([, a]) => a.enabled !== false);
42
- console.log(`\n${B}Yapılandırma${X}`);
43
- console.log(` Operatör CLI: ${cfg.operator?.cli || "(yok)"}`);
44
- console.log(` Uzman ajan sayısı: ${agents.length}`);
45
- for (const [name, a] of agents) console.log(` ${DIM}• ${name} (${a.adapter || a.cmd}) — ${(a.roleFile || "").split("/").pop()}${X}`);
46
-
47
- console.log("");
48
- if (!n.ok) { console.log(no("Node sürümünü 18+ yapın.")); process.exitCode = 1; }
49
- else if (!installed.length) {
50
- console.log(`${Y}⚠ Hiçbir CLI kurulu değil.${X} En az birini kurun (yukarıdaki komutlar), sonra tekrar deneyin.`);
51
- process.exitCode = 1;
52
- } else if (!cfg.operator?.cli) {
53
- console.log(`${Y}⚠ Operatör CLI seçilemedi.${X}`);
54
- process.exitCode = 1;
55
- } else {
56
- console.log(ok(`Hazır. ${B}npm start${X} ile paneli açın.`));
57
- }
58
- if (options.fix) console.log(changed ? ok("Yapilandirma guncellendi.") : `${DIM}Yapilandirma degisikligi gerekmedi.${X}`);
59
- console.log("");
60
- }
61
-
62
- if (require.main === module) main({ fix: process.argv.includes("--fix") });
63
-
64
- module.exports = { main, nodeOk };
1
+ // doctor.js — ortam teşhisi: Node sürümü, kurulu CLI'lar ve yapılandırma özeti.
2
+ // Kullanım: npm run doctor
3
+ const store = require("./store");
4
+ const cliRegistry = require("./cli-registry");
5
+
6
+ const G = "\x1b[32m", R = "\x1b[31m", Y = "\x1b[33m", DIM = "\x1b[90m", B = "\x1b[1m", X = "\x1b[0m";
7
+ const ok = (s) => `${G}✓${X} ${s}`;
8
+ const no = (s) => `${R}✗${X} ${s}`;
9
+
10
+ function nodeOk() {
11
+ const major = Number(process.versions.node.split(".")[0]);
12
+ return { major, ok: major >= 18 };
13
+ }
14
+
15
+ function main(options = {}) {
16
+ store.ensureDirs();
17
+ const n = nodeOk();
18
+ console.log(`\n${B}CrewCtl — Ortam Teşhisi${X}\n`);
19
+ console.log(n.ok ? ok(`Node.js ${process.versions.node} (>=18 gerekli)`) : no(`Node.js ${process.versions.node} — 18+ gerekli!`));
20
+
21
+ const clis = cliRegistry.discoverInstalled();
22
+ const installed = clis.filter((c) => c.installed);
23
+ console.log(`\n${B}CLI araçları${X}`);
24
+ const platform = process.platform === "win32" ? "windows" : process.platform === "darwin" ? "macos" : "linux";
25
+ for (const c of clis) {
26
+ if (c.installed) console.log(" " + ok(`${c.id}${DIM} — ${c.version}${X}`));
27
+ else {
28
+ const hint = c.install && (c.install[platform] || c.install.linux);
29
+ console.log(" " + no(`${c.id}${DIM} — kurulu değil${X}`) + (hint ? `\n ${DIM}kurulum: ${hint}${X}` : ""));
30
+ }
31
+ }
32
+
33
+ const cfg = store.loadConfig();
34
+ // Varsayilan teshis salt okunurdur. Farkli bir PATH ile calisan doctor komutu
35
+ // kullanicinin mevcut agent'larini sessizce devre disi birakmamalidir.
36
+ let changed = false;
37
+ if (options.fix) {
38
+ changed = Boolean(cliRegistry.addMissingAgents(cfg, clis) | cliRegistry.ensureValidOperator(cfg, clis));
39
+ if (changed) store.saveConfig(cfg);
40
+ }
41
+ const agents = Object.entries(cfg.agents).filter(([, a]) => a.enabled !== false);
42
+ console.log(`\n${B}Yapılandırma${X}`);
43
+ console.log(` Operatör CLI: ${cfg.operator?.cli || "(yok)"}`);
44
+ console.log(` Uzman ajan sayısı: ${agents.length}`);
45
+ for (const [name, a] of agents) console.log(` ${DIM}• ${name} (${a.adapter || a.cmd}) — ${(a.roleFile || "").split("/").pop()}${X}`);
46
+
47
+ console.log("");
48
+ if (!n.ok) { console.log(no("Node sürümünü 18+ yapın.")); process.exitCode = 1; }
49
+ else if (!installed.length) {
50
+ console.log(`${Y}⚠ Hiçbir CLI kurulu değil.${X} En az birini kurun (yukarıdaki komutlar), sonra tekrar deneyin.`);
51
+ process.exitCode = 1;
52
+ } else if (!cfg.operator?.cli) {
53
+ console.log(`${Y}⚠ Operatör CLI seçilemedi.${X}`);
54
+ process.exitCode = 1;
55
+ } else {
56
+ console.log(ok(`Hazır. ${B}npm start${X} ile paneli açın.`));
57
+ }
58
+ if (options.fix) console.log(changed ? ok("Yapilandirma guncellendi.") : `${DIM}Yapilandirma degisikligi gerekmedi.${X}`);
59
+ console.log("");
60
+ }
61
+
62
+ if (require.main === module) main({ fix: process.argv.includes("--fix") });
63
+
64
+ module.exports = { main, nodeOk };