@commentray/core 0.0.1
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 +373 -0
- package/README.md +29 -0
- package/dist/anchors.d.ts +22 -0
- package/dist/anchors.d.ts.map +1 -0
- package/dist/anchors.js +29 -0
- package/dist/anchors.js.map +1 -0
- package/dist/cli-bootstrap.d.ts +6 -0
- package/dist/cli-bootstrap.d.ts.map +1 -0
- package/dist/cli-bootstrap.js +14 -0
- package/dist/cli-bootstrap.js.map +1 -0
- package/dist/config.d.ts +53 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +113 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/metadata.d.ts +4 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +55 -0
- package/dist/metadata.js.map +1 -0
- package/dist/migrate.d.ts +7 -0
- package/dist/migrate.d.ts.map +1 -0
- package/dist/migrate.js +54 -0
- package/dist/migrate.js.map +1 -0
- package/dist/model.d.ts +27 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +2 -0
- package/dist/model.js.map +1 -0
- package/dist/paths.d.ts +18 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +35 -0
- package/dist/paths.js.map +1 -0
- package/dist/scm/git-scm-provider.d.ts +6 -0
- package/dist/scm/git-scm-provider.d.ts.map +1 -0
- package/dist/scm/git-scm-provider.js +50 -0
- package/dist/scm/git-scm-provider.js.map +1 -0
- package/dist/scm/scm-provider.d.ts +8 -0
- package/dist/scm/scm-provider.d.ts.map +1 -0
- package/dist/scm/scm-provider.js +2 -0
- package/dist/scm/scm-provider.js.map +1 -0
- package/dist/staleness.d.ts +17 -0
- package/dist/staleness.d.ts.map +1 -0
- package/dist/staleness.js +44 -0
- package/dist/staleness.js.map +1 -0
- package/dist/validate-project.d.ts +11 -0
- package/dist/validate-project.d.ts.map +1 -0
- package/dist/validate-project.js +64 -0
- package/dist/validate-project.js.map +1 -0
- package/package.json +33 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type { CommentrayBlock, CommentrayIndex, SourceFileIndexEntry } from "./model.js";
|
|
2
|
+
export { CURRENT_SCHEMA_VERSION } from "./model.js";
|
|
3
|
+
export { commentrayMarkdownPath, defaultMetadataIndexPath, normalizeRepoRelativePath, } from "./paths.js";
|
|
4
|
+
export type { CommentrayToml, ResolvedCommentrayConfig, ResolvedStaticSite } from "./config.js";
|
|
5
|
+
export { loadCommentrayConfig, mergeCommentrayConfig } from "./config.js";
|
|
6
|
+
export { assertValidIndex, emptyIndex } from "./metadata.js";
|
|
7
|
+
export { migrateIndex } from "./migrate.js";
|
|
8
|
+
export type { ParsedAnchor } from "./anchors.js";
|
|
9
|
+
export { formatLineRange, parseAnchor } from "./anchors.js";
|
|
10
|
+
export type { ScmProvider } from "./scm/scm-provider.js";
|
|
11
|
+
export { GitScmProvider } from "./scm/git-scm-provider.js";
|
|
12
|
+
export type { BlockDiagnostic } from "./staleness.js";
|
|
13
|
+
export { diagnoseBlock } from "./staleness.js";
|
|
14
|
+
export type { ValidationIssue, ValidationResult } from "./validate-project.js";
|
|
15
|
+
export { readIndex, validateProject } from "./validate-project.js";
|
|
16
|
+
export { runCommanderMain } from "./cli-bootstrap.js";
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACzF,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,cAAc,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAChG,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC5D,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { CURRENT_SCHEMA_VERSION } from "./model.js";
|
|
2
|
+
export { commentrayMarkdownPath, defaultMetadataIndexPath, normalizeRepoRelativePath, } from "./paths.js";
|
|
3
|
+
export { loadCommentrayConfig, mergeCommentrayConfig } from "./config.js";
|
|
4
|
+
export { assertValidIndex, emptyIndex } from "./metadata.js";
|
|
5
|
+
export { migrateIndex } from "./migrate.js";
|
|
6
|
+
export { formatLineRange, parseAnchor } from "./anchors.js";
|
|
7
|
+
export { GitScmProvider } from "./scm/git-scm-provider.js";
|
|
8
|
+
export { diagnoseBlock } from "./staleness.js";
|
|
9
|
+
export { readIndex, validateProject } from "./validate-project.js";
|
|
10
|
+
export { runCommanderMain } from "./cli-bootstrap.js";
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAA0B,MAAM,YAAY,CAAC;AAE1E,wBAAgB,UAAU,IAAI,eAAe,CAE5C;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAiBhE"}
|
package/dist/metadata.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { CURRENT_SCHEMA_VERSION } from "./model.js";
|
|
2
|
+
export function emptyIndex() {
|
|
3
|
+
return { schemaVersion: CURRENT_SCHEMA_VERSION, bySourceFile: {} };
|
|
4
|
+
}
|
|
5
|
+
export function assertValidIndex(value) {
|
|
6
|
+
if (typeof value !== "object" || value === null) {
|
|
7
|
+
throw new Error("index.json must be a JSON object");
|
|
8
|
+
}
|
|
9
|
+
const obj = value;
|
|
10
|
+
const schemaVersion = obj.schemaVersion;
|
|
11
|
+
if (schemaVersion !== CURRENT_SCHEMA_VERSION) {
|
|
12
|
+
throw new Error(`Unsupported schemaVersion: ${String(schemaVersion)}`);
|
|
13
|
+
}
|
|
14
|
+
const bySourceFile = obj.bySourceFile;
|
|
15
|
+
if (typeof bySourceFile !== "object" || bySourceFile === null) {
|
|
16
|
+
throw new Error("index.json.bySourceFile must be an object");
|
|
17
|
+
}
|
|
18
|
+
for (const [key, entry] of Object.entries(bySourceFile)) {
|
|
19
|
+
validateSourceEntry(key, entry);
|
|
20
|
+
}
|
|
21
|
+
return obj;
|
|
22
|
+
}
|
|
23
|
+
function validateSourceEntry(sourcePath, entry) {
|
|
24
|
+
if (typeof entry !== "object" || entry === null) {
|
|
25
|
+
throw new Error(`Invalid index entry for ${sourcePath}`);
|
|
26
|
+
}
|
|
27
|
+
const e = entry;
|
|
28
|
+
if (typeof e.sourcePath !== "string")
|
|
29
|
+
throw new Error(`Missing sourcePath for ${sourcePath}`);
|
|
30
|
+
if (typeof e.commentrayPath !== "string") {
|
|
31
|
+
throw new Error(`Missing commentrayPath for ${sourcePath}`);
|
|
32
|
+
}
|
|
33
|
+
if (!Array.isArray(e.blocks))
|
|
34
|
+
throw new Error(`blocks must be an array for ${sourcePath}`);
|
|
35
|
+
for (const block of e.blocks)
|
|
36
|
+
validateBlock(sourcePath, block);
|
|
37
|
+
}
|
|
38
|
+
function validateBlock(sourcePath, block) {
|
|
39
|
+
if (typeof block !== "object" || block === null) {
|
|
40
|
+
throw new Error(`Invalid block under ${sourcePath}`);
|
|
41
|
+
}
|
|
42
|
+
const b = block;
|
|
43
|
+
if (typeof b.id !== "string")
|
|
44
|
+
throw new Error(`block.id must be a string under ${sourcePath}`);
|
|
45
|
+
if (typeof b.anchor !== "string") {
|
|
46
|
+
throw new Error(`block.anchor must be a string under ${sourcePath}`);
|
|
47
|
+
}
|
|
48
|
+
if (b.lastVerifiedCommit !== undefined && typeof b.lastVerifiedCommit !== "string") {
|
|
49
|
+
throw new Error(`block.lastVerifiedCommit must be a string when present under ${sourcePath}`);
|
|
50
|
+
}
|
|
51
|
+
if (b.lastVerifiedBlob !== undefined && typeof b.lastVerifiedBlob !== "string") {
|
|
52
|
+
throw new Error(`block.lastVerifiedBlob must be a string when present under ${sourcePath}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type CommentrayIndex } from "./model.js";
|
|
2
|
+
/** Returns migrated index and whether the file should be rewritten. */
|
|
3
|
+
export declare function migrateIndex(raw: unknown): {
|
|
4
|
+
index: CommentrayIndex;
|
|
5
|
+
changed: boolean;
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=migrate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../src/migrate.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,eAAe,EAGrB,MAAM,YAAY,CAAC;AAEpB,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CA2BvF"}
|
package/dist/migrate.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { CURRENT_SCHEMA_VERSION, } from "./model.js";
|
|
2
|
+
/** Returns migrated index and whether the file should be rewritten. */
|
|
3
|
+
export function migrateIndex(raw) {
|
|
4
|
+
if (typeof raw !== "object" || raw === null) {
|
|
5
|
+
return {
|
|
6
|
+
index: { schemaVersion: CURRENT_SCHEMA_VERSION, bySourceFile: {} },
|
|
7
|
+
changed: true,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
const obj = raw;
|
|
11
|
+
const version = obj.schemaVersion;
|
|
12
|
+
if (version === CURRENT_SCHEMA_VERSION) {
|
|
13
|
+
return { index: obj, changed: false };
|
|
14
|
+
}
|
|
15
|
+
if (version === undefined || version === 0 || version === 1) {
|
|
16
|
+
const bySourceFile = normalizeBySourceFile(obj.bySourceFile);
|
|
17
|
+
const next = {
|
|
18
|
+
schemaVersion: CURRENT_SCHEMA_VERSION,
|
|
19
|
+
bySourceFile,
|
|
20
|
+
};
|
|
21
|
+
const before = JSON.stringify({
|
|
22
|
+
schemaVersion: version ?? 0,
|
|
23
|
+
bySourceFile: obj.bySourceFile ?? {},
|
|
24
|
+
});
|
|
25
|
+
const after = JSON.stringify(next);
|
|
26
|
+
const changed = before !== after;
|
|
27
|
+
return { index: next, changed };
|
|
28
|
+
}
|
|
29
|
+
throw new Error(`Cannot migrate from schemaVersion ${String(version)}`);
|
|
30
|
+
}
|
|
31
|
+
function normalizeBySourceFile(by) {
|
|
32
|
+
if (typeof by !== "object" || by === null)
|
|
33
|
+
return {};
|
|
34
|
+
const out = {};
|
|
35
|
+
for (const [k, entry] of Object.entries(by)) {
|
|
36
|
+
out[k] = normalizeEntry(entry);
|
|
37
|
+
}
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
function normalizeEntry(entry) {
|
|
41
|
+
if (typeof entry !== "object" || entry === null) {
|
|
42
|
+
throw new Error("Invalid index entry");
|
|
43
|
+
}
|
|
44
|
+
const e = entry;
|
|
45
|
+
if (typeof e.commentrayPath === "string") {
|
|
46
|
+
return e;
|
|
47
|
+
}
|
|
48
|
+
if (typeof e.commentaryPath === "string") {
|
|
49
|
+
const { commentaryPath, ...rest } = e;
|
|
50
|
+
return { ...rest, commentrayPath: commentaryPath };
|
|
51
|
+
}
|
|
52
|
+
return e;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../src/migrate.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAEpB,uEAAuE;AACvE,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5C,OAAO;YACL,KAAK,EAAE,EAAE,aAAa,EAAE,sBAAsB,EAAE,YAAY,EAAE,EAAE,EAAE;YAClE,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,GAA8B,CAAC;IAC3C,MAAM,OAAO,GAAG,GAAG,CAAC,aAAa,CAAC;IAClC,IAAI,OAAO,KAAK,sBAAsB,EAAE,CAAC;QACvC,OAAO,EAAE,KAAK,EAAE,GAAsB,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC3D,CAAC;IACD,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;QAC5D,MAAM,YAAY,GAAG,qBAAqB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAoB;YAC5B,aAAa,EAAE,sBAAsB;YACrC,YAAY;SACb,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;YAC5B,aAAa,EAAE,OAAO,IAAI,CAAC;YAC3B,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,EAAE;SACrC,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,KAAK,KAAK,CAAC;QACjC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAClC,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,qCAAqC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAC1E,CAAC;AAED,SAAS,qBAAqB,CAAC,EAAW;IACxC,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IACrD,MAAM,GAAG,GAAyC,EAAE,CAAC;IACrD,KAAK,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,EAA6B,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACzC,CAAC;IACD,MAAM,CAAC,GAAG,KAAgC,CAAC;IAC3C,IAAI,OAAO,CAAC,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;QACzC,OAAO,CAAyB,CAAC;IACnC,CAAC;IACD,IAAI,OAAO,CAAC,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;QACzC,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC;QACtC,OAAO,EAAE,GAAG,IAAI,EAAE,cAAc,EAAE,cAAc,EAA0B,CAAC;IAC7E,CAAC;IACD,OAAO,CAAyB,CAAC;AACnC,CAAC"}
|
package/dist/model.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Commentray block aligned to a region of a primary source file. */
|
|
2
|
+
export type CommentrayBlock = {
|
|
3
|
+
/** Stable id within the commentray markdown file. */
|
|
4
|
+
id: string;
|
|
5
|
+
/** Human or machine anchor string (see anchor grammar in docs). */
|
|
6
|
+
anchor: string;
|
|
7
|
+
/** Last human-verified commit (full SHA) when this block was considered accurate. */
|
|
8
|
+
lastVerifiedCommit?: string;
|
|
9
|
+
/** Git blob id at verification time for the primary file (when known). */
|
|
10
|
+
lastVerifiedBlob?: string;
|
|
11
|
+
/** Optional notes for agents or reviewers. */
|
|
12
|
+
notes?: string;
|
|
13
|
+
};
|
|
14
|
+
export type SourceFileIndexEntry = {
|
|
15
|
+
/** Repo-relative path to the primary file this commentray belongs to. */
|
|
16
|
+
sourcePath: string;
|
|
17
|
+
/** Repo-relative path to the Markdown commentray file. */
|
|
18
|
+
commentrayPath: string;
|
|
19
|
+
blocks: CommentrayBlock[];
|
|
20
|
+
};
|
|
21
|
+
/** Root metadata document stored as JSON under `.commentray/metadata/`. */
|
|
22
|
+
export type CommentrayIndex = {
|
|
23
|
+
schemaVersion: number;
|
|
24
|
+
bySourceFile: Record<string, SourceFileIndexEntry>;
|
|
25
|
+
};
|
|
26
|
+
export declare const CURRENT_SCHEMA_VERSION: 2;
|
|
27
|
+
//# sourceMappingURL=model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,MAAM,MAAM,eAAe,GAAG;IAC5B,qDAAqD;IACrD,EAAE,EAAE,MAAM,CAAC;IACX,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,qFAAqF;IACrF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B,CAAC;AAEF,2EAA2E;AAC3E,MAAM,MAAM,eAAe,GAAG;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CACpD,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAG,CAAU,CAAC"}
|
package/dist/model.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AA4BA,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAU,CAAC"}
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize a repo-relative path to POSIX separators and reject anything that
|
|
3
|
+
* would escape the repository root when joined with it.
|
|
4
|
+
*
|
|
5
|
+
* Rejects:
|
|
6
|
+
* - Windows drive letters (e.g. `C:\foo`).
|
|
7
|
+
* - `..` path segments, which would let a config value or CLI argument walk
|
|
8
|
+
* out of the repo root.
|
|
9
|
+
*
|
|
10
|
+
* Accepts filenames that merely *contain* dots like `..name.ts`; only whole
|
|
11
|
+
* `..` segments are traversal.
|
|
12
|
+
*/
|
|
13
|
+
export declare function normalizeRepoRelativePath(relativePath: string): string;
|
|
14
|
+
/** Commentray Markdown path for a repo-relative source file. */
|
|
15
|
+
export declare function commentrayMarkdownPath(sourceRepoRelativePath: string): string;
|
|
16
|
+
/** Default metadata index location (repo-relative). */
|
|
17
|
+
export declare function defaultMetadataIndexPath(): string;
|
|
18
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAWtE;AAED,gEAAgE;AAChE,wBAAgB,sBAAsB,CAAC,sBAAsB,EAAE,MAAM,GAAG,MAAM,CAG7E;AAED,uDAAuD;AACvD,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD"}
|
package/dist/paths.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
/**
|
|
3
|
+
* Normalize a repo-relative path to POSIX separators and reject anything that
|
|
4
|
+
* would escape the repository root when joined with it.
|
|
5
|
+
*
|
|
6
|
+
* Rejects:
|
|
7
|
+
* - Windows drive letters (e.g. `C:\foo`).
|
|
8
|
+
* - `..` path segments, which would let a config value or CLI argument walk
|
|
9
|
+
* out of the repo root.
|
|
10
|
+
*
|
|
11
|
+
* Accepts filenames that merely *contain* dots like `..name.ts`; only whole
|
|
12
|
+
* `..` segments are traversal.
|
|
13
|
+
*/
|
|
14
|
+
export function normalizeRepoRelativePath(relativePath) {
|
|
15
|
+
const posix = relativePath.replaceAll("\\", "/");
|
|
16
|
+
if (/^[a-zA-Z]:\//.test(posix)) {
|
|
17
|
+
throw new Error(`Path must be repository-relative (got absolute: ${relativePath})`);
|
|
18
|
+
}
|
|
19
|
+
const stripped = posix.replace(/^\/+/, "");
|
|
20
|
+
const segments = stripped.split("/").filter((s) => s !== "" && s !== ".");
|
|
21
|
+
if (segments.some((s) => s === "..")) {
|
|
22
|
+
throw new Error(`Path escapes repository root: ${relativePath}`);
|
|
23
|
+
}
|
|
24
|
+
return segments.join("/");
|
|
25
|
+
}
|
|
26
|
+
/** Commentray Markdown path for a repo-relative source file. */
|
|
27
|
+
export function commentrayMarkdownPath(sourceRepoRelativePath) {
|
|
28
|
+
const normalized = normalizeRepoRelativePath(sourceRepoRelativePath);
|
|
29
|
+
return path.posix.join(".commentray", "source", `${normalized}.md`);
|
|
30
|
+
}
|
|
31
|
+
/** Default metadata index location (repo-relative). */
|
|
32
|
+
export function defaultMetadataIndexPath() {
|
|
33
|
+
return path.posix.join(".commentray", "metadata", "index.json");
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,yBAAyB,CAAC,YAAoB;IAC5D,MAAM,KAAK,GAAG,YAAY,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACjD,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,mDAAmD,YAAY,GAAG,CAAC,CAAC;IACtF,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IAC1E,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,iCAAiC,YAAY,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,sBAAsB,CAAC,sBAA8B;IACnE,MAAM,UAAU,GAAG,yBAAyB,CAAC,sBAAsB,CAAC,CAAC;IACrE,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,GAAG,UAAU,KAAK,CAAC,CAAC;AACtE,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,wBAAwB;IACtC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ScmProvider } from "./scm-provider.js";
|
|
2
|
+
export declare class GitScmProvider implements ScmProvider {
|
|
3
|
+
getBlobIdAtHead(repoRoot: string, repoRelativePath: string): Promise<string | null>;
|
|
4
|
+
isAncestor(repoRoot: string, possibleAncestor: string, commit: string): Promise<boolean>;
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=git-scm-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-scm-provider.d.ts","sourceRoot":"","sources":["../../src/scm/git-scm-provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA0BrD,qBAAa,cAAe,YAAW,WAAW;IAC1C,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAgBnF,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAW/F"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
function runGit(repoRoot, args) {
|
|
3
|
+
return new Promise((resolve, reject) => {
|
|
4
|
+
const child = spawn("git", args, {
|
|
5
|
+
cwd: repoRoot,
|
|
6
|
+
env: process.env,
|
|
7
|
+
});
|
|
8
|
+
let stdout = "";
|
|
9
|
+
let stderr = "";
|
|
10
|
+
child.stdout.on("data", (d) => {
|
|
11
|
+
stdout += String(d);
|
|
12
|
+
});
|
|
13
|
+
child.stderr.on("data", (d) => {
|
|
14
|
+
stderr += String(d);
|
|
15
|
+
});
|
|
16
|
+
child.on("error", reject);
|
|
17
|
+
child.on("close", (code) => {
|
|
18
|
+
resolve({ code: code ?? 1, stdout, stderr });
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export class GitScmProvider {
|
|
23
|
+
async getBlobIdAtHead(repoRoot, repoRelativePath) {
|
|
24
|
+
const posixPath = repoRelativePath.replaceAll("\\", "/").replace(/^\/+/, "");
|
|
25
|
+
const spec = `HEAD:${posixPath}`;
|
|
26
|
+
const { code, stdout, stderr } = await runGit(repoRoot, ["rev-parse", spec]);
|
|
27
|
+
if (code !== 0) {
|
|
28
|
+
if (/fatal: Not a valid object name/.test(stderr) ||
|
|
29
|
+
/fatal: Path .* does not exist/.test(stderr)) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
throw new Error(`git rev-parse failed (${code}): ${stderr.trim()}`);
|
|
33
|
+
}
|
|
34
|
+
return stdout.trim() || null;
|
|
35
|
+
}
|
|
36
|
+
async isAncestor(repoRoot, possibleAncestor, commit) {
|
|
37
|
+
const { code, stderr } = await runGit(repoRoot, [
|
|
38
|
+
"merge-base",
|
|
39
|
+
"--is-ancestor",
|
|
40
|
+
possibleAncestor,
|
|
41
|
+
commit,
|
|
42
|
+
]);
|
|
43
|
+
if (code === 0)
|
|
44
|
+
return true;
|
|
45
|
+
if (code === 1)
|
|
46
|
+
return false;
|
|
47
|
+
throw new Error(`git merge-base failed (${code}): ${stderr.trim()}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=git-scm-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-scm-provider.js","sourceRoot":"","sources":["../../src/scm/git-scm-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAG3C,SAAS,MAAM,CACb,QAAgB,EAChB,IAAc;IAEd,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE;YAC/B,GAAG,EAAE,QAAQ;YACb,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;QACH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAkB,EAAE,EAAE;YAC7C,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;QACtB,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAkB,EAAE,EAAE;YAC7C,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;QACtB,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAmB,EAAE,EAAE;YACxC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,OAAO,cAAc;IACzB,KAAK,CAAC,eAAe,CAAC,QAAgB,EAAE,gBAAwB;QAC9D,MAAM,SAAS,GAAG,gBAAgB,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC7E,MAAM,IAAI,GAAG,QAAQ,SAAS,EAAE,CAAC;QACjC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;QAC7E,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;YACf,IACE,gCAAgC,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC7C,+BAA+B,CAAC,IAAI,CAAC,MAAM,CAAC,EAC5C,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,MAAM,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,QAAgB,EAAE,gBAAwB,EAAE,MAAc;QACzE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE;YAC9C,YAAY;YACZ,eAAe;YACf,gBAAgB;YAChB,MAAM;SACP,CAAC,CAAC;QACH,IAAI,IAAI,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAC5B,IAAI,IAAI,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,MAAM,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACvE,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Pluggable SCM integration; Git is the default implementation. */
|
|
2
|
+
export type ScmProvider = {
|
|
3
|
+
/** Object id for file at HEAD (Git blob), or null if unknown/untracked. */
|
|
4
|
+
getBlobIdAtHead(repoRoot: string, repoRelativePath: string): Promise<string | null>;
|
|
5
|
+
/** True if `possibleAncestor` is an ancestor of `commit` (inclusive). */
|
|
6
|
+
isAncestor(repoRoot: string, possibleAncestor: string, commit: string): Promise<boolean>;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=scm-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scm-provider.d.ts","sourceRoot":"","sources":["../../src/scm/scm-provider.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,MAAM,MAAM,WAAW,GAAG;IACxB,2EAA2E;IAC3E,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACpF,yEAAyE;IACzE,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1F,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scm-provider.js","sourceRoot":"","sources":["../../src/scm/scm-provider.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CommentrayBlock } from "./model.js";
|
|
2
|
+
import type { ScmProvider } from "./scm/scm-provider.js";
|
|
3
|
+
export type BlockDiagnostic = {
|
|
4
|
+
blockId: string;
|
|
5
|
+
anchor: string;
|
|
6
|
+
kind: "broken_anchor" | "review_needed";
|
|
7
|
+
detail: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function diagnoseBlock(args: {
|
|
10
|
+
repoRoot: string;
|
|
11
|
+
sourceRepoRelativePath: string;
|
|
12
|
+
headCommit: string;
|
|
13
|
+
blobAtHead: string | null;
|
|
14
|
+
block: CommentrayBlock;
|
|
15
|
+
scm: ScmProvider;
|
|
16
|
+
}): Promise<BlockDiagnostic | null>;
|
|
17
|
+
//# sourceMappingURL=staleness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staleness.d.ts","sourceRoot":"","sources":["../src/staleness.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGzD,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,eAAe,GAAG,eAAe,CAAC;IACxC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,eAAe,CAAC;IACvB,GAAG,EAAE,WAAW,CAAC;CAClB,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CA4ClC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { parseAnchor } from "./anchors.js";
|
|
2
|
+
export async function diagnoseBlock(args) {
|
|
3
|
+
const { block, scm, repoRoot, headCommit, blobAtHead } = args;
|
|
4
|
+
try {
|
|
5
|
+
parseAnchor(block.anchor);
|
|
6
|
+
}
|
|
7
|
+
catch (err) {
|
|
8
|
+
return {
|
|
9
|
+
blockId: block.id,
|
|
10
|
+
anchor: block.anchor,
|
|
11
|
+
kind: "broken_anchor",
|
|
12
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
if (!block.lastVerifiedCommit)
|
|
16
|
+
return null;
|
|
17
|
+
const isReachable = await scm.isAncestor(repoRoot, block.lastVerifiedCommit, headCommit);
|
|
18
|
+
if (!isReachable) {
|
|
19
|
+
return {
|
|
20
|
+
blockId: block.id,
|
|
21
|
+
anchor: block.anchor,
|
|
22
|
+
kind: "review_needed",
|
|
23
|
+
detail: "lastVerifiedCommit is not an ancestor of HEAD",
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
if (block.lastVerifiedBlob && blobAtHead && block.lastVerifiedBlob !== blobAtHead) {
|
|
27
|
+
return {
|
|
28
|
+
blockId: block.id,
|
|
29
|
+
anchor: block.anchor,
|
|
30
|
+
kind: "review_needed",
|
|
31
|
+
detail: "Primary file content at HEAD differs from lastVerifiedBlob",
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
if (!blobAtHead) {
|
|
35
|
+
return {
|
|
36
|
+
blockId: block.id,
|
|
37
|
+
anchor: block.anchor,
|
|
38
|
+
kind: "review_needed",
|
|
39
|
+
detail: "Source file is not tracked at HEAD; cannot fingerprint blob",
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=staleness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staleness.js","sourceRoot":"","sources":["../src/staleness.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAS3C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAOnC;IACC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAC9D,IAAI,CAAC;QACH,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,IAAI,EAAE,eAAe;YACrB,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACzD,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,kBAAkB;QAAE,OAAO,IAAI,CAAC;IAE3C,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC;IACzF,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO;YACL,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,IAAI,EAAE,eAAe;YACrB,MAAM,EAAE,+CAA+C;SACxD,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,CAAC,gBAAgB,IAAI,UAAU,IAAI,KAAK,CAAC,gBAAgB,KAAK,UAAU,EAAE,CAAC;QAClF,OAAO;YACL,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,IAAI,EAAE,eAAe;YACrB,MAAM,EAAE,4DAA4D;SACrE,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO;YACL,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,IAAI,EAAE,eAAe;YACrB,MAAM,EAAE,6DAA6D;SACtE,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CommentrayIndex } from "./model.js";
|
|
2
|
+
export type ValidationIssue = {
|
|
3
|
+
level: "error" | "warn";
|
|
4
|
+
message: string;
|
|
5
|
+
};
|
|
6
|
+
export type ValidationResult = {
|
|
7
|
+
issues: ValidationIssue[];
|
|
8
|
+
};
|
|
9
|
+
export declare function validateProject(repoRoot: string): Promise<ValidationResult>;
|
|
10
|
+
export declare function readIndex(repoRoot: string): Promise<CommentrayIndex | null>;
|
|
11
|
+
//# sourceMappingURL=validate-project.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-project.d.ts","sourceRoot":"","sources":["../src/validate-project.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,MAAM,eAAe,GAAG;IAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B,CAAC;AAEF,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA2CjF;AAED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAUjF"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { loadCommentrayConfig } from "./config.js";
|
|
4
|
+
import { assertValidIndex } from "./metadata.js";
|
|
5
|
+
import { defaultMetadataIndexPath } from "./paths.js";
|
|
6
|
+
export async function validateProject(repoRoot) {
|
|
7
|
+
const issues = [];
|
|
8
|
+
let config;
|
|
9
|
+
try {
|
|
10
|
+
config = await loadCommentrayConfig(repoRoot);
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
issues.push({
|
|
14
|
+
level: "error",
|
|
15
|
+
message: `Failed to load .commentray.toml: ${err instanceof Error ? err.message : String(err)}`,
|
|
16
|
+
});
|
|
17
|
+
return { issues };
|
|
18
|
+
}
|
|
19
|
+
const storageAbs = path.join(repoRoot, config.storageDir);
|
|
20
|
+
for (const sub of ["source", "metadata"]) {
|
|
21
|
+
const p = path.join(storageAbs, sub);
|
|
22
|
+
try {
|
|
23
|
+
await fs.stat(p);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
issues.push({
|
|
27
|
+
level: "warn",
|
|
28
|
+
message: `Missing directory: ${path.join(config.storageDir, sub)}`,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const indexPath = path.join(repoRoot, defaultMetadataIndexPath());
|
|
33
|
+
try {
|
|
34
|
+
const raw = await fs.readFile(indexPath, "utf8");
|
|
35
|
+
assertValidIndex(JSON.parse(raw));
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
const code = err.code;
|
|
39
|
+
if (code === "ENOENT") {
|
|
40
|
+
issues.push({ level: "warn", message: `No metadata index at ${defaultMetadataIndexPath()}` });
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
issues.push({
|
|
44
|
+
level: "error",
|
|
45
|
+
message: `Invalid metadata index: ${err instanceof Error ? err.message : String(err)}`,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return { issues };
|
|
50
|
+
}
|
|
51
|
+
export async function readIndex(repoRoot) {
|
|
52
|
+
const indexPath = path.join(repoRoot, defaultMetadataIndexPath());
|
|
53
|
+
try {
|
|
54
|
+
const raw = await fs.readFile(indexPath, "utf8");
|
|
55
|
+
return assertValidIndex(JSON.parse(raw));
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
const code = err.code;
|
|
59
|
+
if (code === "ENOENT")
|
|
60
|
+
return null;
|
|
61
|
+
throw err;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=validate-project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-project.js","sourceRoot":"","sources":["../src/validate-project.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@commentray/core",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"description": "Commentray models, validation, SCM adapters, and staleness helpers",
|
|
8
|
+
"license": "MPL-2.0",
|
|
9
|
+
"type": "module",
|
|
10
|
+
"sideEffects": false,
|
|
11
|
+
"main": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc -p tsconfig.build.json",
|
|
25
|
+
"clean": "rm -rf dist"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@iarna/toml": "^2.2.5"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^22.14.1"
|
|
32
|
+
}
|
|
33
|
+
}
|