@andreprado/agentkit 0.1.0-alpha.4 → 0.1.0-alpha.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andreprado/agentkit",
3
- "version": "0.1.0-alpha.4",
3
+ "version": "0.1.0-alpha.5",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "repository": {
@@ -0,0 +1,36 @@
1
+ export type ParsedArgs = {
2
+ command?: string;
3
+ positional: string[];
4
+ flags: Record<string, string | boolean>;
5
+ };
6
+
7
+ export function parseArgs(argv: string[]): ParsedArgs {
8
+ const [command, ...rest] = argv;
9
+ const positional: string[] = [];
10
+ const flags: Record<string, string | boolean> = {};
11
+
12
+ for (let index = 0; index < rest.length; index += 1) {
13
+ const value = rest[index];
14
+
15
+ if (!value.startsWith("--")) {
16
+ positional.push(value);
17
+ continue;
18
+ }
19
+
20
+ const name = value.slice(2);
21
+ const next = rest[index + 1];
22
+
23
+ if (next && !next.startsWith("--")) {
24
+ flags[name] = next;
25
+ index += 1;
26
+ } else {
27
+ flags[name] = true;
28
+ }
29
+ }
30
+
31
+ return { command, positional, flags };
32
+ }
33
+
34
+ export function isHelpRequested(args: ParsedArgs): boolean {
35
+ return args.flags.help === true || args.flags.h === true || args.positional.includes("--help") || args.positional.includes("-h");
36
+ }
@@ -0,0 +1,257 @@
1
+ import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+
5
+ import { AgentKitError } from "../runtime/errors";
6
+ import { defaultAgentKitCloudApiUrl } from "./constants";
7
+ import { parseCloudApiUrl } from "./flags";
8
+
9
+ export type CloudAuthConfig = {
10
+ apiUrl: string;
11
+ token: string;
12
+ source?: "environment" | "file";
13
+ };
14
+
15
+ export type CloudMeResponse = {
16
+ account?: {
17
+ email?: string;
18
+ status?: string;
19
+ };
20
+ };
21
+
22
+ export type CloudCapabilitiesResponse = {
23
+ capabilities?: Array<{
24
+ name?: string;
25
+ status?: string;
26
+ }>;
27
+ };
28
+
29
+ export type CloudLimitsResponse = {
30
+ online_agents?: {
31
+ account?: {
32
+ used?: number | null;
33
+ limit?: number | null;
34
+ };
35
+ global?: {
36
+ used?: number | null;
37
+ limit?: number | null;
38
+ };
39
+ };
40
+ };
41
+
42
+ export type DeployAccessTokenCreateResponse = {
43
+ access_token?: {
44
+ id?: string;
45
+ deploy_id?: string;
46
+ name?: string;
47
+ token?: string;
48
+ };
49
+ };
50
+
51
+ export type DeployAccessTokenListResponse = {
52
+ access_tokens?: Array<{
53
+ id?: string;
54
+ deploy_id?: string;
55
+ name?: string;
56
+ }>;
57
+ };
58
+
59
+ export type CloudSecretsResponse = {
60
+ secrets?: Array<{
61
+ name?: string;
62
+ status?: string;
63
+ updated_at?: string;
64
+ }>;
65
+ };
66
+
67
+ export function cloudAuthPath(): string {
68
+ return join(homedir(), ".agentkit", "cloud.json");
69
+ }
70
+
71
+ export async function readCloudAuth(): Promise<CloudAuthConfig | null> {
72
+ if (process.env.AGENTKIT_CLOUD_API_TOKEN) {
73
+ return {
74
+ apiUrl: process.env.AGENTKIT_CLOUD_API_URL ?? defaultAgentKitCloudApiUrl,
75
+ token: process.env.AGENTKIT_CLOUD_API_TOKEN,
76
+ source: "environment",
77
+ };
78
+ }
79
+
80
+ try {
81
+ const parsed = JSON.parse(await readFile(cloudAuthPath(), "utf8"));
82
+
83
+ if (parsed && typeof parsed === "object" && typeof parsed.token === "string") {
84
+ return {
85
+ apiUrl: typeof parsed.apiUrl === "string" ? parsed.apiUrl : defaultAgentKitCloudApiUrl,
86
+ token: parsed.token,
87
+ source: "file",
88
+ };
89
+ }
90
+ } catch {
91
+ return null;
92
+ }
93
+
94
+ return null;
95
+ }
96
+
97
+ export async function writeCloudAuth(config: CloudAuthConfig): Promise<void> {
98
+ await mkdir(join(homedir(), ".agentkit"), { recursive: true });
99
+ await writeFile(cloudAuthPath(), `${JSON.stringify(config, null, 2)}\n`, { mode: 0o600 });
100
+ }
101
+
102
+ export async function clearCloudAuth(): Promise<void> {
103
+ await rm(cloudAuthPath(), { force: true });
104
+ }
105
+
106
+ export async function resolveCloudApiUrl(flag: string | boolean | undefined): Promise<string> {
107
+ if (flag !== undefined) {
108
+ return parseCloudApiUrl(flag);
109
+ }
110
+
111
+ const auth = await readCloudAuth();
112
+ return auth?.apiUrl ?? parseCloudApiUrl(undefined);
113
+ }
114
+
115
+ export async function verifyCloudLogin(
116
+ apiUrl: string,
117
+ token: string,
118
+ ): Promise<{ me: CloudMeResponse; capabilities: CloudCapabilitiesResponse }> {
119
+ const me = await cloudApiRequestWithToken<CloudMeResponse>(apiUrl, "/v1/me", token, { method: "GET" });
120
+ const capabilities = await cloudApiRequestWithToken<CloudCapabilitiesResponse>(
121
+ apiUrl,
122
+ "/v1/me/capabilities",
123
+ token,
124
+ { method: "GET" },
125
+ );
126
+
127
+ return { me, capabilities };
128
+ }
129
+
130
+ export async function cloudGet<T>(apiUrl: string, path: string): Promise<T> {
131
+ const response = await cloudFetch(apiUrl, path);
132
+ const payload = await response.json();
133
+
134
+ if (!response.ok) {
135
+ throw new Error(readCloudError(payload, response.status));
136
+ }
137
+
138
+ return payload as T;
139
+ }
140
+
141
+ export async function cloudPost<T>(apiUrl: string, path: string, body: unknown): Promise<T> {
142
+ const response = await cloudFetch(apiUrl, path, {
143
+ method: "POST",
144
+ headers: { "Content-Type": "application/json" },
145
+ body: JSON.stringify(body),
146
+ });
147
+ const payload = await response.json();
148
+
149
+ if (!response.ok) {
150
+ throw new Error(readCloudError(payload, response.status));
151
+ }
152
+
153
+ return payload as T;
154
+ }
155
+
156
+ export function cloudFetch(apiUrl: string, path: string, init: RequestInit = {}): Promise<Response> {
157
+ const headers = new Headers(init.headers);
158
+ const apiToken = process.env.AGENTKIT_CLOUD_API_TOKEN;
159
+
160
+ if (apiToken && !headers.has("Authorization")) {
161
+ headers.set("Authorization", `Bearer ${apiToken}`);
162
+ }
163
+
164
+ return fetch(new URL(path, parseCloudApiUrl(apiUrl)).href, {
165
+ ...init,
166
+ headers,
167
+ });
168
+ }
169
+
170
+ export async function cloudApiRequest(apiUrl: string, path: string, init: RequestInit): Promise<unknown> {
171
+ const auth = await readCloudAuth();
172
+ const headers = new Headers(init.headers);
173
+
174
+ if (!headers.has("Content-Type") && init.body !== undefined) {
175
+ headers.set("Content-Type", "application/json");
176
+ }
177
+
178
+ if (auth?.token && !headers.has("Authorization")) {
179
+ headers.set("Authorization", `Bearer ${auth.token}`);
180
+ }
181
+
182
+ const response = await fetch(new URL(path, parseCloudApiUrl(apiUrl)).href, {
183
+ ...init,
184
+ headers,
185
+ });
186
+ const payload = await response.json().catch(() => null);
187
+
188
+ if (!response.ok) {
189
+ const code =
190
+ payload && typeof payload === "object" && "error" in payload
191
+ ? String((payload as { error?: { code?: unknown } }).error?.code ?? "cloud_request_failed")
192
+ : "cloud_request_failed";
193
+ let message = readCloudError(payload, response.status);
194
+
195
+ if (code === "auth_token_invalid") {
196
+ message = `${message} Token source: ${auth ? formatCloudAuthSource(auth) : "none"}. Run: agentkit login --token <token>`;
197
+ }
198
+
199
+ throw new AgentKitError(code, message);
200
+ }
201
+
202
+ return payload;
203
+ }
204
+
205
+ export async function cloudApiRequestWithToken<T>(
206
+ apiUrl: string,
207
+ path: string,
208
+ token: string,
209
+ init: RequestInit,
210
+ ): Promise<T> {
211
+ const headers = new Headers(init.headers);
212
+
213
+ if (!headers.has("Content-Type") && init.body !== undefined) {
214
+ headers.set("Content-Type", "application/json");
215
+ }
216
+
217
+ headers.set("Authorization", `Bearer ${token}`);
218
+
219
+ const response = await fetch(new URL(path, parseCloudApiUrl(apiUrl)).href, {
220
+ ...init,
221
+ headers,
222
+ });
223
+ const payload = await response.json().catch(() => null);
224
+
225
+ if (!response.ok) {
226
+ const code =
227
+ payload && typeof payload === "object" && "error" in payload
228
+ ? String((payload as { error?: { code?: unknown } }).error?.code ?? "cloud_request_failed")
229
+ : "cloud_request_failed";
230
+ throw new AgentKitError(code, readCloudError(payload, response.status));
231
+ }
232
+
233
+ return payload as T;
234
+ }
235
+
236
+ export function readCloudError(payload: unknown, status: number): string {
237
+ if (payload && typeof payload === "object" && "error" in payload) {
238
+ const error = (payload as { error?: { message?: unknown } }).error;
239
+ if (typeof error?.message === "string") {
240
+ return error.message;
241
+ }
242
+ }
243
+
244
+ return `AgentKit Cloud request failed with HTTP ${status}.`;
245
+ }
246
+
247
+ export function formatCloudAuthSource(auth: CloudAuthConfig): string {
248
+ if (auth.source === "environment") {
249
+ return "AGENTKIT_CLOUD_API_TOKEN";
250
+ }
251
+
252
+ if (auth.source === "file") {
253
+ return cloudAuthPath();
254
+ }
255
+
256
+ return "AgentKit Cloud auth";
257
+ }