@aigencydev/cli 0.1.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.
- package/README.md +83 -0
- package/dist/agent/chunker.js +59 -0
- package/dist/agent/chunker.js.map +1 -0
- package/dist/agent/history.js +35 -0
- package/dist/agent/history.js.map +1 -0
- package/dist/agent/loop.js +219 -0
- package/dist/agent/loop.js.map +1 -0
- package/dist/agent/memory.js +177 -0
- package/dist/agent/memory.js.map +1 -0
- package/dist/api-client/auth.js +43 -0
- package/dist/api-client/auth.js.map +1 -0
- package/dist/api-client/base.js +154 -0
- package/dist/api-client/base.js.map +1 -0
- package/dist/api-client/stream.js +123 -0
- package/dist/api-client/stream.js.map +1 -0
- package/dist/api-client/updates.js +31 -0
- package/dist/api-client/updates.js.map +1 -0
- package/dist/api-client/usage.js +15 -0
- package/dist/api-client/usage.js.map +1 -0
- package/dist/auth/oauth.js +178 -0
- package/dist/auth/oauth.js.map +1 -0
- package/dist/auth/pkce.js +19 -0
- package/dist/auth/pkce.js.map +1 -0
- package/dist/auth/session.js +48 -0
- package/dist/auth/session.js.map +1 -0
- package/dist/auth/storage.js +142 -0
- package/dist/auth/storage.js.map +1 -0
- package/dist/cli.js +161 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/chat.js +76 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/help.js +61 -0
- package/dist/commands/help.js.map +1 -0
- package/dist/commands/init.js +43 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.js +153 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.js +30 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/update.js +88 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/usage.js +64 -0
- package/dist/commands/usage.js.map +1 -0
- package/dist/config/defaults.js +54 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/hooks.js +99 -0
- package/dist/config/hooks.js.map +1 -0
- package/dist/config/paths.js +62 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/settings.js +80 -0
- package/dist/config/settings.js.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/security/command-filter.js +121 -0
- package/dist/security/command-filter.js.map +1 -0
- package/dist/security/sandbox.js +182 -0
- package/dist/security/sandbox.js.map +1 -0
- package/dist/security/sanitize.js +59 -0
- package/dist/security/sanitize.js.map +1 -0
- package/dist/tools/bash.js +206 -0
- package/dist/tools/bash.js.map +1 -0
- package/dist/tools/diff.js +56 -0
- package/dist/tools/diff.js.map +1 -0
- package/dist/tools/edit-file.js +165 -0
- package/dist/tools/edit-file.js.map +1 -0
- package/dist/tools/list-files.js +116 -0
- package/dist/tools/list-files.js.map +1 -0
- package/dist/tools/read-file.js +107 -0
- package/dist/tools/read-file.js.map +1 -0
- package/dist/tools/registry.js +54 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/search-files.js +159 -0
- package/dist/tools/search-files.js.map +1 -0
- package/dist/tools/types.js +5 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/write-file.js +141 -0
- package/dist/tools/write-file.js.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/ui/App.js +264 -0
- package/dist/ui/App.js.map +1 -0
- package/dist/ui/InputBar.js +22 -0
- package/dist/ui/InputBar.js.map +1 -0
- package/dist/ui/MessageList.js +82 -0
- package/dist/ui/MessageList.js.map +1 -0
- package/dist/ui/ModeIndicator.js +23 -0
- package/dist/ui/ModeIndicator.js.map +1 -0
- package/dist/ui/PermissionPrompt.js +61 -0
- package/dist/ui/PermissionPrompt.js.map +1 -0
- package/dist/ui/StatusBar.js +39 -0
- package/dist/ui/StatusBar.js.map +1 -0
- package/dist/ui/theme.js +42 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/utils/abort.js +61 -0
- package/dist/utils/abort.js.map +1 -0
- package/dist/utils/errors.js +63 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/formatting.js +102 -0
- package/dist/utils/formatting.js.map +1 -0
- package/dist/utils/logger.js +43 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/version.js +10 -0
- package/dist/version.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIGENCY CLI — ayar okuma ve birleştirme.
|
|
3
|
+
*
|
|
4
|
+
* Öncelik sırası (yüksekten düşüğe):
|
|
5
|
+
* 1. CLI argümanları (--mode plan vs.)
|
|
6
|
+
* 2. <cwd>/.aigency/settings.json (proje)
|
|
7
|
+
* 3. ~/.aigency/config.json (kullanıcı)
|
|
8
|
+
* 4. Kod'daki DEFAULT_SETTINGS
|
|
9
|
+
*/
|
|
10
|
+
import fs from "node:fs/promises";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import { DEFAULT_SETTINGS, SettingsSchema, } from "./defaults.js";
|
|
13
|
+
import { getProjectSettingsFile, getUserAigencyDir, getUserConfigFile, } from "./paths.js";
|
|
14
|
+
import { log } from "../utils/logger.js";
|
|
15
|
+
async function readJsonSafe(filePath) {
|
|
16
|
+
try {
|
|
17
|
+
const raw = await fs.readFile(filePath, "utf8");
|
|
18
|
+
return JSON.parse(raw);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
const code = err?.code;
|
|
22
|
+
if (code === "ENOENT")
|
|
23
|
+
return null;
|
|
24
|
+
log.debug(`JSON okuma hatası ${filePath}: ${err.message}`);
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async function writeJsonSafe(filePath, data) {
|
|
29
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
30
|
+
await fs.writeFile(filePath, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Partial → tam Settings birleşimi.
|
|
34
|
+
* Zod safeParse kullanır; hata olursa default döner ve uyarı yazar.
|
|
35
|
+
*/
|
|
36
|
+
function mergeSettings(base, override, source) {
|
|
37
|
+
if (!override)
|
|
38
|
+
return base;
|
|
39
|
+
const merged = { ...base, ...override };
|
|
40
|
+
const parsed = SettingsSchema.safeParse(merged);
|
|
41
|
+
if (!parsed.success) {
|
|
42
|
+
log.warn(`${source} bozuk, varsayılan kullanılıyor: ${parsed.error.message.slice(0, 120)}`);
|
|
43
|
+
return base;
|
|
44
|
+
}
|
|
45
|
+
return parsed.data;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Tüm kaynakları birleştirip tam Settings döndürür.
|
|
49
|
+
* CLI argümanları ayrıca `overrideArgs` parametresinden enjekte edilebilir.
|
|
50
|
+
*/
|
|
51
|
+
export async function loadSettings(options) {
|
|
52
|
+
const cwd = options?.cwd || process.cwd();
|
|
53
|
+
// Kullanıcı config'i (~/.aigency/config.json)
|
|
54
|
+
const userRaw = (await readJsonSafe(getUserConfigFile()));
|
|
55
|
+
let settings = mergeSettings(DEFAULT_SETTINGS, userRaw, "~/.aigency/config.json");
|
|
56
|
+
// Proje ayarı (<cwd>/.aigency/settings.json)
|
|
57
|
+
const projectRaw = (await readJsonSafe(getProjectSettingsFile(cwd)));
|
|
58
|
+
settings = mergeSettings(settings, projectRaw, ".aigency/settings.json");
|
|
59
|
+
// CLI argüman override (en yüksek öncelik)
|
|
60
|
+
if (options?.overrideArgs) {
|
|
61
|
+
settings = mergeSettings(settings, options.overrideArgs, "CLI args");
|
|
62
|
+
}
|
|
63
|
+
return settings;
|
|
64
|
+
}
|
|
65
|
+
export async function saveUserConfig(patch) {
|
|
66
|
+
const current = (await readJsonSafe(getUserConfigFile()));
|
|
67
|
+
const merged = mergeSettings(DEFAULT_SETTINGS, { ...(current || {}), ...patch }, "~/.aigency/config.json");
|
|
68
|
+
await writeJsonSafe(getUserConfigFile(), merged);
|
|
69
|
+
return merged;
|
|
70
|
+
}
|
|
71
|
+
export async function saveProjectSettings(patch, cwd = process.cwd()) {
|
|
72
|
+
const current = (await readJsonSafe(getProjectSettingsFile(cwd)));
|
|
73
|
+
const merged = mergeSettings(DEFAULT_SETTINGS, { ...(current || {}), ...patch }, ".aigency/settings.json");
|
|
74
|
+
await writeJsonSafe(getProjectSettingsFile(cwd), merged);
|
|
75
|
+
return merged;
|
|
76
|
+
}
|
|
77
|
+
export async function ensureUserAigencyDir() {
|
|
78
|
+
await fs.mkdir(getUserAigencyDir(), { recursive: true });
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/config/settings.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* AIGENCY CLI — entry point.
|
|
4
|
+
*
|
|
5
|
+
* Bu dosya binary tarafından shebang ile çalıştırılır. Komut dispatcher'a
|
|
6
|
+
* argv iletir ve çıkış kodunu döner.
|
|
7
|
+
*/
|
|
8
|
+
import { runCli } from "./cli.js";
|
|
9
|
+
import { log } from "./utils/logger.js";
|
|
10
|
+
// process.title — Windows Credential Manager ve taskmgr'de görünüm için
|
|
11
|
+
try {
|
|
12
|
+
process.title = "aigency";
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// Bazı sandbox ortamlarında başarısız olabilir
|
|
16
|
+
}
|
|
17
|
+
// Uncaught exception handler — son çare yakalama
|
|
18
|
+
process.on("uncaughtException", (err) => {
|
|
19
|
+
log.error(`Beklenmeyen hata: ${err.message}`);
|
|
20
|
+
if (process.env.AIGENCY_CLI_DEBUG === "1") {
|
|
21
|
+
log.dim(err.stack || "");
|
|
22
|
+
}
|
|
23
|
+
process.exit(2);
|
|
24
|
+
});
|
|
25
|
+
process.on("unhandledRejection", (reason) => {
|
|
26
|
+
const message = reason instanceof Error ? reason.message : String(reason);
|
|
27
|
+
log.error(`İşlenmeyen promise reddi: ${message}`);
|
|
28
|
+
process.exit(2);
|
|
29
|
+
});
|
|
30
|
+
// İlk iki arg: node ve script dosyası
|
|
31
|
+
const argv = process.argv.slice(2);
|
|
32
|
+
runCli(argv).then((code) => process.exit(code), (err) => {
|
|
33
|
+
log.error(`CLI hata: ${err.message}`);
|
|
34
|
+
process.exit(2);
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAExC,wEAAwE;AACxE,IAAI,CAAC;IACH,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;AAC5B,CAAC;AAAC,MAAM,CAAC;IACP,+CAA+C;AACjD,CAAC;AAED,iDAAiD;AACjD,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,GAAG,EAAE,EAAE;IACtC,GAAG,CAAC,KAAK,CAAC,qBAAqB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9C,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,GAAG,EAAE,CAAC;QAC1C,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE;IAC1C,MAAM,OAAO,GAAG,MAAM,YAAY,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC1E,GAAG,CAAC,KAAK,CAAC,6BAA6B,OAAO,EAAE,CAAC,CAAC;IAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,sCAAsC;AACtC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CACf,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAC5B,CAAC,GAAG,EAAE,EAAE;IACN,GAAG,CAAC,KAAK,CAAC,aAAc,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CACF,CAAC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIGENCY CLI — Shell komut filtresi.
|
|
3
|
+
*
|
|
4
|
+
* bash_execute tool'u çalıştırmadan önce komut bu filtreden geçer.
|
|
5
|
+
* Block list (regex) + allow list (prefix) hibrit yaklaşım:
|
|
6
|
+
* - Block regex eşleşirse: kesinlikle reddet
|
|
7
|
+
* - Allow prefix eşleşirse: hızlı kabul (Auto mode'da promosyon)
|
|
8
|
+
* - Ne block ne allow: normal izin akışına bırak
|
|
9
|
+
*/
|
|
10
|
+
// ── Block regex listesi ──
|
|
11
|
+
// Büyük-küçük harf duyarsız. Komutun herhangi bir yerinde eşleşirse reddedilir.
|
|
12
|
+
const BLOCK_PATTERNS = [
|
|
13
|
+
// Destructive rm / del
|
|
14
|
+
{ pattern: /\brm\s+(-rf?|--recursive|--force)\s+[/"'~]/i, reason: "rm -rf kök/home" },
|
|
15
|
+
{ pattern: /\brm\s+-[a-z]*r[a-z]*\s+\//i, reason: "rm -r kök" },
|
|
16
|
+
{ pattern: /\bdel\s+\/[sfq]/i, reason: "Windows del /s /f /q" },
|
|
17
|
+
{ pattern: /\brmdir\s+\/s/i, reason: "Windows rmdir /s" },
|
|
18
|
+
// Yetki yükseltme
|
|
19
|
+
{ pattern: /\bsudo\b/i, reason: "sudo yasak" },
|
|
20
|
+
{ pattern: /\bsu\s+-/i, reason: "su - yasak" },
|
|
21
|
+
{ pattern: /\bchmod\s+([0-7]*7[0-7]*|a\+[rwx])/i, reason: "chmod 777/a+rwx yasak" },
|
|
22
|
+
{ pattern: /\bchown\b/i, reason: "chown yasak" },
|
|
23
|
+
// Remote code exec
|
|
24
|
+
{ pattern: /\bcurl\b[^|]*\|\s*(bash|sh|zsh|pwsh|powershell)/i, reason: "curl | sh" },
|
|
25
|
+
{ pattern: /\bwget\b[^|]*\|\s*(bash|sh|zsh)/i, reason: "wget | sh" },
|
|
26
|
+
{ pattern: /\bInvoke-Expression\b/i, reason: "PowerShell Invoke-Expression" },
|
|
27
|
+
{ pattern: /\biex\s*\(/i, reason: "PowerShell iex()" },
|
|
28
|
+
{ pattern: /\beval\s*[(\"']/i, reason: "eval()" },
|
|
29
|
+
// Disk/sistem
|
|
30
|
+
{ pattern: /\bformat\s+[a-z]:/i, reason: "format disk" },
|
|
31
|
+
{ pattern: /\bdd\s+if=/i, reason: "dd if=" },
|
|
32
|
+
{ pattern: /\bmkfs\b/i, reason: "mkfs filesystem" },
|
|
33
|
+
{ pattern: /\bshutdown\b/i, reason: "shutdown" },
|
|
34
|
+
{ pattern: /\breboot\b/i, reason: "reboot" },
|
|
35
|
+
{ pattern: /\bpoweroff\b/i, reason: "poweroff" },
|
|
36
|
+
{ pattern: /\bhalt\b/i, reason: "halt" },
|
|
37
|
+
{ pattern: /\bkill\s+-9\s+1\b/i, reason: "kill init" },
|
|
38
|
+
{ pattern: />\s*\/dev\/(sda|nvme|disk|hda)/i, reason: "block device'a yazma" },
|
|
39
|
+
// Windows registry ve network
|
|
40
|
+
{ pattern: /\breg\s+(add|delete)\b/i, reason: "registry düzenleme" },
|
|
41
|
+
{ pattern: /\bnet\s+user\b/i, reason: "net user" },
|
|
42
|
+
{ pattern: /\bnet\s+localgroup\b/i, reason: "net localgroup" },
|
|
43
|
+
{ pattern: /\bnetsh\b[^]*firewall/i, reason: "firewall düzenleme" },
|
|
44
|
+
// DB destructive
|
|
45
|
+
{ pattern: /\bprisma\s+migrate\s+reset\b/i, reason: "prisma migrate reset YASAK" },
|
|
46
|
+
{ pattern: /\bprisma\s+db\s+push\s+--force/i, reason: "prisma db push --force" },
|
|
47
|
+
{ pattern: /\bDROP\s+DATABASE\b/i, reason: "DROP DATABASE" },
|
|
48
|
+
{ pattern: /\bTRUNCATE\b/i, reason: "TRUNCATE" },
|
|
49
|
+
// SSH key üretimi / self-revoke
|
|
50
|
+
{ pattern: /\bssh-keygen\b/i, reason: "ssh-keygen" },
|
|
51
|
+
{ pattern: /\baigency\s+(logout|revoke)\b/i, reason: "kendi oturumunu revoke etme" },
|
|
52
|
+
// Fork bomb / devasa çıktı
|
|
53
|
+
{ pattern: /:\(\)\s*\{/i, reason: "fork bomb şüphesi" },
|
|
54
|
+
{ pattern: /\byes\b[^|]*\|/i, reason: "yes | komutu büyük çıktı üretir" },
|
|
55
|
+
];
|
|
56
|
+
// ── Allow list (prefix whitelist) ──
|
|
57
|
+
// Komut ilk kelimesi (veya ilk iki kelime) bu listedeyse Auto mode'da
|
|
58
|
+
// promosyonla "safe" kabul edilir. Default mode'da etkisi yok.
|
|
59
|
+
const ALLOW_PREFIXES = new Set([
|
|
60
|
+
// Node ekosistemi
|
|
61
|
+
"node", "npm", "npx", "pnpm", "yarn", "bun", "tsc", "ts-node", "tsx",
|
|
62
|
+
"eslint", "prettier", "biome", "jest", "vitest", "playwright", "cypress",
|
|
63
|
+
// Python ekosistemi
|
|
64
|
+
"python", "python3", "pip", "pip3", "pipx", "poetry", "uv",
|
|
65
|
+
"pytest", "ruff", "black", "mypy", "pyright",
|
|
66
|
+
// Go / Rust / Java
|
|
67
|
+
"go", "gofmt", "cargo", "rustc", "rustup", "java", "javac", "mvn", "gradle",
|
|
68
|
+
// Git
|
|
69
|
+
"git",
|
|
70
|
+
// Dosya keşfi
|
|
71
|
+
"ls", "dir", "cat", "type", "head", "tail", "grep", "rg", "fd", "find",
|
|
72
|
+
"echo", "pwd", "mkdir", "touch", "cp", "mv", "which", "where", "file", "stat",
|
|
73
|
+
// Docker (build/run OK ama compose destructive olabilir)
|
|
74
|
+
"docker", "podman", "make",
|
|
75
|
+
]);
|
|
76
|
+
function firstWord(command) {
|
|
77
|
+
const trimmed = command.trim();
|
|
78
|
+
const match = trimmed.match(/^(\S+)/);
|
|
79
|
+
return (match?.[1] || "").toLowerCase();
|
|
80
|
+
}
|
|
81
|
+
export function checkCommand(command) {
|
|
82
|
+
if (!command || typeof command !== "string") {
|
|
83
|
+
return { verdict: "block", reason: "Boş komut" };
|
|
84
|
+
}
|
|
85
|
+
const trimmed = command.trim();
|
|
86
|
+
if (trimmed.length === 0) {
|
|
87
|
+
return { verdict: "block", reason: "Boş komut" };
|
|
88
|
+
}
|
|
89
|
+
if (trimmed.length > 4000) {
|
|
90
|
+
return { verdict: "block", reason: "Komut çok uzun (>4000 karakter)" };
|
|
91
|
+
}
|
|
92
|
+
// 1) Block kontrolü
|
|
93
|
+
for (const { pattern, reason } of BLOCK_PATTERNS) {
|
|
94
|
+
if (pattern.test(trimmed)) {
|
|
95
|
+
return {
|
|
96
|
+
verdict: "block",
|
|
97
|
+
reason,
|
|
98
|
+
matchedPattern: pattern.source,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// 2) Allow list kontrolü (ilk kelime)
|
|
103
|
+
const first = firstWord(trimmed);
|
|
104
|
+
if (ALLOW_PREFIXES.has(first)) {
|
|
105
|
+
return { verdict: "allow", reason: `bilinen güvenli komut: ${first}` };
|
|
106
|
+
}
|
|
107
|
+
return { verdict: "neutral" };
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Auto mode için kısa karar — classifier yerine hızlı heuristic.
|
|
111
|
+
* Block → reject, Allow → approve, Neutral → prompt.
|
|
112
|
+
*/
|
|
113
|
+
export function autoModeDecision(command) {
|
|
114
|
+
const result = checkCommand(command);
|
|
115
|
+
if (result.verdict === "block")
|
|
116
|
+
return "reject";
|
|
117
|
+
if (result.verdict === "allow")
|
|
118
|
+
return "approve";
|
|
119
|
+
return "prompt";
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=command-filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-filter.js","sourceRoot":"","sources":["../../src/security/command-filter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIGENCY CLI — Sandbox path guard.
|
|
3
|
+
*
|
|
4
|
+
* Tool'ların eriştiği her path bu fonksiyondan geçer. Symlink resolve edilir,
|
|
5
|
+
* cwd altında mı kontrol edilir, yasak segmentler (.git, .env, node_modules vb.)
|
|
6
|
+
* reddedilir, kullanıcı home altındaki hassas klasörler (~/.ssh, ~/.aigency, ...)
|
|
7
|
+
* engellenir.
|
|
8
|
+
*
|
|
9
|
+
* Tüm path guard sonuçları PathCheckResult olarak döner — hata mesajı kullanıcıya
|
|
10
|
+
* gösterilebilir, reason kodu audit log'a yazılabilir.
|
|
11
|
+
*/
|
|
12
|
+
import fs from "node:fs";
|
|
13
|
+
import os from "node:os";
|
|
14
|
+
import path from "node:path";
|
|
15
|
+
// ── Yasak path segmentleri (regex) ──
|
|
16
|
+
// Dosya adı veya dizin adı eşleşmesi — tam path değil.
|
|
17
|
+
const BLOCKED_SEGMENTS = [
|
|
18
|
+
/^\.git$/,
|
|
19
|
+
/^\.env(\..*)?$/, // .env, .env.local, .env.production ...
|
|
20
|
+
/^\.env$/,
|
|
21
|
+
/^node_modules$/,
|
|
22
|
+
/^\.next$/,
|
|
23
|
+
/^\.turbo$/,
|
|
24
|
+
/^\.vscode$/,
|
|
25
|
+
/^\.idea$/,
|
|
26
|
+
/^\.svn$/,
|
|
27
|
+
/^\.hg$/,
|
|
28
|
+
];
|
|
29
|
+
// ── Home altında kesinlikle erişilemeyecek klasörler ──
|
|
30
|
+
const BLOCKED_HOME_DIRS = [
|
|
31
|
+
".ssh",
|
|
32
|
+
".aigency",
|
|
33
|
+
".aws",
|
|
34
|
+
".azure",
|
|
35
|
+
".docker",
|
|
36
|
+
".kube",
|
|
37
|
+
".gnupg",
|
|
38
|
+
".gcp",
|
|
39
|
+
".google",
|
|
40
|
+
".config/gcloud",
|
|
41
|
+
".netrc",
|
|
42
|
+
".pypirc",
|
|
43
|
+
".npmrc",
|
|
44
|
+
];
|
|
45
|
+
function normalizePath(p) {
|
|
46
|
+
// Windows backslash → forward slash, case-insensitive karşılaştırma için lowercase
|
|
47
|
+
return p.replace(/\\/g, "/").toLowerCase();
|
|
48
|
+
}
|
|
49
|
+
function isUnderDir(target, parent) {
|
|
50
|
+
const t = normalizePath(target);
|
|
51
|
+
const p = normalizePath(parent).replace(/\/$/, "");
|
|
52
|
+
return t === p || t.startsWith(p + "/");
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Bir path'in sandbox kurallarına uyup uymadığını kontrol eder.
|
|
56
|
+
* cwd dışına çıkma, yasak segment, home gizli dizini, symlink hedefi kontrol edilir.
|
|
57
|
+
*
|
|
58
|
+
* Dönüş:
|
|
59
|
+
* - ok: true → realPath kullanılabilir
|
|
60
|
+
* - ok: false → reason ve message ile açıklama
|
|
61
|
+
*/
|
|
62
|
+
export function checkPath(rawPath, cwd, options = {}) {
|
|
63
|
+
if (!rawPath || typeof rawPath !== "string") {
|
|
64
|
+
return {
|
|
65
|
+
ok: false,
|
|
66
|
+
reason: "bos_path",
|
|
67
|
+
message: "Boş yol",
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// 1) cwd ile resolve et (göreli → mutlak)
|
|
71
|
+
let resolved;
|
|
72
|
+
try {
|
|
73
|
+
resolved = path.isAbsolute(rawPath)
|
|
74
|
+
? path.resolve(rawPath)
|
|
75
|
+
: path.resolve(cwd, rawPath);
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
return {
|
|
79
|
+
ok: false,
|
|
80
|
+
reason: "cozumlenemedi",
|
|
81
|
+
message: `Yol çözümlenemedi: ${err.message}`,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
// 2) Symlink resolve (gerçek dosya varsa)
|
|
85
|
+
let realPath = resolved;
|
|
86
|
+
try {
|
|
87
|
+
realPath = fs.realpathSync(resolved);
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
// Dosya/dizin henüz yoksa (write_file senaryosu) parent dizini kontrol et
|
|
91
|
+
const parent = path.dirname(resolved);
|
|
92
|
+
try {
|
|
93
|
+
const parentReal = fs.realpathSync(parent);
|
|
94
|
+
realPath = path.join(parentReal, path.basename(resolved));
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
if (options.mustExist) {
|
|
98
|
+
return {
|
|
99
|
+
ok: false,
|
|
100
|
+
reason: "cozumlenemedi",
|
|
101
|
+
message: `Yol bulunamadı: ${rawPath}`,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
// Parent da yoksa resolved'i kullan (ileride mkdir yapılacak belki)
|
|
105
|
+
realPath = resolved;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// 3) cwd altında mı?
|
|
109
|
+
// Windows: path.relative başka disk için "D:\..." döner → isAbsolute true → reddet
|
|
110
|
+
const relative = path.relative(cwd, realPath);
|
|
111
|
+
if (relative === "" ||
|
|
112
|
+
relative === "." ||
|
|
113
|
+
(!relative.startsWith("..") && !path.isAbsolute(relative))) {
|
|
114
|
+
// OK — cwd'nin kendisi veya alt
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
return {
|
|
118
|
+
ok: false,
|
|
119
|
+
reason: "cwd_disi",
|
|
120
|
+
realPath,
|
|
121
|
+
displayPath: rawPath,
|
|
122
|
+
message: `Yol çalışma dizininin dışında: ${rawPath}`,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
// 4) Yasak segmentler (path'in herhangi bir parçası)
|
|
126
|
+
const segments = realPath.split(/[\\/]/).filter(Boolean);
|
|
127
|
+
for (const seg of segments) {
|
|
128
|
+
for (const pattern of BLOCKED_SEGMENTS) {
|
|
129
|
+
if (pattern.test(seg)) {
|
|
130
|
+
return {
|
|
131
|
+
ok: false,
|
|
132
|
+
reason: "yasak_dizin",
|
|
133
|
+
realPath,
|
|
134
|
+
displayPath: rawPath,
|
|
135
|
+
message: `Yasak dizin segmenti: ${seg}`,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// 5) Home altındaki gizli klasörler
|
|
141
|
+
const home = os.homedir();
|
|
142
|
+
for (const blocked of BLOCKED_HOME_DIRS) {
|
|
143
|
+
const full = path.join(home, blocked);
|
|
144
|
+
if (isUnderDir(realPath, full)) {
|
|
145
|
+
return {
|
|
146
|
+
ok: false,
|
|
147
|
+
reason: "home_gizli",
|
|
148
|
+
realPath,
|
|
149
|
+
displayPath: rawPath,
|
|
150
|
+
message: `Hassas klasöre erişim yasak: ~/${blocked}`,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
ok: true,
|
|
156
|
+
realPath,
|
|
157
|
+
displayPath: path.relative(cwd, realPath) || ".",
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Write/edit gibi yazma işlemleri için extra kontrol —
|
|
162
|
+
* symlink hedefi dışarı çıkıyorsa reddet.
|
|
163
|
+
*/
|
|
164
|
+
export function checkWritePath(rawPath, cwd) {
|
|
165
|
+
const base = checkPath(rawPath, cwd);
|
|
166
|
+
if (!base.ok || !base.realPath)
|
|
167
|
+
return base;
|
|
168
|
+
// Parent dizin cwd içinde olmalı
|
|
169
|
+
const parent = path.dirname(base.realPath);
|
|
170
|
+
const parentCheck = checkPath(parent, cwd);
|
|
171
|
+
if (!parentCheck.ok) {
|
|
172
|
+
return {
|
|
173
|
+
ok: false,
|
|
174
|
+
reason: parentCheck.reason,
|
|
175
|
+
realPath: base.realPath,
|
|
176
|
+
displayPath: base.displayPath,
|
|
177
|
+
message: parentCheck.message,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
return base;
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/security/sandbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIGENCY CLI — UI tarafı mesaj sanitize katmanı.
|
|
3
|
+
*
|
|
4
|
+
* Sunucu tarafı `lib/cli/sanitize.ts` zaten tool output'larını geçiriyor;
|
|
5
|
+
* bu CLI tarafı ek bir güvenlik ağı — agent mesajları, hata mesajları ve
|
|
6
|
+
* tool sonuçları kullanıcıya gösterilmeden önce:
|
|
7
|
+
* - 3. parti sağlayıcı/model isimleri AIGENCY ile değiştirilir
|
|
8
|
+
* - Zero-width ve bidi override Unicode karakterleri strip edilir
|
|
9
|
+
*/
|
|
10
|
+
// Sağlayıcı adları base64 encoded sözlük — kaynak dosyada literal olarak
|
|
11
|
+
// hiçbir sağlayıcı adı geçmesin diye. Runtime'da decode edilip regex üretilir.
|
|
12
|
+
const PROVIDER_DICT_B64 = [
|
|
13
|
+
"b3BlbmFp",
|
|
14
|
+
"Y2hhdGdwdA==",
|
|
15
|
+
"Z3B0LTQ=",
|
|
16
|
+
"Z3B0LTM=",
|
|
17
|
+
"ZGFsbC1l",
|
|
18
|
+
"ZGFsbGU=",
|
|
19
|
+
"YW50aHJvcGlj",
|
|
20
|
+
"Y2xhdWRl",
|
|
21
|
+
"Z2VtaW5p",
|
|
22
|
+
"YmFyZA==",
|
|
23
|
+
"bGxhbWE=",
|
|
24
|
+
"Y29waWxvdA==",
|
|
25
|
+
"ZGVlcHNlZWs=",
|
|
26
|
+
"bWlzdHJhbA==",
|
|
27
|
+
];
|
|
28
|
+
let _providerRegex = null;
|
|
29
|
+
function getProviderRegex() {
|
|
30
|
+
if (_providerRegex)
|
|
31
|
+
return _providerRegex;
|
|
32
|
+
const terms = PROVIDER_DICT_B64.map((b) => Buffer.from(b, "base64").toString("utf8"));
|
|
33
|
+
_providerRegex = new RegExp(`\\b(${terms.join("|")})[\\w\\-.]*`, "gi");
|
|
34
|
+
return _providerRegex;
|
|
35
|
+
}
|
|
36
|
+
const ZERO_WIDTH_UNICODE = /[\u200B-\u200F\u202A-\u202E\u2060-\u206F\uFEFF]/g;
|
|
37
|
+
/**
|
|
38
|
+
* String içindeki tüm LLM sağlayıcı/model isimlerini "AIGENCY" ile değiştirir.
|
|
39
|
+
*/
|
|
40
|
+
export function stripProviderMentions(input) {
|
|
41
|
+
if (!input || typeof input !== "string")
|
|
42
|
+
return "";
|
|
43
|
+
return input.replace(getProviderRegex(), "AIGENCY");
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Gizli Unicode karakterlerini strip eder.
|
|
47
|
+
*/
|
|
48
|
+
export function stripHiddenUnicode(input) {
|
|
49
|
+
if (!input || typeof input !== "string")
|
|
50
|
+
return "";
|
|
51
|
+
return input.replace(ZERO_WIDTH_UNICODE, "");
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* UI'da gösterilecek her mesaj için tek satır sanitize.
|
|
55
|
+
*/
|
|
56
|
+
export function sanitizeForDisplay(input) {
|
|
57
|
+
return stripHiddenUnicode(stripProviderMentions(input));
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=sanitize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/security/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,yEAAyE;AACzE,+EAA+E;AAC/E,MAAM,iBAAiB,GAAG;IACxB,UAAU;IACV,cAAc;IACd,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,cAAc;IACd,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,cAAc;IACd,cAAc;IACd,cAAc;CACf,CAAC;AAEF,IAAI,cAAc,GAAkB,IAAI,CAAC;AAEzC,SAAS,gBAAgB;IACvB,IAAI,cAAc;QAAE,OAAO,cAAc,CAAC;IAC1C,MAAM,KAAK,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACxC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAC1C,CAAC;IACF,cAAc,GAAG,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IACvE,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,kBAAkB,GAAG,kDAAkD,CAAC;AAE9E;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAa;IACjD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACnD,OAAO,KAAK,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,SAAS,CAAC,CAAC;AACtD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACnD,OAAO,KAAK,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAO,kBAAkB,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC;AAC1D,CAAC"}
|