@takimcizgisi/ajan 0.2.5 → 0.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.

Potentially problematic release.


This version of @takimcizgisi/ajan might be problematic. Click here for more details.

Files changed (71) hide show
  1. package/LICENSE +227 -674
  2. package/README.md +243 -305
  3. package/ajan-logo.txt +2 -0
  4. package/dist/config/configManager.js +122 -19
  5. package/dist/config/types.d.ts +37 -0
  6. package/dist/core/agent.d.ts +1 -1
  7. package/dist/core/agent.js +25 -4
  8. package/dist/discord/presence.d.ts +65 -0
  9. package/dist/discord/presence.js +401 -0
  10. package/dist/engine/llama.d.ts +5 -0
  11. package/dist/engine/llama.js +19 -5
  12. package/dist/engine/modelManager.d.ts +0 -1
  13. package/dist/engine/modelManager.js +0 -8
  14. package/dist/index.d.ts +1 -0
  15. package/dist/index.js +1 -0
  16. package/dist/service.js +0 -1
  17. package/dist/tools/playground.d.ts +4 -0
  18. package/dist/tools/playground.js +125 -0
  19. package/dist/tools/registry.d.ts +0 -1
  20. package/dist/tools/registry.js +5 -4
  21. package/dist/tools/taskComplete.js +16 -4
  22. package/dist/tools/terminal.js +12 -12
  23. package/dist/utils/paths.d.ts +1 -0
  24. package/dist/utils/paths.js +29 -11
  25. package/package.json +78 -106
  26. package/scripts/build-vscode.mjs +28 -0
  27. package/scripts/ensure-tgz.mjs +27 -0
  28. package/scripts/install-vscode.mjs +236 -0
  29. package/scripts/release.mjs +19 -0
  30. package/scripts/smoke-new-tools.ts +79 -0
  31. package/scripts/smoke-tools.ts +201 -0
  32. package/src/vscode/LICENSE +674 -0
  33. package/src/vscode/README.md +54 -0
  34. package/src/vscode/media/assets/Anton.ttf +0 -0
  35. package/src/vscode/media/chat.js +634 -0
  36. package/src/vscode/media/style.css +767 -0
  37. package/src/vscode/out/extension.js +598 -0
  38. package/src/vscode/package.json +243 -0
  39. package/dist/cli/index.d.ts +0 -2
  40. package/dist/cli/index.js +0 -741
  41. package/dist/cli/tui.d.ts +0 -145
  42. package/dist/cli/tui.js +0 -1003
  43. package/dist/electron/main.d.ts +0 -1
  44. package/dist/electron/main.js +0 -364
  45. package/dist/electron/preload.d.ts +0 -1
  46. package/dist/electron/preload.js +0 -67
  47. package/dist/utils/clipboard.d.ts +0 -2
  48. package/dist/utils/clipboard.js +0 -40
  49. package/dist/utils/lock.d.ts +0 -12
  50. package/dist/utils/lock.js +0 -68
  51. package/dist/utils/sacGuard.d.ts +0 -4
  52. package/dist/utils/sacGuard.js +0 -47
  53. package/dist/utils/spinner.d.ts +0 -10
  54. package/dist/utils/spinner.js +0 -32
  55. package/src/gui/assets/image/logo.svg +0 -1
  56. package/src/gui/assets/image/opencode.svg +0 -18
  57. package/src/gui/css/style.css +0 -430
  58. package/src/gui/html/chat.html +0 -34
  59. package/src/gui/html/downloads.html +0 -11
  60. package/src/gui/html/hakkinda.html +0 -26
  61. package/src/gui/html/index.html +0 -82
  62. package/src/gui/html/projects.html +0 -12
  63. package/src/gui/html/settings.html +0 -4
  64. package/src/gui/js/app.js +0 -197
  65. package/src/gui/js/chat.js +0 -434
  66. package/src/gui/js/downloads.js +0 -172
  67. package/src/gui/js/hakkinda.js +0 -16
  68. package/src/gui/js/projects.js +0 -113
  69. package/src/gui/js/settings.js +0 -177
  70. /package/src/{gui/assets/image → vscode/media/assets}/AJAN_LOGO.svg +0 -0
  71. /package/src/{gui/assets/image → vscode/media/assets}/ajan.png +0 -0
@@ -0,0 +1,79 @@
1
+ import { mkdtempSync, rmSync, existsSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { createCoreTools } from "../src/tools/registry.js";
5
+ import { openPlaygroundTool, setTodosTool, getTodosTool } from "../src/tools/playground.js";
6
+ import { taskCompleteTool } from "../src/tools/taskComplete.js";
7
+
8
+ let failures = 0;
9
+ const check = (name: string, ok: boolean, detail?: string): void => {
10
+ if (ok) console.log(` ok ${name}`);
11
+ else { failures++; console.log(` FAIL ${name}${detail ? ` — ${detail}` : ""}`); }
12
+ };
13
+
14
+ const tmp = mkdtempSync(join(tmpdir(), "ajan-test-"));
15
+ const ctx = { cwd: tmp, config: { modelId: "x", maxToolOutput: 100000 } };
16
+
17
+ const tools = createCoreTools(ctx);
18
+ const names = tools.map(t => t.name);
19
+
20
+ check("çekirdek araçlar korundu", tools.length >= 18, `toplam ${tools.length}`);
21
+ for (const need of [
22
+ "open_playground", "set_todos", "get_todos"
23
+ ]) {
24
+ check(`araç ${need}`, names.includes(need));
25
+ }
26
+ check("GUI otomasyon araçları kaldırıldı",
27
+ !["screen_info", "screenshot", "mouse_move", "mouse_click", "mouse_scroll", "key_press", "type_text"].some(n => names.includes(n)),
28
+ names.filter(n => n.includes("screen") || n.includes("mouse") || n.includes("key_") || n.includes("type")).join(","));
29
+
30
+ const opened = await openPlaygroundTool.handler({}, ctx);
31
+ check("open_playground oluşturur", opened.ok && opened.output.includes(".ajan"), opened.output);
32
+
33
+ const played = await openPlaygroundTool.handler({ note: "deneme" }, ctx);
34
+ check("open_playground korur", played.ok && played.output.includes("0 öğe"), played.output);
35
+
36
+ const set = await setTodosTool.handler(
37
+ { todos: [{ text: "adım 1" }, { text: "adım 2", done: true }] },
38
+ ctx
39
+ );
40
+ check("set_todos kaydeder", set.ok && set.output.includes("2 madde"), set.output);
41
+
42
+ const get = await getTodosTool.handler({}, ctx);
43
+ check("get_todos okur", get.ok && get.output.includes("adım 1") && get.output.includes("[x] 2."), get.output);
44
+
45
+ const reset = await openPlaygroundTool.handler({ reset: true }, ctx);
46
+ check("open_playground reset temizler", reset.ok && reset.output.includes("1 temizlendi"), reset.output);
47
+
48
+ const get2 = await getTodosTool.handler({}, ctx);
49
+ check("reset sonrası TODO boş", get2.ok && get2.output.includes("TODO yok"), get2.output);
50
+
51
+ const sigA: { taskCompleted?: boolean; continueRequested?: boolean } = {};
52
+ const resA = await taskCompleteTool.handler({ report: "ara rapor", continue: true }, { cwd: tmp, config: {}, signals: sigA });
53
+ check("task_complete continue:true tur açar", resA.ok && sigA.continueRequested === true && !sigA.taskCompleted, resA.output);
54
+
55
+ const sigB: { taskCompleted?: boolean; continueRequested?: boolean } = {};
56
+ const resB = await taskCompleteTool.handler({ report: "bitti", continue: false }, { cwd: tmp, config: {}, signals: sigB });
57
+ check("task_complete continue:false bitirir", resB.ok && sigB.taskCompleted === true && !sigB.continueRequested, resB.output);
58
+
59
+ const sigC: { taskCompleted?: boolean; continueRequested?: boolean } = {};
60
+ const resC = await taskCompleteTool.handler({ report: "bitti" }, { cwd: tmp, config: {}, signals: sigC });
61
+ check("task_complete varsayılan bitirir", resC.ok && sigC.taskCompleted === true && !sigC.continueRequested, resC.output);
62
+
63
+ const sigD: { taskCompleted?: boolean; continueRequested?: boolean } = {};
64
+ const resD = await taskCompleteTool.handler({ report: "bitti" }, { cwd: tmp, config: {}, signals: sigD });
65
+ check("task_complete report korunur", resD.ok && resD.output.includes("bitti"), resD.output);
66
+
67
+ // Geçici dizini temizle (Windows kilitleri için birkaç deneme).
68
+ for (let attempt = 0; attempt < 10 && existsSync(tmp); attempt++) {
69
+ try {
70
+ rmSync(tmp, { recursive: true, force: true });
71
+ } catch {
72
+ /* kilitli: bekleyip tekrar dene */
73
+ }
74
+ if (!existsSync(tmp)) break;
75
+ await new Promise((r) => setTimeout(r, 400));
76
+ }
77
+
78
+ console.log(failures === 0 ? "\nYENİ ARAÇ TESTLERİ GEÇTİ" : `\n${failures} TEST BAŞARISIZ`);
79
+ process.exitCode = failures === 0 ? 0 : 1;
@@ -0,0 +1,201 @@
1
+ import { mkdtempSync, rmSync, readFileSync, writeFileSync, existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import os from "node:os";
4
+ import { createCoreTools } from "../src/tools/registry.js";
5
+ import type { AjanConfig, ToolExecutionContext } from "../src/config/types.js";
6
+
7
+ let failures = 0;
8
+
9
+ function check(name: string, ok: boolean, detail?: string): void {
10
+ if (ok) {
11
+ console.log(` ok ${name}`);
12
+ } else {
13
+ failures++;
14
+ console.log(` FAIL ${name}${detail ? ` — ${detail}` : ""}`);
15
+ }
16
+ }
17
+
18
+ async function main(): Promise<void> {
19
+ const tmp = mkdtempSync(join(os.tmpdir(), "ajan-smoke-"));
20
+ const config: AjanConfig = {
21
+ modelId: "smoke",
22
+ toolTimeout: 2_000,
23
+ maxToolOutput: 10_000
24
+ };
25
+ const ctx: ToolExecutionContext = { cwd: tmp, config };
26
+ const tools = new Map(createCoreTools(ctx).map((t) => [t.name, t]));
27
+ const run = (name: string, params: Record<string, unknown>): Promise<{ ok: boolean; output: string }> => {
28
+ const tool = tools.get(name);
29
+ if (!tool) throw new Error(`Araç yok: ${name}`);
30
+ return Promise.resolve(tool.handler(params, ctx));
31
+ };
32
+
33
+ console.log("Araç smoke testi");
34
+ console.log(`Geçici dizin: ${tmp}\n`);
35
+
36
+ try {
37
+ // write_file + read_file
38
+ let res = await run("write_file", { path: "src/merhaba.txt", content: "ilk satır\nikinci satır" });
39
+ check("write_file oluşturur", res.ok && existsSync(join(tmp, "src", "merhaba.txt")), res.output);
40
+
41
+ res = await run("write_file", { path: "src/merhaba.txt", content: "\nüçüncü satır", append: true });
42
+ check("write_file append", res.ok, res.output);
43
+
44
+ res = await run("read_file", { path: "src/merhaba.txt" });
45
+ check("read_file içerik", res.ok && res.output.includes("ilk satır") && res.output.includes("üçüncü satır"), res.output);
46
+
47
+ // list_dir
48
+ res = await run("list_dir", { path: ".", recursive: true });
49
+ check("list_dir recursive", res.ok && res.output.includes("merhaba.txt"), res.output);
50
+
51
+ // search_files
52
+ res = await run("search_files", { pattern: "**/*.txt" });
53
+ check("search_files glob", res.ok && res.output.includes("merhaba.txt"), res.output);
54
+
55
+ // grep_files
56
+ res = await run("grep_files", { pattern: "üçüncü" });
57
+ check("grep_files bulur", res.ok && res.output.includes("üçüncü"), res.output);
58
+
59
+ res = await run("grep_files", { pattern: "[" });
60
+ check("grep_files geçersiz regex hatası", !res.ok && res.output.includes("Geçersiz"), res.output);
61
+
62
+ // apply_patch
63
+ const patch = [
64
+ "--- a/src/merhaba.txt",
65
+ "+++ b/src/merhaba.txt",
66
+ "@@ -1,2 +1,3 @@",
67
+ " ilk satır",
68
+ "-ikinci satır",
69
+ "+yeni satır",
70
+ "+üçüncü satır"
71
+ ].join("\n");
72
+ res = await run("apply_patch", { patch });
73
+ check("apply_patch uygular", res.ok, res.output);
74
+ const patched = readFileSync(join(tmp, "src", "merhaba.txt"), "utf8");
75
+ check("apply_patch içerik", patched.includes("yeni satır") && !patched.includes("ikinci satır"), patched);
76
+
77
+ // edit_file
78
+ res = await run("edit_file", { path: "src/merhaba.txt", oldString: "yeni satır", newString: "düzenlenmiş satır" });
79
+ check("edit_file değiştirir", res.ok, res.output);
80
+ let edited = readFileSync(join(tmp, "src", "merhaba.txt"), "utf8");
81
+ check("edit_file içerik", edited.includes("düzenlenmiş satır") && !edited.includes("yeni satır"), edited);
82
+
83
+ res = await run("edit_file", { path: "src/merhaba.txt", oldString: "yok böyle bir metin", newString: "x" });
84
+ check("edit_file eşleşme yok hatası", !res.ok && res.output.includes("Eşleşme bulunamadı"), res.output);
85
+
86
+ res = await run("edit_file", { path: "src/merhaba.txt", oldString: "satır", newString: "X", replaceAll: false });
87
+ check("edit_file çoklu eşleşme hatası", !res.ok && res.output.includes("kez geçiyor"), res.output);
88
+
89
+ res = await run("edit_file", { path: "src/merhaba.txt", oldString: "satır", newString: "satır", replaceAll: true });
90
+ check("edit_file replaceAll", res.ok, res.output);
91
+
92
+ // run_command: tehlikeli komut engeli
93
+ res = await run("run_command", { command: "format c:" });
94
+ check("run_command tehlikeli komut engellenir", !res.ok && res.output.includes("engellendi"), res.output);
95
+
96
+ // run_command: başarılı
97
+ const echoCmd = process.platform === "win32" ? "echo smoke-test-ok" : "echo smoke-test-ok";
98
+ res = await run("run_command", { command: echoCmd });
99
+ check("run_command başarılı", res.ok && res.output.includes("smoke-test-ok"), res.output);
100
+
101
+ // run_command: göreli cwd ctx.cwd'ye göre çözülür
102
+ res = await run("run_command", { command: echoCmd, cwd: "src" });
103
+ check("run_command göreli cwd", res.ok, res.output);
104
+
105
+ // run_command: timeout + süreç ağacı öldürme (Windows: taskkill)
106
+ const sleepCmd = process.platform === "win32"
107
+ ? "ping -n 30 127.0.0.1 >nul"
108
+ : "sleep 30";
109
+ const started = Date.now();
110
+ res = await run("run_command", { command: sleepCmd, timeout: 1500 });
111
+ const elapsed = Date.now() - started;
112
+ check(
113
+ "run_command timeout döner (askıda kalmaz)",
114
+ !res.ok && res.output.includes("ZAMAN AŞIMI") && elapsed < 20_000,
115
+ `${res.output} (${elapsed}ms)`
116
+ );
117
+ // Windows'ta süreç ağacı tutamaçlarının bırakılması biraz zaman alır;
118
+ // temizlik öncesi kısa bir nefes ver.
119
+ await new Promise((r) => setTimeout(r, 1500));
120
+
121
+ // web_search: ağ varsa dene, yoksa uyar
122
+ res = await run("web_search", { query: "opencode test", maxResults: 3 });
123
+ if (res.ok) {
124
+ check("web_search sonuç", !res.output.includes("bulunamadı"), res.output.slice(0, 200));
125
+ } else {
126
+ console.log(` ---- web_search atlandı (ağ yok olabilir): ${res.output.slice(0, 120)}`);
127
+ }
128
+
129
+ // task_complete: sinyali işaretler
130
+ const signals = { taskCompleted: false };
131
+ const ctxWithSignals: ToolExecutionContext = { ...ctx, signals };
132
+ const completeTool = tools.get("task_complete");
133
+ if (!completeTool) throw new Error("Araç yok: task_complete");
134
+ res = await Promise.resolve(completeTool.handler({ report: "bitti" }, ctxWithSignals));
135
+ check("task_complete sinyal", res.ok && signals.taskCompleted === true, res.output);
136
+
137
+ // not_al / not_oku
138
+ res = await run("not_al", { text: "smoke-test hafıza kaydı" });
139
+ check("not_al kaydeder", res.ok && res.output.includes("#"), res.output);
140
+ res = await run("not_oku", { query: "smoke-test" });
141
+ check("not_oku bulur", res.ok && res.output.includes("hafıza kaydı"), res.output);
142
+
143
+ // move_file + delete_file
144
+ res = await run("move_file", { source: "src/merhaba.txt", destination: "yeni/taşındı.txt" });
145
+ check("move_file taşır", res.ok && existsSync(join(tmp, "yeni", "taşındı.txt")), res.output);
146
+ res = await run("delete_file", { path: "yeni/taşındı.txt" });
147
+ check("delete_file siler", res.ok && !existsSync(join(tmp, "yeni", "taşındı.txt")), res.output);
148
+ res = await run("delete_file", { path: "." , recursive: true });
149
+ check("delete_file cwd koruması", !res.ok && res.output.includes("silemezsin"), res.output);
150
+
151
+ // read_data: JSON ve YAML
152
+ writeFileSync(join(tmp, "veri.json"), JSON.stringify({ ad: "ajan", sayi: 7, liste: [1, 2, 3] }), "utf8");
153
+ res = await run("read_data", { path: "veri.json" });
154
+ check("read_data json", res.ok && res.output.includes("ajan") && res.output.includes("nesne"), res.output);
155
+ writeFileSync(join(tmp, "veri.yaml"), "ad: ajan\nsayi: 7\n", "utf8");
156
+ res = await run("read_data", { path: "veri.yaml" });
157
+ check("read_data yaml", res.ok && res.output.includes("ajan"), res.output);
158
+
159
+ // unzip_file
160
+ const zipPath = join(tmp, "arsiv.zip");
161
+ const AdmZipMod = await import("adm-zip");
162
+ const zip = new AdmZipMod.default();
163
+ zip.addFile("icindekiler/okubeni.txt", Buffer.from("zip içeriği smoke", "utf8"));
164
+ zip.writeZip(zipPath);
165
+ res = await run("unzip_file", { path: "arsiv.zip" });
166
+ check(
167
+ "unzip_file açar",
168
+ res.ok && existsSync(join(tmp, "icindekiler", "okubeni.txt")) && readFileSync(join(tmp, "icindekiler", "okubeni.txt"), "utf8").includes("smoke"),
169
+ res.output
170
+ );
171
+
172
+ // fetch_url: ağ varsa dene
173
+ res = await run("fetch_url", { url: "https://example.com", maxLength: 2000 });
174
+ if (res.ok) {
175
+ check("fetch_url içerik", res.output.includes("example"), res.output.slice(0, 160));
176
+ } else {
177
+ console.log(` ---- fetch_url atlandı (ağ yok olabilir): ${res.output.slice(0, 120)}`);
178
+ }
179
+ } finally {
180
+ // Windows'ta force:true hata fırlatmayıp sessizce kalıntı bırakabildiği için
181
+ // dizinin gerçekten silindiğini kontrol ederek döngüyle dene.
182
+ // (timeout testinden kalan cmd.exe cwd tutamacını bırakana kadar beklenir.)
183
+ for (let attempt = 0; attempt < 15 && existsSync(tmp); attempt++) {
184
+ try {
185
+ rmSync(tmp, { recursive: true, force: true });
186
+ } catch {
187
+ /* kilitli: bekleyip tekrar dene */
188
+ }
189
+ if (!existsSync(tmp)) break;
190
+ await new Promise((r) => setTimeout(r, 500));
191
+ }
192
+ }
193
+
194
+ console.log(failures === 0 ? "\nTÜM TESTLER GEÇTİ" : `\n${failures} TEST BAŞARISIZ`);
195
+ process.exitCode = failures === 0 ? 0 : 1;
196
+ }
197
+
198
+ main().catch((err) => {
199
+ console.error(err);
200
+ process.exit(1);
201
+ });