@elysiumoss/grepo 0.2.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 (72) hide show
  1. package/LICENSE.md +20 -0
  2. package/README.md +61 -0
  3. package/lib/cli.d.ts +1 -0
  4. package/lib/cli.js +84 -0
  5. package/lib/cli.js.map +1 -0
  6. package/lib/commands/analyze.d.ts +11 -0
  7. package/lib/commands/analyze.d.ts.map +1 -0
  8. package/lib/commands/analyze.js +49 -0
  9. package/lib/commands/analyze.js.map +1 -0
  10. package/lib/commands/describe.d.ts +11 -0
  11. package/lib/commands/describe.d.ts.map +1 -0
  12. package/lib/commands/describe.js +89 -0
  13. package/lib/commands/describe.js.map +1 -0
  14. package/lib/commands/readme.d.ts +11 -0
  15. package/lib/commands/readme.d.ts.map +1 -0
  16. package/lib/commands/readme.js +69 -0
  17. package/lib/commands/readme.js.map +1 -0
  18. package/lib/commands/topics.d.ts +11 -0
  19. package/lib/commands/topics.d.ts.map +1 -0
  20. package/lib/commands/topics.js +74 -0
  21. package/lib/commands/topics.js.map +1 -0
  22. package/lib/config.d.ts +31 -0
  23. package/lib/config.d.ts.map +1 -0
  24. package/lib/config.js +149 -0
  25. package/lib/config.js.map +1 -0
  26. package/lib/errors.d.ts +55 -0
  27. package/lib/errors.d.ts.map +1 -0
  28. package/lib/errors.js +27 -0
  29. package/lib/errors.js.map +1 -0
  30. package/lib/index.d.ts +14 -0
  31. package/lib/index.js +14 -0
  32. package/lib/mermaid.d.ts +17 -0
  33. package/lib/mermaid.d.ts.map +1 -0
  34. package/lib/mermaid.js +132 -0
  35. package/lib/mermaid.js.map +1 -0
  36. package/lib/prompts/readme.d.ts +90 -0
  37. package/lib/prompts/readme.d.ts.map +1 -0
  38. package/lib/prompts/readme.js +345 -0
  39. package/lib/prompts/readme.js.map +1 -0
  40. package/lib/services.d.ts +29 -0
  41. package/lib/services.d.ts.map +1 -0
  42. package/lib/services.js +59 -0
  43. package/lib/services.js.map +1 -0
  44. package/lib/utils/args.d.ts +15 -0
  45. package/lib/utils/args.d.ts.map +1 -0
  46. package/lib/utils/args.js +70 -0
  47. package/lib/utils/args.js.map +1 -0
  48. package/lib/utils/fetcher.d.ts +44 -0
  49. package/lib/utils/fetcher.d.ts.map +1 -0
  50. package/lib/utils/fetcher.js +173 -0
  51. package/lib/utils/fetcher.js.map +1 -0
  52. package/lib/utils/gemini.d.ts +25 -0
  53. package/lib/utils/gemini.d.ts.map +1 -0
  54. package/lib/utils/gemini.js +108 -0
  55. package/lib/utils/gemini.js.map +1 -0
  56. package/lib/utils/github.d.ts +28 -0
  57. package/lib/utils/github.d.ts.map +1 -0
  58. package/lib/utils/github.js +94 -0
  59. package/lib/utils/github.js.map +1 -0
  60. package/lib/utils/gitingest.d.ts +19 -0
  61. package/lib/utils/gitingest.d.ts.map +1 -0
  62. package/lib/utils/gitingest.js +46 -0
  63. package/lib/utils/gitingest.js.map +1 -0
  64. package/lib/utils/logger.d.ts +47 -0
  65. package/lib/utils/logger.d.ts.map +1 -0
  66. package/lib/utils/logger.js +155 -0
  67. package/lib/utils/logger.js.map +1 -0
  68. package/lib/utils/validation.d.ts +38 -0
  69. package/lib/utils/validation.d.ts.map +1 -0
  70. package/lib/utils/validation.js +65 -0
  71. package/lib/utils/validation.js.map +1 -0
  72. package/package.json +81 -0
package/lib/config.js ADDED
@@ -0,0 +1,149 @@
1
+ import { GrepoValidationError } from "./errors.js";
2
+ import { parseArgs } from "./utils/args.js";
3
+ import { isValidGeminiApiKey, isValidGitHubUrl } from "./utils/validation.js";
4
+ import { Schema } from "effect";
5
+ import { existsSync, readFileSync } from "node:fs";
6
+ import { dirname, resolve } from "node:path";
7
+ import { fileURLToPath } from "node:url";
8
+ //#region src/config.ts
9
+ /**
10
+ *
11
+ * Copyright 2026 Mike Odnis
12
+ *
13
+ * Licensed under the Apache License, Version 2.0 (the "License");
14
+ * you may not use this file except in compliance with the License.
15
+ * You may obtain a copy of the License at
16
+ *
17
+ * http://www.apache.org/licenses/LICENSE-2.0
18
+ *
19
+ * Unless required by applicable law or agreed to in writing, software
20
+ * distributed under the License is distributed on an "AS IS" BASIS,
21
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
+ * See the License for the specific language governing permissions and
23
+ * limitations under the License.
24
+ *
25
+ */
26
+ const Command = Schema.Literal("readme", "topics", "describe", "summary", "tech", "improve");
27
+ const OutputFormat = Schema.Literal("md", "mdx");
28
+ const DocumentationStyle = Schema.Literal("minimal", "standard", "comprehensive");
29
+ const GrepoConfig = Schema.Struct({
30
+ branch: Schema.String,
31
+ command: Command,
32
+ geminiApiKey: Schema.String,
33
+ githubToken: Schema.optional(Schema.String),
34
+ isDryRun: Schema.Boolean,
35
+ outputFile: Schema.String,
36
+ outputFormat: OutputFormat,
37
+ repoUrl: Schema.String,
38
+ shouldApply: Schema.Boolean,
39
+ shouldMerge: Schema.Boolean,
40
+ shouldPush: Schema.Boolean,
41
+ style: DocumentationStyle,
42
+ tone: Schema.optional(Schema.Literal("casual", "minimal", "professional", "technical"))
43
+ });
44
+ async function loadEnv() {
45
+ const envPath = resolve(dirname(fileURLToPath(import.meta.url)), "../.env");
46
+ if (!existsSync(envPath)) return;
47
+ const envContent = readFileSync(envPath, "utf-8");
48
+ for (const line of envContent.split("\n")) {
49
+ const trimmed = line.trim();
50
+ if (!trimmed || trimmed.startsWith("#")) continue;
51
+ const [key, ...valueParts] = trimmed.split("=");
52
+ if (key && valueParts.length > 0) {
53
+ const value = valueParts.join("=").trim().replaceAll(/(^["'])|(['"]$)/g, "");
54
+ if (!process.env[key.trim()]) process.env[key.trim()] = value;
55
+ }
56
+ }
57
+ }
58
+ const BOOLEAN_FLAGS = [
59
+ "push",
60
+ "apply",
61
+ "merge",
62
+ "dry-run"
63
+ ];
64
+ const USAGE = `Usage: grepo <command> <github-url> [options]
65
+
66
+ Commands:
67
+ readme Generate README documentation
68
+ topics Generate and apply repository topics
69
+ describe Generate repository description and homepage URL
70
+ summary Summarize repository
71
+ tech List technologies used
72
+ improve Suggest improvements
73
+
74
+ Options:
75
+ --format md|mdx Output format (readme only, default: md)
76
+ --style minimal|standard|comprehensive Documentation style (readme only, default: standard)
77
+ --output <file> Output file path (readme only)
78
+ --push Push to GitHub (readme only)
79
+ --apply Apply changes to GitHub (topics, describe)
80
+ --merge Merge with existing topics (topics only)
81
+ --dry-run Preview changes without applying
82
+ --branch <name> Target branch (default: main)
83
+ --tone <voice> Tone: casual, professional, minimal, technical (default: auto-detect)`;
84
+ const VALID_TONES = [
85
+ "casual",
86
+ "professional",
87
+ "minimal",
88
+ "technical"
89
+ ];
90
+ function validateTone(tone) {
91
+ if (!tone) return;
92
+ if (!VALID_TONES.includes(tone)) throw new GrepoValidationError({
93
+ field: "tone",
94
+ message: `Invalid tone "${tone}". Must be one of: ${VALID_TONES.join(", ")}`
95
+ });
96
+ return tone;
97
+ }
98
+ function buildConfig(argv) {
99
+ const { options, positional } = parseArgs(argv, [...BOOLEAN_FLAGS]);
100
+ if (positional.length < 2) {
101
+ console.log(USAGE);
102
+ process.exit(1);
103
+ }
104
+ const command = positional[0];
105
+ if (![
106
+ "readme",
107
+ "topics",
108
+ "describe",
109
+ "summary",
110
+ "tech",
111
+ "improve"
112
+ ].includes(command)) {
113
+ console.error(`Unknown command: ${command}`);
114
+ console.log(USAGE);
115
+ process.exit(1);
116
+ }
117
+ const repoUrl = positional[1];
118
+ if (!isValidGitHubUrl(repoUrl)) throw new GrepoValidationError({
119
+ field: "repoUrl",
120
+ message: "Invalid GitHub URL"
121
+ });
122
+ const geminiApiKey = process.env.GEMINI_API_KEY ?? process.env.GOOGLE_API_KEY ?? "";
123
+ if (!isValidGeminiApiKey(geminiApiKey)) throw new GrepoValidationError({ message: "GEMINI_API_KEY is missing or invalid" });
124
+ const githubToken = process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN;
125
+ const shouldApply = !!options.apply;
126
+ const shouldPush = !!options.push;
127
+ const shouldMerge = !!options.merge;
128
+ if ((shouldApply || shouldPush || shouldMerge) && !githubToken) throw new GrepoValidationError({ message: "GitHub token (GITHUB_TOKEN or GH_TOKEN) is required for mutation operations" });
129
+ const format = options.format || "md";
130
+ return {
131
+ branch: options.branch || "main",
132
+ command,
133
+ geminiApiKey,
134
+ githubToken,
135
+ isDryRun: !!options["dry-run"],
136
+ outputFile: options.output || `README.${format}`,
137
+ outputFormat: format,
138
+ repoUrl,
139
+ shouldApply,
140
+ shouldMerge,
141
+ shouldPush,
142
+ style: options.style || "standard",
143
+ tone: validateTone(options.tone)
144
+ };
145
+ }
146
+ //#endregion
147
+ export { Command, DocumentationStyle, GrepoConfig, OutputFormat, buildConfig, loadEnv };
148
+
149
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","names":["validation.isValidGitHubUrl","validation.isValidGeminiApiKey"],"sources":["../src/config.ts"],"sourcesContent":["/**\n *\n * Copyright 2026 Mike Odnis\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { Schema } from \"effect\";\n\nimport { GrepoValidationError } from \"./errors.js\";\nimport { parseArgs } from \"./utils/args.js\";\nimport * as validation from \"./utils/validation.js\";\n\n// ============================================================================\n// Config Schema\n// ============================================================================\n\nexport const Command = Schema.Literal(\n\t\"readme\",\n\t\"topics\",\n\t\"describe\",\n\t\"summary\",\n\t\"tech\",\n\t\"improve\",\n);\nexport type Command = Schema.Schema.Type<typeof Command>;\n\nexport const OutputFormat = Schema.Literal(\"md\", \"mdx\");\nexport type OutputFormat = Schema.Schema.Type<typeof OutputFormat>;\n\nexport const DocumentationStyle = Schema.Literal(\n\t\"minimal\",\n\t\"standard\",\n\t\"comprehensive\",\n);\nexport type DocumentationStyle = Schema.Schema.Type<typeof DocumentationStyle>;\n\nexport const GrepoConfig = Schema.Struct({\n\tbranch: Schema.String,\n\tcommand: Command,\n\tgeminiApiKey: Schema.String,\n\tgithubToken: Schema.optional(Schema.String),\n\tisDryRun: Schema.Boolean,\n\toutputFile: Schema.String,\n\toutputFormat: OutputFormat,\n\trepoUrl: Schema.String,\n\tshouldApply: Schema.Boolean,\n\tshouldMerge: Schema.Boolean,\n\tshouldPush: Schema.Boolean,\n\tstyle: DocumentationStyle,\n\ttone: Schema.optional(\n\t\tSchema.Literal(\"casual\", \"minimal\", \"professional\", \"technical\"),\n\t),\n});\nexport type GrepoConfig = Schema.Schema.Type<typeof GrepoConfig>;\n\n// ============================================================================\n// Env Loading\n// ============================================================================\n\nexport async function loadEnv(): Promise<void> {\n\tconst __filename = fileURLToPath(import.meta.url);\n\tconst __dirname = dirname(__filename);\n\tconst envPath = resolve(__dirname, \"../.env\");\n\n\tif (!existsSync(envPath)) {\n\t\treturn;\n\t}\n\n\tconst envContent = readFileSync(envPath, \"utf-8\");\n\tfor (const line of envContent.split(\"\\n\")) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed || trimmed.startsWith(\"#\")) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst [key, ...valueParts] = trimmed.split(\"=\");\n\t\tif (key && valueParts.length > 0) {\n\t\t\tconst value = valueParts\n\t\t\t\t.join(\"=\")\n\t\t\t\t.trim()\n\t\t\t\t.replaceAll(/(^[\"'])|(['\"]$)/g, \"\");\n\t\t\tif (!process.env[key.trim()]) {\n\t\t\t\tprocess.env[key.trim()] = value;\n\t\t\t}\n\t\t}\n\t}\n}\n\n// ============================================================================\n// Config Builder\n// ============================================================================\n\nconst BOOLEAN_FLAGS = [\"push\", \"apply\", \"merge\", \"dry-run\"] as const;\n\nconst USAGE = `Usage: grepo <command> <github-url> [options]\n\nCommands:\n readme Generate README documentation\n topics Generate and apply repository topics\n describe Generate repository description and homepage URL\n summary Summarize repository\n tech List technologies used\n improve Suggest improvements\n\nOptions:\n --format md|mdx Output format (readme only, default: md)\n --style minimal|standard|comprehensive Documentation style (readme only, default: standard)\n --output <file> Output file path (readme only)\n --push Push to GitHub (readme only)\n --apply Apply changes to GitHub (topics, describe)\n --merge Merge with existing topics (topics only)\n --dry-run Preview changes without applying\n --branch <name> Target branch (default: main)\n --tone <voice> Tone: casual, professional, minimal, technical (default: auto-detect)`;\n\nconst VALID_TONES = [\"casual\", \"professional\", \"minimal\", \"technical\"] as const;\n\nfunction validateTone(tone: string | undefined): GrepoConfig[\"tone\"] {\n\tif (!tone) {\n\t\treturn undefined;\n\t}\n\tif (!VALID_TONES.includes(tone as (typeof VALID_TONES)[number])) {\n\t\tthrow new GrepoValidationError({\n\t\t\tfield: \"tone\",\n\t\t\tmessage: `Invalid tone \"${tone}\". Must be one of: ${VALID_TONES.join(\", \")}`,\n\t\t});\n\t}\n\treturn tone as GrepoConfig[\"tone\"];\n}\n\nexport function buildConfig(argv: string[]): GrepoConfig {\n\tconst { options, positional } = parseArgs(argv, [...BOOLEAN_FLAGS]);\n\n\tif (positional.length < 2) {\n\t\tconsole.log(USAGE);\n\t\tprocess.exit(1);\n\t}\n\n\tconst command = positional[0];\n\tconst validCommands: Command[] = [\n\t\t\"readme\",\n\t\t\"topics\",\n\t\t\"describe\",\n\t\t\"summary\",\n\t\t\"tech\",\n\t\t\"improve\",\n\t];\n\tif (!validCommands.includes(command as Command)) {\n\t\tconsole.error(`Unknown command: ${command}`);\n\t\tconsole.log(USAGE);\n\t\tprocess.exit(1);\n\t}\n\n\tconst repoUrl = positional[1];\n\tif (!validation.isValidGitHubUrl(repoUrl)) {\n\t\tthrow new GrepoValidationError({\n\t\t\tfield: \"repoUrl\",\n\t\t\tmessage: \"Invalid GitHub URL\",\n\t\t});\n\t}\n\n\tconst geminiApiKey =\n\t\tprocess.env.GEMINI_API_KEY ?? process.env.GOOGLE_API_KEY ?? \"\";\n\tif (!validation.isValidGeminiApiKey(geminiApiKey)) {\n\t\tthrow new GrepoValidationError({\n\t\t\tmessage: \"GEMINI_API_KEY is missing or invalid\",\n\t\t});\n\t}\n\n\tconst githubToken = process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN;\n\tconst shouldApply = !!options.apply;\n\tconst shouldPush = !!options.push;\n\tconst shouldMerge = !!options.merge;\n\n\tif ((shouldApply || shouldPush || shouldMerge) && !githubToken) {\n\t\tthrow new GrepoValidationError({\n\t\t\tmessage:\n\t\t\t\t\"GitHub token (GITHUB_TOKEN or GH_TOKEN) is required for mutation operations\",\n\t\t});\n\t}\n\n\tconst format = (options.format as string) || \"md\";\n\treturn {\n\t\tbranch: (options.branch as string) || \"main\",\n\t\tcommand: command as Command,\n\t\tgeminiApiKey,\n\t\tgithubToken,\n\t\tisDryRun: !!options[\"dry-run\"],\n\t\toutputFile: (options.output as string) || `README.${format}`,\n\t\toutputFormat: format as OutputFormat,\n\t\trepoUrl,\n\t\tshouldApply,\n\t\tshouldMerge,\n\t\tshouldPush,\n\t\tstyle: ((options.style as string) || \"standard\") as DocumentationStyle,\n\t\ttone: validateTone(options.tone as string | undefined),\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,MAAa,UAAU,OAAO,QAC7B,UACA,UACA,YACA,WACA,QACA,UACA;AAGD,MAAa,eAAe,OAAO,QAAQ,MAAM,MAAM;AAGvD,MAAa,qBAAqB,OAAO,QACxC,WACA,YACA,gBACA;AAGD,MAAa,cAAc,OAAO,OAAO;CACxC,QAAQ,OAAO;CACf,SAAS;CACT,cAAc,OAAO;CACrB,aAAa,OAAO,SAAS,OAAO,OAAO;CAC3C,UAAU,OAAO;CACjB,YAAY,OAAO;CACnB,cAAc;CACd,SAAS,OAAO;CAChB,aAAa,OAAO;CACpB,aAAa,OAAO;CACpB,YAAY,OAAO;CACnB,OAAO;CACP,MAAM,OAAO,SACZ,OAAO,QAAQ,UAAU,WAAW,gBAAgB,YAAY,CAChE;CACD,CAAC;AAOF,eAAsB,UAAyB;CAG9C,MAAM,UAAU,QADE,QADC,cAAc,OAAO,KAAK,IAAI,CACZ,EACF,UAAU;AAE7C,KAAI,CAAC,WAAW,QAAQ,CACvB;CAGD,MAAM,aAAa,aAAa,SAAS,QAAQ;AACjD,MAAK,MAAM,QAAQ,WAAW,MAAM,KAAK,EAAE;EAC1C,MAAM,UAAU,KAAK,MAAM;AAC3B,MAAI,CAAC,WAAW,QAAQ,WAAW,IAAI,CACtC;EAED,MAAM,CAAC,KAAK,GAAG,cAAc,QAAQ,MAAM,IAAI;AAC/C,MAAI,OAAO,WAAW,SAAS,GAAG;GACjC,MAAM,QAAQ,WACZ,KAAK,IAAI,CACT,MAAM,CACN,WAAW,oBAAoB,GAAG;AACpC,OAAI,CAAC,QAAQ,IAAI,IAAI,MAAM,EAC1B,SAAQ,IAAI,IAAI,MAAM,IAAI;;;;AAU9B,MAAM,gBAAgB;CAAC;CAAQ;CAAS;CAAS;CAAU;AAE3D,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;AAqBd,MAAM,cAAc;CAAC;CAAU;CAAgB;CAAW;CAAY;AAEtE,SAAS,aAAa,MAA+C;AACpE,KAAI,CAAC,KACJ;AAED,KAAI,CAAC,YAAY,SAAS,KAAqC,CAC9D,OAAM,IAAI,qBAAqB;EAC9B,OAAO;EACP,SAAS,iBAAiB,KAAK,qBAAqB,YAAY,KAAK,KAAK;EAC1E,CAAC;AAEH,QAAO;;AAGR,SAAgB,YAAY,MAA6B;CACxD,MAAM,EAAE,SAAS,eAAe,UAAU,MAAM,CAAC,GAAG,cAAc,CAAC;AAEnE,KAAI,WAAW,SAAS,GAAG;AAC1B,UAAQ,IAAI,MAAM;AAClB,UAAQ,KAAK,EAAE;;CAGhB,MAAM,UAAU,WAAW;AAS3B,KAAI,CAR6B;EAChC;EACA;EACA;EACA;EACA;EACA;EACA,CACkB,SAAS,QAAmB,EAAE;AAChD,UAAQ,MAAM,oBAAoB,UAAU;AAC5C,UAAQ,IAAI,MAAM;AAClB,UAAQ,KAAK,EAAE;;CAGhB,MAAM,UAAU,WAAW;AAC3B,KAAI,CAACA,iBAA4B,QAAQ,CACxC,OAAM,IAAI,qBAAqB;EAC9B,OAAO;EACP,SAAS;EACT,CAAC;CAGH,MAAM,eACL,QAAQ,IAAI,kBAAkB,QAAQ,IAAI,kBAAkB;AAC7D,KAAI,CAACC,oBAA+B,aAAa,CAChD,OAAM,IAAI,qBAAqB,EAC9B,SAAS,wCACT,CAAC;CAGH,MAAM,cAAc,QAAQ,IAAI,gBAAgB,QAAQ,IAAI;CAC5D,MAAM,cAAc,CAAC,CAAC,QAAQ;CAC9B,MAAM,aAAa,CAAC,CAAC,QAAQ;CAC7B,MAAM,cAAc,CAAC,CAAC,QAAQ;AAE9B,MAAK,eAAe,cAAc,gBAAgB,CAAC,YAClD,OAAM,IAAI,qBAAqB,EAC9B,SACC,+EACD,CAAC;CAGH,MAAM,SAAU,QAAQ,UAAqB;AAC7C,QAAO;EACN,QAAS,QAAQ,UAAqB;EAC7B;EACT;EACA;EACA,UAAU,CAAC,CAAC,QAAQ;EACpB,YAAa,QAAQ,UAAqB,UAAU;EACpD,cAAc;EACd;EACA;EACA;EACA;EACA,OAAS,QAAQ,SAAoB;EACrC,MAAM,aAAa,QAAQ,KAA2B;EACtD"}
@@ -0,0 +1,55 @@
1
+ import * as effect_Types0 from "effect/Types";
2
+ import * as effect_Cause0 from "effect/Cause";
3
+
4
+ //#region src/errors.d.ts
5
+
6
+ /**
7
+ *
8
+ * Copyright 2026 Mike Odnis
9
+ *
10
+ * Licensed under the Apache License, Version 2.0 (the "License");
11
+ * you may not use this file except in compliance with the License.
12
+ * You may obtain a copy of the License at
13
+ *
14
+ * http://www.apache.org/licenses/LICENSE-2.0
15
+ *
16
+ * Unless required by applicable law or agreed to in writing, software
17
+ * distributed under the License is distributed on an "AS IS" BASIS,
18
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
+ * See the License for the specific language governing permissions and
20
+ * limitations under the License.
21
+ *
22
+ */
23
+ declare const GrepoValidationError_base: new <A extends Record<string, any> = {}>(args: effect_Types0.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }) => effect_Cause0.YieldableError & {
24
+ readonly _tag: "GrepoValidationError";
25
+ } & Readonly<A>;
26
+ declare class GrepoValidationError extends GrepoValidationError_base<{
27
+ readonly message: string;
28
+ readonly field?: string;
29
+ }> {}
30
+ declare const GeminiError_base: new <A extends Record<string, any> = {}>(args: effect_Types0.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }) => effect_Cause0.YieldableError & {
31
+ readonly _tag: "GeminiError";
32
+ } & Readonly<A>;
33
+ declare class GeminiError extends GeminiError_base<{
34
+ readonly message: string;
35
+ readonly cause?: unknown;
36
+ }> {}
37
+ declare const GitHubError_base: new <A extends Record<string, any> = {}>(args: effect_Types0.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }) => effect_Cause0.YieldableError & {
38
+ readonly _tag: "GitHubError";
39
+ } & Readonly<A>;
40
+ declare class GitHubError extends GitHubError_base<{
41
+ readonly message: string;
42
+ readonly statusCode?: number;
43
+ readonly endpoint?: string;
44
+ }> {}
45
+ declare const GitIngestError_base: new <A extends Record<string, any> = {}>(args: effect_Types0.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }) => effect_Cause0.YieldableError & {
46
+ readonly _tag: "GitIngestError";
47
+ } & Readonly<A>;
48
+ declare class GitIngestError extends GitIngestError_base<{
49
+ readonly message: string;
50
+ readonly cause?: unknown;
51
+ }> {}
52
+ type GrepoError = GeminiError | GitHubError | GitIngestError | GrepoValidationError;
53
+ //#endregion
54
+ export { GeminiError, GitHubError, GitIngestError, GrepoError, GrepoValidationError };
55
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","names":[],"sources":["../src/errors.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAoBA,uCAA0C,EAAA,IAAA,CAAA,gBAAA,CAAA,MAAA,EAAA,GAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,IAAA,sBAAA,EAAA,EAAA,CAAA,CAAA,CAAA,SAAA,IAAA,GAAA,IAAA,GAAA,iBAAA,OAAA,KAAA,SAAA,MAAA,GAAA,KAAA,IAAA,IAAA,EAAA,CAAA,EAAA,EAAA,kCAAA;EAKrC,SAAA,IAAA,EAAA,sBAAA;;cALQ,oBAAA,SAA6B;;;;cAKrC;;;cAEQ,WAAA,SAAoB;;;AAAjC,CAAA,CAAA,CAAA;cAGK;;;cAEQ,WAAA,SAAoB;;;;;cAI5B;;;AAJQ,cAMA,cAAA,SAAuB,mBANH,CAAA;EAI5B,SAAA,OAAA,EAAA,MAAA;;;KAOO,UAAA,GACT,cACA,cACA,iBACA"}
package/lib/errors.js ADDED
@@ -0,0 +1,27 @@
1
+ import { Data } from "effect";
2
+ //#region src/errors.ts
3
+ /**
4
+ *
5
+ * Copyright 2026 Mike Odnis
6
+ *
7
+ * Licensed under the Apache License, Version 2.0 (the "License");
8
+ * you may not use this file except in compliance with the License.
9
+ * You may obtain a copy of the License at
10
+ *
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ *
19
+ */
20
+ var GrepoValidationError = class extends Data.TaggedError("GrepoValidationError") {};
21
+ var GeminiError = class extends Data.TaggedError("GeminiError") {};
22
+ var GitHubError = class extends Data.TaggedError("GitHubError") {};
23
+ var GitIngestError = class extends Data.TaggedError("GitIngestError") {};
24
+ //#endregion
25
+ export { GeminiError, GitHubError, GitIngestError, GrepoValidationError };
26
+
27
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n *\n * Copyright 2026 Mike Odnis\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nimport { Data } from \"effect\";\n\nexport class GrepoValidationError extends Data.TaggedError(\n\t\"GrepoValidationError\",\n)<{\n\treadonly message: string;\n\treadonly field?: string;\n}> {}\n\nexport class GeminiError extends Data.TaggedError(\"GeminiError\")<{\n\treadonly message: string;\n\treadonly cause?: unknown;\n}> {}\n\nexport class GitHubError extends Data.TaggedError(\"GitHubError\")<{\n\treadonly message: string;\n\treadonly statusCode?: number;\n\treadonly endpoint?: string;\n}> {}\n\nexport class GitIngestError extends Data.TaggedError(\"GitIngestError\")<{\n\treadonly message: string;\n\treadonly cause?: unknown;\n}> {}\n\nexport type GrepoError =\n\t| GeminiError\n\t| GitHubError\n\t| GitIngestError\n\t| GrepoValidationError;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAoBA,IAAa,uBAAb,cAA0C,KAAK,YAC9C,uBACA,CAGE;AAEH,IAAa,cAAb,cAAiC,KAAK,YAAY,cAAc,CAG7D;AAEH,IAAa,cAAb,cAAiC,KAAK,YAAY,cAAc,CAI7D;AAEH,IAAa,iBAAb,cAAoC,KAAK,YAAY,iBAAiB,CAGnE"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { GeminiError, GitHubError, GitIngestError, GrepoError, GrepoValidationError } from "./errors.js";
2
+ import { Command, DocumentationStyle, GrepoConfig, OutputFormat, buildConfig, loadEnv } from "./config.js";
3
+ import { fetchRepositoryContent } from "./utils/gitingest.js";
4
+ import { Gemini, GeminiLive, GeminiServiceApi, GitHub, GitHubLive, GitHubServiceApi, RepoData, fetchRepo } from "./services.js";
5
+ import { run } from "./commands/analyze.js";
6
+ import { run as run$1 } from "./commands/describe.js";
7
+ import { run as run$2 } from "./commands/readme.js";
8
+ import { run as run$3 } from "./commands/topics.js";
9
+ import { extractMermaidBlocks, validateAndFixMermaid } from "./mermaid.js";
10
+ import { AnalysisResult, DEFAULT_ANALYSIS, GenerationOptions, STYLE_GUIDANCE, Tone, buildAnalysisPrompt, buildExistingReadmeInstructions, buildGenerationPrompt, extractExistingReadme, parseAnalysis } from "./prompts/readme.js";
11
+ import { GeminiService } from "./utils/gemini.js";
12
+ import { GitHubClient } from "./utils/github.js";
13
+ import { Logger } from "./utils/logger.js";
14
+ export { type AnalysisResult, type Command, DEFAULT_ANALYSIS, type DocumentationStyle, Gemini, GeminiError, GeminiLive, GeminiService, type GeminiServiceApi, type GenerationOptions, GitHub, GitHubClient, GitHubError, GitHubLive, type GitHubServiceApi, GitIngestError, type GrepoConfig, type GrepoError, GrepoValidationError, Logger, type OutputFormat, type RepoData, STYLE_GUIDANCE, type Tone, run as analyze, buildAnalysisPrompt, buildConfig, buildExistingReadmeInstructions, buildGenerationPrompt, run$1 as describe, extractExistingReadme, extractMermaidBlocks, fetchRepo, fetchRepositoryContent, loadEnv, parseAnalysis, run$2 as readme, run$3 as topics, validateAndFixMermaid };
package/lib/index.js ADDED
@@ -0,0 +1,14 @@
1
+ import { GeminiError, GitHubError, GitIngestError, GrepoValidationError } from "./errors.js";
2
+ import { buildConfig, loadEnv } from "./config.js";
3
+ import { Logger } from "./utils/logger.js";
4
+ import { GeminiService } from "./utils/gemini.js";
5
+ import { GitHubClient } from "./utils/github.js";
6
+ import { fetchRepositoryContent } from "./utils/gitingest.js";
7
+ import { Gemini, GeminiLive, GitHub, GitHubLive, fetchRepo } from "./services.js";
8
+ import { run } from "./commands/analyze.js";
9
+ import { run as run$1 } from "./commands/describe.js";
10
+ import { extractMermaidBlocks, validateAndFixMermaid } from "./mermaid.js";
11
+ import { DEFAULT_ANALYSIS, STYLE_GUIDANCE, buildAnalysisPrompt, buildExistingReadmeInstructions, buildGenerationPrompt, extractExistingReadme, parseAnalysis } from "./prompts/readme.js";
12
+ import { run as run$2 } from "./commands/readme.js";
13
+ import { run as run$3 } from "./commands/topics.js";
14
+ export { DEFAULT_ANALYSIS, Gemini, GeminiError, GeminiLive, GeminiService, GitHub, GitHubClient, GitHubError, GitHubLive, GitIngestError, GrepoValidationError, Logger, STYLE_GUIDANCE, run as analyze, buildAnalysisPrompt, buildConfig, buildExistingReadmeInstructions, buildGenerationPrompt, run$1 as describe, extractExistingReadme, extractMermaidBlocks, fetchRepo, fetchRepositoryContent, loadEnv, parseAnalysis, run$2 as readme, run$3 as topics, validateAndFixMermaid };
@@ -0,0 +1,17 @@
1
+ import { GeminiServiceApi } from "./services.js";
2
+ import { Effect, Schema } from "effect";
3
+
4
+ //#region src/mermaid.d.ts
5
+
6
+ declare const MermaidBlock: Schema.Struct<{
7
+ code: typeof Schema.String;
8
+ end: typeof Schema.Number;
9
+ index: typeof Schema.Number;
10
+ start: typeof Schema.Number;
11
+ }>;
12
+ type MermaidBlock = Schema.Schema.Type<typeof MermaidBlock>;
13
+ declare function extractMermaidBlocks(markdown: string): MermaidBlock[];
14
+ declare const validateAndFixMermaid: (content: string, gemini: GeminiServiceApi, maxRetries?: number) => Effect.Effect<string, never>;
15
+ //#endregion
16
+ export { MermaidBlock, extractMermaidBlocks, validateAndFixMermaid };
17
+ //# sourceMappingURL=mermaid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mermaid.d.ts","names":[],"sources":["../src/mermaid.ts"],"sourcesContent":[],"mappings":";;;;;cA+Ba,cAAY,MAAA,CAAA;;;;;;KAMb,YAAA,GAAe,MAAA,CAAO,MAAA,CAAO,YAAY;iBAErC,oBAAA,oBAAwC;cA2E3C,iDAEJ,0CAEN,MAAA,CAAO"}
package/lib/mermaid.js ADDED
@@ -0,0 +1,132 @@
1
+ import { Logger as Logger$1 } from "./utils/logger.js";
2
+ import { Effect, Schema } from "effect";
3
+ import { join } from "node:path";
4
+ import { mkdtemp, rm, writeFile } from "node:fs/promises";
5
+ import { execFile } from "node:child_process";
6
+ import { tmpdir } from "node:os";
7
+ import { promisify } from "node:util";
8
+ //#region src/mermaid.ts
9
+ /**
10
+ *
11
+ * Copyright 2026 Mike Odnis
12
+ *
13
+ * Licensed under the Apache License, Version 2.0 (the "License");
14
+ * you may not use this file except in compliance with the License.
15
+ * You may obtain a copy of the License at
16
+ *
17
+ * http://www.apache.org/licenses/LICENSE-2.0
18
+ *
19
+ * Unless required by applicable law or agreed to in writing, software
20
+ * distributed under the License is distributed on an "AS IS" BASIS,
21
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
+ * See the License for the specific language governing permissions and
23
+ * limitations under the License.
24
+ *
25
+ */
26
+ const execFileAsync = promisify(execFile);
27
+ const logger = new Logger$1("GREPO:MERMAID");
28
+ const MermaidBlock = Schema.Struct({
29
+ code: Schema.String,
30
+ end: Schema.Number,
31
+ index: Schema.Number,
32
+ start: Schema.Number
33
+ });
34
+ function extractMermaidBlocks(markdown) {
35
+ const blocks = [];
36
+ const regex = /```mermaid\n([\s\S]*?)```/g;
37
+ let index = 0;
38
+ for (let match = regex.exec(markdown); match !== null; match = regex.exec(markdown)) blocks.push({
39
+ code: match[1].trim(),
40
+ end: match.index + match[0].length,
41
+ index: index++,
42
+ start: match.index
43
+ });
44
+ return blocks;
45
+ }
46
+ async function validateBlock(block) {
47
+ const dir = await mkdtemp(join(tmpdir(), "mermaid-"));
48
+ const inputFile = join(dir, "input.mmd");
49
+ const outputFile = join(dir, "output.svg");
50
+ try {
51
+ await writeFile(inputFile, block.code);
52
+ await execFileAsync("npx", [
53
+ "mmdc",
54
+ "-i",
55
+ inputFile,
56
+ "-o",
57
+ outputFile,
58
+ "-e",
59
+ "svg"
60
+ ], { timeout: 15e3 });
61
+ return { valid: true };
62
+ } catch (err) {
63
+ const message = err instanceof Error ? err.message : String(err);
64
+ return {
65
+ error: (err && typeof err === "object" && "stderr" in err && typeof err.stderr === "string" ? err.stderr : "").trim() || message,
66
+ valid: false
67
+ };
68
+ } finally {
69
+ await rm(dir, {
70
+ force: true,
71
+ recursive: true
72
+ }).catch(() => {});
73
+ }
74
+ }
75
+ function buildFixPrompt(code, error) {
76
+ return `The following Mermaid diagram has a syntax error. Fix it and return ONLY the corrected Mermaid code — no fences, no explanation.
77
+
78
+ <broken_diagram>
79
+ ${code}
80
+ </broken_diagram>
81
+
82
+ <error>
83
+ ${error}
84
+ </error>
85
+
86
+ Common fixes:
87
+ - Wrap labels with special chars in quotes: A["Label (info)"]
88
+ - Use --> not -> in flowcharts
89
+ - Use ->> not --> in sequence diagrams
90
+ - Use "flowchart" not "graph"
91
+ - Subgraph IDs cannot have spaces
92
+ - No semicolons at end of lines
93
+
94
+ Return ONLY the fixed Mermaid code.`;
95
+ }
96
+ const validateAndFixMermaid = (content, gemini, maxRetries = 2) => Effect.gen(function* () {
97
+ const blocks = extractMermaidBlocks(content);
98
+ if (blocks.length === 0) return content;
99
+ logger.info(`Validating ${blocks.length} Mermaid diagram(s)...`);
100
+ let result = content;
101
+ for (const block of blocks) {
102
+ let currentCode = block.code;
103
+ let attempt = 0;
104
+ let validation = yield* Effect.promise(() => validateBlock({
105
+ ...block,
106
+ code: currentCode
107
+ }));
108
+ while (!validation.valid && attempt < maxRetries) {
109
+ attempt++;
110
+ logger.warn(`Diagram ${block.index + 1} invalid (attempt ${attempt}/${maxRetries}): ${validation.error}`);
111
+ const fixPrompt = buildFixPrompt(currentCode, validation.error ?? "Unknown error");
112
+ currentCode = (yield* Effect.catchAll(gemini.generateContent(fixPrompt), () => Effect.succeed(currentCode))).replace(/^```(?:mermaid)?\s*/i, "").replace(/\s*```\s*$/, "").trim();
113
+ validation = yield* Effect.promise(() => validateBlock({
114
+ ...block,
115
+ code: currentCode
116
+ }));
117
+ }
118
+ if (validation.valid && currentCode !== block.code) {
119
+ logger.success(`Diagram ${block.index + 1} fixed after ${attempt} attempt(s)`);
120
+ result = result.replace(`\`\`\`mermaid\n${block.code}\n\`\`\``, `\`\`\`mermaid\n${currentCode}\n\`\`\``);
121
+ } else if (validation.valid) logger.success(`Diagram ${block.index + 1} valid`);
122
+ else {
123
+ logger.warn(`Diagram ${block.index + 1} could not be fixed, removing it`);
124
+ result = result.replace(`\`\`\`mermaid\n${block.code}\n\`\`\``, "");
125
+ }
126
+ }
127
+ return result;
128
+ });
129
+ //#endregion
130
+ export { MermaidBlock, extractMermaidBlocks, validateAndFixMermaid };
131
+
132
+ //# sourceMappingURL=mermaid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mermaid.js","names":["Logger"],"sources":["../src/mermaid.ts"],"sourcesContent":["/**\n *\n * Copyright 2026 Mike Odnis\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nimport { execFile } from \"node:child_process\";\nimport { mkdtemp, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { Effect, Schema } from \"effect\";\n\nimport type { GeminiServiceApi } from \"./services.js\";\nimport { Logger } from \"./utils/logger.js\";\n\nconst execFileAsync = promisify(execFile);\nconst logger = new Logger(\"GREPO:MERMAID\");\n\nexport const MermaidBlock = Schema.Struct({\n\tcode: Schema.String,\n\tend: Schema.Number,\n\tindex: Schema.Number,\n\tstart: Schema.Number,\n});\nexport type MermaidBlock = Schema.Schema.Type<typeof MermaidBlock>;\n\nexport function extractMermaidBlocks(markdown: string): MermaidBlock[] {\n\tconst blocks: MermaidBlock[] = [];\n\tconst regex = /```mermaid\\n([\\s\\S]*?)```/g;\n\tlet index = 0;\n\n\tfor (\n\t\tlet match = regex.exec(markdown);\n\t\tmatch !== null;\n\t\tmatch = regex.exec(markdown)\n\t) {\n\t\tblocks.push({\n\t\t\tcode: match[1].trim(),\n\t\t\tend: match.index + match[0].length,\n\t\t\tindex: index++,\n\t\t\tstart: match.index,\n\t\t});\n\t}\n\n\treturn blocks;\n}\n\nasync function validateBlock(\n\tblock: MermaidBlock,\n): Promise<{ error?: string; valid: boolean }> {\n\tconst dir = await mkdtemp(join(tmpdir(), \"mermaid-\"));\n\tconst inputFile = join(dir, \"input.mmd\");\n\tconst outputFile = join(dir, \"output.svg\");\n\n\ttry {\n\t\tawait writeFile(inputFile, block.code);\n\n\t\tawait execFileAsync(\n\t\t\t\"npx\",\n\t\t\t[\"mmdc\", \"-i\", inputFile, \"-o\", outputFile, \"-e\", \"svg\"],\n\t\t\t{ timeout: 15_000 },\n\t\t);\n\n\t\treturn { valid: true };\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tconst stderr =\n\t\t\terr &&\n\t\t\ttypeof err === \"object\" &&\n\t\t\t\"stderr\" in err &&\n\t\t\ttypeof err.stderr === \"string\"\n\t\t\t\t? err.stderr\n\t\t\t\t: \"\";\n\t\treturn { error: stderr.trim() || message, valid: false };\n\t} finally {\n\t\tawait rm(dir, { force: true, recursive: true }).catch(() => {});\n\t}\n}\n\nfunction buildFixPrompt(code: string, error: string): string {\n\treturn `The following Mermaid diagram has a syntax error. Fix it and return ONLY the corrected Mermaid code — no fences, no explanation.\n\n<broken_diagram>\n${code}\n</broken_diagram>\n\n<error>\n${error}\n</error>\n\nCommon fixes:\n- Wrap labels with special chars in quotes: A[\"Label (info)\"]\n- Use --> not -> in flowcharts\n- Use ->> not --> in sequence diagrams\n- Use \"flowchart\" not \"graph\"\n- Subgraph IDs cannot have spaces\n- No semicolons at end of lines\n\nReturn ONLY the fixed Mermaid code.`;\n}\n\nexport const validateAndFixMermaid = (\n\tcontent: string,\n\tgemini: GeminiServiceApi,\n\tmaxRetries = 2,\n): Effect.Effect<string, never> =>\n\tEffect.gen(function* () {\n\t\tconst blocks = extractMermaidBlocks(content);\n\t\tif (blocks.length === 0) {\n\t\t\treturn content;\n\t\t}\n\n\t\tlogger.info(`Validating ${blocks.length} Mermaid diagram(s)...`);\n\t\tlet result = content;\n\n\t\tfor (const block of blocks) {\n\t\t\tlet currentCode = block.code;\n\t\t\tlet attempt = 0;\n\t\t\tlet validation = yield* Effect.promise(() =>\n\t\t\t\tvalidateBlock({ ...block, code: currentCode }),\n\t\t\t);\n\n\t\t\twhile (!validation.valid && attempt < maxRetries) {\n\t\t\t\tattempt++;\n\t\t\t\tlogger.warn(\n\t\t\t\t\t`Diagram ${block.index + 1} invalid (attempt ${attempt}/${maxRetries}): ${validation.error}`,\n\t\t\t\t);\n\n\t\t\t\tconst fixPrompt = buildFixPrompt(\n\t\t\t\t\tcurrentCode,\n\t\t\t\t\tvalidation.error ?? \"Unknown error\",\n\t\t\t\t);\n\t\t\t\tconst fixed: string = yield* Effect.catchAll(\n\t\t\t\t\tgemini.generateContent(fixPrompt),\n\t\t\t\t\t() => Effect.succeed(currentCode),\n\t\t\t\t);\n\n\t\t\t\tcurrentCode = fixed\n\t\t\t\t\t.replace(/^```(?:mermaid)?\\s*/i, \"\")\n\t\t\t\t\t.replace(/\\s*```\\s*$/, \"\")\n\t\t\t\t\t.trim();\n\n\t\t\t\tvalidation = yield* Effect.promise(() =>\n\t\t\t\t\tvalidateBlock({ ...block, code: currentCode }),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (validation.valid && currentCode !== block.code) {\n\t\t\t\tlogger.success(\n\t\t\t\t\t`Diagram ${block.index + 1} fixed after ${attempt} attempt(s)`,\n\t\t\t\t);\n\t\t\t\tresult = result.replace(\n\t\t\t\t\t`\\`\\`\\`mermaid\\n${block.code}\\n\\`\\`\\``,\n\t\t\t\t\t`\\`\\`\\`mermaid\\n${currentCode}\\n\\`\\`\\``,\n\t\t\t\t);\n\t\t\t} else if (validation.valid) {\n\t\t\t\tlogger.success(`Diagram ${block.index + 1} valid`);\n\t\t\t} else {\n\t\t\t\tlogger.warn(\n\t\t\t\t\t`Diagram ${block.index + 1} could not be fixed, removing it`,\n\t\t\t\t);\n\t\t\t\tresult = result.replace(`\\`\\`\\`mermaid\\n${block.code}\\n\\`\\`\\``, \"\");\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t});\n"],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ import { DocumentationStyle } from "../config.js";
2
+ import { Schema } from "effect";
3
+
4
+ //#region src/prompts/readme.d.ts
5
+
6
+ declare const DiagramSchema: Schema.Struct<{
7
+ keyNodes: Schema.Array$<typeof Schema.String>;
8
+ purpose: typeof Schema.String;
9
+ scope: typeof Schema.String;
10
+ type: Schema.Literal<["c4-context", "er", "flowchart", "sequence", "state"]>;
11
+ }>;
12
+ declare const ExistingReadmeSchema: Schema.Struct<{
13
+ improve: Schema.Array$<typeof Schema.String>;
14
+ missing: Schema.Array$<typeof Schema.String>;
15
+ preserve: Schema.Array$<typeof Schema.String>;
16
+ quality: Schema.Literal<["decent", "good", "none", "poor"]>;
17
+ }>;
18
+ declare const IdentitySchema: Schema.Struct<{
19
+ differentiators: Schema.Array$<typeof Schema.String>;
20
+ name: typeof Schema.String;
21
+ oneLiner: typeof Schema.String;
22
+ }>;
23
+ declare const SectionsSchema: Schema.Struct<{
24
+ recommended: Schema.Array$<typeof Schema.String>;
25
+ skip: Schema.Array$<Schema.Struct<{
26
+ reason: typeof Schema.String;
27
+ section: typeof Schema.String;
28
+ }>>;
29
+ }>;
30
+ declare const ToneSchema: Schema.Literal<["casual", "minimal", "professional", "technical"]>;
31
+ type Tone = Schema.Schema.Type<typeof ToneSchema>;
32
+ declare const ToneDetectionSchema: Schema.Struct<{
33
+ detected: Schema.Literal<["casual", "minimal", "professional", "technical"]>;
34
+ evidence: typeof Schema.String;
35
+ }>;
36
+ declare const AnalysisResult: Schema.Struct<{
37
+ diagrams: Schema.Array$<Schema.Struct<{
38
+ keyNodes: Schema.Array$<typeof Schema.String>;
39
+ purpose: typeof Schema.String;
40
+ scope: typeof Schema.String;
41
+ type: Schema.Literal<["c4-context", "er", "flowchart", "sequence", "state"]>;
42
+ }>>;
43
+ existingReadme: Schema.Struct<{
44
+ improve: Schema.Array$<typeof Schema.String>;
45
+ missing: Schema.Array$<typeof Schema.String>;
46
+ preserve: Schema.Array$<typeof Schema.String>;
47
+ quality: Schema.Literal<["decent", "good", "none", "poor"]>;
48
+ }>;
49
+ identity: Schema.Struct<{
50
+ differentiators: Schema.Array$<typeof Schema.String>;
51
+ name: typeof Schema.String;
52
+ oneLiner: typeof Schema.String;
53
+ }>;
54
+ repoType: typeof Schema.String;
55
+ sections: Schema.Struct<{
56
+ recommended: Schema.Array$<typeof Schema.String>;
57
+ skip: Schema.Array$<Schema.Struct<{
58
+ reason: typeof Schema.String;
59
+ section: typeof Schema.String;
60
+ }>>;
61
+ }>;
62
+ tone: Schema.Struct<{
63
+ detected: Schema.Literal<["casual", "minimal", "professional", "technical"]>;
64
+ evidence: typeof Schema.String;
65
+ }>;
66
+ }>;
67
+ type AnalysisResult = Schema.Schema.Type<typeof AnalysisResult>;
68
+ declare const GenerationOptions: Schema.Struct<{
69
+ format: Schema.Literal<["md", "mdx"]>;
70
+ style: Schema.Literal<["minimal", "standard", "comprehensive"]>;
71
+ tone: Schema.optional<Schema.Literal<["casual", "minimal", "professional", "technical"]>>;
72
+ }>;
73
+ type GenerationOptions = Schema.Schema.Type<typeof GenerationOptions>;
74
+ declare const RepoData: Schema.Struct<{
75
+ content: typeof Schema.String;
76
+ repo_url: typeof Schema.String;
77
+ summary: typeof Schema.String;
78
+ tree: typeof Schema.String;
79
+ }>;
80
+ type RepoData = Schema.Schema.Type<typeof RepoData>;
81
+ declare const DEFAULT_ANALYSIS: AnalysisResult;
82
+ declare function extractExistingReadme(content: string): string | null;
83
+ declare function parseAnalysis(raw: string): AnalysisResult;
84
+ declare function buildAnalysisPrompt(repoData: RepoData, existingReadme?: string): string;
85
+ declare const STYLE_GUIDANCE: Record<DocumentationStyle, string>;
86
+ declare function buildExistingReadmeInstructions(analysis: AnalysisResult): string;
87
+ declare function buildGenerationPrompt(analysis: AnalysisResult, repoData: RepoData, options: GenerationOptions): string;
88
+ //#endregion
89
+ export { AnalysisResult, DEFAULT_ANALYSIS, DiagramSchema, ExistingReadmeSchema, GenerationOptions, IdentitySchema, RepoData, STYLE_GUIDANCE, SectionsSchema, Tone, ToneDetectionSchema, ToneSchema, buildAnalysisPrompt, buildExistingReadmeInstructions, buildGenerationPrompt, extractExistingReadme, parseAnalysis };
90
+ //# sourceMappingURL=readme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readme.d.ts","names":[],"sources":["../../src/prompts/readme.ts"],"sourcesContent":[],"mappings":";;;;;cA2Ba,eAAa,MAAA,CAAA;EAOO,QAAA,eAAA,CAAA,oBAAA,CAAA;EAAA,OAAA,EAAA,oBAAA;EAOpB,KAAA,EAAA,oBAIX;;;cAXW,sBAAoB,MAAA,CAAA;;EAON,OAAA,eAAA,CAAA,oBAAA,CAAA;EAAA,QAAA,eAAA,CAAA,oBAAA,CAAA;EAMd,OAAA,gBAQX,CAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,EAAA,MAAA,CAAA,CAAA;;cAdW,gBAAc,MAAA,CAAA;;;;;AAMA,cAAd,cAAc,EAAA,MAAA,CAAA,MAAA,CAAA;EAAA,WAAA,eAAA,CAAA,oBAAA,CAAA;EAUd,IAAA,eAKZ,cALsB,CAAA;IAMX,MAAI,EAAA,oBAAG;IAEN,OAAA,EAAA,oBAGX;;;AAH8B,cARnB,UAQmB,EART,MAAA,CAAA,OAQS,CAAA,CAAA,QAAA,EAAA,SAAA,EAAA,cAAA,EAAA,WAAA,CAAA,CAAA;AAAA,KAFpB,IAAA,GAAO,MAAA,CAAO,MAAA,CAAO,IAED,CAAA,OAFa,UAEb,CAAA;AAKnB,cALA,mBAYX,EAZ8B,MAAA,CAAA,MAY9B,CAAA;;;;cAPW,gBAAc,MAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAAA,QAAA,EAAA,oBAAA;EAAA,CAAA,CAAA;AAQ3B,CAAA,CAAA;AAEa,KAFD,cAAA,GAAiB,MAAA,CAAO,MAAA,CAAO,IAMzC,CAAA,OANqD,cAMrD,CAAA;cAJW,mBAAiB,MAAA,CAAA;;;;CAAA,CAAA;AAAA,KAKlB,iBAAA,GAAoB,MAAA,CAAO,MAAA,CAAO,IALhB,CAAA,OAK4B,iBAL5B,CAAA;AAKlB,cAMC,QANgB,EAMR,MAAA,CAAA,MANqC,CAAA;EAM7C,OAAA,EAAA,oBAKX;;;;;AALmB,KAMT,QAAA,GAAW,MAAA,CAAO,MAAA,CAAO,IANhB,CAAA,OAM4B,QAN5B,CAAA;AAAA,cAYR,gBAZQ,EAYU,cAZV;AAMT,iBA0CI,qBAAA,CA1Cc,OAAO,EAAA,MAAI,CAAA,EAAA,MAAA,GAAA,IAAA;AAM5B,iBA+CG,aAAA,CA/Ce,GAAA,EAAA,MAAA,CA8B9B,EAiB2C,cAjB3C;AAMe,iBAyCA,mBAAA,CAzCqB,QAAA,EA0C1B,QA1C0B,EAAA,cAAA,CAAA,EAAA,MAAA,CAAA,EAAA,MAAA;AAWrB,cA4HH,cA5H+B,EA4Hf,MA5He,CA4HR,kBA5HsB,EAAA,MAAA,CAAA;AA8B1C,iBAuGA,+BAAA,CAtGG,QAAA,EAuGR,cAvGQ,CAAA,EAAA,MAAA;AA6FN,iBA6CG,qBAAA,CA7CoB,QAAP,EA8ClB,cA9CwB,EAAA,QAAA,EA+CxB,QA/CwB,EAAA,OAAA,EAgDzB,iBAhDyB,CAAA,EAAA,MAAA"}