@aigencydev/cli 0.3.3 → 0.3.4
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/README.md +2 -2
- package/dist/tools/bash.js +121 -27
- package/dist/tools/registry.js +2 -0
- package/dist/tools/verify-project.js +339 -0
- package/dist/ui/App.js +19 -9
- package/dist/ui/StatusBar.js +1 -1
- package/dist/ui/WelcomeBox.js +123 -0
- package/dist/ui/theme.js +5 -4
- package/dist/version.js +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -201,8 +201,8 @@ Bu alan **git'e commit edilmez** ve senkronize de olmaz — her makinede ayrı.
|
|
|
201
201
|
|
|
202
202
|
| Paket | Fiyat | Aylık Token | Ek Özellikler |
|
|
203
203
|
|---|---|---|---|
|
|
204
|
-
| **AIGENCY CLI Pro** | 1.500 ₺/ay |
|
|
205
|
-
| **AIGENCY CLI Max** | 3.000 ₺/ay |
|
|
204
|
+
| **AIGENCY CLI Pro** | 1.500 ₺/ay | 100.000.000 | Standart |
|
|
205
|
+
| **AIGENCY CLI Max** | 3.000 ₺/ay | 500.000.000 | Öncelikli kuyruk, Auto mode |
|
|
206
206
|
|
|
207
207
|
Paketleri [aigency.dev/developer/cli](https://aigency.dev/developer/cli) üzerinden
|
|
208
208
|
yönetebilir, kullanımınızı canlı izleyebilirsiniz.
|
package/dist/tools/bash.js
CHANGED
|
@@ -1,9 +1,101 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { checkCommand, autoModeDecision } from "../security/command-filter.js";
|
|
3
3
|
import { checkPath } from "../security/sandbox.js";
|
|
4
|
-
const MAX_OUTPUT_BYTES =
|
|
4
|
+
const MAX_OUTPUT_BYTES = 80_000;
|
|
5
|
+
const HEAD_KEEP_BYTES = 4_000;
|
|
6
|
+
const TAIL_KEEP_BYTES = 36_000;
|
|
5
7
|
const DEFAULT_TIMEOUT_MS = 300_000;
|
|
6
8
|
const LIVE_OUTPUT_THROTTLE_MS = 150;
|
|
9
|
+
const NON_INTERACTIVE_ENV = {
|
|
10
|
+
CI: "1",
|
|
11
|
+
CONTINUOUS_INTEGRATION: "true",
|
|
12
|
+
npm_config_yes: "true",
|
|
13
|
+
NPM_CONFIG_YES: "true",
|
|
14
|
+
NPM_CONFIG_FUND: "false",
|
|
15
|
+
NPM_CONFIG_AUDIT: "false",
|
|
16
|
+
NPM_CONFIG_UPDATE_NOTIFIER: "false",
|
|
17
|
+
NPM_CONFIG_LOGLEVEL: "error",
|
|
18
|
+
ADBLOCK: "1",
|
|
19
|
+
DISABLE_OPENCOLLECTIVE: "1",
|
|
20
|
+
NO_COLOR: "1",
|
|
21
|
+
FORCE_COLOR: "0",
|
|
22
|
+
TERM: "dumb",
|
|
23
|
+
HUSKY: "0",
|
|
24
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
25
|
+
DEBIAN_FRONTEND: "noninteractive",
|
|
26
|
+
PIP_DISABLE_PIP_VERSION_CHECK: "1",
|
|
27
|
+
};
|
|
28
|
+
function truncateWithTail(s) {
|
|
29
|
+
if (s.length <= MAX_OUTPUT_BYTES)
|
|
30
|
+
return s;
|
|
31
|
+
const head = s.slice(0, HEAD_KEEP_BYTES);
|
|
32
|
+
const tail = s.slice(-TAIL_KEEP_BYTES);
|
|
33
|
+
const omitted = s.length - HEAD_KEEP_BYTES - TAIL_KEEP_BYTES;
|
|
34
|
+
return `${head}\n\n[... ${omitted} bayt kırpıldı ...]\n\n${tail}`;
|
|
35
|
+
}
|
|
36
|
+
function classifyError(stderr, stdout, exitCode) {
|
|
37
|
+
const combined = (stderr + "\n" + stdout).toLowerCase();
|
|
38
|
+
if (combined.includes("contains files that could conflict") || combined.includes("directory is not empty")) {
|
|
39
|
+
return {
|
|
40
|
+
class: "directory_not_empty",
|
|
41
|
+
hint: "Hedef dizin boş değil. Farklı bir isim seç veya dizini temizle.",
|
|
42
|
+
retryable: true,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
if (combined.includes("eintegrity") || combined.includes("sha512 integrity")) {
|
|
46
|
+
return {
|
|
47
|
+
class: "npm_cache_corrupted",
|
|
48
|
+
hint: "npm cache bozuk. 'npm cache clean --force' ile temizle ve tekrar dene.",
|
|
49
|
+
retryable: true,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
if (combined.includes("etimedout") || combined.includes("enotfound") || combined.includes("network timeout")) {
|
|
53
|
+
return {
|
|
54
|
+
class: "network_error",
|
|
55
|
+
hint: "Ağ hatası. Kısa bir beklemeden sonra tekrar dene.",
|
|
56
|
+
retryable: true,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
if (combined.includes("eacces") || combined.includes("eperm") || combined.includes("permission denied")) {
|
|
60
|
+
return {
|
|
61
|
+
class: "permission_denied",
|
|
62
|
+
hint: "İzin reddedildi. Bu dosya/dizin üzerinde yazma hakkı yok.",
|
|
63
|
+
retryable: false,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
if (combined.includes("the engine \"node\"") || combined.includes("node version")) {
|
|
67
|
+
return {
|
|
68
|
+
class: "node_version_mismatch",
|
|
69
|
+
hint: "Node.js sürümü uyumsuz. Kullanıcıya bildir, node sürümünü değiştirme.",
|
|
70
|
+
retryable: false,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (combined.includes("command not found") || combined.includes("not recognized") || combined.includes("enoent")) {
|
|
74
|
+
return {
|
|
75
|
+
class: "command_not_found",
|
|
76
|
+
hint: "Komut bulunamadı. Kontrol et: 'which <komut>' veya paketi yükle.",
|
|
77
|
+
retryable: false,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (combined.includes("module not found") || combined.includes("cannot find module")) {
|
|
81
|
+
return {
|
|
82
|
+
class: "missing_dependency",
|
|
83
|
+
hint: "Eksik modül. İlgili paketi 'npm install <pkg>' ile yükle.",
|
|
84
|
+
retryable: true,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
if (combined.includes("syntaxerror") || combined.includes("parse error")) {
|
|
88
|
+
return {
|
|
89
|
+
class: "syntax_error",
|
|
90
|
+
hint: "Sözdizimi hatası — ilgili dosyayı read_file ile oku ve düzelt.",
|
|
91
|
+
retryable: true,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
class: `exit_${exitCode ?? "unknown"}`,
|
|
96
|
+
retryable: true,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
7
99
|
const INTERACTIVE_PATTERNS = [
|
|
8
100
|
{
|
|
9
101
|
regex: /\bcreate-next-app\b(?![^|]*(?:--ts|--javascript|--yes|-y\b))/i,
|
|
@@ -99,17 +191,13 @@ function runShell(command, cwd, timeoutMs, signal, onLive) {
|
|
|
99
191
|
stdio: ["ignore", "pipe", "pipe"],
|
|
100
192
|
env: {
|
|
101
193
|
...process.env,
|
|
102
|
-
|
|
103
|
-
NO_COLOR: "0",
|
|
104
|
-
npm_config_yes: "true",
|
|
105
|
-
DEBIAN_FRONTEND: "noninteractive",
|
|
194
|
+
...NON_INTERACTIVE_ENV,
|
|
106
195
|
},
|
|
107
196
|
windowsHide: true,
|
|
108
197
|
});
|
|
109
|
-
|
|
110
|
-
let
|
|
111
|
-
let
|
|
112
|
-
let errBytes = 0;
|
|
198
|
+
const HARD_CAP = 2 * 1024 * 1024;
|
|
199
|
+
let stdoutFull = "";
|
|
200
|
+
let stderrFull = "";
|
|
113
201
|
let timedOut = false;
|
|
114
202
|
let stdoutBuffer = "";
|
|
115
203
|
let stderrBuffer = "";
|
|
@@ -166,11 +254,8 @@ function runShell(command, cwd, timeoutMs, signal, onLive) {
|
|
|
166
254
|
}
|
|
167
255
|
child.stdout.on("data", (chunk) => {
|
|
168
256
|
const text = chunk.toString("utf8");
|
|
169
|
-
if (
|
|
170
|
-
|
|
171
|
-
const trimmed = text.slice(0, remaining);
|
|
172
|
-
stdout += trimmed;
|
|
173
|
-
outBytes += trimmed.length;
|
|
257
|
+
if (stdoutFull.length < HARD_CAP) {
|
|
258
|
+
stdoutFull += text;
|
|
174
259
|
}
|
|
175
260
|
if (onLive) {
|
|
176
261
|
stdoutBuffer += text;
|
|
@@ -179,11 +264,8 @@ function runShell(command, cwd, timeoutMs, signal, onLive) {
|
|
|
179
264
|
});
|
|
180
265
|
child.stderr.on("data", (chunk) => {
|
|
181
266
|
const text = chunk.toString("utf8");
|
|
182
|
-
if (
|
|
183
|
-
|
|
184
|
-
const trimmed = text.slice(0, remaining);
|
|
185
|
-
stderr += trimmed;
|
|
186
|
-
errBytes += trimmed.length;
|
|
267
|
+
if (stderrFull.length < HARD_CAP) {
|
|
268
|
+
stderrFull += text;
|
|
187
269
|
}
|
|
188
270
|
if (onLive) {
|
|
189
271
|
stderrBuffer += text;
|
|
@@ -194,9 +276,9 @@ function runShell(command, cwd, timeoutMs, signal, onLive) {
|
|
|
194
276
|
clearTimeout(timeoutHandle);
|
|
195
277
|
finalFlush();
|
|
196
278
|
resolve({
|
|
197
|
-
stdout,
|
|
198
|
-
stderr:
|
|
199
|
-
exitCode: 1,
|
|
279
|
+
stdout: truncateWithTail(stdoutFull),
|
|
280
|
+
stderr: truncateWithTail(stderrFull + `\nSpawn hatası: ${err.message}`),
|
|
281
|
+
exitCode: -1,
|
|
200
282
|
timedOut,
|
|
201
283
|
});
|
|
202
284
|
});
|
|
@@ -206,8 +288,8 @@ function runShell(command, cwd, timeoutMs, signal, onLive) {
|
|
|
206
288
|
signal.removeEventListener("abort", onAbort);
|
|
207
289
|
finalFlush();
|
|
208
290
|
resolve({
|
|
209
|
-
stdout,
|
|
210
|
-
stderr,
|
|
291
|
+
stdout: truncateWithTail(stdoutFull),
|
|
292
|
+
stderr: truncateWithTail(stderrFull),
|
|
211
293
|
exitCode: code,
|
|
212
294
|
timedOut,
|
|
213
295
|
});
|
|
@@ -346,16 +428,24 @@ export const bashTool = async (params, ctx) => {
|
|
|
346
428
|
};
|
|
347
429
|
}
|
|
348
430
|
let errorMsg;
|
|
431
|
+
let errorClass;
|
|
432
|
+
let errorHint;
|
|
349
433
|
if (result.exitCode !== 0) {
|
|
434
|
+
const classification = classifyError(result.stderr, result.stdout, result.exitCode);
|
|
435
|
+
errorClass = classification.class;
|
|
436
|
+
errorHint = classification.hint;
|
|
350
437
|
const stderrTrim = result.stderr.trim();
|
|
351
438
|
const stdoutTrim = result.stdout.trim();
|
|
352
439
|
const errorDetail = stderrTrim || stdoutTrim;
|
|
353
440
|
if (errorDetail) {
|
|
354
|
-
const tail = errorDetail.slice(-
|
|
355
|
-
errorMsg = `Komut başarısız (exit code ${result.exitCode}): ${tail}`;
|
|
441
|
+
const tail = errorDetail.slice(-800);
|
|
442
|
+
errorMsg = `Komut başarısız (exit code ${result.exitCode}, class=${classification.class}): ${tail}`;
|
|
443
|
+
if (classification.hint) {
|
|
444
|
+
errorMsg += `\n\nOneri: ${classification.hint}`;
|
|
445
|
+
}
|
|
356
446
|
}
|
|
357
447
|
else {
|
|
358
|
-
errorMsg = `Komut çıktı vermeden başarısız oldu (exit code ${result.exitCode}). Komut yanlış olabilir veya binary bulunamamış olabilir.`;
|
|
448
|
+
errorMsg = `Komut çıktı vermeden başarısız oldu (exit code ${result.exitCode}, class=${classification.class}). Komut yanlış olabilir veya binary bulunamamış olabilir.`;
|
|
359
449
|
}
|
|
360
450
|
}
|
|
361
451
|
return {
|
|
@@ -366,6 +456,10 @@ export const bashTool = async (params, ctx) => {
|
|
|
366
456
|
exit_code: result.exitCode,
|
|
367
457
|
stdout_length: result.stdout.length,
|
|
368
458
|
stderr_length: result.stderr.length,
|
|
459
|
+
error_class: errorClass,
|
|
460
|
+
error_hint: errorHint,
|
|
461
|
+
command: command.slice(0, 200),
|
|
462
|
+
working_directory: cwdCheck.realPath,
|
|
369
463
|
},
|
|
370
464
|
approvalState,
|
|
371
465
|
duration: Date.now() - start,
|
package/dist/tools/registry.js
CHANGED
|
@@ -6,6 +6,7 @@ import { editFileTool } from "./edit-file.js";
|
|
|
6
6
|
import { bashTool } from "./bash.js";
|
|
7
7
|
import { saveMemoryToolHandler, readMemoryToolHandler, deleteMemoryToolHandler, } from "./memory-tools.js";
|
|
8
8
|
import { writeTasksHandler, readTasksHandler } from "./task-tools.js";
|
|
9
|
+
import { verifyProjectHandler } from "./verify-project.js";
|
|
9
10
|
const HANDLERS = {
|
|
10
11
|
read_file: readFileTool,
|
|
11
12
|
list_files: listFilesTool,
|
|
@@ -18,6 +19,7 @@ const HANDLERS = {
|
|
|
18
19
|
delete_memory: deleteMemoryToolHandler,
|
|
19
20
|
write_tasks: writeTasksHandler,
|
|
20
21
|
read_tasks: readTasksHandler,
|
|
22
|
+
verify_project: verifyProjectHandler,
|
|
21
23
|
};
|
|
22
24
|
export function hasLocalTool(name) {
|
|
23
25
|
return name in HANDLERS;
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { checkPath } from "../security/sandbox.js";
|
|
4
|
+
async function exists(p) {
|
|
5
|
+
try {
|
|
6
|
+
await fs.access(p);
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
async function isDirectory(p) {
|
|
14
|
+
try {
|
|
15
|
+
const stat = await fs.stat(p);
|
|
16
|
+
return stat.isDirectory();
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async function readJsonSafe(p) {
|
|
23
|
+
try {
|
|
24
|
+
const raw = await fs.readFile(p, "utf8");
|
|
25
|
+
return JSON.parse(raw);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async function countDirEntries(p, limit = 50) {
|
|
32
|
+
try {
|
|
33
|
+
const entries = await fs.readdir(p);
|
|
34
|
+
return Math.min(entries.length, limit);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function detectProjectType(projectPath) {
|
|
41
|
+
const pkgPath = path.join(projectPath, "package.json");
|
|
42
|
+
const pkg = await readJsonSafe(pkgPath);
|
|
43
|
+
if (!pkg)
|
|
44
|
+
return "unknown";
|
|
45
|
+
const deps = {
|
|
46
|
+
...(pkg.dependencies || {}),
|
|
47
|
+
...(pkg.devDependencies || {}),
|
|
48
|
+
};
|
|
49
|
+
if (deps.next)
|
|
50
|
+
return "next";
|
|
51
|
+
if (deps.vite)
|
|
52
|
+
return "vite";
|
|
53
|
+
if (deps["react-scripts"])
|
|
54
|
+
return "cra";
|
|
55
|
+
if (deps.nuxt)
|
|
56
|
+
return "nuxt";
|
|
57
|
+
if (deps["@remix-run/dev"])
|
|
58
|
+
return "remix";
|
|
59
|
+
if (deps.astro)
|
|
60
|
+
return "astro";
|
|
61
|
+
if (deps.react)
|
|
62
|
+
return "react";
|
|
63
|
+
if (deps.express || deps.fastify || deps.koa)
|
|
64
|
+
return "node-server";
|
|
65
|
+
return "node";
|
|
66
|
+
}
|
|
67
|
+
async function checkNextProject(projectPath) {
|
|
68
|
+
const checks = [];
|
|
69
|
+
const missing = [];
|
|
70
|
+
const dirExists = await isDirectory(projectPath);
|
|
71
|
+
checks.push({
|
|
72
|
+
name: "Proje dizini mevcut",
|
|
73
|
+
ok: dirExists,
|
|
74
|
+
detail: dirExists ? projectPath : "Dizin bulunamadı",
|
|
75
|
+
});
|
|
76
|
+
if (!dirExists) {
|
|
77
|
+
missing.push("Proje dizini hiç oluşmamış");
|
|
78
|
+
return {
|
|
79
|
+
projectPath,
|
|
80
|
+
projectType: "next",
|
|
81
|
+
ok: false,
|
|
82
|
+
checks,
|
|
83
|
+
missing,
|
|
84
|
+
suggestedFix: "Proje oluşturulmamış. create-next-app komutunu yeniden çalıştır ve bu sefer exit code'unu kontrol et.",
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const pkgPath = path.join(projectPath, "package.json");
|
|
88
|
+
const pkgExists = await exists(pkgPath);
|
|
89
|
+
checks.push({ name: "package.json mevcut", ok: pkgExists });
|
|
90
|
+
if (!pkgExists) {
|
|
91
|
+
missing.push("package.json yok");
|
|
92
|
+
return {
|
|
93
|
+
projectPath,
|
|
94
|
+
projectType: "next",
|
|
95
|
+
ok: false,
|
|
96
|
+
checks,
|
|
97
|
+
missing,
|
|
98
|
+
suggestedFix: "package.json hiç oluşmamış, create-next-app başlamadan fail olmuş. Dizini temizle ve yeniden kur.",
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
const pkg = await readJsonSafe(pkgPath);
|
|
102
|
+
const pkgValid = pkg !== null;
|
|
103
|
+
checks.push({ name: "package.json geçerli JSON", ok: pkgValid });
|
|
104
|
+
if (!pkg) {
|
|
105
|
+
missing.push("package.json bozuk JSON");
|
|
106
|
+
return {
|
|
107
|
+
projectPath,
|
|
108
|
+
projectType: "next",
|
|
109
|
+
ok: false,
|
|
110
|
+
checks,
|
|
111
|
+
missing,
|
|
112
|
+
suggestedFix: "package.json bozuk. Dosyayı sil ve yeniden kur.",
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
const scripts = pkg.scripts || {};
|
|
116
|
+
const hasDev = typeof scripts.dev === "string" && scripts.dev.length > 0;
|
|
117
|
+
const hasBuild = typeof scripts.build === "string" && scripts.build.length > 0;
|
|
118
|
+
const hasStart = typeof scripts.start === "string" && scripts.start.length > 0;
|
|
119
|
+
checks.push({
|
|
120
|
+
name: "scripts.dev mevcut",
|
|
121
|
+
ok: hasDev,
|
|
122
|
+
detail: hasDev ? scripts.dev : "Eksik",
|
|
123
|
+
});
|
|
124
|
+
checks.push({
|
|
125
|
+
name: "scripts.build mevcut",
|
|
126
|
+
ok: hasBuild,
|
|
127
|
+
detail: hasBuild ? scripts.build : "Eksik",
|
|
128
|
+
});
|
|
129
|
+
checks.push({ name: "scripts.start mevcut", ok: hasStart });
|
|
130
|
+
if (!hasDev)
|
|
131
|
+
missing.push("package.json'da 'dev' script yok");
|
|
132
|
+
if (!hasBuild)
|
|
133
|
+
missing.push("package.json'da 'build' script yok");
|
|
134
|
+
const deps = {
|
|
135
|
+
...(pkg.dependencies || {}),
|
|
136
|
+
...(pkg.devDependencies || {}),
|
|
137
|
+
};
|
|
138
|
+
const hasNext = typeof deps.next === "string";
|
|
139
|
+
const hasReact = typeof deps.react === "string";
|
|
140
|
+
checks.push({
|
|
141
|
+
name: "next bağımlılığı mevcut",
|
|
142
|
+
ok: hasNext,
|
|
143
|
+
detail: hasNext ? deps.next : "Eksik",
|
|
144
|
+
});
|
|
145
|
+
checks.push({ name: "react bağımlılığı mevcut", ok: hasReact });
|
|
146
|
+
if (!hasNext)
|
|
147
|
+
missing.push("'next' paketi package.json'da yok");
|
|
148
|
+
if (!hasReact)
|
|
149
|
+
missing.push("'react' paketi package.json'da yok");
|
|
150
|
+
const nmPath = path.join(projectPath, "node_modules");
|
|
151
|
+
const nmExists = await isDirectory(nmPath);
|
|
152
|
+
checks.push({ name: "node_modules dizini mevcut", ok: nmExists });
|
|
153
|
+
if (!nmExists) {
|
|
154
|
+
missing.push("node_modules kurulmamış");
|
|
155
|
+
return {
|
|
156
|
+
projectPath,
|
|
157
|
+
projectType: "next",
|
|
158
|
+
ok: false,
|
|
159
|
+
checks,
|
|
160
|
+
missing,
|
|
161
|
+
suggestedFix: `Paketler yüklenmemiş. Çalıştır: cd "${projectPath}" && npm install --no-audit --no-fund --loglevel=error`,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
const nmNextExists = await isDirectory(path.join(nmPath, "next"));
|
|
165
|
+
checks.push({
|
|
166
|
+
name: "node_modules/next mevcut (kurulum tamamlandı mı)",
|
|
167
|
+
ok: nmNextExists,
|
|
168
|
+
});
|
|
169
|
+
if (!nmNextExists) {
|
|
170
|
+
missing.push("node_modules/next yok — npm install yarıda kalmış olabilir");
|
|
171
|
+
}
|
|
172
|
+
const nmCount = await countDirEntries(nmPath, 100);
|
|
173
|
+
const nmPopulated = nmCount >= 50;
|
|
174
|
+
checks.push({
|
|
175
|
+
name: "node_modules yeterince dolu",
|
|
176
|
+
ok: nmPopulated,
|
|
177
|
+
detail: `${nmCount} dizin`,
|
|
178
|
+
});
|
|
179
|
+
if (!nmPopulated)
|
|
180
|
+
missing.push(`node_modules sadece ${nmCount} paket içeriyor, beklenen 50+`);
|
|
181
|
+
const hasLockfile = await exists(path.join(projectPath, "package-lock.json"));
|
|
182
|
+
checks.push({ name: "package-lock.json mevcut", ok: hasLockfile });
|
|
183
|
+
if (!hasLockfile)
|
|
184
|
+
missing.push("package-lock.json yok — install tamamlanmamış");
|
|
185
|
+
const appPageExists = (await exists(path.join(projectPath, "src", "app", "page.tsx"))) ||
|
|
186
|
+
(await exists(path.join(projectPath, "src", "app", "page.jsx"))) ||
|
|
187
|
+
(await exists(path.join(projectPath, "app", "page.tsx"))) ||
|
|
188
|
+
(await exists(path.join(projectPath, "app", "page.jsx")));
|
|
189
|
+
const pagesIndexExists = (await exists(path.join(projectPath, "src", "pages", "index.tsx"))) ||
|
|
190
|
+
(await exists(path.join(projectPath, "src", "pages", "index.jsx"))) ||
|
|
191
|
+
(await exists(path.join(projectPath, "pages", "index.tsx"))) ||
|
|
192
|
+
(await exists(path.join(projectPath, "pages", "index.jsx")));
|
|
193
|
+
const hasEntryPage = appPageExists || pagesIndexExists;
|
|
194
|
+
checks.push({
|
|
195
|
+
name: "Ana sayfa (app/page.tsx veya pages/index.tsx) mevcut",
|
|
196
|
+
ok: hasEntryPage,
|
|
197
|
+
});
|
|
198
|
+
if (!hasEntryPage)
|
|
199
|
+
missing.push("Ana sayfa dosyası yok");
|
|
200
|
+
const tsconfigExists = await exists(path.join(projectPath, "tsconfig.json"));
|
|
201
|
+
checks.push({ name: "tsconfig.json mevcut", ok: tsconfigExists });
|
|
202
|
+
const ok = missing.length === 0;
|
|
203
|
+
let suggestedFix;
|
|
204
|
+
if (!ok) {
|
|
205
|
+
if (missing.some((m) => m.includes("node_modules"))) {
|
|
206
|
+
suggestedFix = `Paketler eksik. Çalıştır: cd "${projectPath}" && npm install --no-audit --no-fund --loglevel=error`;
|
|
207
|
+
}
|
|
208
|
+
else if (missing.some((m) => m.includes("script"))) {
|
|
209
|
+
suggestedFix = "package.json scripts bölümü bozuk. Projeyi sıfırdan yeniden kur.";
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
projectPath,
|
|
214
|
+
projectType: "next",
|
|
215
|
+
ok,
|
|
216
|
+
checks,
|
|
217
|
+
missing,
|
|
218
|
+
suggestedFix,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
async function checkGenericNodeProject(projectPath) {
|
|
222
|
+
const checks = [];
|
|
223
|
+
const missing = [];
|
|
224
|
+
const dirExists = await isDirectory(projectPath);
|
|
225
|
+
checks.push({ name: "Proje dizini mevcut", ok: dirExists });
|
|
226
|
+
if (!dirExists) {
|
|
227
|
+
missing.push("Proje dizini yok");
|
|
228
|
+
return {
|
|
229
|
+
projectPath,
|
|
230
|
+
projectType: "node",
|
|
231
|
+
ok: false,
|
|
232
|
+
checks,
|
|
233
|
+
missing,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
const pkgPath = path.join(projectPath, "package.json");
|
|
237
|
+
const pkg = await readJsonSafe(pkgPath);
|
|
238
|
+
const pkgOk = pkg !== null;
|
|
239
|
+
checks.push({ name: "package.json parse edildi", ok: pkgOk });
|
|
240
|
+
if (!pkg) {
|
|
241
|
+
missing.push("package.json yok veya bozuk");
|
|
242
|
+
return {
|
|
243
|
+
projectPath,
|
|
244
|
+
projectType: "node",
|
|
245
|
+
ok: false,
|
|
246
|
+
checks,
|
|
247
|
+
missing,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
const scripts = pkg.scripts || {};
|
|
251
|
+
const hasStart = typeof scripts.start === "string" || typeof scripts.dev === "string";
|
|
252
|
+
checks.push({ name: "start veya dev script mevcut", ok: hasStart });
|
|
253
|
+
const nmExists = await isDirectory(path.join(projectPath, "node_modules"));
|
|
254
|
+
checks.push({ name: "node_modules mevcut", ok: nmExists });
|
|
255
|
+
if (!nmExists)
|
|
256
|
+
missing.push("node_modules yok — npm install çalıştırılmamış");
|
|
257
|
+
return {
|
|
258
|
+
projectPath,
|
|
259
|
+
projectType: "node",
|
|
260
|
+
ok: missing.length === 0,
|
|
261
|
+
checks,
|
|
262
|
+
missing,
|
|
263
|
+
suggestedFix: nmExists ? undefined : `cd "${projectPath}" && npm install --no-audit --no-fund`,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
export const verifyProjectHandler = async (params, ctx) => {
|
|
267
|
+
const start = Date.now();
|
|
268
|
+
const rawPath = (params.path || ".");
|
|
269
|
+
const requestedType = params.type || "auto";
|
|
270
|
+
const check = checkPath(rawPath, ctx.cwd, { mustExist: false });
|
|
271
|
+
if (!check.ok || !check.realPath) {
|
|
272
|
+
return {
|
|
273
|
+
success: false,
|
|
274
|
+
output: "",
|
|
275
|
+
error: `Proje yolu reddedildi: ${check.message || rawPath}`,
|
|
276
|
+
duration: Date.now() - start,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
const projectPath = check.realPath;
|
|
280
|
+
if (!(await isDirectory(projectPath))) {
|
|
281
|
+
return {
|
|
282
|
+
success: false,
|
|
283
|
+
output: "",
|
|
284
|
+
error: `Dizin bulunamadı: ${projectPath}`,
|
|
285
|
+
metadata: { project_ok: false, missing: ["dizin yok"] },
|
|
286
|
+
duration: Date.now() - start,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
let projectType = requestedType;
|
|
290
|
+
if (projectType === "auto") {
|
|
291
|
+
projectType = await detectProjectType(projectPath);
|
|
292
|
+
}
|
|
293
|
+
let report;
|
|
294
|
+
if (projectType === "next") {
|
|
295
|
+
report = await checkNextProject(projectPath);
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
report = await checkGenericNodeProject(projectPath);
|
|
299
|
+
}
|
|
300
|
+
const lines = [];
|
|
301
|
+
lines.push(`## Proje Sağlık Raporu: ${report.projectType}`);
|
|
302
|
+
lines.push(`Dizin: ${report.projectPath}`);
|
|
303
|
+
lines.push(`Sonuç: ${report.ok ? "✓ SAĞLIKLI" : "✗ EKSİK"}`);
|
|
304
|
+
lines.push("");
|
|
305
|
+
lines.push("### Kontroller");
|
|
306
|
+
for (const c of report.checks) {
|
|
307
|
+
const mark = c.ok ? "[✓]" : "[✗]";
|
|
308
|
+
const detail = c.detail ? ` — ${c.detail}` : "";
|
|
309
|
+
lines.push(`${mark} ${c.name}${detail}`);
|
|
310
|
+
}
|
|
311
|
+
if (report.missing.length > 0) {
|
|
312
|
+
lines.push("");
|
|
313
|
+
lines.push("### Eksikler");
|
|
314
|
+
for (const m of report.missing) {
|
|
315
|
+
lines.push(`- ${m}`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
if (report.suggestedFix) {
|
|
319
|
+
lines.push("");
|
|
320
|
+
lines.push("### Önerilen Düzeltme");
|
|
321
|
+
lines.push(report.suggestedFix);
|
|
322
|
+
}
|
|
323
|
+
return {
|
|
324
|
+
success: report.ok,
|
|
325
|
+
output: lines.join("\n"),
|
|
326
|
+
error: report.ok ? undefined : `Proje sağlık kontrolü başarısız: ${report.missing.join(", ")}`,
|
|
327
|
+
metadata: {
|
|
328
|
+
project_ok: report.ok,
|
|
329
|
+
project_type: report.projectType,
|
|
330
|
+
project_path: report.projectPath,
|
|
331
|
+
missing: report.missing,
|
|
332
|
+
suggested_fix: report.suggestedFix,
|
|
333
|
+
check_count: report.checks.length,
|
|
334
|
+
passed_count: report.checks.filter((c) => c.ok).length,
|
|
335
|
+
},
|
|
336
|
+
approvalState: 2,
|
|
337
|
+
duration: Date.now() - start,
|
|
338
|
+
};
|
|
339
|
+
};
|
package/dist/ui/App.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
2
2
|
import { Box, Text, useApp, useInput } from "ink";
|
|
3
|
+
import Spinner from "ink-spinner";
|
|
3
4
|
import { MessageList } from "./MessageList.js";
|
|
4
5
|
import { InputBar } from "./InputBar.js";
|
|
5
6
|
import { StatusBar } from "./StatusBar.js";
|
|
6
7
|
import { PermissionPrompt } from "./PermissionPrompt.js";
|
|
8
|
+
import { WelcomeBox } from "./WelcomeBox.js";
|
|
7
9
|
import { ChatHistory } from "../agent/history.js";
|
|
8
10
|
import { runAgentLoop, clearSessionApprovalCache } from "../agent/loop.js";
|
|
9
11
|
import { SessionRecorder, generateSessionId, } from "../agent/session-store.js";
|
|
@@ -22,9 +24,10 @@ export function App({ session, initialMode, initialModel, cwd, projectRoot, init
|
|
|
22
24
|
const [mode, setMode] = useState(initialMode);
|
|
23
25
|
const [model] = useState(initialModel);
|
|
24
26
|
const [tokensUsed, setTokensUsed] = useState(0);
|
|
25
|
-
const [tokensLimit, setTokensLimit] = useState(initialModel === "max" ?
|
|
27
|
+
const [tokensLimit, setTokensLimit] = useState(initialModel === "max" ? 500_000_000 : 100_000_000);
|
|
26
28
|
const [pending, setPending] = useState(null);
|
|
27
29
|
const [liveOutput, setLiveOutput] = useState("");
|
|
30
|
+
const [thinking, setThinking] = useState("");
|
|
28
31
|
const [taskList, setTaskList] = useState([]);
|
|
29
32
|
const historyRef = useRef(new ChatHistory());
|
|
30
33
|
const abortRef = useRef(null);
|
|
@@ -35,10 +38,6 @@ export function App({ session, initialMode, initialModel, cwd, projectRoot, init
|
|
|
35
38
|
setMessages((prev) => [...prev, { ...msg, id: newId() }]);
|
|
36
39
|
}, []);
|
|
37
40
|
useEffect(() => {
|
|
38
|
-
pushMessage({
|
|
39
|
-
kind: "info",
|
|
40
|
-
content: "Shift+Tab ile mod değiştirin · /help yardım · ESC ile iptal · Ctrl+C çıkış",
|
|
41
|
-
});
|
|
42
41
|
setLogContext({
|
|
43
42
|
sessionId: sessionIdRef.current,
|
|
44
43
|
cwd: projectRoot,
|
|
@@ -47,7 +46,7 @@ export function App({ session, initialMode, initialModel, cwd, projectRoot, init
|
|
|
47
46
|
return () => {
|
|
48
47
|
void recorderRef.current.end("exit");
|
|
49
48
|
};
|
|
50
|
-
}, [
|
|
49
|
+
}, [projectRoot]);
|
|
51
50
|
useInput((input, key) => {
|
|
52
51
|
if (key.shift && key.tab) {
|
|
53
52
|
if (busy)
|
|
@@ -197,10 +196,11 @@ export function App({ session, initialMode, initialModel, cwd, projectRoot, init
|
|
|
197
196
|
const onEvent = (event) => {
|
|
198
197
|
switch (event.type) {
|
|
199
198
|
case "agent_think":
|
|
200
|
-
|
|
199
|
+
setThinking(event.content);
|
|
201
200
|
void recorderRef.current.think(event.content);
|
|
202
201
|
break;
|
|
203
202
|
case "agent_tool_call":
|
|
203
|
+
setThinking("");
|
|
204
204
|
if (event.toolName === "write_tasks") {
|
|
205
205
|
const rawTasks = event.params.tasks;
|
|
206
206
|
if (Array.isArray(rawTasks)) {
|
|
@@ -250,6 +250,7 @@ export function App({ session, initialMode, initialModel, cwd, projectRoot, init
|
|
|
250
250
|
}
|
|
251
251
|
case "agent_message":
|
|
252
252
|
if (!event.delta) {
|
|
253
|
+
setThinking("");
|
|
253
254
|
pushMessage({ kind: "assistant", content: event.content });
|
|
254
255
|
void recorderRef.current.assistantMessage(event.content);
|
|
255
256
|
}
|
|
@@ -311,6 +312,7 @@ export function App({ session, initialMode, initialModel, cwd, projectRoot, init
|
|
|
311
312
|
}
|
|
312
313
|
finally {
|
|
313
314
|
setBusy(false);
|
|
315
|
+
setThinking("");
|
|
314
316
|
abortRef.current = null;
|
|
315
317
|
liveBufferRef.current = "";
|
|
316
318
|
setLiveOutput("");
|
|
@@ -336,8 +338,10 @@ export function App({ session, initialMode, initialModel, cwd, projectRoot, init
|
|
|
336
338
|
handleSubmit(initialPrompt);
|
|
337
339
|
}
|
|
338
340
|
}, [busy, handleSubmit, initialPrompt]);
|
|
341
|
+
const hasUserMessage = messages.some((m) => m.kind === "user");
|
|
342
|
+
const showWelcome = !hasUserMessage && !busy;
|
|
339
343
|
return (React.createElement(Box, { flexDirection: "column" },
|
|
340
|
-
React.createElement(Box, { paddingX: 1, marginBottom: 1 },
|
|
344
|
+
showWelcome ? (React.createElement(WelcomeBox, { userName: session.user.name || "", userEmail: session.user.email, modelLabel: model === "max" ? "CLI Max" : "CLI Pro", cwd: cwd, cliVersion: CLI_VERSION, projectRoot: projectRoot })) : (React.createElement(Box, { paddingX: 1, marginBottom: 1 },
|
|
341
345
|
React.createElement(Text, { color: palette.brand, bold: true },
|
|
342
346
|
symbols.sparkle,
|
|
343
347
|
" AIGENCY CLI"),
|
|
@@ -345,7 +349,7 @@ export function App({ session, initialMode, initialModel, cwd, projectRoot, init
|
|
|
345
349
|
" v",
|
|
346
350
|
CLI_VERSION),
|
|
347
351
|
React.createElement(Text, { color: palette.textFaint }, " \u00B7 "),
|
|
348
|
-
React.createElement(Text, { color: palette.textMuted }, session.user.name || session.user.email)),
|
|
352
|
+
React.createElement(Text, { color: palette.textMuted }, session.user.name || session.user.email))),
|
|
349
353
|
React.createElement(MessageList, { messages: messages }),
|
|
350
354
|
taskList.length > 0 && (React.createElement(Box, { marginX: 1, marginY: 1, paddingX: 1, flexDirection: "column", borderStyle: "round", borderColor: palette.brand },
|
|
351
355
|
React.createElement(Box, { marginBottom: 0 },
|
|
@@ -383,6 +387,12 @@ export function App({ session, initialMode, initialModel, cwd, projectRoot, init
|
|
|
383
387
|
? palette.textPrimary
|
|
384
388
|
: palette.textDim, strikethrough: task.status === "completed" }, label)));
|
|
385
389
|
}))),
|
|
390
|
+
thinking && busy && (React.createElement(Box, { paddingX: 2, marginTop: 1 },
|
|
391
|
+
React.createElement(Text, { color: palette.brandBright },
|
|
392
|
+
React.createElement(Spinner, { type: "dots" })),
|
|
393
|
+
React.createElement(Text, { color: palette.textMuted },
|
|
394
|
+
" ",
|
|
395
|
+
thinking))),
|
|
386
396
|
liveOutput && (React.createElement(Box, { marginX: 1, marginY: 1, paddingX: 1, flexDirection: "column", borderStyle: "round", borderColor: palette.warning },
|
|
387
397
|
React.createElement(Box, { marginBottom: 0 },
|
|
388
398
|
React.createElement(Text, { color: palette.warning, bold: true },
|
package/dist/ui/StatusBar.js
CHANGED
|
@@ -14,7 +14,7 @@ function pct(used, limit) {
|
|
|
14
14
|
export function StatusBar({ tokensUsed, tokensLimit, mode, model, cwd, busy, }) {
|
|
15
15
|
const percent = pct(tokensUsed, tokensLimit);
|
|
16
16
|
const projectName = path.basename(cwd) || cwd;
|
|
17
|
-
const modelLabel = model === "max" ? "
|
|
17
|
+
const modelLabel = model === "max" ? "CLI Max" : "CLI Pro";
|
|
18
18
|
const modelColor = model === "max" ? palette.accent : palette.brand;
|
|
19
19
|
const pctColor = usageColor(percent);
|
|
20
20
|
return (React.createElement(Box, { borderStyle: "single", borderColor: palette.border, paddingX: 1, justifyContent: "space-between" },
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { palette, symbols } from "./theme.js";
|
|
5
|
+
import { listSessions } from "../agent/session-store.js";
|
|
6
|
+
function relativeTime(date) {
|
|
7
|
+
const diff = Date.now() - date.getTime();
|
|
8
|
+
if (diff < 60_000)
|
|
9
|
+
return "az önce";
|
|
10
|
+
if (diff < 3_600_000)
|
|
11
|
+
return `${Math.floor(diff / 60_000)} dk önce`;
|
|
12
|
+
if (diff < 86_400_000)
|
|
13
|
+
return `${Math.floor(diff / 3_600_000)} saat önce`;
|
|
14
|
+
if (diff < 7 * 86_400_000)
|
|
15
|
+
return `${Math.floor(diff / 86_400_000)} gün önce`;
|
|
16
|
+
return date.toLocaleDateString("tr-TR");
|
|
17
|
+
}
|
|
18
|
+
async function buildActivityPreview(sessionId, cwd) {
|
|
19
|
+
try {
|
|
20
|
+
const { readSessionTranscript } = await import("../agent/session-store.js");
|
|
21
|
+
const events = await readSessionTranscript(sessionId, cwd);
|
|
22
|
+
const firstUser = events.find((e) => e.type === "user");
|
|
23
|
+
if (firstUser && firstUser.type === "user") {
|
|
24
|
+
return firstUser.content.slice(0, 80);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
}
|
|
29
|
+
return "(geçmiş oturum)";
|
|
30
|
+
}
|
|
31
|
+
export function WelcomeBox({ userName, userEmail, modelLabel, cwd, cliVersion, projectRoot, }) {
|
|
32
|
+
const [recent, setRecent] = useState([]);
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
let cancelled = false;
|
|
35
|
+
(async () => {
|
|
36
|
+
try {
|
|
37
|
+
const sessions = await listSessions(projectRoot);
|
|
38
|
+
const prior = sessions.slice(1, 4);
|
|
39
|
+
const previews = [];
|
|
40
|
+
for (const s of prior) {
|
|
41
|
+
const preview = await buildActivityPreview(s.sessionId, projectRoot);
|
|
42
|
+
previews.push({
|
|
43
|
+
sessionId: s.sessionId,
|
|
44
|
+
preview,
|
|
45
|
+
whenLabel: relativeTime(s.lastActivityAt),
|
|
46
|
+
messageCount: s.userMessageCount,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (!cancelled)
|
|
50
|
+
setRecent(previews);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
}
|
|
54
|
+
})();
|
|
55
|
+
return () => {
|
|
56
|
+
cancelled = true;
|
|
57
|
+
};
|
|
58
|
+
}, [projectRoot]);
|
|
59
|
+
const projectName = path.basename(cwd) || cwd;
|
|
60
|
+
const displayName = userName.trim() || userEmail || "Geliştirici";
|
|
61
|
+
return (React.createElement(Box, { borderStyle: "round", borderColor: palette.brand, flexDirection: "column", paddingX: 1, paddingY: 0, marginBottom: 1 },
|
|
62
|
+
React.createElement(Box, null,
|
|
63
|
+
React.createElement(Text, { color: palette.brand, bold: true },
|
|
64
|
+
symbols.sparkle,
|
|
65
|
+
" AIGENCY CLI"),
|
|
66
|
+
React.createElement(Text, { color: palette.textFaint },
|
|
67
|
+
" v",
|
|
68
|
+
cliVersion)),
|
|
69
|
+
React.createElement(Box, { marginTop: 1 },
|
|
70
|
+
React.createElement(Box, { flexDirection: "column", width: "50%", paddingRight: 1 },
|
|
71
|
+
React.createElement(Text, null,
|
|
72
|
+
React.createElement(Text, { color: palette.accent }, symbols.star),
|
|
73
|
+
" ",
|
|
74
|
+
React.createElement(Text, { color: palette.textPrimary, bold: true },
|
|
75
|
+
"Ho\u015F geldin",
|
|
76
|
+
displayName !== "Geliştirici" ? `, ${displayName}` : "",
|
|
77
|
+
"!")),
|
|
78
|
+
React.createElement(Box, { marginTop: 1 },
|
|
79
|
+
React.createElement(Text, { color: palette.textDim },
|
|
80
|
+
symbols.bullet,
|
|
81
|
+
" Paket: "),
|
|
82
|
+
React.createElement(Text, { color: palette.brandBright, bold: true }, modelLabel)),
|
|
83
|
+
React.createElement(Box, null,
|
|
84
|
+
React.createElement(Text, { color: palette.textDim },
|
|
85
|
+
symbols.bullet,
|
|
86
|
+
" Dizin: "),
|
|
87
|
+
React.createElement(Text, { color: palette.textSecondary }, projectName)),
|
|
88
|
+
userEmail && (React.createElement(Box, null,
|
|
89
|
+
React.createElement(Text, { color: palette.textDim },
|
|
90
|
+
symbols.bullet,
|
|
91
|
+
" Hesap: "),
|
|
92
|
+
React.createElement(Text, { color: palette.textMuted }, userEmail)))),
|
|
93
|
+
React.createElement(Box, { flexDirection: "column", width: "50%", paddingLeft: 1 },
|
|
94
|
+
React.createElement(Text, { color: palette.accent, bold: true },
|
|
95
|
+
symbols.lightning,
|
|
96
|
+
" Ba\u015Flang\u0131\u00E7 ipu\u00E7lar\u0131"),
|
|
97
|
+
React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
98
|
+
React.createElement(Text, { color: palette.textMuted },
|
|
99
|
+
React.createElement(Text, { color: palette.brand }, "/init"),
|
|
100
|
+
" \u2014 proje i\u00E7in AIGENCY.md olu\u015Ftur"),
|
|
101
|
+
React.createElement(Text, { color: palette.textMuted },
|
|
102
|
+
React.createElement(Text, { color: palette.brand }, "/help"),
|
|
103
|
+
" \u2014 komut listesi"),
|
|
104
|
+
React.createElement(Text, { color: palette.textMuted },
|
|
105
|
+
React.createElement(Text, { color: palette.brand }, "Shift+Tab"),
|
|
106
|
+
" \u2014 izin modu de\u011Fi\u015Ftir"),
|
|
107
|
+
React.createElement(Text, { color: palette.textMuted },
|
|
108
|
+
React.createElement(Text, { color: palette.brand }, "ESC"),
|
|
109
|
+
" \u2014 aktif i\u015Flemi iptal et")))),
|
|
110
|
+
recent.length > 0 && (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
|
|
111
|
+
React.createElement(Text, { color: palette.success, bold: true },
|
|
112
|
+
symbols.triangle,
|
|
113
|
+
" Son aktiviteler"),
|
|
114
|
+
recent.map((r) => (React.createElement(Box, { key: r.sessionId },
|
|
115
|
+
React.createElement(Text, { color: palette.textFaint }, r.whenLabel.padEnd(12)),
|
|
116
|
+
React.createElement(Text, { color: palette.textSecondary }, r.preview)))))),
|
|
117
|
+
React.createElement(Box, { marginTop: 1 },
|
|
118
|
+
React.createElement(Text, { color: palette.textFaint },
|
|
119
|
+
symbols.arrow,
|
|
120
|
+
" Mesaj yazmaya ba\u015Fla veya ",
|
|
121
|
+
React.createElement(Text, { color: palette.brand }, "/help"),
|
|
122
|
+
" ile komutlar\u0131 ke\u015Ffet"))));
|
|
123
|
+
}
|
package/dist/ui/theme.js
CHANGED
|
@@ -56,22 +56,22 @@ export const agentRoleColor = {
|
|
|
56
56
|
export const modeColors = {
|
|
57
57
|
default: {
|
|
58
58
|
color: palette.brand,
|
|
59
|
-
label: "
|
|
59
|
+
label: "onay iste",
|
|
60
60
|
icon: "●",
|
|
61
61
|
},
|
|
62
62
|
plan: {
|
|
63
63
|
color: palette.info,
|
|
64
|
-
label: "
|
|
64
|
+
label: "plan",
|
|
65
65
|
icon: "◇",
|
|
66
66
|
},
|
|
67
67
|
accept_edits: {
|
|
68
68
|
color: palette.warning,
|
|
69
|
-
label: "
|
|
69
|
+
label: "oto. düzenle",
|
|
70
70
|
icon: "✎",
|
|
71
71
|
},
|
|
72
72
|
auto: {
|
|
73
73
|
color: palette.accent,
|
|
74
|
-
label: "
|
|
74
|
+
label: "otomatik",
|
|
75
75
|
icon: "⚡",
|
|
76
76
|
},
|
|
77
77
|
};
|
|
@@ -113,4 +113,5 @@ export const symbols = {
|
|
|
113
113
|
star: "★",
|
|
114
114
|
hourglass: "⧗",
|
|
115
115
|
lightning: "⚡",
|
|
116
|
+
spinner: "◜",
|
|
116
117
|
};
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigencydev/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "AIGENCY CLI — terminalden yapay zeka destekli kod üretimi, dosya yönetimi ve proje otomasyonu.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"commander": "^12.1.0",
|
|
30
30
|
"ink": "^5.0.1",
|
|
31
|
+
"ink-spinner": "^5.0.0",
|
|
31
32
|
"ink-text-input": "^6.0.0",
|
|
32
33
|
"react": "^18.3.1",
|
|
33
34
|
"zod": "^3.23.8"
|