@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,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIGENCY CLI — HTTP istemci temel katmanı.
|
|
3
|
+
*
|
|
4
|
+
* `fetch` üzerine basit bir sarmalayıcı; retry, timeout, JSON body,
|
|
5
|
+
* Authorization header ve hata normalize etme sağlar.
|
|
6
|
+
*
|
|
7
|
+
* NOT: Node 18+ global `fetch` kullanılır (bağımlılık eklemez).
|
|
8
|
+
*/
|
|
9
|
+
import { AuthError, CliError, NetworkError, QuotaError, ValidationError, } from "../utils/errors.js";
|
|
10
|
+
import { DEFAULT_TIMEOUTS } from "../config/defaults.js";
|
|
11
|
+
import { getApiBaseUrl } from "../config/defaults.js";
|
|
12
|
+
import { CLI_VERSION } from "../version.js";
|
|
13
|
+
function buildUrl(path, query) {
|
|
14
|
+
const base = getApiBaseUrl();
|
|
15
|
+
const full = path.startsWith("http") ? path : `${base}${path}`;
|
|
16
|
+
if (!query)
|
|
17
|
+
return full;
|
|
18
|
+
const url = new URL(full);
|
|
19
|
+
for (const [k, v] of Object.entries(query)) {
|
|
20
|
+
if (v === undefined || v === null)
|
|
21
|
+
continue;
|
|
22
|
+
url.searchParams.set(k, String(v));
|
|
23
|
+
}
|
|
24
|
+
return url.toString();
|
|
25
|
+
}
|
|
26
|
+
function delay(ms) {
|
|
27
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* HTTP isteği gönder + JSON parse et.
|
|
31
|
+
*/
|
|
32
|
+
export async function apiRequest(path, options = {}) {
|
|
33
|
+
const { method = "GET", body, query, bearer, headers = {}, timeoutMs = DEFAULT_TIMEOUTS.http, signal, maxRetries = 2, } = options;
|
|
34
|
+
const url = buildUrl(path, query);
|
|
35
|
+
const requestHeaders = {
|
|
36
|
+
Accept: "application/json",
|
|
37
|
+
"User-Agent": `aigency-cli/${CLI_VERSION} (${process.platform})`,
|
|
38
|
+
...headers,
|
|
39
|
+
};
|
|
40
|
+
if (bearer)
|
|
41
|
+
requestHeaders.Authorization = `Bearer ${bearer}`;
|
|
42
|
+
if (body !== undefined && !requestHeaders["Content-Type"]) {
|
|
43
|
+
requestHeaders["Content-Type"] = "application/json";
|
|
44
|
+
}
|
|
45
|
+
let lastError = null;
|
|
46
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
47
|
+
const controller = new AbortController();
|
|
48
|
+
const timeoutHandle = setTimeout(() => controller.abort("timeout"), timeoutMs);
|
|
49
|
+
// Üst AbortSignal ile zincirle
|
|
50
|
+
const onParentAbort = () => controller.abort("parent_abort");
|
|
51
|
+
if (signal) {
|
|
52
|
+
if (signal.aborted) {
|
|
53
|
+
clearTimeout(timeoutHandle);
|
|
54
|
+
throw new CliError("İşlem iptal edildi", { code: "aborted" });
|
|
55
|
+
}
|
|
56
|
+
signal.addEventListener("abort", onParentAbort, { once: true });
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
const res = await fetch(url, {
|
|
60
|
+
method,
|
|
61
|
+
headers: requestHeaders,
|
|
62
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
63
|
+
signal: controller.signal,
|
|
64
|
+
});
|
|
65
|
+
clearTimeout(timeoutHandle);
|
|
66
|
+
if (signal)
|
|
67
|
+
signal.removeEventListener("abort", onParentAbort);
|
|
68
|
+
let parsed = undefined;
|
|
69
|
+
const contentType = res.headers.get("content-type") || "";
|
|
70
|
+
if (contentType.includes("application/json")) {
|
|
71
|
+
try {
|
|
72
|
+
parsed = await res.json();
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
parsed = undefined;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else if (res.status !== 204) {
|
|
79
|
+
parsed = await res.text();
|
|
80
|
+
}
|
|
81
|
+
if (res.ok) {
|
|
82
|
+
return {
|
|
83
|
+
data: parsed,
|
|
84
|
+
status: res.status,
|
|
85
|
+
headers: res.headers,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// Hata durumu
|
|
89
|
+
throw mapHttpError(res.status, parsed);
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
clearTimeout(timeoutHandle);
|
|
93
|
+
if (signal)
|
|
94
|
+
signal.removeEventListener("abort", onParentAbort);
|
|
95
|
+
if (err instanceof CliError) {
|
|
96
|
+
// 5xx ve network hataları tekrar denenebilir
|
|
97
|
+
const isRetryable = err.code === "network_error" ||
|
|
98
|
+
(typeof err.status === "number" && err.status >= 500);
|
|
99
|
+
if (isRetryable && attempt < maxRetries) {
|
|
100
|
+
lastError = err;
|
|
101
|
+
await delay(500 * (attempt + 1));
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
throw err;
|
|
105
|
+
}
|
|
106
|
+
// Native abort
|
|
107
|
+
if (err?.name === "AbortError") {
|
|
108
|
+
if (signal?.aborted) {
|
|
109
|
+
throw new CliError("İşlem iptal edildi", { code: "aborted" });
|
|
110
|
+
}
|
|
111
|
+
throw new NetworkError("İstek zaman aşımına uğradı", err);
|
|
112
|
+
}
|
|
113
|
+
const netErr = new NetworkError(`Sunucuya ulaşılamadı: ${err.message}`, err);
|
|
114
|
+
if (attempt < maxRetries) {
|
|
115
|
+
lastError = netErr;
|
|
116
|
+
await delay(500 * (attempt + 1));
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
throw netErr;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
throw lastError || new NetworkError("Bilinmeyen ağ hatası");
|
|
123
|
+
}
|
|
124
|
+
function mapHttpError(status, body) {
|
|
125
|
+
const errMessage = body?.error ||
|
|
126
|
+
body?.message ||
|
|
127
|
+
`HTTP ${status}`;
|
|
128
|
+
if (status === 401) {
|
|
129
|
+
return new AuthError(errMessage, "`aigency login` ile yeniden giriş yapın.");
|
|
130
|
+
}
|
|
131
|
+
if (status === 403) {
|
|
132
|
+
const upgrade = body?.upgrade_required;
|
|
133
|
+
return new CliError(errMessage, {
|
|
134
|
+
code: upgrade ? "upgrade_required" : "forbidden",
|
|
135
|
+
status,
|
|
136
|
+
hint: upgrade
|
|
137
|
+
? "AIGENCY CLI Pro veya Max paketine yükseltin."
|
|
138
|
+
: undefined,
|
|
139
|
+
details: body,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
if (status === 429) {
|
|
143
|
+
return new QuotaError(errMessage, body);
|
|
144
|
+
}
|
|
145
|
+
if (status >= 400 && status < 500) {
|
|
146
|
+
return new ValidationError(errMessage, body);
|
|
147
|
+
}
|
|
148
|
+
return new CliError(errMessage, {
|
|
149
|
+
code: "server_error",
|
|
150
|
+
status,
|
|
151
|
+
details: body,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/api-client/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIGENCY CLI — SSE stream istemcisi.
|
|
3
|
+
*
|
|
4
|
+
* `/api/cli/stream` endpoint'ine POST gönderir ve SSE akışını yakalar.
|
|
5
|
+
* Server-Sent Events basit bir metin protokolü: `data: {...}\n\n`.
|
|
6
|
+
*
|
|
7
|
+
* Node 18+ global fetch stream body'yi ReadableStream olarak döner.
|
|
8
|
+
* Biz bu stream'i decoder ile parse edip satır satır okuruz.
|
|
9
|
+
*
|
|
10
|
+
* Faz 4'te Ink UI bu modülü kullanarak real-time render yapacak.
|
|
11
|
+
*/
|
|
12
|
+
import { apiRequest } from "./base.js";
|
|
13
|
+
import { getApiBaseUrl } from "../config/defaults.js";
|
|
14
|
+
import { CLI_VERSION } from "../version.js";
|
|
15
|
+
import { NetworkError, AuthError, QuotaError, CliError } from "../utils/errors.js";
|
|
16
|
+
/**
|
|
17
|
+
* SSE akışını aç ve her event için callback çağır.
|
|
18
|
+
* Promise tüm akış bitince veya hata olunca resolve/reject olur.
|
|
19
|
+
*/
|
|
20
|
+
export async function openStream(accessToken, params, onEvent, signal) {
|
|
21
|
+
const url = `${getApiBaseUrl()}/api/cli/stream`;
|
|
22
|
+
const headers = {
|
|
23
|
+
Accept: "text/event-stream",
|
|
24
|
+
"Content-Type": "application/json",
|
|
25
|
+
Authorization: `Bearer ${accessToken}`,
|
|
26
|
+
"User-Agent": `aigency-cli/${CLI_VERSION} (${process.platform})`,
|
|
27
|
+
};
|
|
28
|
+
let response;
|
|
29
|
+
try {
|
|
30
|
+
response = await fetch(url, {
|
|
31
|
+
method: "POST",
|
|
32
|
+
headers,
|
|
33
|
+
body: JSON.stringify(params),
|
|
34
|
+
signal,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
if (err?.name === "AbortError") {
|
|
39
|
+
throw new CliError("İşlem iptal edildi", { code: "aborted" });
|
|
40
|
+
}
|
|
41
|
+
throw new NetworkError(`Stream bağlantısı kurulamadı: ${err.message}`, err);
|
|
42
|
+
}
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
// JSON body okumayı dene
|
|
45
|
+
let errBody = null;
|
|
46
|
+
try {
|
|
47
|
+
errBody = await response.json();
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// ignore
|
|
51
|
+
}
|
|
52
|
+
const message = errBody?.error || `Stream başlatılamadı (HTTP ${response.status})`;
|
|
53
|
+
if (response.status === 401)
|
|
54
|
+
throw new AuthError(message);
|
|
55
|
+
if (response.status === 429)
|
|
56
|
+
throw new QuotaError(message, errBody);
|
|
57
|
+
throw new CliError(message, { code: "stream_error", status: response.status, details: errBody });
|
|
58
|
+
}
|
|
59
|
+
if (!response.body) {
|
|
60
|
+
throw new NetworkError("Stream gövdesi boş");
|
|
61
|
+
}
|
|
62
|
+
const reader = response.body.getReader();
|
|
63
|
+
const decoder = new TextDecoder("utf-8");
|
|
64
|
+
let buffer = "";
|
|
65
|
+
try {
|
|
66
|
+
while (true) {
|
|
67
|
+
const { done, value } = await reader.read();
|
|
68
|
+
if (done)
|
|
69
|
+
break;
|
|
70
|
+
buffer += decoder.decode(value, { stream: true });
|
|
71
|
+
// SSE formatı: `data: ...\n\n`
|
|
72
|
+
let idx;
|
|
73
|
+
while ((idx = buffer.indexOf("\n\n")) !== -1) {
|
|
74
|
+
const rawEvent = buffer.slice(0, idx);
|
|
75
|
+
buffer = buffer.slice(idx + 2);
|
|
76
|
+
const dataLine = rawEvent.split("\n").find((l) => l.startsWith("data:"));
|
|
77
|
+
if (!dataLine)
|
|
78
|
+
continue;
|
|
79
|
+
const payload = dataLine.slice("data:".length).trim();
|
|
80
|
+
if (!payload)
|
|
81
|
+
continue;
|
|
82
|
+
try {
|
|
83
|
+
const event = JSON.parse(payload);
|
|
84
|
+
onEvent(event);
|
|
85
|
+
if (event.type === "done" || event.type === "error") {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
// JSON parse hatası — bu event'i atla
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
try {
|
|
97
|
+
reader.releaseLock();
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// ignore
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* CLI tool'u yerel çalıştırdıktan sonra sunucuya sonucu gönderir.
|
|
106
|
+
* Sunucu bekleyen agent loop'u bu çağrıyla devam eder.
|
|
107
|
+
*/
|
|
108
|
+
export async function sendToolResult(accessToken, params) {
|
|
109
|
+
await apiRequest("/api/cli/stream/tool-result", {
|
|
110
|
+
method: "POST",
|
|
111
|
+
bearer: accessToken,
|
|
112
|
+
body: {
|
|
113
|
+
request_id: params.requestId,
|
|
114
|
+
step_id: params.stepId,
|
|
115
|
+
tool_name: params.toolName,
|
|
116
|
+
result: params.result,
|
|
117
|
+
mode: params.mode,
|
|
118
|
+
approved: params.approved,
|
|
119
|
+
},
|
|
120
|
+
maxRetries: 1,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/api-client/stream.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIGENCY CLI — sürüm check istemcisi.
|
|
3
|
+
*/
|
|
4
|
+
import { apiRequest } from "./base.js";
|
|
5
|
+
import { CLI_VERSION } from "../version.js";
|
|
6
|
+
/**
|
|
7
|
+
* Platform string'i: darwin-arm64, linux-x64, win32-x64
|
|
8
|
+
*/
|
|
9
|
+
export function getPlatformString() {
|
|
10
|
+
const os = process.platform; // darwin | linux | win32
|
|
11
|
+
let arch = process.arch;
|
|
12
|
+
if (arch === "x64")
|
|
13
|
+
arch = "x64";
|
|
14
|
+
else if (arch === "arm64")
|
|
15
|
+
arch = "arm64";
|
|
16
|
+
else
|
|
17
|
+
arch = "x64";
|
|
18
|
+
return `${os}-${arch}`;
|
|
19
|
+
}
|
|
20
|
+
export async function checkForUpdates() {
|
|
21
|
+
const res = await apiRequest("/api/cli/updates", {
|
|
22
|
+
query: {
|
|
23
|
+
current: CLI_VERSION,
|
|
24
|
+
platform: getPlatformString(),
|
|
25
|
+
},
|
|
26
|
+
timeoutMs: 5000, // Kısa — sessiz başlatma check'i için
|
|
27
|
+
maxRetries: 0,
|
|
28
|
+
});
|
|
29
|
+
return res.data;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=updates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"updates.js","sourceRoot":"","sources":["../../src/api-client/updates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,yBAAyB;IACtD,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IACxB,IAAI,IAAI,KAAK,KAAK;QAAE,IAAI,GAAG,KAAK,CAAC;SAC5B,IAAI,IAAI,KAAK,OAAO;QAAE,IAAI,GAAG,OAAO,CAAC;;QACrC,IAAI,GAAG,KAAK,CAAC;IAClB,OAAO,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,GAAG,GAAG,MAAM,UAAU,CAAiB,kBAAkB,EAAE;QAC/D,KAAK,EAAE;YACL,OAAO,EAAE,WAAW;YACpB,QAAQ,EAAE,iBAAiB,EAAE;SAC9B;QACD,SAAS,EAAE,IAAI,EAAE,sCAAsC;QACvD,UAAU,EAAE,CAAC;KACd,CAAC,CAAC;IACH,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIGENCY CLI — kullanım ve paket bilgisi istemcisi.
|
|
3
|
+
*/
|
|
4
|
+
import { apiRequest } from "./base.js";
|
|
5
|
+
export async function fetchUsage(accessToken) {
|
|
6
|
+
const res = await apiRequest("/api/cli/usage", {
|
|
7
|
+
bearer: accessToken,
|
|
8
|
+
});
|
|
9
|
+
return res.data;
|
|
10
|
+
}
|
|
11
|
+
export async function fetchPackages() {
|
|
12
|
+
const res = await apiRequest("/api/cli/packages");
|
|
13
|
+
return res.data;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/api-client/usage.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAGvC,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,WAAmB;IAClD,MAAM,GAAG,GAAG,MAAM,UAAU,CAAgB,gBAAgB,EAAE;QAC5D,MAAM,EAAE,WAAW;KACpB,CAAC,CAAC;IACH,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IAKjC,MAAM,GAAG,GAAG,MAAM,UAAU,CAIzB,mBAAmB,CAAC,CAAC;IACxB,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIGENCY CLI — Local HTTP callback server.
|
|
3
|
+
*
|
|
4
|
+
* `aigency login` çalıştırıldığında random bir port (12000-65000 arası)
|
|
5
|
+
* üzerinde loopback (127.0.0.1) adresinde HTTP server başlatılır.
|
|
6
|
+
* Kullanıcı tarayıcıda `aigency.dev/cli/authorize` sayfasından onay
|
|
7
|
+
* verdikten sonra bu sayfa `http://127.0.0.1:<port>/cli/auth/callback?state=...`
|
|
8
|
+
* adresine yönlendirilir; server state parametresini yakalar ve CLI ana
|
|
9
|
+
* akışına iletir.
|
|
10
|
+
*
|
|
11
|
+
* Güvenlik:
|
|
12
|
+
* - Sadece 127.0.0.1'e bind (dış erişim yok)
|
|
13
|
+
* - 5 dakika timeout
|
|
14
|
+
* - Tek bir callback kabul edilir; sonra server kapanır
|
|
15
|
+
*/
|
|
16
|
+
import http from "node:http";
|
|
17
|
+
import { AuthError, CliError } from "../utils/errors.js";
|
|
18
|
+
import { log } from "../utils/logger.js";
|
|
19
|
+
import { DEFAULT_TIMEOUTS } from "../config/defaults.js";
|
|
20
|
+
const MIN_PORT = 12_000;
|
|
21
|
+
const MAX_PORT = 65_000;
|
|
22
|
+
/**
|
|
23
|
+
* Random port üzerinde HTTP callback server başlatır.
|
|
24
|
+
* OS'ye portu seçtirtmek daha güvenilir (çakışma riski yok) ama random sayısı
|
|
25
|
+
* talep ediyoruz ki kullanıcıya tarayıcı URL'sine ekleyeceğimiz port tahmin
|
|
26
|
+
* edilemez olsun.
|
|
27
|
+
*/
|
|
28
|
+
export async function startLocalAuthServer() {
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
// OS'den boş port iste: port 0 → OS otomatik seçsin.
|
|
31
|
+
// Proje kuralı 12000-65000 arası tutmamızı istiyor; o yüzden 0'dan kaçınıp
|
|
32
|
+
// OS'nin ephemeral range'ine düşmesini kabul ediyoruz.
|
|
33
|
+
const preferredPort = Math.floor(Math.random() * (MAX_PORT - MIN_PORT)) + MIN_PORT;
|
|
34
|
+
let resolver = null;
|
|
35
|
+
let rejecter = null;
|
|
36
|
+
const callbackPromise = new Promise((res, rej) => {
|
|
37
|
+
resolver = res;
|
|
38
|
+
rejecter = rej;
|
|
39
|
+
});
|
|
40
|
+
const server = http.createServer((req, res) => {
|
|
41
|
+
try {
|
|
42
|
+
if (!req.url) {
|
|
43
|
+
res.writeHead(400).end();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const url = new URL(req.url, `http://127.0.0.1:${preferredPort}`);
|
|
47
|
+
if (url.pathname !== "/cli/auth/callback") {
|
|
48
|
+
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
|
|
49
|
+
res.end("Bulunamadı");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const state = url.searchParams.get("state") || "";
|
|
53
|
+
const err = url.searchParams.get("error") || undefined;
|
|
54
|
+
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
55
|
+
res.end(buildSuccessHtml());
|
|
56
|
+
// Kısa gecikmeyle close (tarayıcının HTML'i alması için)
|
|
57
|
+
setTimeout(() => {
|
|
58
|
+
try {
|
|
59
|
+
server.close();
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// ignore
|
|
63
|
+
}
|
|
64
|
+
}, 300);
|
|
65
|
+
if (resolver) {
|
|
66
|
+
resolver({ state, error: err });
|
|
67
|
+
resolver = null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
res.writeHead(500).end();
|
|
72
|
+
if (rejecter) {
|
|
73
|
+
rejecter(new AuthError("Callback işlenemedi", e.message));
|
|
74
|
+
rejecter = null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
// 5 dakika timeout
|
|
79
|
+
const timeoutHandle = setTimeout(() => {
|
|
80
|
+
try {
|
|
81
|
+
server.close();
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// ignore
|
|
85
|
+
}
|
|
86
|
+
if (rejecter) {
|
|
87
|
+
rejecter(new AuthError("Yetkilendirme zaman aşımına uğradı (5 dakika)", "Tarayıcıda onay sayfasını açıp tekrar deneyin."));
|
|
88
|
+
rejecter = null;
|
|
89
|
+
}
|
|
90
|
+
}, DEFAULT_TIMEOUTS.oauthServer);
|
|
91
|
+
server.once("error", (err) => {
|
|
92
|
+
clearTimeout(timeoutHandle);
|
|
93
|
+
if (err.code === "EADDRINUSE") {
|
|
94
|
+
// Farklı port ile retry et — basit 5 deneme
|
|
95
|
+
log.debug(`Port ${preferredPort} kullanımda, yeniden deneniyor`);
|
|
96
|
+
startLocalAuthServer().then(resolve, reject);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
reject(new CliError("Yerel auth server başlatılamadı", {
|
|
100
|
+
code: "oauth_server_error",
|
|
101
|
+
cause: err,
|
|
102
|
+
}));
|
|
103
|
+
});
|
|
104
|
+
server.listen(preferredPort, "127.0.0.1", () => {
|
|
105
|
+
const addr = server.address();
|
|
106
|
+
if (!addr || typeof addr === "string") {
|
|
107
|
+
reject(new CliError("Yerel port alınamadı", { code: "oauth_server_error" }));
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
resolve({
|
|
111
|
+
port: addr.port,
|
|
112
|
+
waitForCallback: () => callbackPromise,
|
|
113
|
+
close: () => {
|
|
114
|
+
clearTimeout(timeoutHandle);
|
|
115
|
+
try {
|
|
116
|
+
server.close();
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// ignore
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
function buildSuccessHtml() {
|
|
127
|
+
return `<!doctype html>
|
|
128
|
+
<html lang="tr">
|
|
129
|
+
<head>
|
|
130
|
+
<meta charset="utf-8" />
|
|
131
|
+
<title>AIGENCY CLI — Yetkilendirme Başarılı</title>
|
|
132
|
+
<style>
|
|
133
|
+
* { box-sizing: border-box }
|
|
134
|
+
body {
|
|
135
|
+
margin: 0;
|
|
136
|
+
font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", system-ui, sans-serif;
|
|
137
|
+
background: #000;
|
|
138
|
+
color: #fff;
|
|
139
|
+
min-height: 100vh;
|
|
140
|
+
display: flex;
|
|
141
|
+
align-items: center;
|
|
142
|
+
justify-content: center;
|
|
143
|
+
padding: 24px;
|
|
144
|
+
}
|
|
145
|
+
.card {
|
|
146
|
+
max-width: 420px;
|
|
147
|
+
width: 100%;
|
|
148
|
+
padding: 32px;
|
|
149
|
+
background: rgba(255,255,255,0.03);
|
|
150
|
+
border: 1px solid rgba(255,255,255,0.1);
|
|
151
|
+
border-radius: 16px;
|
|
152
|
+
backdrop-filter: blur(40px) saturate(150%);
|
|
153
|
+
text-align: center;
|
|
154
|
+
}
|
|
155
|
+
.icon {
|
|
156
|
+
width: 56px; height: 56px; margin: 0 auto 16px;
|
|
157
|
+
border-radius: 50%;
|
|
158
|
+
background: rgba(16,185,129,0.1);
|
|
159
|
+
display: flex; align-items: center; justify-content: center;
|
|
160
|
+
}
|
|
161
|
+
h1 { font-size: 18px; margin: 0 0 8px; font-weight: 600; }
|
|
162
|
+
p { font-size: 13px; color: rgba(255,255,255,0.6); margin: 0; line-height: 1.6; }
|
|
163
|
+
</style>
|
|
164
|
+
</head>
|
|
165
|
+
<body>
|
|
166
|
+
<div class="card">
|
|
167
|
+
<div class="icon">
|
|
168
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
|
169
|
+
<polyline points="20 6 9 17 4 12"/>
|
|
170
|
+
</svg>
|
|
171
|
+
</div>
|
|
172
|
+
<h1>Yetkilendirme başarılı</h1>
|
|
173
|
+
<p>AIGENCY CLI hesabınıza bağlandı. Bu sekmeyi kapatıp terminale dönebilirsiniz.</p>
|
|
174
|
+
</div>
|
|
175
|
+
</body>
|
|
176
|
+
</html>`;
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIGENCY CLI — PKCE yardımcıları (RFC 7636).
|
|
3
|
+
*
|
|
4
|
+
* Sunucu tarafındaki `lib/cli/pkce.ts` ile aynı method (SHA-256, base64url).
|
|
5
|
+
* CLI verifier üretir; challenge sunucuya init'te gönderilir; exchange'de
|
|
6
|
+
* verifier geri gönderilir ve sunucu aynı hash'i tekrar hesaplayıp karşılaştırır.
|
|
7
|
+
*/
|
|
8
|
+
import crypto from "node:crypto";
|
|
9
|
+
const VERIFIER_BYTES = 48; // 64 base64url karakter
|
|
10
|
+
export function generatePkceVerifier() {
|
|
11
|
+
return crypto.randomBytes(VERIFIER_BYTES).toString("base64url");
|
|
12
|
+
}
|
|
13
|
+
export function deriveChallenge(verifier) {
|
|
14
|
+
return crypto.createHash("sha256").update(verifier, "ascii").digest("base64url");
|
|
15
|
+
}
|
|
16
|
+
export function generateState() {
|
|
17
|
+
return crypto.randomBytes(24).toString("base64url");
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=pkce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../src/auth/pkce.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,MAAM,cAAc,GAAG,EAAE,CAAC,CAAC,wBAAwB;AAEnD,MAAM,UAAU,oBAAoB;IAClC,OAAO,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AACnF,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIGENCY CLI — oturum yönetimi.
|
|
3
|
+
*
|
|
4
|
+
* Saklanan credentials'ı yükler; süresi yaklaşıyorsa refresh token ile
|
|
5
|
+
* yeniler. Üst katman (komutlar) sadece `requireActiveSession()` çağırır.
|
|
6
|
+
*/
|
|
7
|
+
import { readStoredCredentials, writeStoredCredentials, clearStoredCredentials, } from "./storage.js";
|
|
8
|
+
import { AuthError } from "../utils/errors.js";
|
|
9
|
+
import { log } from "../utils/logger.js";
|
|
10
|
+
/**
|
|
11
|
+
* Token süresi dolmadan önce yenilemek için eşik (2 dakika).
|
|
12
|
+
*/
|
|
13
|
+
const REFRESH_EARLY_MS = 2 * 60 * 1000;
|
|
14
|
+
export async function getActiveSession() {
|
|
15
|
+
const creds = await readStoredCredentials();
|
|
16
|
+
if (!creds)
|
|
17
|
+
return null;
|
|
18
|
+
return creds;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Saklanan oturumu döner; yoksa AuthError.
|
|
22
|
+
*/
|
|
23
|
+
export async function requireActiveSession() {
|
|
24
|
+
const creds = await getActiveSession();
|
|
25
|
+
if (!creds) {
|
|
26
|
+
throw new AuthError("Giriş yapılmamış", "`aigency login` ile hesabınıza bağlanın.");
|
|
27
|
+
}
|
|
28
|
+
return creds;
|
|
29
|
+
}
|
|
30
|
+
export function isExpiringSoon(creds) {
|
|
31
|
+
const expiresAt = new Date(creds.expires_at).getTime();
|
|
32
|
+
return expiresAt - Date.now() <= REFRESH_EARLY_MS;
|
|
33
|
+
}
|
|
34
|
+
export function isExpired(creds) {
|
|
35
|
+
return new Date(creds.expires_at).getTime() <= Date.now();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Yeni token'ları kaydet (login veya refresh sonrası).
|
|
39
|
+
*/
|
|
40
|
+
export async function saveSession(creds) {
|
|
41
|
+
await writeStoredCredentials(creds);
|
|
42
|
+
log.debug("Session kaydedildi");
|
|
43
|
+
}
|
|
44
|
+
export async function deleteSession() {
|
|
45
|
+
await clearStoredCredentials();
|
|
46
|
+
log.debug("Session silindi");
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAEzC;;GAEG;AACH,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAEvC,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,KAAK,GAAG,MAAM,qBAAqB,EAAE,CAAC;IAC5C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,MAAM,KAAK,GAAG,MAAM,gBAAgB,EAAE,CAAC;IACvC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,SAAS,CACjB,kBAAkB,EAClB,0CAA0C,CAC3C,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAwB;IACrD,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC;IACvD,OAAO,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,gBAAgB,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAwB;IAChD,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;AAC5D,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAwB;IACxD,MAAM,sBAAsB,CAAC,KAAK,CAAC,CAAC;IACpC,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,sBAAsB,EAAE,CAAC;IAC/B,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;AAC/B,CAAC"}
|