diffdoc 0.6.0 → 0.6.2

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.
@@ -22,34 +22,22 @@ function getSummaryPath(summaryDir, hash) {
22
22
  return node_path_1.default.resolve(summaryDir, `${hash}.json`);
23
23
  }
24
24
  async function readManifest(manifestPath) {
25
- const parsed = JSON.parse(await promises_1.default.readFile(manifestPath, "utf8"));
26
- if (parsed.schemaVersion !== artifacts_1.MANIFEST_SCHEMA_VERSION) {
27
- throw new Error(`Unsupported manifest schema in ${manifestPath}. Expected schemaVersion ${artifacts_1.MANIFEST_SCHEMA_VERSION}.`);
25
+ const raw = JSON.parse(await promises_1.default.readFile(manifestPath, "utf8"));
26
+ const result = artifacts_1.RepoManifestSchema.safeParse(raw);
27
+ if (!result.success) {
28
+ const issues = result.error.issues.map((i) => ` - ${i.path.join(".")}: ${i.message}`).join("\n");
29
+ throw new Error(`Invalid manifest in ${manifestPath}:\n${issues}`);
28
30
  }
29
- return {
30
- schemaVersion: artifacts_1.MANIFEST_SCHEMA_VERSION,
31
- lastSyncedCommit: typeof parsed.lastSyncedCommit === "string" ? parsed.lastSyncedCommit : "",
32
- files: parsed.files && typeof parsed.files === "object" ? parsed.files : {}
33
- };
31
+ return result.data;
34
32
  }
35
33
  async function readSummaryAsset(summaryPath) {
36
- const parsed = JSON.parse(await promises_1.default.readFile(summaryPath, "utf8"));
37
- if (typeof parsed.schemaVersion !== "number" || parsed.schemaVersion < 1 || parsed.schemaVersion > artifacts_1.SUMMARY_ASSET_SCHEMA_VERSION) {
38
- throw new Error(`Unsupported summary schema in ${summaryPath}. Expected schemaVersion 1-${artifacts_1.SUMMARY_ASSET_SCHEMA_VERSION}.`);
34
+ const raw = JSON.parse(await promises_1.default.readFile(summaryPath, "utf8"));
35
+ const result = artifacts_1.SummaryAssetSchema.safeParse(raw);
36
+ if (!result.success) {
37
+ const issues = result.error.issues.map((i) => ` - ${i.path.join(".")}: ${i.message}`).join("\n");
38
+ throw new Error(`Invalid summary asset in ${summaryPath}:\n${issues}`);
39
39
  }
40
- if (typeof parsed.content_hash !== "string") {
41
- throw new Error(`Invalid summary hash in ${summaryPath}.`);
42
- }
43
- if (typeof parsed.summary !== "string") {
44
- throw new Error(`Invalid summary text in ${summaryPath}.`);
45
- }
46
- return {
47
- schemaVersion: parsed.schemaVersion,
48
- content_hash: parsed.content_hash,
49
- metadata: parsed.metadata && typeof parsed.metadata === "object" ? parsed.metadata : undefined,
50
- summary: parsed.summary,
51
- raw_code_snapshot: typeof parsed.raw_code_snapshot === "string" ? parsed.raw_code_snapshot : undefined
52
- };
40
+ return result.data;
53
41
  }
54
42
  function buildDocument(summaryAsset) {
55
43
  return summaryAsset.summary;
@@ -8,7 +8,9 @@ const promises_1 = __importDefault(require("node:fs/promises"));
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const promises_2 = require("node:readline/promises");
10
10
  const node_process_1 = require("node:process");
11
+ const schemas_1 = require("../schemas");
11
12
  const DEFAULT_CONFIG = {
13
+ $schema: `${schemas_1.SCHEMA_BASE_URL}/diffdocrc.schema.json`,
12
14
  baseDir: "./.diffdoc",
13
15
  aiProvider: "local",
14
16
  localLlmEndpoint: "http://localhost:11434/v1",
@@ -26,18 +26,12 @@ async function readManifest(manifestPath) {
26
26
  }
27
27
  throw error;
28
28
  }
29
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
30
- throw new Error(`Invalid manifest JSON in ${manifestPath}. Expected an object.`);
29
+ const result = artifacts_1.RepoManifestSchema.safeParse(parsed);
30
+ if (!result.success) {
31
+ const issues = result.error.issues.map((i) => ` - ${i.path.join(".")}: ${i.message}`).join("\n");
32
+ throw new Error(`Invalid manifest in ${manifestPath}:\n${issues}`);
31
33
  }
32
- const manifest = parsed;
33
- if (manifest.schemaVersion !== artifacts_1.MANIFEST_SCHEMA_VERSION) {
34
- throw new Error(`Unsupported manifest schema in ${manifestPath}. Expected schemaVersion ${artifacts_1.MANIFEST_SCHEMA_VERSION}.`);
35
- }
36
- return {
37
- schemaVersion: artifacts_1.MANIFEST_SCHEMA_VERSION,
38
- lastSyncedCommit: typeof manifest.lastSyncedCommit === "string" ? manifest.lastSyncedCommit : "",
39
- files: manifest.files && typeof manifest.files === "object" ? manifest.files : {}
40
- };
34
+ return result.data;
41
35
  }
42
36
  async function getSummaryStats(manifestPath, manifest) {
43
37
  const summaryDir = getSummaryDir(manifestPath);
@@ -71,19 +65,18 @@ async function getSummaryStats(manifestPath, manifest) {
71
65
  continue;
72
66
  }
73
67
  try {
74
- const parsed = JSON.parse(await promises_1.default.readFile(node_path_1.default.resolve(summaryDir, `${hash}.json`), "utf8"));
75
- const metadata = parsed.metadata && typeof parsed.metadata === "object" && !Array.isArray(parsed.metadata)
76
- ? parsed.metadata
77
- : undefined;
78
- if (parsed.schemaVersion !== artifacts_1.SUMMARY_ASSET_SCHEMA_VERSION ||
79
- parsed.content_hash !== hash ||
80
- !metadata ||
81
- typeof metadata.file_path !== "string" ||
82
- typeof metadata.file_name !== "string" ||
83
- typeof metadata.extension !== "string" ||
84
- metadata.content_hash !== hash ||
85
- metadata.prompt_version !== llm_1.SUMMARY_PROMPT_VERSION ||
86
- metadata.summary_format !== llm_1.SUMMARY_FORMAT) {
68
+ const raw = JSON.parse(await promises_1.default.readFile(node_path_1.default.resolve(summaryDir, `${hash}.json`), "utf8"));
69
+ const result = artifacts_1.SummaryAssetSchema.safeParse(raw);
70
+ if (!result.success) {
71
+ staleCount += 1;
72
+ continue;
73
+ }
74
+ const asset = result.data;
75
+ if (asset.content_hash !== hash ||
76
+ !asset.metadata ||
77
+ asset.metadata.content_hash !== hash ||
78
+ asset.metadata.prompt_version !== llm_1.SUMMARY_PROMPT_VERSION ||
79
+ asset.metadata.summary_format !== llm_1.SUMMARY_FORMAT) {
87
80
  staleCount += 1;
88
81
  }
89
82
  }
@@ -8,10 +8,13 @@ const promises_1 = __importDefault(require("node:fs/promises"));
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const ignore_1 = __importDefault(require("ignore"));
10
10
  const artifacts_1 = require("../types/artifacts");
11
+ const schemas_1 = require("../schemas");
11
12
  const git_1 = require("../utils/git");
12
13
  const hashing_1 = require("../utils/hashing");
13
14
  const llm_1 = require("../utils/llm");
14
15
  const paths_1 = require("../utils/paths");
16
+ const MANIFEST_SCHEMA_URL = `${schemas_1.SCHEMA_BASE_URL}/manifest.schema.json`;
17
+ const SUMMARY_ASSET_SCHEMA_URL = `${schemas_1.SCHEMA_BASE_URL}/summary-asset.schema.json`;
15
18
  function normalizeRelativePath(filePath) {
16
19
  return filePath.split(node_path_1.default.sep).join("/");
17
20
  }
@@ -158,20 +161,19 @@ async function isSummaryAssetFresh(summaryPath, expected) {
158
161
  }
159
162
  async function readManifest(manifestPath) {
160
163
  try {
161
- const parsed = JSON.parse(await promises_1.default.readFile(manifestPath, "utf8"));
162
- if (parsed.schemaVersion !== artifacts_1.MANIFEST_SCHEMA_VERSION) {
163
- throw new Error(`Unsupported manifest schema in ${manifestPath}. Expected schemaVersion ${artifacts_1.MANIFEST_SCHEMA_VERSION}.`);
164
+ const raw = JSON.parse(await promises_1.default.readFile(manifestPath, "utf8"));
165
+ const result = artifacts_1.RepoManifestSchema.safeParse(raw);
166
+ if (!result.success) {
167
+ const issues = result.error.issues.map((i) => ` - ${i.path.join(".")}: ${i.message}`).join("\n");
168
+ throw new Error(`Invalid manifest in ${manifestPath}:\n${issues}`);
164
169
  }
165
- return {
166
- schemaVersion: artifacts_1.MANIFEST_SCHEMA_VERSION,
167
- lastSyncedCommit: typeof parsed.lastSyncedCommit === "string" ? parsed.lastSyncedCommit : "",
168
- files: parsed.files && typeof parsed.files === "object" ? parsed.files : {}
169
- };
170
+ return result.data;
170
171
  }
171
172
  catch (error) {
172
173
  const nodeError = error;
173
174
  if (nodeError.code === "ENOENT") {
174
175
  return {
176
+ $schema: MANIFEST_SCHEMA_URL,
175
177
  schemaVersion: artifacts_1.MANIFEST_SCHEMA_VERSION,
176
178
  lastSyncedCommit: "",
177
179
  files: {}
@@ -270,6 +272,7 @@ async function removeManifestPath(filePath, manifest, manifestPath, summaryDir,
270
272
  async function ensureSummaryAsset(summaryDir, hash, metadata, summaryText, rawCodeSnapshot, includeCodeSnapshot) {
271
273
  const summaryPath = getSummaryPath(summaryDir, hash);
272
274
  const summary = {
275
+ $schema: SUMMARY_ASSET_SCHEMA_URL,
273
276
  schemaVersion: artifacts_1.SUMMARY_ASSET_SCHEMA_VERSION,
274
277
  content_hash: hash,
275
278
  metadata,
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.runValidate = runValidate;
7
+ const promises_1 = __importDefault(require("node:fs/promises"));
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const artifacts_1 = require("../types/artifacts");
10
+ const paths_1 = require("../utils/paths");
11
+ function getSummaryDir(manifestPath) {
12
+ return node_path_1.default.resolve(node_path_1.default.dirname(manifestPath), "summaries");
13
+ }
14
+ async function runValidate(options, config) {
15
+ const manifestPath = (0, paths_1.resolveDiffdocArtifactPath)(options.manifest, config.baseDir);
16
+ const issues = [];
17
+ let manifestValid = false;
18
+ let summaryAssetsChecked = 0;
19
+ let summaryAssetsValid = 0;
20
+ // Validate manifest
21
+ let manifestData;
22
+ try {
23
+ manifestData = JSON.parse(await promises_1.default.readFile(manifestPath, "utf8"));
24
+ }
25
+ catch (error) {
26
+ const nodeError = error;
27
+ if (nodeError.code === "ENOENT") {
28
+ issues.push({ file: manifestPath, path: "", message: "Manifest file not found." });
29
+ }
30
+ else {
31
+ issues.push({ file: manifestPath, path: "", message: `Failed to parse JSON: ${error.message}` });
32
+ }
33
+ manifestData = undefined;
34
+ }
35
+ if (manifestData !== undefined) {
36
+ const result = artifacts_1.RepoManifestSchema.safeParse(manifestData);
37
+ if (result.success) {
38
+ manifestValid = true;
39
+ // Validate each referenced summary asset
40
+ const summaryDir = getSummaryDir(manifestPath);
41
+ const hashes = new Set(Object.values(result.data.files));
42
+ for (const hash of hashes) {
43
+ summaryAssetsChecked += 1;
44
+ const summaryPath = node_path_1.default.resolve(summaryDir, `${hash}.json`);
45
+ let summaryRaw;
46
+ try {
47
+ summaryRaw = JSON.parse(await promises_1.default.readFile(summaryPath, "utf8"));
48
+ }
49
+ catch (error) {
50
+ const nodeError = error;
51
+ if (nodeError.code === "ENOENT") {
52
+ issues.push({ file: summaryPath, path: "", message: "Summary asset file not found." });
53
+ }
54
+ else {
55
+ issues.push({ file: summaryPath, path: "", message: `Failed to parse JSON: ${error.message}` });
56
+ }
57
+ continue;
58
+ }
59
+ const assetResult = artifacts_1.SummaryAssetSchema.safeParse(summaryRaw);
60
+ if (assetResult.success) {
61
+ // Cross-check content_hash matches filename
62
+ if (assetResult.data.content_hash !== hash) {
63
+ issues.push({ file: summaryPath, path: "content_hash", message: `Expected "${hash}" but got "${assetResult.data.content_hash}".` });
64
+ }
65
+ else {
66
+ summaryAssetsValid += 1;
67
+ }
68
+ }
69
+ else {
70
+ for (const issue of assetResult.error.issues) {
71
+ issues.push({ file: summaryPath, path: issue.path.join("."), message: issue.message });
72
+ }
73
+ }
74
+ }
75
+ }
76
+ else {
77
+ for (const issue of result.error.issues) {
78
+ issues.push({ file: manifestPath, path: issue.path.join("."), message: issue.message });
79
+ }
80
+ }
81
+ }
82
+ const report = {
83
+ valid: manifestValid && issues.length === 0,
84
+ manifestPath,
85
+ manifestValid,
86
+ summaryAssetsChecked,
87
+ summaryAssetsValid,
88
+ issues
89
+ };
90
+ if (options.json) {
91
+ console.log(JSON.stringify(report, null, 2));
92
+ }
93
+ else {
94
+ console.log(`Manifest: ${manifestPath}`);
95
+ console.log(`Manifest valid: ${manifestValid ? "yes" : "NO"}`);
96
+ console.log(`Summary assets checked: ${summaryAssetsChecked}`);
97
+ console.log(`Summary assets valid: ${summaryAssetsValid}`);
98
+ console.log("---");
99
+ if (issues.length === 0) {
100
+ console.log("All artifacts pass schema validation.");
101
+ }
102
+ else {
103
+ console.log(`Issues (${issues.length}):`);
104
+ for (const issue of issues) {
105
+ const location = issue.path ? `${issue.file} -> ${issue.path}` : issue.file;
106
+ console.log(` - ${location}: ${issue.message}`);
107
+ }
108
+ }
109
+ }
110
+ if (!report.valid) {
111
+ process.exitCode = 1;
112
+ }
113
+ }
package/dist/config.js CHANGED
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.buildRuntimeConfig = buildRuntimeConfig;
7
7
  const node_fs_1 = __importDefault(require("node:fs"));
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
+ const schemas_1 = require("./schemas");
9
10
  function readOption(value, envName, fallback = "") {
10
11
  return value || process.env[envName] || fallback;
11
12
  }
@@ -56,7 +57,12 @@ function loadRcFile(configPath) {
56
57
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
57
58
  throw new Error(`Config file must contain a JSON object: ${resolvedPath}`);
58
59
  }
59
- return parsed;
60
+ const result = schemas_1.DiffdocConfigSchema.safeParse(parsed);
61
+ if (!result.success) {
62
+ const issues = result.error.issues.map((i) => ` - ${i.path.join(".")}: ${i.message}`).join("\n");
63
+ throw new Error(`Invalid config file ${resolvedPath}:\n${issues}`);
64
+ }
65
+ return result.data;
60
66
  }
61
67
  function mergeConfigOptions(options) {
62
68
  const rcOptions = loadRcFile(options.config);
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ const init_1 = require("./commands/init");
8
8
  const query_1 = require("./commands/query");
9
9
  const status_1 = require("./commands/status");
10
10
  const summarize_1 = require("./commands/summarize");
11
+ const validate_1 = require("./commands/validate");
11
12
  const program = new commander_1.Command();
12
13
  function collectOption(value, previous) {
13
14
  previous.push(value);
@@ -157,6 +158,21 @@ addBaseOptions(program
157
158
  process.exit(1);
158
159
  }
159
160
  });
161
+ addBaseOptions(program
162
+ .command("validate"))
163
+ .description("Validate manifest and summary assets against JSON schemas")
164
+ .option("--manifest <path>", "manifest input path under --base-dir", "manifest.json")
165
+ .option("--json", "print validation report as JSON for CI", false)
166
+ .action(async (options) => {
167
+ try {
168
+ const config = (0, config_1.buildRuntimeConfig)(options, { embeddings: false, chat: false });
169
+ await (0, validate_1.runValidate)({ manifest: options.manifest, json: options.json }, config);
170
+ }
171
+ catch (error) {
172
+ console.error(error instanceof Error ? error.message : error);
173
+ process.exit(1);
174
+ }
175
+ });
160
176
  program.parseAsync(process.argv).catch((error) => {
161
177
  console.error(error instanceof Error ? error.message : error);
162
178
  process.exit(1);
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SummaryAssetSchema = exports.SummaryMetadataSchema = exports.RepoManifestSchema = exports.DiffdocConfigSchema = exports.SCHEMA_BASE_URL = exports.SCHEMA_DIR_VERSION = exports.SUMMARY_ASSET_SCHEMA_VERSION = exports.MANIFEST_SCHEMA_VERSION = void 0;
4
+ const zod_1 = require("zod");
5
+ // ---------------------------------------------------------------------------
6
+ // Schema version constants
7
+ // ---------------------------------------------------------------------------
8
+ exports.MANIFEST_SCHEMA_VERSION = 2;
9
+ exports.SUMMARY_ASSET_SCHEMA_VERSION = 2;
10
+ exports.SCHEMA_DIR_VERSION = 2;
11
+ exports.SCHEMA_BASE_URL = `https://raw.githubusercontent.com/sullyTheDev/diffdoc/main/schemas/v${exports.SCHEMA_DIR_VERSION}`;
12
+ // ---------------------------------------------------------------------------
13
+ // Configuration schema (.diffdocrc)
14
+ // ---------------------------------------------------------------------------
15
+ exports.DiffdocConfigSchema = zod_1.z.object({
16
+ $schema: zod_1.z.string().optional(),
17
+ baseDir: zod_1.z.string().optional(),
18
+ aiProvider: zod_1.z.enum(["local", "cloud"]).optional(),
19
+ localLlmEndpoint: zod_1.z.string().optional(),
20
+ localEmbedEndpoint: zod_1.z.string().optional(),
21
+ localChatModel: zod_1.z.string().optional(),
22
+ localEmbedModel: zod_1.z.string().optional(),
23
+ cloudLlmEndpoint: zod_1.z.string().optional(),
24
+ cloudChatModel: zod_1.z.string().optional(),
25
+ cloudEmbedModel: zod_1.z.string().optional(),
26
+ embedBatchSize: zod_1.z.union([zod_1.z.number().int().positive(), zod_1.z.string()]).optional(),
27
+ summarizeConcurrency: zod_1.z.union([zod_1.z.number().int().positive(), zod_1.z.string()]).optional(),
28
+ openaiApiKey: zod_1.z.string().optional(),
29
+ includeGlobs: zod_1.z.union([zod_1.z.array(zod_1.z.string()), zod_1.z.string()]).optional(),
30
+ excludeGlobs: zod_1.z.union([zod_1.z.array(zod_1.z.string()), zod_1.z.string()]).optional(),
31
+ ignoreFile: zod_1.z.string().optional(),
32
+ summaryPrompt: zod_1.z.string().optional(),
33
+ summaryPromptFile: zod_1.z.string().optional()
34
+ }).strict();
35
+ // ---------------------------------------------------------------------------
36
+ // Repository manifest schema
37
+ // ---------------------------------------------------------------------------
38
+ exports.RepoManifestSchema = zod_1.z.object({
39
+ $schema: zod_1.z.string().optional(),
40
+ schemaVersion: zod_1.z.literal(exports.MANIFEST_SCHEMA_VERSION),
41
+ lastSyncedCommit: zod_1.z.string(),
42
+ files: zod_1.z.record(zod_1.z.string(), zod_1.z.string())
43
+ });
44
+ // ---------------------------------------------------------------------------
45
+ // Summary metadata schema (nested within summary assets)
46
+ // ---------------------------------------------------------------------------
47
+ exports.SummaryMetadataSchema = zod_1.z.object({
48
+ file_path: zod_1.z.string(),
49
+ file_name: zod_1.z.string(),
50
+ extension: zod_1.z.string(),
51
+ line_count: zod_1.z.number().int().nonnegative(),
52
+ byte_size: zod_1.z.number().int().nonnegative(),
53
+ content_hash: zod_1.z.string(),
54
+ generated_at: zod_1.z.string(),
55
+ generator: zod_1.z.object({
56
+ provider: zod_1.z.string(),
57
+ model: zod_1.z.string()
58
+ }),
59
+ prompt_version: zod_1.z.number().int(),
60
+ summary_format: zod_1.z.string(),
61
+ custom_prompt_hash: zod_1.z.string().optional(),
62
+ custom_prompt_source: zod_1.z.string().optional()
63
+ });
64
+ // ---------------------------------------------------------------------------
65
+ // Summary asset schema (individual hash-named JSON files)
66
+ // ---------------------------------------------------------------------------
67
+ exports.SummaryAssetSchema = zod_1.z.object({
68
+ $schema: zod_1.z.string().optional(),
69
+ schemaVersion: zod_1.z.literal(exports.SUMMARY_ASSET_SCHEMA_VERSION),
70
+ content_hash: zod_1.z.string(),
71
+ metadata: exports.SummaryMetadataSchema.optional(),
72
+ summary: zod_1.z.string(),
73
+ raw_code_snapshot: zod_1.z.string().optional()
74
+ });
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_fs_1 = __importDefault(require("node:fs"));
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const zod_to_json_schema_1 = require("zod-to-json-schema");
9
+ const schemas_1 = require("../schemas");
10
+ const schemas = [
11
+ { name: "diffdocrc.schema.json", zodSchema: schemas_1.DiffdocConfigSchema },
12
+ { name: "manifest.schema.json", zodSchema: schemas_1.RepoManifestSchema },
13
+ { name: "summary-asset.schema.json", zodSchema: schemas_1.SummaryAssetSchema }
14
+ ];
15
+ const outDir = node_path_1.default.resolve(__dirname, `../../schemas/v${schemas_1.SCHEMA_DIR_VERSION}`);
16
+ node_fs_1.default.mkdirSync(outDir, { recursive: true });
17
+ for (const entry of schemas) {
18
+ const jsonSchema = (0, zod_to_json_schema_1.zodToJsonSchema)(entry.zodSchema, {
19
+ name: entry.name.replace(".schema.json", ""),
20
+ $refStrategy: "none"
21
+ });
22
+ const schemaWithId = {
23
+ ...jsonSchema,
24
+ $id: `${schemas_1.SCHEMA_BASE_URL}/${entry.name}`
25
+ };
26
+ const outPath = node_path_1.default.resolve(outDir, entry.name);
27
+ node_fs_1.default.writeFileSync(outPath, `${JSON.stringify(schemaWithId, null, 2)}\n`);
28
+ console.log(`Generated: ${outPath}`);
29
+ }
30
+ console.log("Schema generation complete.");
@@ -1,5 +1,14 @@
1
1
  "use strict";
2
+ // Re-export all schema definitions and types from the canonical source.
3
+ // This file exists for backwards-compatible import paths.
2
4
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SUMMARY_ASSET_SCHEMA_VERSION = exports.MANIFEST_SCHEMA_VERSION = void 0;
4
- exports.MANIFEST_SCHEMA_VERSION = 2;
5
- exports.SUMMARY_ASSET_SCHEMA_VERSION = 2;
5
+ exports.DiffdocConfigSchema = exports.SummaryAssetSchema = exports.SummaryMetadataSchema = exports.RepoManifestSchema = exports.SCHEMA_BASE_URL = exports.SCHEMA_DIR_VERSION = exports.SUMMARY_ASSET_SCHEMA_VERSION = exports.MANIFEST_SCHEMA_VERSION = void 0;
6
+ var schemas_1 = require("../schemas");
7
+ Object.defineProperty(exports, "MANIFEST_SCHEMA_VERSION", { enumerable: true, get: function () { return schemas_1.MANIFEST_SCHEMA_VERSION; } });
8
+ Object.defineProperty(exports, "SUMMARY_ASSET_SCHEMA_VERSION", { enumerable: true, get: function () { return schemas_1.SUMMARY_ASSET_SCHEMA_VERSION; } });
9
+ Object.defineProperty(exports, "SCHEMA_DIR_VERSION", { enumerable: true, get: function () { return schemas_1.SCHEMA_DIR_VERSION; } });
10
+ Object.defineProperty(exports, "SCHEMA_BASE_URL", { enumerable: true, get: function () { return schemas_1.SCHEMA_BASE_URL; } });
11
+ Object.defineProperty(exports, "RepoManifestSchema", { enumerable: true, get: function () { return schemas_1.RepoManifestSchema; } });
12
+ Object.defineProperty(exports, "SummaryMetadataSchema", { enumerable: true, get: function () { return schemas_1.SummaryMetadataSchema; } });
13
+ Object.defineProperty(exports, "SummaryAssetSchema", { enumerable: true, get: function () { return schemas_1.SummaryAssetSchema; } });
14
+ Object.defineProperty(exports, "DiffdocConfigSchema", { enumerable: true, get: function () { return schemas_1.DiffdocConfigSchema; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "diffdoc",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "Translate repository code shifts into plain-English business context",
5
5
  "license": "MIT",
6
6
  "author": "Christopher Sullivan",
@@ -20,6 +20,7 @@
20
20
  },
21
21
  "files": [
22
22
  "dist",
23
+ "schemas",
23
24
  "README.md",
24
25
  "LICENSE",
25
26
  ".diffdocrc.example"
@@ -28,7 +29,8 @@
28
29
  "node": ">=22"
29
30
  },
30
31
  "scripts": {
31
- "build": "tsc",
32
+ "build": "tsc && node dist/scripts/generate-schemas.js",
33
+ "generate:schemas": "node dist/scripts/generate-schemas.js",
32
34
  "clean": "node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"",
33
35
  "start": "tsc && node ./dist/index.js",
34
36
  "prepare": "npm run build"
@@ -44,6 +46,7 @@
44
46
  },
45
47
  "devDependencies": {
46
48
  "@types/node": "^20.19.41",
47
- "typescript": "^5.3.3"
49
+ "typescript": "^5.3.3",
50
+ "zod-to-json-schema": "^3.25.2"
48
51
  }
49
52
  }
@@ -0,0 +1,107 @@
1
+ {
2
+ "$ref": "#/definitions/diffdocrc",
3
+ "definitions": {
4
+ "diffdocrc": {
5
+ "type": "object",
6
+ "properties": {
7
+ "$schema": {
8
+ "type": "string"
9
+ },
10
+ "baseDir": {
11
+ "type": "string"
12
+ },
13
+ "aiProvider": {
14
+ "type": "string",
15
+ "enum": [
16
+ "local",
17
+ "cloud"
18
+ ]
19
+ },
20
+ "localLlmEndpoint": {
21
+ "type": "string"
22
+ },
23
+ "localEmbedEndpoint": {
24
+ "type": "string"
25
+ },
26
+ "localChatModel": {
27
+ "type": "string"
28
+ },
29
+ "localEmbedModel": {
30
+ "type": "string"
31
+ },
32
+ "cloudLlmEndpoint": {
33
+ "type": "string"
34
+ },
35
+ "cloudChatModel": {
36
+ "type": "string"
37
+ },
38
+ "cloudEmbedModel": {
39
+ "type": "string"
40
+ },
41
+ "embedBatchSize": {
42
+ "anyOf": [
43
+ {
44
+ "type": "integer",
45
+ "exclusiveMinimum": 0
46
+ },
47
+ {
48
+ "type": "string"
49
+ }
50
+ ]
51
+ },
52
+ "summarizeConcurrency": {
53
+ "anyOf": [
54
+ {
55
+ "type": "integer",
56
+ "exclusiveMinimum": 0
57
+ },
58
+ {
59
+ "type": "string"
60
+ }
61
+ ]
62
+ },
63
+ "openaiApiKey": {
64
+ "type": "string"
65
+ },
66
+ "includeGlobs": {
67
+ "anyOf": [
68
+ {
69
+ "type": "array",
70
+ "items": {
71
+ "type": "string"
72
+ }
73
+ },
74
+ {
75
+ "type": "string"
76
+ }
77
+ ]
78
+ },
79
+ "excludeGlobs": {
80
+ "anyOf": [
81
+ {
82
+ "type": "array",
83
+ "items": {
84
+ "type": "string"
85
+ }
86
+ },
87
+ {
88
+ "type": "string"
89
+ }
90
+ ]
91
+ },
92
+ "ignoreFile": {
93
+ "type": "string"
94
+ },
95
+ "summaryPrompt": {
96
+ "type": "string"
97
+ },
98
+ "summaryPromptFile": {
99
+ "type": "string"
100
+ }
101
+ },
102
+ "additionalProperties": false
103
+ }
104
+ },
105
+ "$schema": "http://json-schema.org/draft-07/schema#",
106
+ "$id": "https://raw.githubusercontent.com/sullyTheDev/diffdoc/main/schemas/v2/diffdocrc.schema.json"
107
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "$ref": "#/definitions/manifest",
3
+ "definitions": {
4
+ "manifest": {
5
+ "type": "object",
6
+ "properties": {
7
+ "$schema": {
8
+ "type": "string"
9
+ },
10
+ "schemaVersion": {
11
+ "type": "number",
12
+ "const": 2
13
+ },
14
+ "lastSyncedCommit": {
15
+ "type": "string"
16
+ },
17
+ "files": {
18
+ "type": "object",
19
+ "additionalProperties": {
20
+ "type": "string"
21
+ }
22
+ }
23
+ },
24
+ "required": [
25
+ "schemaVersion",
26
+ "lastSyncedCommit",
27
+ "files"
28
+ ],
29
+ "additionalProperties": false
30
+ }
31
+ },
32
+ "$schema": "http://json-schema.org/draft-07/schema#",
33
+ "$id": "https://raw.githubusercontent.com/sullyTheDev/diffdoc/main/schemas/v2/manifest.schema.json"
34
+ }
@@ -0,0 +1,103 @@
1
+ {
2
+ "$ref": "#/definitions/summary-asset",
3
+ "definitions": {
4
+ "summary-asset": {
5
+ "type": "object",
6
+ "properties": {
7
+ "$schema": {
8
+ "type": "string"
9
+ },
10
+ "schemaVersion": {
11
+ "type": "number",
12
+ "const": 2
13
+ },
14
+ "content_hash": {
15
+ "type": "string"
16
+ },
17
+ "metadata": {
18
+ "type": "object",
19
+ "properties": {
20
+ "file_path": {
21
+ "type": "string"
22
+ },
23
+ "file_name": {
24
+ "type": "string"
25
+ },
26
+ "extension": {
27
+ "type": "string"
28
+ },
29
+ "line_count": {
30
+ "type": "integer",
31
+ "minimum": 0
32
+ },
33
+ "byte_size": {
34
+ "type": "integer",
35
+ "minimum": 0
36
+ },
37
+ "content_hash": {
38
+ "type": "string"
39
+ },
40
+ "generated_at": {
41
+ "type": "string"
42
+ },
43
+ "generator": {
44
+ "type": "object",
45
+ "properties": {
46
+ "provider": {
47
+ "type": "string"
48
+ },
49
+ "model": {
50
+ "type": "string"
51
+ }
52
+ },
53
+ "required": [
54
+ "provider",
55
+ "model"
56
+ ],
57
+ "additionalProperties": false
58
+ },
59
+ "prompt_version": {
60
+ "type": "integer"
61
+ },
62
+ "summary_format": {
63
+ "type": "string"
64
+ },
65
+ "custom_prompt_hash": {
66
+ "type": "string"
67
+ },
68
+ "custom_prompt_source": {
69
+ "type": "string"
70
+ }
71
+ },
72
+ "required": [
73
+ "file_path",
74
+ "file_name",
75
+ "extension",
76
+ "line_count",
77
+ "byte_size",
78
+ "content_hash",
79
+ "generated_at",
80
+ "generator",
81
+ "prompt_version",
82
+ "summary_format"
83
+ ],
84
+ "additionalProperties": false
85
+ },
86
+ "summary": {
87
+ "type": "string"
88
+ },
89
+ "raw_code_snapshot": {
90
+ "type": "string"
91
+ }
92
+ },
93
+ "required": [
94
+ "schemaVersion",
95
+ "content_hash",
96
+ "summary"
97
+ ],
98
+ "additionalProperties": false
99
+ }
100
+ },
101
+ "$schema": "http://json-schema.org/draft-07/schema#",
102
+ "$id": "https://raw.githubusercontent.com/sullyTheDev/diffdoc/main/schemas/v2/summary-asset.schema.json"
103
+ }