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.
Files changed (106) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/README.md +20 -87
  3. package/dist/__tests__/lib/Config.test.d.ts +2 -0
  4. package/dist/__tests__/lib/Config.test.d.ts.map +1 -0
  5. package/dist/__tests__/lib/Config.test.js +281 -0
  6. package/dist/__tests__/lib/Config.test.js.map +1 -0
  7. package/dist/__tests__/lib/EnvironmentSelector.test.d.ts +2 -0
  8. package/dist/__tests__/lib/EnvironmentSelector.test.d.ts.map +1 -0
  9. package/dist/__tests__/lib/EnvironmentSelector.test.js +117 -0
  10. package/dist/__tests__/lib/EnvironmentSelector.test.js.map +1 -0
  11. package/dist/__tests__/lib/PhaseSelector.test.d.ts +2 -0
  12. package/dist/__tests__/lib/PhaseSelector.test.d.ts.map +1 -0
  13. package/dist/__tests__/lib/PhaseSelector.test.js +77 -0
  14. package/dist/__tests__/lib/PhaseSelector.test.js.map +1 -0
  15. package/dist/__tests__/util/env.test.d.ts +2 -0
  16. package/dist/__tests__/util/env.test.d.ts.map +1 -0
  17. package/dist/__tests__/util/env.test.js +166 -0
  18. package/dist/__tests__/util/env.test.js.map +1 -0
  19. package/dist/commands/init.d.ts +2 -2
  20. package/dist/commands/init.d.ts.map +1 -1
  21. package/dist/commands/init.js +54 -73
  22. package/dist/commands/init.js.map +1 -1
  23. package/dist/commands/phase.d.ts.map +1 -1
  24. package/dist/commands/phase.js +1 -5
  25. package/dist/commands/phase.js.map +1 -1
  26. package/dist/lib/Config.d.ts +5 -2
  27. package/dist/lib/Config.d.ts.map +1 -1
  28. package/dist/lib/Config.js +18 -3
  29. package/dist/lib/Config.js.map +1 -1
  30. package/dist/lib/EnvironmentSelector.d.ts +7 -0
  31. package/dist/lib/EnvironmentSelector.d.ts.map +1 -0
  32. package/dist/lib/EnvironmentSelector.js +62 -0
  33. package/dist/lib/EnvironmentSelector.js.map +1 -0
  34. package/dist/lib/PhaseSelector.d.ts +8 -0
  35. package/dist/lib/PhaseSelector.d.ts.map +1 -0
  36. package/dist/lib/PhaseSelector.js +58 -0
  37. package/dist/lib/PhaseSelector.js.map +1 -0
  38. package/dist/lib/TemplateManager.d.ts +5 -5
  39. package/dist/lib/TemplateManager.d.ts.map +1 -1
  40. package/dist/lib/TemplateManager.js +73 -66
  41. package/dist/lib/TemplateManager.js.map +1 -1
  42. package/dist/types.d.ts +9 -2
  43. package/dist/types.d.ts.map +1 -1
  44. package/dist/types.js.map +1 -1
  45. package/dist/util/env.d.ts +11 -0
  46. package/dist/util/env.d.ts.map +1 -0
  47. package/dist/util/env.js +109 -0
  48. package/dist/util/env.js.map +1 -0
  49. package/jest.config.js +22 -0
  50. package/package.json +16 -11
  51. package/templates/commands/capture-knowledge.md +46 -0
  52. package/templates/commands/debug.md +45 -0
  53. package/templates/{env/cursor/commands → commands}/new-requirement.md +1 -1
  54. package/web/.nojekyll +2 -0
  55. package/web/CNAME +1 -0
  56. package/web/README.md +100 -0
  57. package/web/app/favicon.ico +0 -0
  58. package/web/app/globals.css +122 -0
  59. package/web/app/layout.tsx +106 -0
  60. package/web/app/page.tsx +119 -0
  61. package/web/app/roadmap/page.tsx +150 -0
  62. package/web/app/robots.ts +16 -0
  63. package/web/app/sitemap.ts +46 -0
  64. package/web/app/vision/page.tsx +49 -0
  65. package/web/components/Footer.tsx +81 -0
  66. package/web/components/GitHubButton.tsx +49 -0
  67. package/web/components/GitHubStars.tsx +27 -0
  68. package/web/components/Header.tsx +108 -0
  69. package/web/components/MarkdownContent.tsx +35 -0
  70. package/web/components/SkipToContent.tsx +11 -0
  71. package/web/content/pages/vision.md +42 -0
  72. package/web/content/roadmap/1-web.md +9 -0
  73. package/web/content/roadmap/2-integrations.md +7 -0
  74. package/web/content/roadmap/3-cli-enhancements.md +8 -0
  75. package/web/content/roadmap/4-local-memory.md +8 -0
  76. package/web/eslint.config.mjs +18 -0
  77. package/web/lib/GitHubContext.tsx +57 -0
  78. package/web/lib/content/loader.ts +152 -0
  79. package/web/lib/content/types.ts +37 -0
  80. package/web/lib/utils.ts +12 -0
  81. package/web/next.config.ts +11 -0
  82. package/web/package-lock.json +8837 -0
  83. package/web/package.json +34 -0
  84. package/web/postcss.config.mjs +7 -0
  85. package/web/public/file.svg +1 -0
  86. package/web/public/globe.svg +1 -0
  87. package/web/public/next.svg +1 -0
  88. package/web/public/vercel.svg +1 -0
  89. package/web/public/window.svg +1 -0
  90. package/templates/env/claude/CLAUDE.md +0 -52
  91. package/templates/env/claude/commands/code-review.md +0 -81
  92. package/templates/env/claude/commands/execute-plan.md +0 -71
  93. package/templates/env/claude/commands/new-requirement.md +0 -127
  94. package/templates/env/claude/commands/update-planning.md +0 -61
  95. package/templates/env/cursor/commands/check-implementation.md +0 -21
  96. package/templates/env/cursor/commands/review-design.md +0 -11
  97. package/templates/env/cursor/commands/review-requirements.md +0 -9
  98. package/templates/env/cursor/commands/writing-test.md +0 -44
  99. package/templates/env/cursor/rules/ai-devkit.md +0 -51
  100. /package/templates/{env/claude/commands → commands}/check-implementation.md +0 -0
  101. /package/templates/{env/cursor/commands → commands}/code-review.md +0 -0
  102. /package/templates/{env/cursor/commands → commands}/execute-plan.md +0 -0
  103. /package/templates/{env/claude/commands → commands}/review-design.md +0 -0
  104. /package/templates/{env/claude/commands → commands}/review-requirements.md +0 -0
  105. /package/templates/{env/cursor/commands → commands}/update-planning.md +0 -0
  106. /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
+
@@ -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
+
@@ -0,0 +1,11 @@
1
+ import type { NextConfig } from "next";
2
+
3
+ const nextConfig: NextConfig = {
4
+ output: 'export',
5
+ images: {
6
+ unoptimized: true,
7
+ },
8
+ trailingSlash: true,
9
+ };
10
+
11
+ export default nextConfig;