@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.
- package/LICENSE +227 -674
- package/README.md +243 -305
- package/ajan-logo.txt +2 -0
- package/dist/config/configManager.js +122 -19
- package/dist/config/types.d.ts +37 -0
- package/dist/core/agent.d.ts +1 -1
- package/dist/core/agent.js +25 -4
- package/dist/discord/presence.d.ts +65 -0
- package/dist/discord/presence.js +401 -0
- package/dist/engine/llama.d.ts +5 -0
- package/dist/engine/llama.js +19 -5
- package/dist/engine/modelManager.d.ts +0 -1
- package/dist/engine/modelManager.js +0 -8
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/service.js +0 -1
- package/dist/tools/playground.d.ts +4 -0
- package/dist/tools/playground.js +125 -0
- package/dist/tools/registry.d.ts +0 -1
- package/dist/tools/registry.js +5 -4
- package/dist/tools/taskComplete.js +16 -4
- package/dist/tools/terminal.js +12 -12
- package/dist/utils/paths.d.ts +1 -0
- package/dist/utils/paths.js +29 -11
- package/package.json +78 -106
- package/scripts/build-vscode.mjs +28 -0
- package/scripts/ensure-tgz.mjs +27 -0
- package/scripts/install-vscode.mjs +236 -0
- package/scripts/release.mjs +19 -0
- package/scripts/smoke-new-tools.ts +79 -0
- package/scripts/smoke-tools.ts +201 -0
- package/src/vscode/LICENSE +674 -0
- package/src/vscode/README.md +54 -0
- package/src/vscode/media/assets/Anton.ttf +0 -0
- package/src/vscode/media/chat.js +634 -0
- package/src/vscode/media/style.css +767 -0
- package/src/vscode/out/extension.js +598 -0
- package/src/vscode/package.json +243 -0
- package/dist/cli/index.d.ts +0 -2
- package/dist/cli/index.js +0 -741
- package/dist/cli/tui.d.ts +0 -145
- package/dist/cli/tui.js +0 -1003
- package/dist/electron/main.d.ts +0 -1
- package/dist/electron/main.js +0 -364
- package/dist/electron/preload.d.ts +0 -1
- package/dist/electron/preload.js +0 -67
- package/dist/utils/clipboard.d.ts +0 -2
- package/dist/utils/clipboard.js +0 -40
- package/dist/utils/lock.d.ts +0 -12
- package/dist/utils/lock.js +0 -68
- package/dist/utils/sacGuard.d.ts +0 -4
- package/dist/utils/sacGuard.js +0 -47
- package/dist/utils/spinner.d.ts +0 -10
- package/dist/utils/spinner.js +0 -32
- package/src/gui/assets/image/logo.svg +0 -1
- package/src/gui/assets/image/opencode.svg +0 -18
- package/src/gui/css/style.css +0 -430
- package/src/gui/html/chat.html +0 -34
- package/src/gui/html/downloads.html +0 -11
- package/src/gui/html/hakkinda.html +0 -26
- package/src/gui/html/index.html +0 -82
- package/src/gui/html/projects.html +0 -12
- package/src/gui/html/settings.html +0 -4
- package/src/gui/js/app.js +0 -197
- package/src/gui/js/chat.js +0 -434
- package/src/gui/js/downloads.js +0 -172
- package/src/gui/js/hakkinda.js +0 -16
- package/src/gui/js/projects.js +0 -113
- package/src/gui/js/settings.js +0 -177
- /package/src/{gui/assets/image → vscode/media/assets}/AJAN_LOGO.svg +0 -0
- /package/src/{gui/assets/image → vscode/media/assets}/ajan.png +0 -0
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
export const taskCompleteTool = {
|
|
2
2
|
name: "task_complete",
|
|
3
|
-
description: "
|
|
3
|
+
description: "Görev akışını KENDİ kararınla kontrol eder. " +
|
|
4
|
+
"İşin henüz bitmediyse, kalan adımlara devam etmek için continue:true ile çağır (yeni bir tur açılır). " +
|
|
5
|
+
"Görev TAMAMLANDIĞINDA ve doğrulandığında continue:false (veya continue vermeden) ile çağır; " +
|
|
4
6
|
"report parametresine yapılan işlerin özetini yaz.",
|
|
5
7
|
parameters: {
|
|
6
8
|
type: "object",
|
|
7
9
|
properties: {
|
|
8
|
-
report: { type: "string", description: "
|
|
10
|
+
report: { type: "string", description: "İşin durumu / tamamlanan işlerin kısa özeti" },
|
|
11
|
+
continue: {
|
|
12
|
+
type: "boolean",
|
|
13
|
+
description: "true: göreve devam et, yeni bir tur iste (tur sonunda model tekrar görüşmelere devam eder). " +
|
|
14
|
+
"false veya verilmezse: görevi bitir."
|
|
15
|
+
}
|
|
9
16
|
},
|
|
10
|
-
required: [
|
|
17
|
+
required: []
|
|
11
18
|
},
|
|
12
19
|
handler: async (params, ctx) => {
|
|
13
|
-
if (ctx.signals)
|
|
20
|
+
if (ctx.signals) {
|
|
21
|
+
if (params.continue === true) {
|
|
22
|
+
ctx.signals.continueRequested = true;
|
|
23
|
+
return { ok: true, output: "Devam turu istendi (continue:true). Model kalan adımına devam edecek." };
|
|
24
|
+
}
|
|
14
25
|
ctx.signals.taskCompleted = true;
|
|
26
|
+
}
|
|
15
27
|
const report = (params.report ?? "").trim();
|
|
16
28
|
return { ok: true, output: report || "Görev tamamlandı." };
|
|
17
29
|
}
|
package/dist/tools/terminal.js
CHANGED
|
@@ -69,8 +69,18 @@ export const runCommandTool = {
|
|
|
69
69
|
const timer = setTimeout(() => {
|
|
70
70
|
timedOut = true;
|
|
71
71
|
try {
|
|
72
|
-
if (isWin) {
|
|
73
|
-
|
|
72
|
+
if (isWin && child.pid != null) {
|
|
73
|
+
// Önce taskkill /T ile SÜREÇ AĞACINI (cmd + alt komutlar) öldür.
|
|
74
|
+
// Önce ağaçta çocuk öldürülür, ardından taskkill "process not found"
|
|
75
|
+
// ile ağacı kaçırır; bu yüzden önce taskkill, TerminateProcess'ten önce gelir.
|
|
76
|
+
const killer = spawn("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
|
|
77
|
+
windowsHide: true,
|
|
78
|
+
stdio: "ignore"
|
|
79
|
+
});
|
|
80
|
+
killer.unref();
|
|
81
|
+
killer.on("error", () => {
|
|
82
|
+
/* taskkill başlatılamadıysa sessiz geç */
|
|
83
|
+
});
|
|
74
84
|
}
|
|
75
85
|
else if (child.pid != null) {
|
|
76
86
|
process.kill(-child.pid, "SIGKILL");
|
|
@@ -79,16 +89,6 @@ export const runCommandTool = {
|
|
|
79
89
|
catch {
|
|
80
90
|
/* zaten ölmüş olabilir */
|
|
81
91
|
}
|
|
82
|
-
if (isWin && child.pid != null) {
|
|
83
|
-
const killer = spawn("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
|
|
84
|
-
windowsHide: true,
|
|
85
|
-
stdio: "ignore"
|
|
86
|
-
});
|
|
87
|
-
killer.unref();
|
|
88
|
-
killer.on("error", () => {
|
|
89
|
-
/* taskkill başlatılamadıysa sessiz geç */
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
92
|
}, timeoutMs);
|
|
93
93
|
// 'close' ancak süreç bitip tüm pipe'lar kapanınca tetiklenir; askıda kalmamak için
|
|
94
94
|
// güvenlik zamanlayıcısı pipe'ları serbest bırakıp sonucu zorla döndürür.
|
package/dist/utils/paths.d.ts
CHANGED
package/dist/utils/paths.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mkdirSync } from "node:fs";
|
|
1
|
+
import { mkdirSync, appendFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import os from "node:os";
|
|
4
4
|
let currentLevel = "info";
|
|
@@ -12,19 +12,32 @@ const levelOrder = {
|
|
|
12
12
|
info: 3,
|
|
13
13
|
debug: 4
|
|
14
14
|
};
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
/** Her seviyedeki logu (debug dahil) diskteki günlüğe de yazar. */
|
|
16
|
+
function writeLogFile(level, prefix, ...args) {
|
|
17
|
+
try {
|
|
18
|
+
const line = `[${new Date().toISOString()}] [${level}] ${prefix} ${args
|
|
19
|
+
.map((a) => (typeof a === "string" ? a : JSON.stringify(a)))
|
|
20
|
+
.join(" ")}\n`;
|
|
21
|
+
appendFileSync(join(getLogDir(), "ajan.log"), line);
|
|
21
22
|
}
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
catch {
|
|
24
|
+
/* log dosyasına yazılamazsa sessizce geç */
|
|
24
25
|
}
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
}
|
|
27
|
+
function log(level, tag, ...args) {
|
|
28
|
+
const prefix = `[${tag}]`;
|
|
29
|
+
if (levelOrder[level] <= levelOrder[currentLevel]) {
|
|
30
|
+
if (level === "error") {
|
|
31
|
+
console.error(prefix, ...args);
|
|
32
|
+
}
|
|
33
|
+
else if (level === "warn") {
|
|
34
|
+
console.warn(prefix, ...args);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.log(prefix, ...args);
|
|
38
|
+
}
|
|
27
39
|
}
|
|
40
|
+
writeLogFile(level, prefix, ...args);
|
|
28
41
|
}
|
|
29
42
|
export const logger = {
|
|
30
43
|
error: (...args) => log("error", "hata", ...args),
|
|
@@ -55,4 +68,9 @@ export function getLogDir() {
|
|
|
55
68
|
mkdirSync(dir, { recursive: true });
|
|
56
69
|
return dir;
|
|
57
70
|
}
|
|
71
|
+
export function getOutputDir() {
|
|
72
|
+
const dir = join(getDataDir(), "outputs");
|
|
73
|
+
mkdirSync(dir, { recursive: true });
|
|
74
|
+
return dir;
|
|
75
|
+
}
|
|
58
76
|
//# sourceMappingURL=paths.js.map
|
package/package.json
CHANGED
|
@@ -1,106 +1,78 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@takimcizgisi/ajan",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "AJAN AI - Otonom yerel
|
|
5
|
-
"type": "module",
|
|
6
|
-
"license": "GPL-3.0",
|
|
7
|
-
"author": "TakimCizgisi Yazilim Gelistirme Grubu",
|
|
8
|
-
"keywords": [
|
|
9
|
-
"ai",
|
|
10
|
-
"llm",
|
|
11
|
-
"local",
|
|
12
|
-
"agent",
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
],
|
|
19
|
-
"repository": {
|
|
20
|
-
"type": "git",
|
|
21
|
-
"url": "https://github.com/takimcizgisi/ajan.git"
|
|
22
|
-
},
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"src/
|
|
39
|
-
"src/
|
|
40
|
-
"src/
|
|
41
|
-
"
|
|
42
|
-
"README.md"
|
|
43
|
-
],
|
|
44
|
-
"scripts": {
|
|
45
|
-
"build": "tsc -p tsconfig.json",
|
|
46
|
-
"build:
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
"
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
"@types/
|
|
73
|
-
"@types/
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
"build": {
|
|
80
|
-
"appId": "com.takimcizgisi.ajan",
|
|
81
|
-
"productName": "AJAN AI",
|
|
82
|
-
"directories": {
|
|
83
|
-
"output": "release"
|
|
84
|
-
},
|
|
85
|
-
"files": [
|
|
86
|
-
"dist/**/*",
|
|
87
|
-
"src/gui/**/*",
|
|
88
|
-
"config/**/*"
|
|
89
|
-
],
|
|
90
|
-
"extraResources": [
|
|
91
|
-
{
|
|
92
|
-
"from": "config",
|
|
93
|
-
"to": "config"
|
|
94
|
-
}
|
|
95
|
-
],
|
|
96
|
-
"win": {
|
|
97
|
-
"target": "nsis",
|
|
98
|
-
"icon": "src/gui/assets/image/ajan.png"
|
|
99
|
-
},
|
|
100
|
-
"nsis": {
|
|
101
|
-
"oneClick": false,
|
|
102
|
-
"allowToChangeInstallationDirectory": true,
|
|
103
|
-
"createDesktopShortcut": true
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@takimcizgisi/ajan",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "AJAN AI - Otonom yerel AI kodlama ajanı (Gemma 4 E2B + node-llama-cpp, VSCode uzantısı)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "GPL-3.0",
|
|
7
|
+
"author": "TakimCizgisi Yazilim Gelistirme Grubu",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"ai",
|
|
10
|
+
"llm",
|
|
11
|
+
"local",
|
|
12
|
+
"agent",
|
|
13
|
+
"coding-agent",
|
|
14
|
+
"llama-cpp",
|
|
15
|
+
"gemma",
|
|
16
|
+
"cuda",
|
|
17
|
+
"vscode"
|
|
18
|
+
],
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/takimcizgisi/ajan.git"
|
|
22
|
+
},
|
|
23
|
+
"main": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"import": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"!dist/**/*.map",
|
|
34
|
+
"config",
|
|
35
|
+
"scripts",
|
|
36
|
+
"src/vscode/out",
|
|
37
|
+
"src/vscode/media",
|
|
38
|
+
"src/vscode/package.json",
|
|
39
|
+
"src/vscode/LICENSE",
|
|
40
|
+
"src/vscode/README.md",
|
|
41
|
+
"ajan-logo.txt",
|
|
42
|
+
"README.md"
|
|
43
|
+
],
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "tsc -p tsconfig.json",
|
|
46
|
+
"build:vscode": "node scripts/build-vscode.mjs",
|
|
47
|
+
"vscode:package": "npm --prefix src/vscode run package",
|
|
48
|
+
"install:vscode": "node scripts/install-vscode.mjs",
|
|
49
|
+
"build:all": "npm run build && npm run build:vscode",
|
|
50
|
+
"clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
51
|
+
"test:tools": "tsx scripts/smoke-tools.ts",
|
|
52
|
+
"test:new": "tsx scripts/smoke-new-tools.ts",
|
|
53
|
+
"release": "node scripts/release.mjs",
|
|
54
|
+
"release:patch": "npm version patch && node scripts/release.mjs",
|
|
55
|
+
"prepack": "npm run clean && npm run build && npm run build:vscode && npm run vscode:package",
|
|
56
|
+
"postinstall": "node scripts/install-vscode.mjs"
|
|
57
|
+
},
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=26.4.0"
|
|
60
|
+
},
|
|
61
|
+
"allowScripts": {
|
|
62
|
+
"node-llama-cpp": true,
|
|
63
|
+
"esbuild": true
|
|
64
|
+
},
|
|
65
|
+
"dependencies": {
|
|
66
|
+
"@xhayper/discord-rpc": "^1.3.4",
|
|
67
|
+
"adm-zip": "^0.6.0",
|
|
68
|
+
"js-yaml": "^5.3.0",
|
|
69
|
+
"node-llama-cpp": "^3.19.1"
|
|
70
|
+
},
|
|
71
|
+
"devDependencies": {
|
|
72
|
+
"@types/adm-zip": "^0.5.8",
|
|
73
|
+
"@types/js-yaml": "^4.0.9",
|
|
74
|
+
"@types/node": "^24.13.3",
|
|
75
|
+
"tsx": "^4.23.12",
|
|
76
|
+
"typescript": "^7.0.2"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VSCode uzantısını derler.
|
|
3
|
+
*
|
|
4
|
+
* `npm run` alt süreçlere `npm_config_allow_scripts` ortam değişkenini geçirir;
|
|
5
|
+
* iç içe `npm install` bunu CLI bayrağı sanıp EALLOWSCRIPTS ile reddeder.
|
|
6
|
+
* Bu betik, ortamdan ilgili değişkeni temizleyerek npm'i çağırır.
|
|
7
|
+
*
|
|
8
|
+
* Akış:
|
|
9
|
+
* 1. ensure-tgz.mjs ile kök kütüphane paketini (tgz) hazırla.
|
|
10
|
+
* 2. Uzantının bağımlılıklarını kur (node-llama-cpp motoru dahil).
|
|
11
|
+
* 3. Uzantıyı derle (out/extension.js).
|
|
12
|
+
*/
|
|
13
|
+
import { execSync } from "node:child_process";
|
|
14
|
+
import { dirname, resolve } from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
|
|
17
|
+
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
18
|
+
const env = { ...process.env };
|
|
19
|
+
delete env.npm_config_allow_scripts;
|
|
20
|
+
|
|
21
|
+
const run = (cmd) => {
|
|
22
|
+
console.log(`> ${cmd}`);
|
|
23
|
+
execSync(cmd, { cwd: ROOT, env, stdio: "inherit", shell: true });
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
run("node scripts/ensure-tgz.mjs");
|
|
27
|
+
run('npm --prefix "src/vscode" install --no-audit --no-fund');
|
|
28
|
+
run('npm --prefix "src/vscode" run build');
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VSCode uzantısının `@takimcizgisi/ajan` bağımlılığını kurarken ihtiyaç duyduğu
|
|
3
|
+
* `takimcizgisi-ajan-<sürüm>.tgz` paketini yoksa üretir.
|
|
4
|
+
*
|
|
5
|
+
* Akış:
|
|
6
|
+
* 1. tgz kökte yoksa, derlenmiş çıktı (dist) yoksa önce `npm run build` çalıştır.
|
|
7
|
+
* 2. `npm pack --ignore-scripts` ile tgz üret (prepack/postinstall döngüsüne girmez).
|
|
8
|
+
*
|
|
9
|
+
* Böylece ilk kurulumda `postinstall` otomatik olarak hem VSCode uzantısını
|
|
10
|
+
* kurar hem de node-llama-cpp motorunu (kütüphane bağımlılığı olarak) hazırlar.
|
|
11
|
+
*/
|
|
12
|
+
import { execSync } from "node:child_process";
|
|
13
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
14
|
+
import { dirname, join, resolve } from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
|
|
17
|
+
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
18
|
+
const pkg = JSON.parse(readFileSync(join(ROOT, "package.json"), "utf8"));
|
|
19
|
+
const tgz = join(ROOT, `takimcizgisi-ajan-${pkg.version}.tgz`);
|
|
20
|
+
|
|
21
|
+
if (!existsSync(tgz)) {
|
|
22
|
+
if (!existsSync(join(ROOT, "dist", "index.js"))) {
|
|
23
|
+
execSync("npm run build", { cwd: ROOT, stdio: "inherit", shell: true });
|
|
24
|
+
}
|
|
25
|
+
execSync("npm pack --ignore-scripts", { cwd: ROOT, stdio: "inherit", shell: true });
|
|
26
|
+
console.log(`AJAN kütüphane paketi üretildi: ${tgz}`);
|
|
27
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AJAN global kurulumu sırasında VSCode uzantısını (kullanıcı onayıyla) kurar.
|
|
3
|
+
*
|
|
4
|
+
* Akış:
|
|
5
|
+
* 1. VSCode CLI'ı bul (Code.exe + cli.js | code / code-insiders | bilinen yollar).
|
|
6
|
+
* 2. VSIX'i sırasıyla bul: paket kökündeki gömülü VSIX → (geliştirme ortamında) kaynaktan üret →
|
|
7
|
+
* GitHub Releases'tan indir. (npm tarball boyut limiti nedeniyle registry paketine VSIX gömülmez.)
|
|
8
|
+
* 3. Kullanıcıdan onay iste (etkileşimli terminal; AJAN_YES=1 ile sessiz onay).
|
|
9
|
+
* 4. Onay halinde `code --install-extension <vsix>` ile kur ve doğrula.
|
|
10
|
+
*
|
|
11
|
+
* Uzantı kurulumundaki her sorun (VSCode açıkken yeniden yükleme engeli, CLI eksikliği,
|
|
12
|
+
* vsix eksikliği) YALNIZCA uyarıdır; global kütüphane kurulumu asla başarısız sayılmaz.
|
|
13
|
+
*
|
|
14
|
+
* "AJAN node ile kurulursa uzantı da kurulur, ama kullanıcı onayıyla" ilkesinin uygulaması.
|
|
15
|
+
*/
|
|
16
|
+
import { execFileSync, execSync } from "node:child_process";
|
|
17
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
18
|
+
import { createInterface } from "node:readline/promises";
|
|
19
|
+
import { dirname, join, resolve } from "node:path";
|
|
20
|
+
import { env, stdin, stdout } from "node:process";
|
|
21
|
+
import { fileURLToPath } from "node:url";
|
|
22
|
+
|
|
23
|
+
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
24
|
+
const VSCODE_DIR = join(ROOT, "src", "vscode");
|
|
25
|
+
const VERSION = JSON.parse(readFileSync(join(ROOT, "package.json"), "utf8")).version;
|
|
26
|
+
|
|
27
|
+
const run = (cmd) => {
|
|
28
|
+
console.log(`> ${cmd}`);
|
|
29
|
+
// npm run ortamı npm_config_allow_scripts'i alt süreçlere geçirir;
|
|
30
|
+
// iç içe npm install bunu CLI bayrağı sanıp EALLOWSCRIPTS ile reddeder.
|
|
31
|
+
const env = { ...process.env };
|
|
32
|
+
delete env.npm_config_allow_scripts;
|
|
33
|
+
return execSync(cmd, { stdio: "inherit", shell: true, env });
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/** Code.exe + resources/app/out/cli.js çiftini bul (batch bug'larını tamamen atlar, çıktı yakalanır). */
|
|
37
|
+
function findCodeExeCli() {
|
|
38
|
+
const exes = [
|
|
39
|
+
join(env.LOCALAPPDATA || "", "Programs", "Microsoft VS Code Insiders", "Code - Insiders.exe"),
|
|
40
|
+
join(env.LOCALAPPDATA || "", "Programs", "Microsoft VS Code", "Code.exe"),
|
|
41
|
+
join(env.ProgramFiles || "", "Microsoft VS Code Insiders", "Code - Insiders.exe"),
|
|
42
|
+
join(env.ProgramFiles || "", "Microsoft VS Code", "Code.exe")
|
|
43
|
+
];
|
|
44
|
+
for (const exe of exes) {
|
|
45
|
+
const base = dirname(exe);
|
|
46
|
+
const candidates = [
|
|
47
|
+
join(base, "resources", "app", "out", "cli.js"),
|
|
48
|
+
// cli.js bazen sürüm-commit klasörü altındadır (kod.cmd'deki ~dp0..\a44adf7f53\resources\...)
|
|
49
|
+
...(existsSync(base)
|
|
50
|
+
? readdirSync(base)
|
|
51
|
+
.map((d) => join(base, d, "resources", "app", "out", "cli.js"))
|
|
52
|
+
: [])
|
|
53
|
+
];
|
|
54
|
+
for (const cli of candidates) {
|
|
55
|
+
if (existsSync(exe) && existsSync(cli)) {
|
|
56
|
+
return { exe, cli };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** CLI çiftini çalıştırır ve stdout'u döndürür (Türkçe karakterli yollarda da güvenli). */
|
|
64
|
+
function runCodeCli({ exe, cli }, args) {
|
|
65
|
+
return execFileSync(exe, [cli, ...args], {
|
|
66
|
+
shell: false,
|
|
67
|
+
encoding: "utf8",
|
|
68
|
+
env: { ...env, ELECTRON_RUN_AS_NODE: "1" }
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Bilinen komutlardan VSCode CLI bul (Code.exe tercih; yoksa .cmd yolları). */
|
|
73
|
+
function findCodeCli() {
|
|
74
|
+
const exePair = findCodeExeCli();
|
|
75
|
+
if (exePair) {
|
|
76
|
+
try {
|
|
77
|
+
runCodeCli(exePair, ["--version"]);
|
|
78
|
+
return exePair;
|
|
79
|
+
} catch {
|
|
80
|
+
/* CLI çalışmadı, diğer adaylara geç */
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const cmdCandidates = [
|
|
84
|
+
"code-insiders",
|
|
85
|
+
"code",
|
|
86
|
+
join(env.LOCALAPPDATA || "", "Programs", "Microsoft VS Code Insiders", "bin", "code-insiders.cmd"),
|
|
87
|
+
join(env.LOCALAPPDATA || "", "Programs", "Microsoft VS Code", "bin", "code.cmd")
|
|
88
|
+
];
|
|
89
|
+
for (const c of cmdCandidates) {
|
|
90
|
+
try {
|
|
91
|
+
execSync(`call ${c} --version`, { stdio: "ignore" });
|
|
92
|
+
return c;
|
|
93
|
+
} catch {
|
|
94
|
+
/* yok veya başarısız */
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Paket kökünde veya src/vscode içinde üretilmiş VSIX ara (global kurulum senaryosu). */
|
|
101
|
+
function findBundledVsix() {
|
|
102
|
+
const dirs = [ROOT, VSCODE_DIR];
|
|
103
|
+
for (const dir of dirs) {
|
|
104
|
+
try {
|
|
105
|
+
const files = readdirSync(dir);
|
|
106
|
+
const vsix = files.find((f) => f.startsWith("ajan-ai-") && f.endsWith(".vsix"));
|
|
107
|
+
if (vsix) return join(dir, vsix);
|
|
108
|
+
} catch {
|
|
109
|
+
/* dizin yok */
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Registry paketine VSIX gömülmediğinde GitHub Releases'tan indir (npm tarball limiti nedeniyle). */
|
|
116
|
+
async function downloadVsix() {
|
|
117
|
+
const url = `https://github.com/takimcizgisi/ajan/releases/latest/download/ajan-ai-${VERSION}.vsix`;
|
|
118
|
+
console.log(`[ajan] VSIX internetten indiriliyor: ${url}`);
|
|
119
|
+
const res = await fetch(url, { redirect: "follow" });
|
|
120
|
+
if (!res.ok) {
|
|
121
|
+
throw new Error(`VSIX indirilemedi (HTTP ${res.status}): ${url}`);
|
|
122
|
+
}
|
|
123
|
+
const buf = Buffer.from(await res.arrayBuffer());
|
|
124
|
+
mkdirSync(VSCODE_DIR, { recursive: true });
|
|
125
|
+
const dest = join(VSCODE_DIR, `ajan-ai-${VERSION}.vsix`);
|
|
126
|
+
writeFileSync(dest, buf);
|
|
127
|
+
return dest;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** VSIX'i kaynaktan üret (geliştirme senaryosu). */
|
|
131
|
+
function buildVsixFromSource() {
|
|
132
|
+
if (!existsSync(VSCODE_DIR)) return null;
|
|
133
|
+
// Uzantının @takimcizgisi/ajan bağımlılığı tgz olarak kurulur; yoksa üret.
|
|
134
|
+
run("node scripts/ensure-tgz.mjs");
|
|
135
|
+
if (!existsSync(join(VSCODE_DIR, "node_modules", ".package-lock.json"))) {
|
|
136
|
+
run('npm --prefix "src/vscode" install --no-audit --no-fund');
|
|
137
|
+
}
|
|
138
|
+
run('npm --prefix "src/vscode" run package');
|
|
139
|
+
const files = readdirSync(VSCODE_DIR);
|
|
140
|
+
const vsix = files.find((f) => f.startsWith("ajan-ai-") && f.endsWith(".vsix"));
|
|
141
|
+
return vsix ? join(VSCODE_DIR, vsix) : null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Kullanıcıdan VSCode uzantısını kurmak için onay ister.
|
|
146
|
+
* Otomatik/etkileşimsiz ortamlarda (stdin TTY değil) onay sorulmaz, kurulum atlanır.
|
|
147
|
+
* `AJAN_YES` ortam değişkeni ile otomatik onay verilebilir.
|
|
148
|
+
*/
|
|
149
|
+
async function askConsent() {
|
|
150
|
+
if (env.AJAN_YES === "1" || env.AJAN_YES === "true") return true;
|
|
151
|
+
if (!stdin.isTTY) {
|
|
152
|
+
console.warn(
|
|
153
|
+
"[ajan] Etkileşimli terminal bulunamadı, VSCode uzantısı kurulmadı.\n" +
|
|
154
|
+
" Uzantıyı kurmak için: code --install-extension <ajan-ai-*.vsix>"
|
|
155
|
+
);
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
const rl = createInterface({ input: stdin, output: stdout });
|
|
159
|
+
const answer = (await rl.question(
|
|
160
|
+
"\n[sor] AJAN, VSCode uzantısını (takimcizgisi.ajan-ai) sisteminize kurmak istiyor.\n" +
|
|
161
|
+
" Devam etmek istiyor musunuz? [e/h] "
|
|
162
|
+
)).trim().toLowerCase();
|
|
163
|
+
rl.close();
|
|
164
|
+
const yes = answer === "e" || answer === "evet" || answer === "y" || answer === "yes";
|
|
165
|
+
if (!yes) console.log("[ajan] Onay verilmedi, VSCode uzantısı kurulmadı.");
|
|
166
|
+
return yes;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const CLI = "takimcizgisi.ajan-ai";
|
|
170
|
+
|
|
171
|
+
// Paket bir bağımlılık olarak kurulurken (npm install olarak src/vscode/nodes_modules altında) bu postinstall,
|
|
172
|
+
// pakete gömülü src/vscode kopyasını yeniden kurarak sonsuz döngüye girer. Bağımlılık kurulumlarında
|
|
173
|
+
// yalnızca gömülü VSIX kullanılabilir; kaynaktan üretim yalnızca gerçek kök kurulumlara aittir.
|
|
174
|
+
const inNodeModules = ROOT.split(/[\\/]/).includes("node_modules");
|
|
175
|
+
|
|
176
|
+
async function main() {
|
|
177
|
+
const codeCli = findCodeCli();
|
|
178
|
+
if (!codeCli) {
|
|
179
|
+
console.warn(
|
|
180
|
+
"[ajan] VSCode CLI bulunamadı. Uzantı kurulmadı.\n" +
|
|
181
|
+
'VSCode kuruluysa "code" komutunu PATH\'e ekleyin; değilse uzantıyı VSIX olarak manuel kurun:\n' +
|
|
182
|
+
" code --install-extension <ajan-ai-*.vsix>"
|
|
183
|
+
);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
if (!(await askConsent())) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
let vsix = findBundledVsix();
|
|
193
|
+
if (!vsix) {
|
|
194
|
+
if (!inNodeModules) {
|
|
195
|
+
vsix = buildVsixFromSource();
|
|
196
|
+
}
|
|
197
|
+
if (!vsix) {
|
|
198
|
+
vsix = await downloadVsix();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (!vsix) {
|
|
202
|
+
console.warn("[ajan] Kurulabilir VSIX bulunamadı. Uzantı atlandı (geliştirme için önce `npm run vscode:package`).");
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (typeof codeCli === "string") {
|
|
207
|
+
run(`"${codeCli}" --install-extension "${vsix}" --force`);
|
|
208
|
+
} else {
|
|
209
|
+
const out = runCodeCli(codeCli, ["--install-extension", vsix, "--force"]);
|
|
210
|
+
if (out.trim()) console.log(out);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Gerçekten kurulduğunu doğrula
|
|
214
|
+
let installed = [];
|
|
215
|
+
try {
|
|
216
|
+
installed = typeof codeCli === "string"
|
|
217
|
+
? execSync(`${codeCli} --list-extensions`, { encoding: "utf8" }).split(/\r?\n/)
|
|
218
|
+
: runCodeCli(codeCli, ["--list-extensions"]).split(/\r?\n/);
|
|
219
|
+
} catch (err) {
|
|
220
|
+
console.warn("AJAN VSCode uzantısı doğrulanamadı:", err.message);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (installed.some((id) => id.trim() === CLI)) {
|
|
225
|
+
console.log("\nAJAN VSCode uzantısı kuruldu ve doğrulandı.");
|
|
226
|
+
} else {
|
|
227
|
+
console.warn(`AJAN VSCode uzantısı kurulum görünmüyor (${CLI} bulunamadı).`);
|
|
228
|
+
console.warn("Kurulu uzantılar:\n" + installed.filter((l) => l.trim()).join("\n"));
|
|
229
|
+
console.warn("VSCode kapalıyken elle kurmak için: code --install-extension <ajan-ai-*.vsix>");
|
|
230
|
+
}
|
|
231
|
+
} catch (err) {
|
|
232
|
+
console.warn("AJAN VSCode uzantısı kurulamadı (önemsiz, elle kurulabilir):", err.message);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
main();
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
3
|
+
|
|
4
|
+
const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
|
|
5
|
+
const tgz = `takimcizgisi-ajan-${pkg.version}.tgz`;
|
|
6
|
+
|
|
7
|
+
const run = (cmd) => {
|
|
8
|
+
console.log(`\n> ${cmd}`);
|
|
9
|
+
execSync(cmd, { stdio: "inherit", shell: true });
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
run("npm pack");
|
|
13
|
+
if (!existsSync(tgz)) {
|
|
14
|
+
console.error(`\nArtefakt bulunamadı: ${tgz}`);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
run("npm uninstall -g @takimcizgisi/ajan");
|
|
18
|
+
run(`npm install -g ./${tgz}`);
|
|
19
|
+
console.log(`\nGlobal kurulum tamamlandı: ajan ${pkg.version}`);
|