@googlarz/agents-sync 1.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/LICENSE +21 -0
- package/README.md +507 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +267 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/loader.d.ts +9 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +55 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +69 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +33 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/derivers/aider.d.ts +19 -0
- package/dist/derivers/aider.d.ts.map +1 -0
- package/dist/derivers/aider.js +117 -0
- package/dist/derivers/aider.js.map +1 -0
- package/dist/derivers/claude.d.ts +19 -0
- package/dist/derivers/claude.d.ts.map +1 -0
- package/dist/derivers/claude.js +93 -0
- package/dist/derivers/claude.js.map +1 -0
- package/dist/derivers/cline.d.ts +17 -0
- package/dist/derivers/cline.d.ts.map +1 -0
- package/dist/derivers/cline.js +92 -0
- package/dist/derivers/cline.js.map +1 -0
- package/dist/derivers/copilot.d.ts +16 -0
- package/dist/derivers/copilot.d.ts.map +1 -0
- package/dist/derivers/copilot.js +162 -0
- package/dist/derivers/copilot.js.map +1 -0
- package/dist/derivers/cursor.d.ts +16 -0
- package/dist/derivers/cursor.d.ts.map +1 -0
- package/dist/derivers/cursor.js +121 -0
- package/dist/derivers/cursor.js.map +1 -0
- package/dist/derivers/gemini.d.ts +19 -0
- package/dist/derivers/gemini.d.ts.map +1 -0
- package/dist/derivers/gemini.js +33 -0
- package/dist/derivers/gemini.js.map +1 -0
- package/dist/derivers/index.d.ts +33 -0
- package/dist/derivers/index.d.ts.map +1 -0
- package/dist/derivers/index.js +134 -0
- package/dist/derivers/index.js.map +1 -0
- package/dist/derivers/merger.d.ts +36 -0
- package/dist/derivers/merger.d.ts.map +1 -0
- package/dist/derivers/merger.js +83 -0
- package/dist/derivers/merger.js.map +1 -0
- package/dist/derivers/roo.d.ts +18 -0
- package/dist/derivers/roo.d.ts.map +1 -0
- package/dist/derivers/roo.js +92 -0
- package/dist/derivers/roo.js.map +1 -0
- package/dist/derivers/windsurf.d.ts +16 -0
- package/dist/derivers/windsurf.d.ts.map +1 -0
- package/dist/derivers/windsurf.js +91 -0
- package/dist/derivers/windsurf.js.map +1 -0
- package/dist/extractor/extractor.d.ts +4 -0
- package/dist/extractor/extractor.d.ts.map +1 -0
- package/dist/extractor/extractor.js +125 -0
- package/dist/extractor/extractor.js.map +1 -0
- package/dist/extractor/schema.d.ts +187 -0
- package/dist/extractor/schema.d.ts.map +1 -0
- package/dist/extractor/schema.js +44 -0
- package/dist/extractor/schema.js.map +1 -0
- package/dist/generator/agents-md.d.ts +6 -0
- package/dist/generator/agents-md.d.ts.map +1 -0
- package/dist/generator/agents-md.js +135 -0
- package/dist/generator/agents-md.js.map +1 -0
- package/dist/generator/validator.d.ts +7 -0
- package/dist/generator/validator.d.ts.map +1 -0
- package/dist/generator/validator.js +67 -0
- package/dist/generator/validator.js.map +1 -0
- package/dist/lib/claude-client.d.ts +11 -0
- package/dist/lib/claude-client.d.ts.map +1 -0
- package/dist/lib/claude-client.js +74 -0
- package/dist/lib/claude-client.js.map +1 -0
- package/dist/lib/errors.d.ts +10 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +27 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/file-utils.d.ts +7 -0
- package/dist/lib/file-utils.d.ts.map +1 -0
- package/dist/lib/file-utils.js +56 -0
- package/dist/lib/file-utils.js.map +1 -0
- package/dist/lib/token-estimate.d.ts +7 -0
- package/dist/lib/token-estimate.d.ts.map +1 -0
- package/dist/lib/token-estimate.js +15 -0
- package/dist/lib/token-estimate.js.map +1 -0
- package/dist/scanner/codegraph.d.ts +13 -0
- package/dist/scanner/codegraph.d.ts.map +1 -0
- package/dist/scanner/codegraph.js +65 -0
- package/dist/scanner/codegraph.js.map +1 -0
- package/dist/scanner/docs.d.ts +13 -0
- package/dist/scanner/docs.d.ts.map +1 -0
- package/dist/scanner/docs.js +63 -0
- package/dist/scanner/docs.js.map +1 -0
- package/dist/scanner/gotchas.d.ts +8 -0
- package/dist/scanner/gotchas.d.ts.map +1 -0
- package/dist/scanner/gotchas.js +107 -0
- package/dist/scanner/gotchas.js.map +1 -0
- package/dist/scanner/index.d.ts +26 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +95 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/manifest.d.ts +13 -0
- package/dist/scanner/manifest.d.ts.map +1 -0
- package/dist/scanner/manifest.js +285 -0
- package/dist/scanner/manifest.js.map +1 -0
- package/dist/scanner/mcp.d.ts +12 -0
- package/dist/scanner/mcp.d.ts.map +1 -0
- package/dist/scanner/mcp.js +96 -0
- package/dist/scanner/mcp.js.map +1 -0
- package/dist/scanner/repomix.d.ts +11 -0
- package/dist/scanner/repomix.d.ts.map +1 -0
- package/dist/scanner/repomix.js +87 -0
- package/dist/scanner/repomix.js.map +1 -0
- package/dist/scanner/skills.d.ts +18 -0
- package/dist/scanner/skills.d.ts.map +1 -0
- package/dist/scanner/skills.js +100 -0
- package/dist/scanner/skills.js.map +1 -0
- package/dist/scanner/source.d.ts +13 -0
- package/dist/scanner/source.d.ts.map +1 -0
- package/dist/scanner/source.js +157 -0
- package/dist/scanner/source.js.map +1 -0
- package/dist/scanner/structure.d.ts +10 -0
- package/dist/scanner/structure.d.ts.map +1 -0
- package/dist/scanner/structure.js +168 -0
- package/dist/scanner/structure.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +245 -0
- package/dist/server.js.map +1 -0
- package/dist/snapshot/drift.d.ts +28 -0
- package/dist/snapshot/drift.d.ts.map +1 -0
- package/dist/snapshot/drift.js +205 -0
- package/dist/snapshot/drift.js.map +1 -0
- package/dist/snapshot/schema.d.ts +94 -0
- package/dist/snapshot/schema.d.ts.map +1 -0
- package/dist/snapshot/schema.js +24 -0
- package/dist/snapshot/schema.js.map +1 -0
- package/dist/snapshot/writer.d.ts +17 -0
- package/dist/snapshot/writer.d.ts.map +1 -0
- package/dist/snapshot/writer.js +44 -0
- package/dist/snapshot/writer.js.map +1 -0
- package/dist/tools/drift.d.ts +15 -0
- package/dist/tools/drift.d.ts.map +1 -0
- package/dist/tools/drift.js +51 -0
- package/dist/tools/drift.js.map +1 -0
- package/dist/tools/export.d.ts +14 -0
- package/dist/tools/export.d.ts.map +1 -0
- package/dist/tools/export.js +53 -0
- package/dist/tools/export.js.map +1 -0
- package/dist/tools/init.d.ts +28 -0
- package/dist/tools/init.d.ts.map +1 -0
- package/dist/tools/init.js +103 -0
- package/dist/tools/init.js.map +1 -0
- package/dist/tools/lint.d.ts +24 -0
- package/dist/tools/lint.d.ts.map +1 -0
- package/dist/tools/lint.js +213 -0
- package/dist/tools/lint.js.map +1 -0
- package/dist/tools/scan-report.d.ts +14 -0
- package/dist/tools/scan-report.d.ts.map +1 -0
- package/dist/tools/scan-report.js +136 -0
- package/dist/tools/scan-report.js.map +1 -0
- package/dist/tools/status.d.ts +18 -0
- package/dist/tools/status.d.ts.map +1 -0
- package/dist/tools/status.js +38 -0
- package/dist/tools/status.js.map +1 -0
- package/dist/tools/sync.d.ts +22 -0
- package/dist/tools/sync.d.ts.map +1 -0
- package/dist/tools/sync.js +123 -0
- package/dist/tools/sync.js.map +1 -0
- package/dist/tools/validate.d.ts +22 -0
- package/dist/tools/validate.d.ts.map +1 -0
- package/dist/tools/validate.js +97 -0
- package/dist/tools/validate.js.map +1 -0
- package/docs/agents-md-spec.md +233 -0
- package/docs/examples/.clinerules +29 -0
- package/docs/examples/.cursorrules +19 -0
- package/docs/examples/.windsurfrules +14 -0
- package/docs/examples/AGENTS.md +97 -0
- package/docs/examples/CLAUDE.md +88 -0
- package/docs/examples/GEMINI.md +61 -0
- package/docs/examples/copilot-instructions.md +24 -0
- package/docs/github-action.yml +89 -0
- package/package.json +63 -0
- package/scripts/demo.sh +138 -0
- package/skill/SKILL.md +158 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { callClaude } from "../lib/claude-client.js";
|
|
2
|
+
import { AgentsSyncError } from "../lib/errors.js";
|
|
3
|
+
import { ProjectMetadataSchema } from "./schema.js";
|
|
4
|
+
import { formatCodegraphContext } from "../scanner/codegraph.js";
|
|
5
|
+
const SYSTEM_PROMPT = `You are a code analyst. Your job is to extract factual information about a software project from the files provided.
|
|
6
|
+
|
|
7
|
+
Rules:
|
|
8
|
+
- Extract ONLY concrete facts you can observe in the provided files
|
|
9
|
+
- NEVER hallucinate framework names, directories, or conventions you cannot see
|
|
10
|
+
- If you are not certain about a field, omit it entirely
|
|
11
|
+
- Conventions must be specific: "kebab-case filenames" not "follow best practices"
|
|
12
|
+
- Gotchas must include the consequence: "Do X or Y will happen"
|
|
13
|
+
- Return ONLY valid JSON matching the schema — no markdown, no explanation
|
|
14
|
+
|
|
15
|
+
Schema:
|
|
16
|
+
{
|
|
17
|
+
"project": { "name", "description", "language", "framework?", "version?" },
|
|
18
|
+
"stack": { "runtime?", "database?", "auth?", "testing?", "deploy?", "other": [] },
|
|
19
|
+
"architecture": { "style?", "keyDirs": {}, "entryPoints": [] },
|
|
20
|
+
"conventions": [],
|
|
21
|
+
"gotchas": [],
|
|
22
|
+
"boundaries": { "alwaysDo": [], "askFirst": [], "never": [] },
|
|
23
|
+
"testing": { "framework?", "command?", "location?", "coverageCommand?" },
|
|
24
|
+
"deployment": { "target?", "command?", "envFile?", "notes": [] }
|
|
25
|
+
}`;
|
|
26
|
+
export async function extractMetadata(corpus) {
|
|
27
|
+
const userPrompt = buildPrompt(corpus);
|
|
28
|
+
for (let attempt = 1; attempt <= 2; attempt++) {
|
|
29
|
+
const { content } = await callClaude(SYSTEM_PROMPT, userPrompt, 2048);
|
|
30
|
+
try {
|
|
31
|
+
const raw = extractJson(content);
|
|
32
|
+
return ProjectMetadataSchema.parse(raw);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
if (attempt === 2) {
|
|
36
|
+
throw new AgentsSyncError("EXTRACTION_FAILED", "Failed to extract valid project metadata after 2 attempts.", "Run with AGENTS_SYNC_DEBUG=1 to see Claude's raw output.");
|
|
37
|
+
}
|
|
38
|
+
// Retry with correction hint appended to next call
|
|
39
|
+
const retryPrompt = `${userPrompt}\n\nYour previous output was not valid JSON. Output ONLY the JSON object, no other text.`;
|
|
40
|
+
const { content: retryContent } = await callClaude(SYSTEM_PROMPT, retryPrompt, 2048);
|
|
41
|
+
try {
|
|
42
|
+
const raw = extractJson(retryContent);
|
|
43
|
+
return ProjectMetadataSchema.parse(raw);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
throw new AgentsSyncError("EXTRACTION_FAILED", "Failed to extract valid project metadata after 2 attempts.", "Run with AGENTS_SYNC_DEBUG=1 to see Claude's raw output.");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// TypeScript requires this but it's unreachable
|
|
51
|
+
throw new AgentsSyncError("EXTRACTION_FAILED", "Unexpected extraction failure.");
|
|
52
|
+
}
|
|
53
|
+
function extractJson(text) {
|
|
54
|
+
// Strip markdown code fences if present
|
|
55
|
+
const stripped = text.replace(/^```(?:json)?\n?/m, "").replace(/\n?```$/m, "").trim();
|
|
56
|
+
return JSON.parse(stripped);
|
|
57
|
+
}
|
|
58
|
+
function buildPrompt(corpus) {
|
|
59
|
+
const sections = [];
|
|
60
|
+
sections.push("=== MANIFEST / DEPENDENCIES ===");
|
|
61
|
+
sections.push(`Language: ${corpus.manifest.language}`);
|
|
62
|
+
if (corpus.manifest.framework)
|
|
63
|
+
sections.push(`Detected framework: ${corpus.manifest.framework}`);
|
|
64
|
+
if (corpus.manifest.runtime)
|
|
65
|
+
sections.push(`Runtime: ${corpus.manifest.runtime}`);
|
|
66
|
+
if (corpus.manifest.projectName)
|
|
67
|
+
sections.push(`Project name: ${corpus.manifest.projectName}`);
|
|
68
|
+
sections.push(`Dependencies (${corpus.manifest.dependencies.length}): ${corpus.manifest.dependencies.slice(0, 25).join(", ")}`);
|
|
69
|
+
if (corpus.manifest.devDependencies.length > 0) {
|
|
70
|
+
sections.push(`Dev deps: ${corpus.manifest.devDependencies.slice(0, 15).join(", ")}`);
|
|
71
|
+
}
|
|
72
|
+
if (Object.keys(corpus.manifest.scripts).length > 0) {
|
|
73
|
+
sections.push(`Scripts: ${JSON.stringify(corpus.manifest.scripts)}`);
|
|
74
|
+
}
|
|
75
|
+
sections.push("\n=== PROJECT STRUCTURE ===");
|
|
76
|
+
sections.push(`Top-level dirs: ${corpus.structure.topLevelDirs.join(", ")}`);
|
|
77
|
+
sections.push(`Entry points: ${corpus.structure.entryPoints.join(", ") || "none detected"}`);
|
|
78
|
+
sections.push(`Test dirs: ${corpus.structure.testDirs.join(", ") || "none detected"}`);
|
|
79
|
+
sections.push(`Naming convention: ${corpus.structure.namingConvention}`);
|
|
80
|
+
sections.push(`Total files: ~${corpus.structure.totalFileCount}`);
|
|
81
|
+
sections.push(`\nDirectory tree:\n${corpus.structure.tree}`);
|
|
82
|
+
if (corpus.source.files.length > 0) {
|
|
83
|
+
sections.push("\n=== SAMPLED SOURCE FILES ===");
|
|
84
|
+
sections.push(`Import style: ${corpus.source.importStyle}`);
|
|
85
|
+
if (corpus.source.detectedPatterns.length > 0) {
|
|
86
|
+
sections.push(`Detected patterns: ${corpus.source.detectedPatterns.join(", ")}`);
|
|
87
|
+
}
|
|
88
|
+
for (const f of corpus.source.files.slice(0, 10)) {
|
|
89
|
+
sections.push(`\n--- ${f.path} ---`);
|
|
90
|
+
sections.push(f.content.slice(0, 800));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (corpus.docs.readme) {
|
|
94
|
+
sections.push("\n=== README ===");
|
|
95
|
+
sections.push(corpus.docs.readme.slice(0, 1500));
|
|
96
|
+
}
|
|
97
|
+
if (corpus.docs.contributing) {
|
|
98
|
+
sections.push("\n=== CONTRIBUTING ===");
|
|
99
|
+
sections.push(corpus.docs.contributing.slice(0, 800));
|
|
100
|
+
}
|
|
101
|
+
if (corpus.docs.existingAgentsMd) {
|
|
102
|
+
sections.push("\n=== EXISTING AGENTS.MD (use as baseline) ===");
|
|
103
|
+
sections.push(corpus.docs.existingAgentsMd);
|
|
104
|
+
}
|
|
105
|
+
if (corpus.docs.existingClaudeMd) {
|
|
106
|
+
sections.push("\n=== EXISTING CLAUDE.MD (extract unique conventions) ===");
|
|
107
|
+
sections.push(corpus.docs.existingClaudeMd.slice(0, 1000));
|
|
108
|
+
}
|
|
109
|
+
if (corpus.gotchas.length > 0) {
|
|
110
|
+
sections.push("\n=== GOTCHAS FOUND IN SOURCE (TODO/FIXME/HACK comments) ===");
|
|
111
|
+
for (const g of corpus.gotchas) {
|
|
112
|
+
sections.push(`${g.type} in ${g.file}:${g.line} — ${g.comment}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (corpus.codegraph?.available) {
|
|
116
|
+
const cgContext = formatCodegraphContext(corpus.codegraph);
|
|
117
|
+
if (cgContext) {
|
|
118
|
+
sections.push("\n=== CODE GRAPH (structural analysis) ===");
|
|
119
|
+
sections.push(cgContext);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
sections.push("\nNow extract the project metadata as JSON:");
|
|
123
|
+
return sections.join("\n");
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractor.js","sourceRoot":"","sources":["../../src/extractor/extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const ProjectMetadataSchema: z.ZodObject<{
|
|
3
|
+
project: z.ZodObject<{
|
|
4
|
+
name: z.ZodString;
|
|
5
|
+
description: z.ZodString;
|
|
6
|
+
language: z.ZodString;
|
|
7
|
+
framework: z.ZodOptional<z.ZodString>;
|
|
8
|
+
version: z.ZodOptional<z.ZodString>;
|
|
9
|
+
}, "strip", z.ZodTypeAny, {
|
|
10
|
+
name: string;
|
|
11
|
+
language: string;
|
|
12
|
+
description: string;
|
|
13
|
+
version?: string | undefined;
|
|
14
|
+
framework?: string | undefined;
|
|
15
|
+
}, {
|
|
16
|
+
name: string;
|
|
17
|
+
language: string;
|
|
18
|
+
description: string;
|
|
19
|
+
version?: string | undefined;
|
|
20
|
+
framework?: string | undefined;
|
|
21
|
+
}>;
|
|
22
|
+
stack: z.ZodObject<{
|
|
23
|
+
runtime: z.ZodOptional<z.ZodString>;
|
|
24
|
+
database: z.ZodOptional<z.ZodString>;
|
|
25
|
+
auth: z.ZodOptional<z.ZodString>;
|
|
26
|
+
testing: z.ZodOptional<z.ZodString>;
|
|
27
|
+
deploy: z.ZodOptional<z.ZodString>;
|
|
28
|
+
other: z.ZodArray<z.ZodString, "many">;
|
|
29
|
+
}, "strip", z.ZodTypeAny, {
|
|
30
|
+
other: string[];
|
|
31
|
+
runtime?: string | undefined;
|
|
32
|
+
database?: string | undefined;
|
|
33
|
+
auth?: string | undefined;
|
|
34
|
+
testing?: string | undefined;
|
|
35
|
+
deploy?: string | undefined;
|
|
36
|
+
}, {
|
|
37
|
+
other: string[];
|
|
38
|
+
runtime?: string | undefined;
|
|
39
|
+
database?: string | undefined;
|
|
40
|
+
auth?: string | undefined;
|
|
41
|
+
testing?: string | undefined;
|
|
42
|
+
deploy?: string | undefined;
|
|
43
|
+
}>;
|
|
44
|
+
architecture: z.ZodObject<{
|
|
45
|
+
style: z.ZodOptional<z.ZodString>;
|
|
46
|
+
keyDirs: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
47
|
+
entryPoints: z.ZodArray<z.ZodString, "many">;
|
|
48
|
+
}, "strip", z.ZodTypeAny, {
|
|
49
|
+
entryPoints: string[];
|
|
50
|
+
keyDirs: Record<string, string>;
|
|
51
|
+
style?: string | undefined;
|
|
52
|
+
}, {
|
|
53
|
+
entryPoints: string[];
|
|
54
|
+
keyDirs: Record<string, string>;
|
|
55
|
+
style?: string | undefined;
|
|
56
|
+
}>;
|
|
57
|
+
conventions: z.ZodArray<z.ZodString, "many">;
|
|
58
|
+
gotchas: z.ZodArray<z.ZodString, "many">;
|
|
59
|
+
boundaries: z.ZodObject<{
|
|
60
|
+
alwaysDo: z.ZodArray<z.ZodString, "many">;
|
|
61
|
+
askFirst: z.ZodArray<z.ZodString, "many">;
|
|
62
|
+
never: z.ZodArray<z.ZodString, "many">;
|
|
63
|
+
}, "strip", z.ZodTypeAny, {
|
|
64
|
+
never: string[];
|
|
65
|
+
alwaysDo: string[];
|
|
66
|
+
askFirst: string[];
|
|
67
|
+
}, {
|
|
68
|
+
never: string[];
|
|
69
|
+
alwaysDo: string[];
|
|
70
|
+
askFirst: string[];
|
|
71
|
+
}>;
|
|
72
|
+
testing: z.ZodObject<{
|
|
73
|
+
framework: z.ZodOptional<z.ZodString>;
|
|
74
|
+
command: z.ZodOptional<z.ZodString>;
|
|
75
|
+
location: z.ZodOptional<z.ZodString>;
|
|
76
|
+
coverageCommand: z.ZodOptional<z.ZodString>;
|
|
77
|
+
}, "strip", z.ZodTypeAny, {
|
|
78
|
+
framework?: string | undefined;
|
|
79
|
+
command?: string | undefined;
|
|
80
|
+
location?: string | undefined;
|
|
81
|
+
coverageCommand?: string | undefined;
|
|
82
|
+
}, {
|
|
83
|
+
framework?: string | undefined;
|
|
84
|
+
command?: string | undefined;
|
|
85
|
+
location?: string | undefined;
|
|
86
|
+
coverageCommand?: string | undefined;
|
|
87
|
+
}>;
|
|
88
|
+
deployment: z.ZodObject<{
|
|
89
|
+
target: z.ZodOptional<z.ZodString>;
|
|
90
|
+
command: z.ZodOptional<z.ZodString>;
|
|
91
|
+
envFile: z.ZodOptional<z.ZodString>;
|
|
92
|
+
notes: z.ZodArray<z.ZodString, "many">;
|
|
93
|
+
}, "strip", z.ZodTypeAny, {
|
|
94
|
+
notes: string[];
|
|
95
|
+
command?: string | undefined;
|
|
96
|
+
target?: string | undefined;
|
|
97
|
+
envFile?: string | undefined;
|
|
98
|
+
}, {
|
|
99
|
+
notes: string[];
|
|
100
|
+
command?: string | undefined;
|
|
101
|
+
target?: string | undefined;
|
|
102
|
+
envFile?: string | undefined;
|
|
103
|
+
}>;
|
|
104
|
+
}, "strip", z.ZodTypeAny, {
|
|
105
|
+
architecture: {
|
|
106
|
+
entryPoints: string[];
|
|
107
|
+
keyDirs: Record<string, string>;
|
|
108
|
+
style?: string | undefined;
|
|
109
|
+
};
|
|
110
|
+
gotchas: string[];
|
|
111
|
+
project: {
|
|
112
|
+
name: string;
|
|
113
|
+
language: string;
|
|
114
|
+
description: string;
|
|
115
|
+
version?: string | undefined;
|
|
116
|
+
framework?: string | undefined;
|
|
117
|
+
};
|
|
118
|
+
stack: {
|
|
119
|
+
other: string[];
|
|
120
|
+
runtime?: string | undefined;
|
|
121
|
+
database?: string | undefined;
|
|
122
|
+
auth?: string | undefined;
|
|
123
|
+
testing?: string | undefined;
|
|
124
|
+
deploy?: string | undefined;
|
|
125
|
+
};
|
|
126
|
+
testing: {
|
|
127
|
+
framework?: string | undefined;
|
|
128
|
+
command?: string | undefined;
|
|
129
|
+
location?: string | undefined;
|
|
130
|
+
coverageCommand?: string | undefined;
|
|
131
|
+
};
|
|
132
|
+
conventions: string[];
|
|
133
|
+
boundaries: {
|
|
134
|
+
never: string[];
|
|
135
|
+
alwaysDo: string[];
|
|
136
|
+
askFirst: string[];
|
|
137
|
+
};
|
|
138
|
+
deployment: {
|
|
139
|
+
notes: string[];
|
|
140
|
+
command?: string | undefined;
|
|
141
|
+
target?: string | undefined;
|
|
142
|
+
envFile?: string | undefined;
|
|
143
|
+
};
|
|
144
|
+
}, {
|
|
145
|
+
architecture: {
|
|
146
|
+
entryPoints: string[];
|
|
147
|
+
keyDirs: Record<string, string>;
|
|
148
|
+
style?: string | undefined;
|
|
149
|
+
};
|
|
150
|
+
gotchas: string[];
|
|
151
|
+
project: {
|
|
152
|
+
name: string;
|
|
153
|
+
language: string;
|
|
154
|
+
description: string;
|
|
155
|
+
version?: string | undefined;
|
|
156
|
+
framework?: string | undefined;
|
|
157
|
+
};
|
|
158
|
+
stack: {
|
|
159
|
+
other: string[];
|
|
160
|
+
runtime?: string | undefined;
|
|
161
|
+
database?: string | undefined;
|
|
162
|
+
auth?: string | undefined;
|
|
163
|
+
testing?: string | undefined;
|
|
164
|
+
deploy?: string | undefined;
|
|
165
|
+
};
|
|
166
|
+
testing: {
|
|
167
|
+
framework?: string | undefined;
|
|
168
|
+
command?: string | undefined;
|
|
169
|
+
location?: string | undefined;
|
|
170
|
+
coverageCommand?: string | undefined;
|
|
171
|
+
};
|
|
172
|
+
conventions: string[];
|
|
173
|
+
boundaries: {
|
|
174
|
+
never: string[];
|
|
175
|
+
alwaysDo: string[];
|
|
176
|
+
askFirst: string[];
|
|
177
|
+
};
|
|
178
|
+
deployment: {
|
|
179
|
+
notes: string[];
|
|
180
|
+
command?: string | undefined;
|
|
181
|
+
target?: string | undefined;
|
|
182
|
+
envFile?: string | undefined;
|
|
183
|
+
};
|
|
184
|
+
}>;
|
|
185
|
+
export type ProjectMetadata = z.infer<typeof ProjectMetadataSchema>;
|
|
186
|
+
export declare const METADATA_VERSION = "1.0";
|
|
187
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/extractor/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4ChC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,gBAAgB,QAAQ,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const ProjectMetadataSchema = z.object({
|
|
3
|
+
project: z.object({
|
|
4
|
+
name: z.string().describe("Project name from manifest"),
|
|
5
|
+
description: z.string().describe("What this project does, 1-2 sentences"),
|
|
6
|
+
language: z.string().describe("Primary language: typescript, javascript, python, rust, go, etc"),
|
|
7
|
+
framework: z.string().optional().describe("Primary framework: nextjs, django, express, axum, etc"),
|
|
8
|
+
version: z.string().optional().describe("Project version from manifest"),
|
|
9
|
+
}),
|
|
10
|
+
stack: z.object({
|
|
11
|
+
runtime: z.string().optional().describe("Runtime and version: node 20, python 3.11, etc"),
|
|
12
|
+
database: z.string().optional().describe("Database + ORM: postgres via prisma, sqlite via drizzle, etc"),
|
|
13
|
+
auth: z.string().optional().describe("Auth solution: next-auth, jwt, supabase auth, etc"),
|
|
14
|
+
testing: z.string().optional().describe("Test framework and runner: vitest, pytest, cargo test, etc"),
|
|
15
|
+
deploy: z.string().optional().describe("Deployment target: vercel, railway, fly.io, docker, etc"),
|
|
16
|
+
other: z.array(z.string()).describe("Other notable stack items: redis, stripe, openai, etc"),
|
|
17
|
+
}),
|
|
18
|
+
architecture: z.object({
|
|
19
|
+
style: z.string().optional().describe("feature-first, layered, monorepo, flat, etc"),
|
|
20
|
+
keyDirs: z.record(z.string()).describe("Map of important dirs to their purpose: { 'src/features': 'domain modules' }"),
|
|
21
|
+
entryPoints: z.array(z.string()).describe("Main entry point files relative to project root"),
|
|
22
|
+
}),
|
|
23
|
+
conventions: z.array(z.string()).describe("Specific coding conventions Claude must follow. Be concrete: 'kebab-case filenames', 'named exports only', 'zod for all external input'. No generic advice."),
|
|
24
|
+
gotchas: z.array(z.string()).describe("Things that will break if ignored. Include consequence: 'Do not import PrismaClient directly — causes connection pool exhaustion. Use lib/db.ts singleton instead.'"),
|
|
25
|
+
boundaries: z.object({
|
|
26
|
+
alwaysDo: z.array(z.string()).describe("Things AI must always do"),
|
|
27
|
+
askFirst: z.array(z.string()).describe("Things requiring human approval before doing"),
|
|
28
|
+
never: z.array(z.string()).describe("Hard constraints — never violate these"),
|
|
29
|
+
}),
|
|
30
|
+
testing: z.object({
|
|
31
|
+
framework: z.string().optional().describe("Test framework name"),
|
|
32
|
+
command: z.string().optional().describe("Exact command to run tests: npm test, pytest, cargo test"),
|
|
33
|
+
location: z.string().optional().describe("Where tests live: colocated, tests/, __tests__/"),
|
|
34
|
+
coverageCommand: z.string().optional().describe("Command to run with coverage"),
|
|
35
|
+
}),
|
|
36
|
+
deployment: z.object({
|
|
37
|
+
target: z.string().optional().describe("Where it deploys: vercel, fly.io, etc"),
|
|
38
|
+
command: z.string().optional().describe("Deploy command if any"),
|
|
39
|
+
envFile: z.string().optional().describe(".env file name if non-standard"),
|
|
40
|
+
notes: z.array(z.string()).describe("Important deployment notes"),
|
|
41
|
+
}),
|
|
42
|
+
});
|
|
43
|
+
export const METADATA_VERSION = "1.0";
|
|
44
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/extractor/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ProjectMetadata } from "../extractor/schema.js";
|
|
2
|
+
import type { McpScanResult } from "../scanner/mcp.js";
|
|
3
|
+
/** Appends an MCP Servers section to an already-generated AGENTS.md if servers were found. */
|
|
4
|
+
export declare function appendMcpSection(agentsMd: string, mcp: McpScanResult): string;
|
|
5
|
+
export declare function generateAgentsMd(metadata: ProjectMetadata): Promise<string>;
|
|
6
|
+
//# sourceMappingURL=agents-md.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-md.d.ts","sourceRoot":"","sources":["../../src/generator/agents-md.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAwDvD,8FAA8F;AAC9F,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,GAAG,MAAM,CAI7E;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAsBjF"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { callClaude } from "../lib/claude-client.js";
|
|
2
|
+
import { AgentsSyncError } from "../lib/errors.js";
|
|
3
|
+
import { formatMcpSection } from "../scanner/mcp.js";
|
|
4
|
+
const SYSTEM_PROMPT = `You are writing an AGENTS.md file — the canonical AI context file for a software project.
|
|
5
|
+
|
|
6
|
+
This file will be read by AI coding assistants (Claude, Cursor, Copilot, Codex) to understand the project.
|
|
7
|
+
A session starting with ONLY this file must be able to:
|
|
8
|
+
1. Identify the correct directory for a new feature
|
|
9
|
+
2. Know the naming convention for new files
|
|
10
|
+
3. Know the exact test command to run
|
|
11
|
+
4. Avoid the project's top gotchas
|
|
12
|
+
|
|
13
|
+
Quality rules:
|
|
14
|
+
- Every convention must be SPECIFIC: "kebab-case filenames" not "follow conventions"
|
|
15
|
+
- Every gotcha must include CONSEQUENCE: "Do not import PrismaClient directly — causes pool exhaustion"
|
|
16
|
+
- Architecture section must name REAL directories (from the data provided)
|
|
17
|
+
- No section may be generic advice that applies to any project
|
|
18
|
+
- No empty sections — omit a section entirely if you have no real data for it
|
|
19
|
+
- Length: 400–900 words
|
|
20
|
+
|
|
21
|
+
Format the output as valid markdown starting with "# AGENTS.md".`;
|
|
22
|
+
const TEMPLATE = `# AGENTS.md
|
|
23
|
+
|
|
24
|
+
<!-- Generated by agents-sync v1.0.0 on {DATE} -->
|
|
25
|
+
<!-- Edit this file, then run /agents-sync sync to propagate changes to all tool files -->
|
|
26
|
+
|
|
27
|
+
## Project Overview
|
|
28
|
+
{OVERVIEW}
|
|
29
|
+
|
|
30
|
+
## Tech Stack
|
|
31
|
+
{STACK}
|
|
32
|
+
|
|
33
|
+
## Architecture
|
|
34
|
+
{ARCHITECTURE}
|
|
35
|
+
|
|
36
|
+
## Conventions
|
|
37
|
+
{CONVENTIONS}
|
|
38
|
+
|
|
39
|
+
## Gotchas
|
|
40
|
+
{GOTCHAS}
|
|
41
|
+
|
|
42
|
+
## Testing
|
|
43
|
+
{TESTING}
|
|
44
|
+
|
|
45
|
+
## Boundaries
|
|
46
|
+
|
|
47
|
+
### Always
|
|
48
|
+
{ALWAYS}
|
|
49
|
+
|
|
50
|
+
### Ask First
|
|
51
|
+
{ASK_FIRST}
|
|
52
|
+
|
|
53
|
+
### Never
|
|
54
|
+
{NEVER}`;
|
|
55
|
+
/** Appends an MCP Servers section to an already-generated AGENTS.md if servers were found. */
|
|
56
|
+
export function appendMcpSection(agentsMd, mcp) {
|
|
57
|
+
if (!mcp.hasAny)
|
|
58
|
+
return agentsMd;
|
|
59
|
+
const section = formatMcpSection(mcp);
|
|
60
|
+
return `${agentsMd.trimEnd()}\n\n${section}`;
|
|
61
|
+
}
|
|
62
|
+
export async function generateAgentsMd(metadata) {
|
|
63
|
+
const userPrompt = buildPrompt(metadata);
|
|
64
|
+
const { content } = await callClaude(SYSTEM_PROMPT, userPrompt, 2048);
|
|
65
|
+
// Ensure it starts with the header
|
|
66
|
+
if (!content.trim().startsWith("# AGENTS.md") && !content.trim().startsWith("# agents-sync")) {
|
|
67
|
+
throw new AgentsSyncError("GENERATION_FAILED", "Generated output did not produce a valid AGENTS.md header.", "Run with AGENTS_SYNC_DEBUG=1 to inspect output.");
|
|
68
|
+
}
|
|
69
|
+
// Inject generated timestamp if Claude didn't include a comment
|
|
70
|
+
const dated = content.includes("Generated by agents-sync")
|
|
71
|
+
? content
|
|
72
|
+
: content.replace("# AGENTS.md", `# AGENTS.md\n\n<!-- Generated by agents-sync v1.0.0 on ${new Date().toISOString().slice(0, 10)} -->\n<!-- Edit this file, then run /agents-sync sync to propagate changes to all tool files -->`);
|
|
73
|
+
return dated.trim();
|
|
74
|
+
}
|
|
75
|
+
function buildPrompt(m) {
|
|
76
|
+
const lines = ["Here is the extracted project metadata. Generate the AGENTS.md:\n"];
|
|
77
|
+
lines.push(`PROJECT: ${m.project.name} — ${m.project.description}`);
|
|
78
|
+
lines.push(`Language: ${m.project.language}${m.project.framework ? `, Framework: ${m.project.framework}` : ""}${m.project.version ? `, v${m.project.version}` : ""}`);
|
|
79
|
+
lines.push("\nSTACK:");
|
|
80
|
+
if (m.stack.runtime)
|
|
81
|
+
lines.push(` Runtime: ${m.stack.runtime}`);
|
|
82
|
+
if (m.stack.database)
|
|
83
|
+
lines.push(` Database: ${m.stack.database}`);
|
|
84
|
+
if (m.stack.auth)
|
|
85
|
+
lines.push(` Auth: ${m.stack.auth}`);
|
|
86
|
+
if (m.stack.testing)
|
|
87
|
+
lines.push(` Testing: ${m.stack.testing}`);
|
|
88
|
+
if (m.stack.deploy)
|
|
89
|
+
lines.push(` Deploy: ${m.stack.deploy}`);
|
|
90
|
+
if (m.stack.other.length > 0)
|
|
91
|
+
lines.push(` Other: ${m.stack.other.join(", ")}`);
|
|
92
|
+
lines.push("\nARCHITECTURE:");
|
|
93
|
+
if (m.architecture.style)
|
|
94
|
+
lines.push(` Style: ${m.architecture.style}`);
|
|
95
|
+
lines.push(` Entry points: ${m.architecture.entryPoints.join(", ") || "unknown"}`);
|
|
96
|
+
for (const [dir, desc] of Object.entries(m.architecture.keyDirs)) {
|
|
97
|
+
lines.push(` ${dir}: ${desc}`);
|
|
98
|
+
}
|
|
99
|
+
if (m.conventions.length > 0) {
|
|
100
|
+
lines.push("\nCONVENTIONS:");
|
|
101
|
+
m.conventions.forEach((c, i) => lines.push(` ${i + 1}. ${c}`));
|
|
102
|
+
}
|
|
103
|
+
if (m.gotchas.length > 0) {
|
|
104
|
+
lines.push("\nGOTCHAS:");
|
|
105
|
+
m.gotchas.forEach((g, i) => lines.push(` ${i + 1}. ${g}`));
|
|
106
|
+
}
|
|
107
|
+
lines.push("\nBOUNDARIES:");
|
|
108
|
+
if (m.boundaries.alwaysDo.length > 0)
|
|
109
|
+
lines.push(` Always: ${m.boundaries.alwaysDo.join("; ")}`);
|
|
110
|
+
if (m.boundaries.askFirst.length > 0)
|
|
111
|
+
lines.push(` Ask first: ${m.boundaries.askFirst.join("; ")}`);
|
|
112
|
+
if (m.boundaries.never.length > 0)
|
|
113
|
+
lines.push(` Never: ${m.boundaries.never.join("; ")}`);
|
|
114
|
+
lines.push("\nTESTING:");
|
|
115
|
+
if (m.testing.framework)
|
|
116
|
+
lines.push(` Framework: ${m.testing.framework}`);
|
|
117
|
+
if (m.testing.command)
|
|
118
|
+
lines.push(` Command: ${m.testing.command}`);
|
|
119
|
+
if (m.testing.location)
|
|
120
|
+
lines.push(` Location: ${m.testing.location}`);
|
|
121
|
+
if (m.testing.coverageCommand)
|
|
122
|
+
lines.push(` Coverage: ${m.testing.coverageCommand}`);
|
|
123
|
+
if (m.deployment.target || m.deployment.notes.length > 0) {
|
|
124
|
+
lines.push("\nDEPLOYMENT:");
|
|
125
|
+
if (m.deployment.target)
|
|
126
|
+
lines.push(` Target: ${m.deployment.target}`);
|
|
127
|
+
if (m.deployment.command)
|
|
128
|
+
lines.push(` Command: ${m.deployment.command}`);
|
|
129
|
+
m.deployment.notes.forEach((n) => lines.push(` Note: ${n}`));
|
|
130
|
+
}
|
|
131
|
+
lines.push(`\nUse this template structure:\n${TEMPLATE.replace("{DATE}", new Date().toISOString().slice(0, 10))}`);
|
|
132
|
+
lines.push("\nGenerate the complete AGENTS.md now:");
|
|
133
|
+
return lines.join("\n");
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=agents-md.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-md.js","sourceRoot":"","sources":["../../src/generator/agents-md.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/generator/validator.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAMD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,EAAO,GAAG,gBAAgB,CAsE5F"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const MIN_CONVENTIONS = 2;
|
|
2
|
+
const MIN_WORDS = 300;
|
|
3
|
+
const MAX_WORDS = 1200;
|
|
4
|
+
export function validateAgentsMd(content, knownDirs = []) {
|
|
5
|
+
const failures = [];
|
|
6
|
+
const warnings = [];
|
|
7
|
+
// Must have the header
|
|
8
|
+
if (!content.includes("# AGENTS.md")) {
|
|
9
|
+
failures.push("Missing '# AGENTS.md' header");
|
|
10
|
+
}
|
|
11
|
+
// Word count
|
|
12
|
+
const words = content.split(/\s+/).filter(Boolean).length;
|
|
13
|
+
if (words < MIN_WORDS) {
|
|
14
|
+
failures.push(`Too short: ${words} words (minimum ${MIN_WORDS}). Output is too generic.`);
|
|
15
|
+
}
|
|
16
|
+
if (words > MAX_WORDS) {
|
|
17
|
+
warnings.push(`Long: ${words} words. Consider trimming for readability.`);
|
|
18
|
+
}
|
|
19
|
+
// Must have conventions section with specific rules
|
|
20
|
+
const conventionsMatch = content.match(/## Conventions\n([\s\S]*?)(?=\n## |\n# |$)/);
|
|
21
|
+
if (!conventionsMatch) {
|
|
22
|
+
failures.push("Missing '## Conventions' section");
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
const convText = conventionsMatch[1];
|
|
26
|
+
const bulletCount = (convText.match(/^[-*\d]/gm) ?? []).length;
|
|
27
|
+
if (bulletCount < MIN_CONVENTIONS) {
|
|
28
|
+
failures.push(`Conventions section has ${bulletCount} items (minimum ${MIN_CONVENTIONS})`);
|
|
29
|
+
}
|
|
30
|
+
// Detect generic advice
|
|
31
|
+
const genericPhrases = ["best practices", "follow conventions", "write clean code", "use good names"];
|
|
32
|
+
for (const phrase of genericPhrases) {
|
|
33
|
+
if (convText.toLowerCase().includes(phrase)) {
|
|
34
|
+
warnings.push(`Generic phrase detected in Conventions: "${phrase}" — should be specific`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Must have boundaries section
|
|
39
|
+
if (!content.includes("### Never")) {
|
|
40
|
+
failures.push("Missing '### Never' section under Boundaries");
|
|
41
|
+
}
|
|
42
|
+
// Architecture dirs should reference real directories
|
|
43
|
+
if (knownDirs.length > 0) {
|
|
44
|
+
const archMatch = content.match(/## Architecture\n([\s\S]*?)(?=\n## |\n# |$)/);
|
|
45
|
+
if (archMatch) {
|
|
46
|
+
const archText = archMatch[1];
|
|
47
|
+
const referencedDirs = archText.match(/`([^`]+)`|`([^`]+)`|\b(src\/\w+|tests?\/|\w+\/)/g) ?? [];
|
|
48
|
+
const hasRealDir = referencedDirs.some((d) => knownDirs.some((kd) => d.includes(kd.split("/")[0])));
|
|
49
|
+
if (!hasRealDir && knownDirs.length > 2) {
|
|
50
|
+
warnings.push("Architecture section may not reference actual project directories");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Testing section should have a command
|
|
55
|
+
if (content.includes("## Testing")) {
|
|
56
|
+
const testMatch = content.match(/## Testing\n([\s\S]*?)(?=\n## |\n# |$)/);
|
|
57
|
+
if (testMatch && !testMatch[1].match(/`[^`]+`/)) {
|
|
58
|
+
warnings.push("Testing section has no code-formatted command (e.g. `npm test`)");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
passed: failures.length === 0,
|
|
63
|
+
failures,
|
|
64
|
+
warnings,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/generator/validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ClaudeResponse {
|
|
2
|
+
content: string;
|
|
3
|
+
usage: {
|
|
4
|
+
inputTokens: number;
|
|
5
|
+
outputTokens: number;
|
|
6
|
+
cacheReadTokens: number;
|
|
7
|
+
cacheWriteTokens: number;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export declare function callClaude(systemPrompt: string, userPrompt: string, maxTokens?: number): Promise<ClaudeResponse>;
|
|
11
|
+
//# sourceMappingURL=claude-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-client.d.ts","sourceRoot":"","sources":["../../src/lib/claude-client.ts"],"names":[],"mappings":"AA8BA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;CACzG;AAED,wBAAsB,UAAU,CAC9B,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,SAAS,SAAO,GACf,OAAO,CAAC,cAAc,CAAC,CA+DzB"}
|