Skip to content

Commit c6e6def

Browse files
committed
wip
1 parent 53739c3 commit c6e6def

File tree

15 files changed

+434
-425
lines changed

15 files changed

+434
-425
lines changed

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,20 @@ Clears stored credentials.
3737

3838
Lists all projects you have access to across your organizations.
3939

40-
| Flag | Description |
41-
|------|-------------|
40+
| Flag | Description |
41+
| -------- | -------------- |
4242
| `--json` | Output as JSON |
4343

4444
### `yavy generate <org/project>`
4545

4646
Generates a skill file from a project's indexed documentation.
4747

48-
| Flag | Description |
49-
|------|-------------|
50-
| `--global` | Save to global skills directory (`~/.claude/skills/`) |
51-
| `--output <path>` | Custom output path |
52-
| `--force` | Force regeneration even if cached |
53-
| `--json` | Output as JSON |
48+
| Flag | Description |
49+
| ----------------- | ----------------------------------------------------- |
50+
| `--global` | Save to global skills directory (`~/.claude/skills/`) |
51+
| `--output <path>` | Custom output path |
52+
| `--force` | Force regeneration even if cached |
53+
| `--json` | Output as JSON |
5454

5555
By default, skills are saved to `.claude/skills/<project>/SKILL.md` in the current directory.
5656

package.json

Lines changed: 54 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,56 @@
11
{
2-
"name": "@yavydev/cli",
3-
"version": "0.1.0",
4-
"description": "Generate AI skills from your indexed documentation on Yavy",
5-
"type": "module",
6-
"bin": {
7-
"yavy": "./bin/yavy.js"
8-
},
9-
"main": "./dist/index.js",
10-
"scripts": {
11-
"build": "tsup",
12-
"dev": "tsup --watch",
13-
"typecheck": "tsc --noEmit"
14-
},
15-
"keywords": [
16-
"yavy",
17-
"ai",
18-
"ai",
19-
"skills",
20-
"documentation",
21-
"cli"
22-
],
23-
"author": {
24-
"name": "Yavy",
25-
"url": "https://yavy.dev"
26-
},
27-
"homepage": "https://github.com/yavydev/cli#readme",
28-
"repository": {
29-
"type": "git",
30-
"url": "git+https://github.com/yavydev/cli.git"
31-
},
32-
"bugs": {
33-
"url": "https://github.com/yavydev/cli/issues"
34-
},
35-
"dependencies": {
36-
"chalk": "^5.3.0",
37-
"commander": "^13.1.0",
38-
"open": "^10.1.0",
39-
"ora": "^8.1.1"
40-
},
41-
"devDependencies": {
42-
"@types/node": "^22.0.0",
43-
"tsup": "^8.4.0",
44-
"typescript": "^5.7.0"
45-
},
46-
"engines": {
47-
"node": ">=18"
48-
},
49-
"publishConfig": {
50-
"access": "public"
51-
},
52-
"files": [
53-
"dist",
54-
"bin"
55-
],
56-
"license": "MIT"
2+
"name": "@yavydev/cli",
3+
"version": "0.1.0",
4+
"description": "Generate AI skills from your indexed documentation on Yavy",
5+
"type": "module",
6+
"bin": {
7+
"yavy": "./bin/yavy.js"
8+
},
9+
"main": "./dist/index.js",
10+
"scripts": {
11+
"build": "tsup",
12+
"dev": "tsup --watch",
13+
"typecheck": "tsc --noEmit"
14+
},
15+
"keywords": [
16+
"yavy",
17+
"ai",
18+
"skills",
19+
"documentation",
20+
"cli"
21+
],
22+
"author": {
23+
"name": "Yavy",
24+
"url": "https://yavy.dev"
25+
},
26+
"homepage": "https://github.com/yavydev/cli#readme",
27+
"repository": {
28+
"type": "git",
29+
"url": "git+https://github.com/yavydev/cli.git"
30+
},
31+
"bugs": {
32+
"url": "https://github.com/yavydev/cli/issues"
33+
},
34+
"dependencies": {
35+
"chalk": "^5.3.0",
36+
"commander": "^13.1.0",
37+
"open": "^10.1.0",
38+
"ora": "^8.1.1"
39+
},
40+
"devDependencies": {
41+
"@types/node": "^22.0.0",
42+
"tsup": "^8.4.0",
43+
"typescript": "^5.7.0"
44+
},
45+
"engines": {
46+
"node": ">=18"
47+
},
48+
"publishConfig": {
49+
"access": "public"
50+
},
51+
"files": [
52+
"dist",
53+
"bin"
54+
],
55+
"license": "MIT"
5756
}

src/api/client.ts

Lines changed: 61 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,85 @@
11
import { getAccessToken } from '../auth/store.js';
2-
3-
const YAVY_BASE_URL = 'https://yavy.dev';
2+
import { YAVY_BASE_URL } from '../config.js';
43

54
export interface ApiProject {
6-
id: number;
7-
name: string;
8-
slug: string;
9-
description: string | null;
10-
organization: {
5+
id: number;
116
name: string;
127
slug: string;
13-
};
14-
pages_count: number;
15-
last_indexed_at: string | null;
16-
has_skill: boolean;
8+
description: string | null;
9+
organization: {
10+
name: string;
11+
slug: string;
12+
};
13+
pages_count: number;
14+
last_indexed_at: string | null;
15+
has_skill: boolean;
1716
}
1817

1918
export interface ApiSkill {
20-
content: string;
21-
format: string;
22-
generated_at: string;
23-
token_count: number;
24-
project: {
25-
name: string;
26-
slug: string;
27-
};
19+
content: string;
20+
format: string;
21+
generated_at: string;
22+
token_count: number;
23+
project: {
24+
name: string;
25+
slug: string;
26+
};
2827
}
2928

3029
export class YavyApiClient {
31-
private token: string;
30+
private token: string;
3231

33-
constructor(token: string) {
34-
this.token = token;
35-
}
32+
constructor(token: string) {
33+
this.token = token;
34+
}
3635

37-
static create(): YavyApiClient {
38-
const token = getAccessToken();
39-
if (!token) {
40-
throw new Error('Not authenticated. Run `yavy login` first.');
36+
static async create(): Promise<YavyApiClient> {
37+
const token = await getAccessToken();
38+
if (!token) {
39+
throw new Error('Not authenticated. Run `yavy login` first.');
40+
}
41+
return new YavyApiClient(token);
4142
}
42-
return new YavyApiClient(token);
43-
}
4443

45-
private async request<T>(method: string, path: string, body?: unknown): Promise<T> {
46-
const url = `${YAVY_BASE_URL}/api/v1${path}`;
47-
const headers: Record<string, string> = {
48-
'Authorization': `Bearer ${this.token}`,
49-
'Accept': 'application/json',
50-
};
44+
private async request<T>(method: string, path: string, body?: unknown): Promise<T> {
45+
const url = `${YAVY_BASE_URL}/api/v1${path}`;
46+
const headers: Record<string, string> = {
47+
Authorization: `Bearer ${this.token}`,
48+
Accept: 'application/json',
49+
};
5150

52-
if (body) {
53-
headers['Content-Type'] = 'application/json';
54-
}
51+
if (body) {
52+
headers['Content-Type'] = 'application/json';
53+
}
5554

56-
const response = await fetch(url, {
57-
method,
58-
headers,
59-
body: body ? JSON.stringify(body) : undefined,
60-
});
55+
const response = await fetch(url, {
56+
method,
57+
headers,
58+
body: body ? JSON.stringify(body) : undefined,
59+
});
6160

62-
if (response.status === 401) {
63-
throw new Error('Authentication expired. Run `yavy login` to re-authenticate.');
64-
}
61+
if (response.status === 401) {
62+
throw new Error('Authentication expired. Run `yavy login` to re-authenticate.');
63+
}
6564

66-
if (!response.ok) {
67-
const errorData = await response.json().catch(() => ({})) as { error?: string };
68-
throw new Error(errorData.error ?? `API request failed with status ${response.status}`);
69-
}
65+
if (!response.ok) {
66+
const errorData = (await response.json().catch(() => ({}))) as { error?: string };
67+
throw new Error(errorData.error ?? `API request failed with status ${response.status}`);
68+
}
7069

71-
return response.json() as Promise<T>;
72-
}
70+
return response.json() as Promise<T>;
71+
}
7372

74-
async listProjects(): Promise<ApiProject[]> {
75-
const result = await this.request<{ data: ApiProject[] }>('GET', '/projects');
76-
return result.data;
77-
}
73+
async listProjects(): Promise<ApiProject[]> {
74+
const result = await this.request<{ data: ApiProject[] }>('GET', '/projects');
75+
return result.data;
76+
}
7877

79-
async generateSkill(orgSlug: string, projectSlug: string, force = false): Promise<ApiSkill> {
80-
return this.request<ApiSkill>('POST', `/${orgSlug}/${projectSlug}/skill/generate`, force ? { force: true } : undefined);
81-
}
78+
async generateSkill(orgSlug: string, projectSlug: string, force = false): Promise<ApiSkill> {
79+
return this.request<ApiSkill>('POST', `/${orgSlug}/${projectSlug}/skill/generate`, force ? { force: true } : undefined);
80+
}
8281

83-
async getSkill(orgSlug: string, projectSlug: string): Promise<ApiSkill> {
84-
return this.request<ApiSkill>('GET', `/${orgSlug}/${projectSlug}/skill`);
85-
}
82+
async getSkill(orgSlug: string, projectSlug: string): Promise<ApiSkill> {
83+
return this.request<ApiSkill>('GET', `/${orgSlug}/${projectSlug}/skill`);
84+
}
8685
}

0 commit comments

Comments
 (0)