opencode-conductor-cdd-plugin 1.0.0-beta.13

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 (91) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +163 -0
  3. package/README.test.md +51 -0
  4. package/dist/commands/implement.d.ts +1 -0
  5. package/dist/commands/implement.js +30 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +108 -0
  8. package/dist/index.test.d.ts +1 -0
  9. package/dist/index.test.js +122 -0
  10. package/dist/prompts/agent/cdd.md +41 -0
  11. package/dist/prompts/agent/implementer.md +22 -0
  12. package/dist/prompts/agent.md +23 -0
  13. package/dist/prompts/cdd/implement.json +4 -0
  14. package/dist/prompts/cdd/newTrack.json +4 -0
  15. package/dist/prompts/cdd/revert.json +4 -0
  16. package/dist/prompts/cdd/setup.json +4 -0
  17. package/dist/prompts/cdd/setup.test.d.ts +1 -0
  18. package/dist/prompts/cdd/setup.test.js +132 -0
  19. package/dist/prompts/cdd/setup.test.ts +168 -0
  20. package/dist/prompts/cdd/status.json +4 -0
  21. package/dist/prompts/strategies/delegate.md +11 -0
  22. package/dist/prompts/strategies/manual.md +9 -0
  23. package/dist/templates/code_styleguides/c.md +28 -0
  24. package/dist/templates/code_styleguides/cpp.md +46 -0
  25. package/dist/templates/code_styleguides/csharp.md +115 -0
  26. package/dist/templates/code_styleguides/dart.md +238 -0
  27. package/dist/templates/code_styleguides/general.md +23 -0
  28. package/dist/templates/code_styleguides/go.md +48 -0
  29. package/dist/templates/code_styleguides/html-css.md +49 -0
  30. package/dist/templates/code_styleguides/java.md +39 -0
  31. package/dist/templates/code_styleguides/javascript.md +51 -0
  32. package/dist/templates/code_styleguides/julia.md +27 -0
  33. package/dist/templates/code_styleguides/kotlin.md +41 -0
  34. package/dist/templates/code_styleguides/php.md +37 -0
  35. package/dist/templates/code_styleguides/python.md +37 -0
  36. package/dist/templates/code_styleguides/react.md +37 -0
  37. package/dist/templates/code_styleguides/ruby.md +39 -0
  38. package/dist/templates/code_styleguides/rust.md +44 -0
  39. package/dist/templates/code_styleguides/shell.md +35 -0
  40. package/dist/templates/code_styleguides/solidity.md +60 -0
  41. package/dist/templates/code_styleguides/sql.md +39 -0
  42. package/dist/templates/code_styleguides/swift.md +36 -0
  43. package/dist/templates/code_styleguides/typescript.md +43 -0
  44. package/dist/templates/code_styleguides/vue.md +38 -0
  45. package/dist/templates/code_styleguides/zig.md +27 -0
  46. package/dist/templates/workflow.md +336 -0
  47. package/dist/tools/background.d.ts +54 -0
  48. package/dist/tools/background.js +198 -0
  49. package/dist/tools/commands.d.ts +11 -0
  50. package/dist/tools/commands.js +80 -0
  51. package/dist/tools/commands.test.d.ts +1 -0
  52. package/dist/tools/commands.test.js +142 -0
  53. package/dist/tools/delegate.d.ts +3 -0
  54. package/dist/tools/delegate.js +45 -0
  55. package/dist/utils/autogenerateFlow.d.ts +65 -0
  56. package/dist/utils/autogenerateFlow.js +391 -0
  57. package/dist/utils/autogenerateFlow.test.d.ts +1 -0
  58. package/dist/utils/autogenerateFlow.test.js +610 -0
  59. package/dist/utils/bootstrap.d.ts +1 -0
  60. package/dist/utils/bootstrap.js +46 -0
  61. package/dist/utils/commandFactory.d.ts +11 -0
  62. package/dist/utils/commandFactory.js +69 -0
  63. package/dist/utils/commitMessages.d.ts +35 -0
  64. package/dist/utils/commitMessages.js +33 -0
  65. package/dist/utils/commitMessages.test.d.ts +1 -0
  66. package/dist/utils/commitMessages.test.js +79 -0
  67. package/dist/utils/configDetection.d.ts +7 -0
  68. package/dist/utils/configDetection.js +49 -0
  69. package/dist/utils/configDetection.test.d.ts +1 -0
  70. package/dist/utils/configDetection.test.js +119 -0
  71. package/dist/utils/contentGeneration.d.ts +10 -0
  72. package/dist/utils/contentGeneration.js +141 -0
  73. package/dist/utils/contentGeneration.test.d.ts +1 -0
  74. package/dist/utils/contentGeneration.test.js +147 -0
  75. package/dist/utils/contextAnalysis.d.ts +100 -0
  76. package/dist/utils/contextAnalysis.js +308 -0
  77. package/dist/utils/contextAnalysis.test.d.ts +1 -0
  78. package/dist/utils/contextAnalysis.test.js +307 -0
  79. package/dist/utils/gitNotes.d.ts +23 -0
  80. package/dist/utils/gitNotes.js +53 -0
  81. package/dist/utils/gitNotes.test.d.ts +1 -0
  82. package/dist/utils/gitNotes.test.js +105 -0
  83. package/dist/utils/ignoreMatcher.d.ts +9 -0
  84. package/dist/utils/ignoreMatcher.js +77 -0
  85. package/dist/utils/ignoreMatcher.test.d.ts +1 -0
  86. package/dist/utils/ignoreMatcher.test.js +126 -0
  87. package/dist/utils/stateManager.d.ts +10 -0
  88. package/dist/utils/stateManager.js +30 -0
  89. package/package.json +90 -0
  90. package/scripts/convert-legacy.cjs +17 -0
  91. package/scripts/postinstall.cjs +38 -0
@@ -0,0 +1,147 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { generateProductGuide, generateProductGuidelines, generateTechStack, generateWorkflow, } from "./contentGeneration.js";
3
+ describe("Content Generation Module", () => {
4
+ const mockContext = {
5
+ raw: {
6
+ manifests: [
7
+ {
8
+ type: "package.json",
9
+ dependencies: ["react", "typescript", "vitest"],
10
+ devDependencies: ["@types/node"],
11
+ scripts: { test: "vitest", build: "tsc" },
12
+ },
13
+ ],
14
+ docs: [
15
+ {
16
+ filename: "README.md",
17
+ content: "# Test Project\n\nA React TypeScript application for testing workflows",
18
+ },
19
+ ],
20
+ git: {
21
+ commitCount: 50,
22
+ conventionalCommits: 45,
23
+ patterns: ["conventional"],
24
+ warnings: [],
25
+ },
26
+ structure: {
27
+ structure: ["src/", "tests/", "dist/"],
28
+ fileExtensions: [".ts", ".tsx", ".json"],
29
+ warnings: [],
30
+ },
31
+ ignores: {
32
+ patterns: ["node_modules/", "dist/", ".env"],
33
+ },
34
+ cicd: [
35
+ {
36
+ type: "github-actions",
37
+ commands: ["npm test", "npm run build"],
38
+ },
39
+ ],
40
+ },
41
+ insights: {
42
+ techStack: {
43
+ languages: [{ name: "TypeScript", confidence: 1.0, percentage: 100 }],
44
+ frameworks: [{ name: "react", version: "", confidence: 1.0 }],
45
+ databases: [],
46
+ infrastructure: [],
47
+ testing: [{ framework: "vitest", confidence: 1.0 }],
48
+ },
49
+ product: {
50
+ targetUsers: [],
51
+ coreProblems: [],
52
+ keyFeatures: [],
53
+ confidence: 0.0,
54
+ },
55
+ workflow: {
56
+ commitConvention: "conventional",
57
+ testingStrategy: "TDD",
58
+ branchStrategy: "trunk-based",
59
+ confidence: 0.8,
60
+ },
61
+ projectType: "application",
62
+ maturity: "active",
63
+ },
64
+ meta: {
65
+ analyzedAt: new Date().toISOString(),
66
+ analysisTimeMs: 100,
67
+ filesAnalyzed: 2,
68
+ categoriesCompleted: ["manifests", "docs", "git", "structure", "ignores", "cicd"],
69
+ warnings: [],
70
+ },
71
+ };
72
+ describe("generateProductGuide", () => {
73
+ it("should generate product guide from context", () => {
74
+ const result = generateProductGuide(mockContext);
75
+ expect(result.content).toBeTruthy();
76
+ expect(result.content.length).toBeGreaterThan(50);
77
+ expect(result.confidence).toBeGreaterThan(0.5);
78
+ expect(result.confidence).toBeLessThanOrEqual(1.0);
79
+ });
80
+ it("should extract target users from README", () => {
81
+ const result = generateProductGuide(mockContext);
82
+ expect(result.content).toContain("application");
83
+ });
84
+ it("should mention project type in guide", () => {
85
+ const result = generateProductGuide(mockContext);
86
+ expect(result.content.toLowerCase()).toMatch(/application|tool|library/);
87
+ });
88
+ it("should return low confidence when no context available", () => {
89
+ const emptyContext = {
90
+ ...mockContext,
91
+ raw: { ...mockContext.raw, docs: [] },
92
+ insights: { ...mockContext.insights, techStack: { ...mockContext.insights.techStack, frameworks: [] } },
93
+ };
94
+ const result = generateProductGuide(emptyContext);
95
+ expect(result.confidence).toBeLessThan(0.5);
96
+ });
97
+ });
98
+ describe("generateProductGuidelines", () => {
99
+ it("should generate guidelines from context", () => {
100
+ const result = generateProductGuidelines(mockContext);
101
+ expect(result.content).toBeTruthy();
102
+ expect(result.content.length).toBeGreaterThan(30);
103
+ expect(result.confidence).toBeGreaterThan(0);
104
+ });
105
+ it("should infer guidelines from tech stack", () => {
106
+ const result = generateProductGuidelines(mockContext);
107
+ expect(result.content.toLowerCase()).toMatch(/type|component|test/);
108
+ });
109
+ });
110
+ describe("generateTechStack", () => {
111
+ it("should generate tech stack description", () => {
112
+ const result = generateTechStack(mockContext);
113
+ expect(result.content).toBeTruthy();
114
+ expect(result.content).toContain("TypeScript");
115
+ expect(result.content.toLowerCase()).toContain("react");
116
+ expect(result.confidence).toBeGreaterThan(0.7);
117
+ });
118
+ it("should list all detected technologies", () => {
119
+ const result = generateTechStack(mockContext);
120
+ expect(result.content).toContain("vitest");
121
+ });
122
+ it("should format as structured list", () => {
123
+ const result = generateTechStack(mockContext);
124
+ expect(result.content).toMatch(/Language|Framework|Testing/);
125
+ });
126
+ });
127
+ describe("generateWorkflow", () => {
128
+ it("should generate workflow description", () => {
129
+ const result = generateWorkflow(mockContext);
130
+ expect(result.content).toBeTruthy();
131
+ expect(result.content.length).toBeGreaterThan(50);
132
+ expect(result.confidence).toBeGreaterThan(0.5);
133
+ });
134
+ it("should detect conventional commits", () => {
135
+ const result = generateWorkflow(mockContext);
136
+ expect(result.content.toLowerCase()).toContain("conventional");
137
+ });
138
+ it("should mention testing strategy", () => {
139
+ const result = generateWorkflow(mockContext);
140
+ expect(result.content.toLowerCase()).toMatch(/test|tdd/);
141
+ });
142
+ it("should include CI/CD information when available", () => {
143
+ const result = generateWorkflow(mockContext);
144
+ expect(result.content).toContain("CI");
145
+ });
146
+ });
147
+ });
@@ -0,0 +1,100 @@
1
+ export interface ManifestData {
2
+ type: string;
3
+ dependencies: string[];
4
+ devDependencies?: string[];
5
+ scripts?: Record<string, string>;
6
+ }
7
+ export interface DocumentData {
8
+ filename: string;
9
+ content: string;
10
+ }
11
+ export interface GitHistoryData {
12
+ commitCount: number;
13
+ conventionalCommits: number;
14
+ patterns: string[];
15
+ warnings: string[];
16
+ }
17
+ export interface DirectoryStructure {
18
+ structure: string[];
19
+ fileExtensions: string[];
20
+ warnings: string[];
21
+ }
22
+ export interface IgnorePatterns {
23
+ patterns: string[];
24
+ }
25
+ export interface CICDConfig {
26
+ type: string;
27
+ commands: string[];
28
+ }
29
+ export interface ProjectContext {
30
+ raw: {
31
+ manifests: ManifestData[];
32
+ docs: DocumentData[];
33
+ git: GitHistoryData;
34
+ structure: DirectoryStructure;
35
+ ignores: IgnorePatterns;
36
+ cicd: CICDConfig[];
37
+ };
38
+ insights: {
39
+ techStack: {
40
+ languages: Array<{
41
+ name: string;
42
+ confidence: number;
43
+ percentage: number;
44
+ }>;
45
+ frameworks: Array<{
46
+ name: string;
47
+ version: string;
48
+ confidence: number;
49
+ }>;
50
+ databases: Array<{
51
+ type: string;
52
+ confidence: number;
53
+ }>;
54
+ infrastructure: Array<{
55
+ type: string;
56
+ confidence: number;
57
+ }>;
58
+ testing: Array<{
59
+ framework: string;
60
+ confidence: number;
61
+ }>;
62
+ };
63
+ product: {
64
+ targetUsers: string[];
65
+ coreProblems: string[];
66
+ keyFeatures: string[];
67
+ confidence: number;
68
+ };
69
+ workflow: {
70
+ commitConvention: string;
71
+ testingStrategy: string;
72
+ branchStrategy: string;
73
+ confidence: number;
74
+ };
75
+ projectType: "library" | "application" | "tool" | "framework" | "unknown";
76
+ maturity: "early" | "active" | "mature" | "legacy";
77
+ };
78
+ meta: {
79
+ analyzedAt: string;
80
+ analysisTimeMs: number;
81
+ filesAnalyzed: number;
82
+ categoriesCompleted: string[];
83
+ warnings: string[];
84
+ };
85
+ }
86
+ export declare function parseManifests(projectPath: string): Promise<{
87
+ manifests: ManifestData[];
88
+ warnings: string[];
89
+ }>;
90
+ export declare function analyzeDocs(projectPath: string): Promise<{
91
+ docs: DocumentData[];
92
+ warnings: string[];
93
+ }>;
94
+ export declare function analyzeGitHistory(projectPath: string): Promise<GitHistoryData>;
95
+ export declare function analyzeCodeStructure(projectPath: string, currentDepth?: number, maxDepth?: number): Promise<DirectoryStructure>;
96
+ export declare function parseIgnoreFiles(projectPath: string): Promise<IgnorePatterns>;
97
+ export declare function parseCICDConfigs(projectPath: string): Promise<{
98
+ configs: CICDConfig[];
99
+ }>;
100
+ export declare function analyzeProjectContext(projectPath: string): Promise<ProjectContext>;
@@ -0,0 +1,308 @@
1
+ import { readFile, readdir, stat } from "fs/promises";
2
+ import { execSync } from "child_process";
3
+ import { join } from "path";
4
+ export async function parseManifests(projectPath) {
5
+ const manifests = [];
6
+ const warnings = [];
7
+ try {
8
+ const files = await readdir(projectPath);
9
+ if (files.includes("package.json")) {
10
+ try {
11
+ const content = await readFile(join(projectPath, "package.json"), "utf-8");
12
+ const pkg = JSON.parse(content);
13
+ manifests.push({
14
+ type: "package.json",
15
+ dependencies: Object.keys(pkg.dependencies || {}),
16
+ devDependencies: Object.keys(pkg.devDependencies || {}),
17
+ scripts: pkg.scripts || {},
18
+ });
19
+ }
20
+ catch (error) {
21
+ warnings.push(`Failed to read package.json: ${error.message}`);
22
+ }
23
+ }
24
+ if (files.includes("requirements.txt")) {
25
+ try {
26
+ const content = await readFile(join(projectPath, "requirements.txt"), "utf-8");
27
+ const dependencies = content
28
+ .split("\n")
29
+ .filter((line) => line.trim() && !line.startsWith("#"))
30
+ .map((line) => line.split(/[=<>]/)[0].trim());
31
+ manifests.push({
32
+ type: "requirements.txt",
33
+ dependencies,
34
+ });
35
+ }
36
+ catch (error) {
37
+ warnings.push(`Failed to read requirements.txt: ${error.message}`);
38
+ }
39
+ }
40
+ if (files.includes("Cargo.toml")) {
41
+ try {
42
+ const content = await readFile(join(projectPath, "Cargo.toml"), "utf-8");
43
+ const depSection = content.match(/\[dependencies\]([\s\S]*?)(\[|$)/)?.[1] || "";
44
+ const dependencies = depSection
45
+ .split("\n")
46
+ .filter((line) => line.trim() && !line.startsWith("#"))
47
+ .map((line) => line.split("=")[0].trim())
48
+ .filter((dep) => dep.length > 0);
49
+ manifests.push({
50
+ type: "Cargo.toml",
51
+ dependencies,
52
+ });
53
+ }
54
+ catch (error) {
55
+ warnings.push(`Failed to read Cargo.toml: ${error.message}`);
56
+ }
57
+ }
58
+ if (manifests.length === 0) {
59
+ warnings.push("No manifest files found");
60
+ }
61
+ }
62
+ catch (error) {
63
+ warnings.push(`Failed to read project directory: ${error.message}`);
64
+ }
65
+ return { manifests, warnings };
66
+ }
67
+ export async function analyzeDocs(projectPath) {
68
+ const docs = [];
69
+ const warnings = [];
70
+ try {
71
+ const files = await readdir(projectPath);
72
+ if (files.includes("README.md")) {
73
+ try {
74
+ const content = await readFile(join(projectPath, "README.md"), "utf-8");
75
+ const fileSize = Buffer.byteLength(content, "utf-8");
76
+ if (fileSize > 10 * 1024) {
77
+ warnings.push("Large file detected, using sampling");
78
+ const lines = content.split("\n");
79
+ const totalLines = lines.length;
80
+ if (totalLines > 200) {
81
+ const sampled = [
82
+ ...lines.slice(0, 100),
83
+ `\n... (${totalLines - 200} lines omitted) ...\n`,
84
+ ...lines.slice(-100),
85
+ ].join("\n");
86
+ docs.push({
87
+ filename: "README.md",
88
+ content: sampled,
89
+ });
90
+ }
91
+ else {
92
+ docs.push({
93
+ filename: "README.md",
94
+ content,
95
+ });
96
+ }
97
+ }
98
+ else {
99
+ docs.push({
100
+ filename: "README.md",
101
+ content,
102
+ });
103
+ }
104
+ }
105
+ catch (error) {
106
+ warnings.push(`Failed to read README.md: ${error.message}`);
107
+ }
108
+ }
109
+ if (docs.length === 0) {
110
+ warnings.push("No README found");
111
+ }
112
+ }
113
+ catch (error) {
114
+ warnings.push(`Failed to read docs: ${error.message}`);
115
+ }
116
+ return { docs, warnings };
117
+ }
118
+ export async function analyzeGitHistory(projectPath) {
119
+ const warnings = [];
120
+ try {
121
+ const output = execSync('git log --oneline --no-merges -n 100', {
122
+ cwd: projectPath,
123
+ encoding: "utf-8",
124
+ });
125
+ const commits = output.trim().split("\n").filter((line) => line.length > 0);
126
+ const conventionalPattern = /^[a-f0-9]+ (feat|fix|chore|docs|style|refactor|test|perf|ci|build)(\([^)]+\))?:/;
127
+ const conventionalCommits = commits.filter((commit) => conventionalPattern.test(commit)).length;
128
+ const patterns = [];
129
+ if (conventionalCommits > commits.length * 0.7) {
130
+ patterns.push("conventional");
131
+ }
132
+ return {
133
+ commitCount: commits.length,
134
+ conventionalCommits,
135
+ patterns,
136
+ warnings,
137
+ };
138
+ }
139
+ catch (error) {
140
+ warnings.push(`Not a git repository: ${error.message}`);
141
+ return {
142
+ commitCount: 0,
143
+ conventionalCommits: 0,
144
+ patterns: [],
145
+ warnings,
146
+ };
147
+ }
148
+ }
149
+ export async function analyzeCodeStructure(projectPath, currentDepth = 0, maxDepth = 5) {
150
+ const structure = [];
151
+ const fileExtensions = new Set();
152
+ const warnings = [];
153
+ if (currentDepth >= maxDepth) {
154
+ return { structure, fileExtensions: Array.from(fileExtensions), warnings };
155
+ }
156
+ try {
157
+ const files = await readdir(projectPath);
158
+ for (const file of files) {
159
+ if (file.startsWith(".") || file === "node_modules")
160
+ continue;
161
+ const fullPath = join(projectPath, file);
162
+ try {
163
+ const stats = await stat(fullPath);
164
+ if (stats.isDirectory()) {
165
+ structure.push(`${file}/`);
166
+ }
167
+ else {
168
+ const ext = file.substring(file.lastIndexOf("."));
169
+ if (ext) {
170
+ fileExtensions.add(ext);
171
+ }
172
+ }
173
+ }
174
+ catch (error) {
175
+ warnings.push(`Failed to stat ${file}: ${error.message}`);
176
+ }
177
+ }
178
+ }
179
+ catch (error) {
180
+ warnings.push(`Failed to read directory: ${error.message}`);
181
+ }
182
+ return { structure, fileExtensions: Array.from(fileExtensions), warnings };
183
+ }
184
+ export async function parseIgnoreFiles(projectPath) {
185
+ const patterns = [];
186
+ try {
187
+ const files = await readdir(projectPath);
188
+ if (files.includes(".gitignore")) {
189
+ try {
190
+ const content = await readFile(join(projectPath, ".gitignore"), "utf-8");
191
+ const lines = content
192
+ .split("\n")
193
+ .filter((line) => line.trim() && !line.startsWith("#"));
194
+ patterns.push(...lines);
195
+ }
196
+ catch (error) {
197
+ { }
198
+ }
199
+ }
200
+ }
201
+ catch (error) {
202
+ { }
203
+ }
204
+ return { patterns };
205
+ }
206
+ export async function parseCICDConfigs(projectPath) {
207
+ const configs = [];
208
+ try {
209
+ const files = await readdir(projectPath);
210
+ if (files.includes(".github")) {
211
+ try {
212
+ const workflowsPath = join(projectPath, ".github", "workflows");
213
+ const workflowFiles = await readdir(workflowsPath);
214
+ for (const file of workflowFiles) {
215
+ if (file.endsWith(".yml") || file.endsWith(".yaml")) {
216
+ const content = await readFile(join(workflowsPath, file), "utf-8");
217
+ const commands = [];
218
+ const runMatches = content.matchAll(/run:\s*(.+)/g);
219
+ for (const match of runMatches) {
220
+ commands.push(match[1].trim());
221
+ }
222
+ configs.push({
223
+ type: "github-actions",
224
+ commands,
225
+ });
226
+ }
227
+ }
228
+ }
229
+ catch (error) {
230
+ { }
231
+ }
232
+ }
233
+ }
234
+ catch (error) {
235
+ { }
236
+ }
237
+ return { configs };
238
+ }
239
+ export async function analyzeProjectContext(projectPath) {
240
+ const startTime = Date.now();
241
+ const warnings = [];
242
+ const categoriesCompleted = [];
243
+ const { manifests, warnings: manifestWarnings } = await parseManifests(projectPath);
244
+ warnings.push(...manifestWarnings);
245
+ categoriesCompleted.push("manifests");
246
+ const { docs, warnings: docWarnings } = await analyzeDocs(projectPath);
247
+ warnings.push(...docWarnings);
248
+ categoriesCompleted.push("docs");
249
+ const git = await analyzeGitHistory(projectPath);
250
+ warnings.push(...git.warnings);
251
+ categoriesCompleted.push("git");
252
+ const structure = await analyzeCodeStructure(projectPath);
253
+ warnings.push(...structure.warnings);
254
+ categoriesCompleted.push("structure");
255
+ const ignores = await parseIgnoreFiles(projectPath);
256
+ categoriesCompleted.push("ignores");
257
+ const { configs: cicd } = await parseCICDConfigs(projectPath);
258
+ categoriesCompleted.push("cicd");
259
+ const frameworks = [];
260
+ for (const manifest of manifests) {
261
+ if (manifest.type === "package.json") {
262
+ if (manifest.dependencies.includes("react")) {
263
+ frameworks.push({ name: "react", version: "", confidence: 1.0 });
264
+ }
265
+ }
266
+ }
267
+ const analysisTime = Date.now() - startTime;
268
+ return {
269
+ raw: {
270
+ manifests,
271
+ docs,
272
+ git,
273
+ structure,
274
+ ignores,
275
+ cicd,
276
+ },
277
+ insights: {
278
+ techStack: {
279
+ languages: [],
280
+ frameworks,
281
+ databases: [],
282
+ infrastructure: [],
283
+ testing: [],
284
+ },
285
+ product: {
286
+ targetUsers: [],
287
+ coreProblems: [],
288
+ keyFeatures: [],
289
+ confidence: 0.0,
290
+ },
291
+ workflow: {
292
+ commitConvention: git.patterns.includes("conventional") ? "conventional" : "none",
293
+ testingStrategy: "unknown",
294
+ branchStrategy: "unknown",
295
+ confidence: 0.5,
296
+ },
297
+ projectType: "unknown",
298
+ maturity: "active",
299
+ },
300
+ meta: {
301
+ analyzedAt: new Date().toISOString(),
302
+ analysisTimeMs: analysisTime,
303
+ filesAnalyzed: manifests.length + docs.length,
304
+ categoriesCompleted,
305
+ warnings,
306
+ },
307
+ };
308
+ }
@@ -0,0 +1 @@
1
+ export {};