ai-devkit 0.2.0 → 0.4.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/CHANGELOG.md +11 -1
- package/README.md +20 -87
- package/dist/__tests__/lib/Config.test.d.ts +2 -0
- package/dist/__tests__/lib/Config.test.d.ts.map +1 -0
- package/dist/__tests__/lib/Config.test.js +281 -0
- package/dist/__tests__/lib/Config.test.js.map +1 -0
- package/dist/__tests__/lib/EnvironmentSelector.test.d.ts +2 -0
- package/dist/__tests__/lib/EnvironmentSelector.test.d.ts.map +1 -0
- package/dist/__tests__/lib/EnvironmentSelector.test.js +117 -0
- package/dist/__tests__/lib/EnvironmentSelector.test.js.map +1 -0
- package/dist/__tests__/lib/PhaseSelector.test.d.ts +2 -0
- package/dist/__tests__/lib/PhaseSelector.test.d.ts.map +1 -0
- package/dist/__tests__/lib/PhaseSelector.test.js +77 -0
- package/dist/__tests__/lib/PhaseSelector.test.js.map +1 -0
- package/dist/__tests__/util/env.test.d.ts +2 -0
- package/dist/__tests__/util/env.test.d.ts.map +1 -0
- package/dist/__tests__/util/env.test.js +166 -0
- package/dist/__tests__/util/env.test.js.map +1 -0
- package/dist/commands/init.d.ts +2 -2
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +54 -73
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/phase.d.ts.map +1 -1
- package/dist/commands/phase.js +1 -5
- package/dist/commands/phase.js.map +1 -1
- package/dist/lib/Config.d.ts +5 -2
- package/dist/lib/Config.d.ts.map +1 -1
- package/dist/lib/Config.js +18 -3
- package/dist/lib/Config.js.map +1 -1
- package/dist/lib/EnvironmentSelector.d.ts +7 -0
- package/dist/lib/EnvironmentSelector.d.ts.map +1 -0
- package/dist/lib/EnvironmentSelector.js +62 -0
- package/dist/lib/EnvironmentSelector.js.map +1 -0
- package/dist/lib/PhaseSelector.d.ts +8 -0
- package/dist/lib/PhaseSelector.d.ts.map +1 -0
- package/dist/lib/PhaseSelector.js +58 -0
- package/dist/lib/PhaseSelector.js.map +1 -0
- package/dist/lib/TemplateManager.d.ts +5 -5
- package/dist/lib/TemplateManager.d.ts.map +1 -1
- package/dist/lib/TemplateManager.js +73 -66
- package/dist/lib/TemplateManager.js.map +1 -1
- package/dist/types.d.ts +9 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/util/env.d.ts +11 -0
- package/dist/util/env.d.ts.map +1 -0
- package/dist/util/env.js +109 -0
- package/dist/util/env.js.map +1 -0
- package/jest.config.js +22 -0
- package/package.json +16 -11
- package/templates/commands/capture-knowledge.md +46 -0
- package/templates/commands/debug.md +45 -0
- package/templates/{env/cursor/commands → commands}/new-requirement.md +1 -1
- package/web/.nojekyll +2 -0
- package/web/CNAME +1 -0
- package/web/README.md +100 -0
- package/web/app/favicon.ico +0 -0
- package/web/app/globals.css +122 -0
- package/web/app/layout.tsx +106 -0
- package/web/app/page.tsx +119 -0
- package/web/app/roadmap/page.tsx +150 -0
- package/web/app/robots.ts +16 -0
- package/web/app/sitemap.ts +46 -0
- package/web/app/vision/page.tsx +49 -0
- package/web/components/Footer.tsx +81 -0
- package/web/components/GitHubButton.tsx +49 -0
- package/web/components/GitHubStars.tsx +27 -0
- package/web/components/Header.tsx +108 -0
- package/web/components/MarkdownContent.tsx +35 -0
- package/web/components/SkipToContent.tsx +11 -0
- package/web/content/pages/vision.md +42 -0
- package/web/content/roadmap/1-web.md +9 -0
- package/web/content/roadmap/2-integrations.md +7 -0
- package/web/content/roadmap/3-cli-enhancements.md +8 -0
- package/web/content/roadmap/4-local-memory.md +8 -0
- package/web/eslint.config.mjs +18 -0
- package/web/lib/GitHubContext.tsx +57 -0
- package/web/lib/content/loader.ts +152 -0
- package/web/lib/content/types.ts +37 -0
- package/web/lib/utils.ts +12 -0
- package/web/next.config.ts +11 -0
- package/web/package-lock.json +8837 -0
- package/web/package.json +34 -0
- package/web/postcss.config.mjs +7 -0
- package/web/public/file.svg +1 -0
- package/web/public/globe.svg +1 -0
- package/web/public/next.svg +1 -0
- package/web/public/vercel.svg +1 -0
- package/web/public/window.svg +1 -0
- package/templates/env/claude/CLAUDE.md +0 -52
- package/templates/env/claude/commands/code-review.md +0 -81
- package/templates/env/claude/commands/execute-plan.md +0 -71
- package/templates/env/claude/commands/new-requirement.md +0 -127
- package/templates/env/claude/commands/update-planning.md +0 -61
- package/templates/env/cursor/commands/check-implementation.md +0 -21
- package/templates/env/cursor/commands/review-design.md +0 -11
- package/templates/env/cursor/commands/review-requirements.md +0 -9
- package/templates/env/cursor/commands/writing-test.md +0 -44
- package/templates/env/cursor/rules/ai-devkit.md +0 -51
- /package/templates/{env/claude/commands → commands}/check-implementation.md +0 -0
- /package/templates/{env/cursor/commands → commands}/code-review.md +0 -0
- /package/templates/{env/cursor/commands → commands}/execute-plan.md +0 -0
- /package/templates/{env/claude/commands → commands}/review-design.md +0 -0
- /package/templates/{env/claude/commands → commands}/review-requirements.md +0 -0
- /package/templates/{env/cursor/commands → commands}/update-planning.md +0 -0
- /package/templates/{env/claude/commands → commands}/writing-test.md +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineConfig, globalIgnores } from "eslint/config";
|
|
2
|
+
import nextVitals from "eslint-config-next/core-web-vitals";
|
|
3
|
+
import nextTs from "eslint-config-next/typescript";
|
|
4
|
+
|
|
5
|
+
const eslintConfig = defineConfig([
|
|
6
|
+
...nextVitals,
|
|
7
|
+
...nextTs,
|
|
8
|
+
// Override default ignores of eslint-config-next.
|
|
9
|
+
globalIgnores([
|
|
10
|
+
// Default ignores of eslint-config-next:
|
|
11
|
+
".next/**",
|
|
12
|
+
"out/**",
|
|
13
|
+
"build/**",
|
|
14
|
+
"next-env.d.ts",
|
|
15
|
+
]),
|
|
16
|
+
]);
|
|
17
|
+
|
|
18
|
+
export default eslintConfig;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { createContext, useContext, useState, useEffect, ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
interface GitHubContextType {
|
|
6
|
+
stars: number | null;
|
|
7
|
+
loading: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const GitHubContext = createContext<GitHubContextType>({
|
|
11
|
+
stars: null,
|
|
12
|
+
loading: true,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export function GitHubProvider({
|
|
16
|
+
children,
|
|
17
|
+
repo
|
|
18
|
+
}: {
|
|
19
|
+
children: ReactNode;
|
|
20
|
+
repo: string;
|
|
21
|
+
}) {
|
|
22
|
+
const [stars, setStars] = useState<number | null>(null);
|
|
23
|
+
const [loading, setLoading] = useState(true);
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
async function fetchStars() {
|
|
27
|
+
try {
|
|
28
|
+
const response = await fetch(`https://api.github.com/repos/${repo}`);
|
|
29
|
+
if (response.ok) {
|
|
30
|
+
const data = await response.json();
|
|
31
|
+
setStars(data.stargazers_count);
|
|
32
|
+
}
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error('Failed to fetch GitHub stars:', error);
|
|
35
|
+
} finally {
|
|
36
|
+
setLoading(false);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
fetchStars();
|
|
41
|
+
}, [repo]);
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<GitHubContext.Provider value={{ stars, loading }}>
|
|
45
|
+
{children}
|
|
46
|
+
</GitHubContext.Provider>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function useGitHubStars() {
|
|
51
|
+
const context = useContext(GitHubContext);
|
|
52
|
+
if (!context) {
|
|
53
|
+
throw new Error('useGitHubStars must be used within a GitHubProvider');
|
|
54
|
+
}
|
|
55
|
+
return context;
|
|
56
|
+
}
|
|
57
|
+
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import matter from 'gray-matter';
|
|
4
|
+
import { Page, PageMetadata, RoadmapItem, RoadmapItemMetadata } from './types';
|
|
5
|
+
|
|
6
|
+
const contentDirectory = path.join(process.cwd(), 'content');
|
|
7
|
+
const docsDirectory = path.join(contentDirectory, 'docs');
|
|
8
|
+
const pagesDirectory = path.join(contentDirectory, 'pages');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Get all Markdown files from a directory
|
|
12
|
+
*/
|
|
13
|
+
function getMarkdownFiles(dir: string): string[] {
|
|
14
|
+
if (!fs.existsSync(dir)) {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const files = fs.readdirSync(dir);
|
|
19
|
+
return files
|
|
20
|
+
.filter(file => file.endsWith('.md') || file.endsWith('.mdx'))
|
|
21
|
+
.map(file => path.join(dir, file));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Parse a Markdown file with frontmatter
|
|
26
|
+
*/
|
|
27
|
+
function parseMarkdownFile<T>(filePath: string): { metadata: T; content: string } {
|
|
28
|
+
const fileContents = fs.readFileSync(filePath, 'utf8');
|
|
29
|
+
const { data, content } = matter(fileContents);
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
metadata: data as T,
|
|
33
|
+
content: content.trim(),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Get a single page by slug
|
|
39
|
+
*/
|
|
40
|
+
export function getPage(slug: string): Page | null {
|
|
41
|
+
const filePath = path.join(pagesDirectory, `${slug}.md`);
|
|
42
|
+
|
|
43
|
+
if (!fs.existsSync(filePath)) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const parsed = parseMarkdownFile<PageMetadata>(filePath);
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
metadata: {
|
|
51
|
+
...parsed.metadata,
|
|
52
|
+
slug,
|
|
53
|
+
},
|
|
54
|
+
content: parsed.content,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Get all pages
|
|
60
|
+
*/
|
|
61
|
+
export function getAllPages(): Page[] {
|
|
62
|
+
const files = getMarkdownFiles(pagesDirectory);
|
|
63
|
+
|
|
64
|
+
const pages = files.map(filePath => {
|
|
65
|
+
const slug = path.basename(filePath, path.extname(filePath));
|
|
66
|
+
const parsed = parseMarkdownFile<PageMetadata>(filePath);
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
metadata: {
|
|
70
|
+
...parsed.metadata,
|
|
71
|
+
slug,
|
|
72
|
+
},
|
|
73
|
+
content: parsed.content,
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Sort by order if specified
|
|
78
|
+
return pages.sort((a, b) => {
|
|
79
|
+
const orderA = a.metadata.order ?? 999;
|
|
80
|
+
const orderB = b.metadata.order ?? 999;
|
|
81
|
+
return orderA - orderB;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Get a single documentation page by slug
|
|
87
|
+
*/
|
|
88
|
+
export function getDocPage(slug: string): Page | null {
|
|
89
|
+
const filePath = path.join(docsDirectory, `${slug}.md`);
|
|
90
|
+
|
|
91
|
+
if (!fs.existsSync(filePath)) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const parsed = parseMarkdownFile<PageMetadata>(filePath);
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
metadata: {
|
|
99
|
+
...parsed.metadata,
|
|
100
|
+
slug,
|
|
101
|
+
},
|
|
102
|
+
content: parsed.content,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get all documentation pages
|
|
108
|
+
*/
|
|
109
|
+
export function getAllDocPages(): Page[] {
|
|
110
|
+
const files = getMarkdownFiles(docsDirectory);
|
|
111
|
+
|
|
112
|
+
const pages = files.map(filePath => {
|
|
113
|
+
const slug = path.basename(filePath, path.extname(filePath));
|
|
114
|
+
const parsed = parseMarkdownFile<PageMetadata>(filePath);
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
metadata: {
|
|
118
|
+
...parsed.metadata,
|
|
119
|
+
slug,
|
|
120
|
+
},
|
|
121
|
+
content: parsed.content,
|
|
122
|
+
};
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Sort by order if specified
|
|
126
|
+
return pages.sort((a, b) => {
|
|
127
|
+
const orderA = a.metadata.order ?? 999;
|
|
128
|
+
const orderB = b.metadata.order ?? 999;
|
|
129
|
+
return orderA - orderB;
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Get all roadmap items
|
|
135
|
+
*/
|
|
136
|
+
export function getRoadmap(): RoadmapItem[] {
|
|
137
|
+
const roadmapDir = path.join(contentDirectory, 'roadmap');
|
|
138
|
+
const files = getMarkdownFiles(roadmapDir);
|
|
139
|
+
|
|
140
|
+
const items = files.map(filePath => {
|
|
141
|
+
const parsed = parseMarkdownFile<RoadmapItemMetadata>(filePath);
|
|
142
|
+
return parsed as RoadmapItem;
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// Sort by order if specified, then by priority
|
|
146
|
+
return items.sort((a, b) => {
|
|
147
|
+
const orderA = a.metadata.order ?? 999;
|
|
148
|
+
const orderB = b.metadata.order ?? 999;
|
|
149
|
+
return orderA - orderB;
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface PageMetadata {
|
|
2
|
+
title: string;
|
|
3
|
+
description: string;
|
|
4
|
+
slug: string;
|
|
5
|
+
heroImage?: string;
|
|
6
|
+
order?: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface Page {
|
|
10
|
+
metadata: PageMetadata;
|
|
11
|
+
content: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface RoadmapItemMetadata {
|
|
15
|
+
title: string;
|
|
16
|
+
status: 'planned' | 'in-progress' | 'completed' | 'on-hold';
|
|
17
|
+
timeframe?: string;
|
|
18
|
+
priority?: 'low' | 'medium' | 'high';
|
|
19
|
+
order?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface RoadmapItem {
|
|
23
|
+
metadata: RoadmapItemMetadata;
|
|
24
|
+
content: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface NavigationLink {
|
|
28
|
+
label: string;
|
|
29
|
+
href: string;
|
|
30
|
+
external?: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface NavigationSection {
|
|
34
|
+
title: string;
|
|
35
|
+
links: NavigationLink[];
|
|
36
|
+
}
|
|
37
|
+
|
package/web/lib/utils.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format star count for display
|
|
3
|
+
* @param count - The number of stars
|
|
4
|
+
* @returns Formatted string (e.g., "1.5k" for 1500)
|
|
5
|
+
*/
|
|
6
|
+
export function formatStars(count: number): string {
|
|
7
|
+
if (count >= 1000) {
|
|
8
|
+
return `${(count / 1000).toFixed(1)}k`;
|
|
9
|
+
}
|
|
10
|
+
return count.toString();
|
|
11
|
+
}
|
|
12
|
+
|