@digital-lake/lognexus 1.0.0 → 1.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.
- package/README.md +101 -7
- package/dist/audit/audit.d.ts +17 -1
- package/dist/audit/audit.d.ts.map +1 -1
- package/dist/audit/audit.js +55 -15
- package/dist/audit/audit.js.map +1 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +160 -2
- package/dist/cli.js.map +1 -1
- package/dist/commit.d.ts +27 -0
- package/dist/commit.d.ts.map +1 -0
- package/dist/commit.js +211 -0
- package/dist/commit.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +125 -0
- package/dist/mcp/tools.js.map +1 -1
- package/dist/notes/attach.d.ts +1 -0
- package/dist/notes/attach.d.ts.map +1 -1
- package/dist/notes/attach.js +29 -2
- package/dist/notes/attach.js.map +1 -1
- package/dist/notes/notes.d.ts +1 -0
- package/dist/notes/notes.d.ts.map +1 -1
- package/dist/notes/notes.js.map +1 -1
- package/dist/scaffold.d.ts +1 -1
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +4 -4
- package/dist/state/manager.d.ts.map +1 -1
- package/dist/state/manager.js +11 -1
- package/dist/state/manager.js.map +1 -1
- package/dist/telemetry/collector.d.ts +31 -0
- package/dist/telemetry/collector.d.ts.map +1 -0
- package/dist/telemetry/collector.js +257 -0
- package/dist/telemetry/collector.js.map +1 -0
- package/dist/telemetry/detector.d.ts +15 -0
- package/dist/telemetry/detector.d.ts.map +1 -0
- package/dist/telemetry/detector.js +120 -0
- package/dist/telemetry/detector.js.map +1 -0
- package/dist/telemetry/index.d.ts +5 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +5 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/report.d.ts +7 -0
- package/dist/telemetry/report.d.ts.map +1 -0
- package/dist/telemetry/report.js +98 -0
- package/dist/telemetry/report.js.map +1 -0
- package/dist/telemetry/schema.d.ts +140 -0
- package/dist/telemetry/schema.d.ts.map +1 -0
- package/dist/telemetry/schema.js +78 -0
- package/dist/telemetry/schema.js.map +1 -0
- package/dist/timeline/timeline.d.ts.map +1 -1
- package/dist/timeline/timeline.js +8 -3
- package/dist/timeline/timeline.js.map +1 -1
- package/package.json +16 -5
package/dist/notes/attach.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { checkSelfApproval, extractTrailers } from "../audit/audit.js";
|
|
1
3
|
import { loadState } from "../state/manager.js";
|
|
2
4
|
import { attachNote } from "./notes.js";
|
|
3
5
|
export function buildStateNotePayload(targetDir = process.cwd()) {
|
|
@@ -5,21 +7,46 @@ export function buildStateNotePayload(targetDir = process.cwd()) {
|
|
|
5
7
|
return {
|
|
6
8
|
$schema: "https://lognexus.digital-lake.ai/schemas/git-note-v1.json",
|
|
7
9
|
generator: "LogNexus",
|
|
8
|
-
version: "1.
|
|
10
|
+
version: "1.1.0",
|
|
9
11
|
timestamp: new Date().toISOString(),
|
|
10
12
|
issue: state.activeIssue ? { id: state.activeIssue.id, title: state.activeIssue.title } : null,
|
|
11
13
|
subtask: state.currentSubtask
|
|
12
14
|
? {
|
|
13
15
|
id: state.currentSubtask.id,
|
|
14
16
|
title: state.currentSubtask.title,
|
|
17
|
+
status: state.currentSubtask.status,
|
|
15
18
|
contract: state.currentSubtask.contract,
|
|
16
19
|
}
|
|
17
20
|
: null,
|
|
18
21
|
tier: state.activeIssue?.tier ?? "tier-3",
|
|
19
22
|
};
|
|
20
23
|
}
|
|
24
|
+
function getCommitMessage(commitRef, cwd) {
|
|
25
|
+
try {
|
|
26
|
+
return execSync(`git log -1 --format=%B ${commitRef}`, {
|
|
27
|
+
cwd,
|
|
28
|
+
encoding: "utf8",
|
|
29
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return "";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
21
36
|
export function attachCurrentStateToCommit(commitRef = "HEAD", options = {}) {
|
|
22
|
-
const
|
|
37
|
+
const cwd = options.cwd ?? process.cwd();
|
|
38
|
+
// Parche 3: Pre-flight validation against review-gate separation (self-approval)
|
|
39
|
+
if (!options.force) {
|
|
40
|
+
const commitBody = getCommitMessage(commitRef, cwd);
|
|
41
|
+
if (commitBody) {
|
|
42
|
+
const { author, reviewer } = extractTrailers(commitBody);
|
|
43
|
+
const check = checkSelfApproval(author, reviewer);
|
|
44
|
+
if (check.isSelfApproval) {
|
|
45
|
+
throw new Error(`Review-gate separation violation: ${check.message}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const payload = buildStateNotePayload(cwd);
|
|
23
50
|
const serialized = JSON.stringify(payload, null, 2);
|
|
24
51
|
attachNote(serialized, commitRef, options);
|
|
25
52
|
return payload;
|
package/dist/notes/attach.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attach.js","sourceRoot":"","sources":["../../src/notes/attach.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAoB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"attach.js","sourceRoot":"","sources":["../../src/notes/attach.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAoB,MAAM,YAAY,CAAC;AAiB1D,MAAM,UAAU,qBAAqB,CAAC,SAAS,GAAW,OAAO,CAAC,GAAG,EAAE;IACrE,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IAEnC,OAAO;QACL,OAAO,EAAE,2DAA2D;QACpE,SAAS,EAAE,UAAU;QACrB,OAAO,EAAE,OAAO;QAChB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI;QAC9F,OAAO,EAAE,KAAK,CAAC,cAAc;YAC3B,CAAC,CAAC;gBACE,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,EAAE;gBAC3B,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK;gBACjC,MAAM,EAAE,KAAK,CAAC,cAAc,CAAC,MAAM;gBACnC,QAAQ,EAAE,KAAK,CAAC,cAAc,CAAC,QAAQ;aACxC;YACH,CAAC,CAAC,IAAI;QACR,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,IAAI,IAAI,QAAQ;KAC1C,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,SAAiB,EAAE,GAAW;IACtD,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,0BAA0B,SAAS,EAAE,EAAE;YACrD,GAAG;YACH,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,SAAS,GAAW,MAAM,EAC1B,OAAO,GAAgB,EAAE;IAEzB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAEzC,iFAAiF;IACjF,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,UAAU,GAAG,gBAAgB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QACpD,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;YACzD,MAAM,KAAK,GAAG,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAClD,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CAAC,qCAAqC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACpD,UAAU,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAC3C,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/notes/notes.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export declare const DEFAULT_NOTES_REF = "refs/notes/lognexus";
|
|
|
2
2
|
export interface NoteOptions {
|
|
3
3
|
ref?: string;
|
|
4
4
|
cwd?: string;
|
|
5
|
+
force?: boolean;
|
|
5
6
|
}
|
|
6
7
|
export declare function attachNote(content: string, commitRef?: string, options?: NoteOptions): void;
|
|
7
8
|
export declare function getNote(commitRef?: string, options?: NoteOptions): string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notes.d.ts","sourceRoot":"","sources":["../../src/notes/notes.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AAEvD,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"notes.d.ts","sourceRoot":"","sources":["../../src/notes/notes.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AAEvD,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAe,EAC1B,OAAO,GAAE,WAAgB,GACxB,IAAI,CAWN;AAED,wBAAgB,OAAO,CAAC,SAAS,GAAE,MAAe,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,GAAG,IAAI,CAc5F;AAED,wBAAgB,SAAS,CACvB,OAAO,GAAE,WAAgB,GACxB,KAAK,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAuBhD;AAED,wBAAgB,SAAS,CAAC,MAAM,GAAE,MAAiB,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAcvF;AAED,wBAAgB,UAAU,CAAC,MAAM,GAAE,MAAiB,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAcxF"}
|
package/dist/notes/notes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notes.js","sourceRoot":"","sources":["../../src/notes/notes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,MAAM,CAAC,MAAM,iBAAiB,GAAG,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"notes.js","sourceRoot":"","sources":["../../src/notes/notes.ts"],"names":[],"mappings":"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"}
|
package/dist/scaffold.d.ts
CHANGED
|
@@ -2,6 +2,6 @@ export interface InitResult {
|
|
|
2
2
|
created: string[];
|
|
3
3
|
skipped: string[];
|
|
4
4
|
}
|
|
5
|
-
export declare const DEFAULT_ROUTING_TEMPLATE = "# Model-Tier Routing Configuration\n\n# Modes: confirm (pause and prompt) | warn (banner only) | off (silent)\nrouting: confirm\n\n# Operational Tier Taxonomy (
|
|
5
|
+
export declare const DEFAULT_ROUTING_TEMPLATE = "# Model-Tier Routing Configuration\n\n# Modes: confirm (pause and prompt) | warn (banner only) | off (silent)\nrouting: confirm\n\n# Operational Tier Taxonomy (Empirical recommendations across Gemini, Claude, OpenAI, DeepSeek, Kimi)\n# tier-1 (Reasoning / Arch / Review Gate): Gemini 1.5/2.0 Pro, Google Antigravity, Claude 3.5/3.7 Sonnet, OpenAI o3/o1, DeepSeek R1\n# tier-2 (Orchestration / Large Context >500 lines): Gemini 1.5 Pro (2M), Claude Sonnet, Kimi K2.7 Code\n# tier-3 (Scoped Execution / Focused Modules <500 lines): Gemini 2.0/1.5 Flash, DeepSeek V3, Kimi K2.7 Code, Claude Haiku, GPT-4o-mini\n";
|
|
6
6
|
export declare function initProject(targetDir?: string): InitResult;
|
|
7
7
|
//# sourceMappingURL=scaffold.d.ts.map
|
package/dist/scaffold.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,eAAO,MAAM,wBAAwB,
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,eAAO,MAAM,wBAAwB,qmBASpC,CAAC;AAEF,wBAAgB,WAAW,CAAC,SAAS,GAAE,MAAsB,GAAG,UAAU,CAoBzE"}
|
package/dist/scaffold.js
CHANGED
|
@@ -5,10 +5,10 @@ export const DEFAULT_ROUTING_TEMPLATE = `# Model-Tier Routing Configuration
|
|
|
5
5
|
# Modes: confirm (pause and prompt) | warn (banner only) | off (silent)
|
|
6
6
|
routing: confirm
|
|
7
7
|
|
|
8
|
-
# Operational Tier Taxonomy (
|
|
9
|
-
# tier-1 (Reasoning / Arch / Review): Claude
|
|
10
|
-
# tier-2 (
|
|
11
|
-
# tier-3 (Scoped Execution /
|
|
8
|
+
# Operational Tier Taxonomy (Empirical recommendations across Gemini, Claude, OpenAI, DeepSeek, Kimi)
|
|
9
|
+
# tier-1 (Reasoning / Arch / Review Gate): Gemini 1.5/2.0 Pro, Google Antigravity, Claude 3.5/3.7 Sonnet, OpenAI o3/o1, DeepSeek R1
|
|
10
|
+
# tier-2 (Orchestration / Large Context >500 lines): Gemini 1.5 Pro (2M), Claude Sonnet, Kimi K2.7 Code
|
|
11
|
+
# tier-3 (Scoped Execution / Focused Modules <500 lines): Gemini 2.0/1.5 Flash, DeepSeek V3, Kimi K2.7 Code, Claude Haiku, GPT-4o-mini
|
|
12
12
|
`;
|
|
13
13
|
export function initProject(targetDir = process.cwd()) {
|
|
14
14
|
const result = { created: [], skipped: [] };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/state/manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/state/manager.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,aAAa,EAElB,KAAK,eAAe,EAErB,MAAM,aAAa,CAAC;AAErB,wBAAgB,YAAY,CAAC,SAAS,GAAE,MAAsB,GAAG,MAAM,CAEtE;AAED,wBAAgB,gBAAgB,IAAI,aAAa,CAQhD;AAED,wBAAgB,SAAS,CAAC,SAAS,GAAE,MAAsB,GAAG,aAAa,CAkB1E;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,aAAa,EAAE,SAAS,GAAE,MAAsB,GAAG,IAAI,CAUvF;AAED,wBAAgB,UAAU,CAAC,SAAS,GAAE,MAAsB,GAAG,aAAa,CAI3E;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,MAAW,EAClB,QAAQ,CAAC,EAAE,eAAe,EAC1B,SAAS,GAAE,MAAsB,GAChC,aAAa,CAYf;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,GAAE,MAAsB,GAAG,aAAa,CAiB9F"}
|
package/dist/state/manager.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { recordTaskFinish, recordTaskStart } from "../telemetry/collector.js";
|
|
3
4
|
import { LognexusStateSchema, } from "./schema.js";
|
|
4
5
|
export function getStatePath(targetDir = process.cwd()) {
|
|
5
6
|
return join(targetDir, ".lognexus", "state.json");
|
|
@@ -56,6 +57,7 @@ export function setSubtask(taskId, title = "", contract, targetDir = process.cwd
|
|
|
56
57
|
};
|
|
57
58
|
state.currentSubtask = subtask;
|
|
58
59
|
saveState(state, targetDir);
|
|
60
|
+
recordTaskStart(taskId, targetDir);
|
|
59
61
|
return state;
|
|
60
62
|
}
|
|
61
63
|
export function finishSubtask(taskId, targetDir = process.cwd()) {
|
|
@@ -64,9 +66,17 @@ export function finishSubtask(taskId, targetDir = process.cwd()) {
|
|
|
64
66
|
state.completedSubtasks.push(taskId);
|
|
65
67
|
}
|
|
66
68
|
if (state.currentSubtask?.id === taskId) {
|
|
67
|
-
state.currentSubtask =
|
|
69
|
+
state.currentSubtask.status = "completed";
|
|
70
|
+
}
|
|
71
|
+
else if (!state.currentSubtask) {
|
|
72
|
+
state.currentSubtask = {
|
|
73
|
+
id: taskId,
|
|
74
|
+
title: "",
|
|
75
|
+
status: "completed",
|
|
76
|
+
};
|
|
68
77
|
}
|
|
69
78
|
saveState(state, targetDir);
|
|
79
|
+
recordTaskFinish(taskId, targetDir);
|
|
70
80
|
return state;
|
|
71
81
|
}
|
|
72
82
|
//# sourceMappingURL=manager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/state/manager.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/state/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type AnonymousCommunityPayload, type TelemetryMode, type TelemetryStore } from "./schema.js";
|
|
2
|
+
export declare const DEFAULT_TELEMETRY_ENDPOINT = "https://telemetry.digital-lake.ai/v1/events";
|
|
3
|
+
export declare function isTelemetryGloballyDisabled(): boolean;
|
|
4
|
+
export declare function getTelemetryPath(targetDir?: string): string;
|
|
5
|
+
export declare function createDefaultTelemetryStore(targetDir?: string): TelemetryStore;
|
|
6
|
+
export declare function loadTelemetry(targetDir?: string): TelemetryStore;
|
|
7
|
+
export declare function saveTelemetry(store: TelemetryStore, targetDir?: string): void;
|
|
8
|
+
export declare function isTelemetryActive(targetDir?: string): boolean;
|
|
9
|
+
export declare function enableTelemetry(options: {
|
|
10
|
+
share?: boolean;
|
|
11
|
+
acceptTerms?: boolean;
|
|
12
|
+
cwd?: string;
|
|
13
|
+
}): {
|
|
14
|
+
mode: TelemetryMode;
|
|
15
|
+
anonymousProjectId: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function disableTelemetry(targetDir?: string): void;
|
|
18
|
+
export declare function clearTelemetry(targetDir?: string): void;
|
|
19
|
+
export declare function recordTaskStart(taskId: string, targetDir?: string): void;
|
|
20
|
+
export declare function recordTaskFinish(taskId: string, targetDir?: string): number;
|
|
21
|
+
export declare function recordReviewGateBlock(targetDir?: string): void;
|
|
22
|
+
export declare function updateCostSavingsEstimate(store: TelemetryStore): void;
|
|
23
|
+
export declare function recordCommitTelemetry(options: {
|
|
24
|
+
sha: string;
|
|
25
|
+
author?: string;
|
|
26
|
+
tier?: string;
|
|
27
|
+
targetDir?: string;
|
|
28
|
+
}): void;
|
|
29
|
+
export declare function buildAnonymousCommunityPayload(store: TelemetryStore): AnonymousCommunityPayload;
|
|
30
|
+
export declare function dispatchCommunityTelemetry(store: TelemetryStore, endpoint?: string): Promise<boolean>;
|
|
31
|
+
//# sourceMappingURL=collector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../src/telemetry/collector.ts"],"names":[],"mappings":"AASA,OAAO,EACL,KAAK,yBAAyB,EAG9B,KAAK,aAAa,EAClB,KAAK,cAAc,EAEpB,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,0BAA0B,gDAAgD,CAAC;AAExF,wBAAgB,2BAA2B,IAAI,OAAO,CAOrD;AAED,wBAAgB,gBAAgB,CAAC,SAAS,GAAE,MAAsB,GAAG,MAAM,CAE1E;AAED,wBAAgB,2BAA2B,CAAC,SAAS,GAAE,MAAsB,GAAG,cAAc,CA4B7F;AAED,wBAAgB,aAAa,CAAC,SAAS,GAAE,MAAsB,GAAG,cAAc,CAwB/E;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,EAAE,SAAS,GAAE,MAAsB,GAAG,IAAI,CAW5F;AAED,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,MAAsB,GAAG,OAAO,CAI5E;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE;IACvC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,kBAAkB,EAAE,MAAM,CAAA;CAAE,CAmBtD;AAED,wBAAgB,gBAAgB,CAAC,SAAS,GAAE,MAAsB,GAAG,IAAI,CAIxE;AAED,wBAAgB,cAAc,CAAC,SAAS,GAAE,MAAsB,GAAG,IAAI,CAItE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,GAAE,MAAsB,GAAG,IAAI,CAWvF;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,GAAE,MAAsB,GAAG,MAAM,CAkB1F;AAED,wBAAgB,qBAAqB,CAAC,SAAS,GAAE,MAAsB,GAAG,IAAI,CAM7E;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAgCrE;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,IAAI,CAmDP;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,cAAc,GAAG,yBAAyB,CAgB/F;AAED,wBAAsB,0BAA0B,CAC9C,KAAK,EAAE,cAAc,EACrB,QAAQ,GAAE,MAAyE,GAClF,OAAO,CAAC,OAAO,CAAC,CAkBlB"}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { getCliVersion } from "../cli.js";
|
|
5
|
+
import { detectProjectStacks, extractCommitDiffStats, extractModelFamilyCategory, } from "./detector.js";
|
|
6
|
+
import { TelemetryStoreSchema, } from "./schema.js";
|
|
7
|
+
export const DEFAULT_TELEMETRY_ENDPOINT = "https://telemetry.digital-lake.ai/v1/events";
|
|
8
|
+
export function isTelemetryGloballyDisabled() {
|
|
9
|
+
return (process.env.DO_NOT_TRACK === "1" ||
|
|
10
|
+
process.env.DO_NOT_TRACK === "true" ||
|
|
11
|
+
process.env.LOGNEXUS_TELEMETRY_DISABLED === "1" ||
|
|
12
|
+
process.env.LOGNEXUS_TELEMETRY_DISABLED === "true");
|
|
13
|
+
}
|
|
14
|
+
export function getTelemetryPath(targetDir = process.cwd()) {
|
|
15
|
+
return join(targetDir, ".lognexus", "telemetry.json");
|
|
16
|
+
}
|
|
17
|
+
export function createDefaultTelemetryStore(targetDir = process.cwd()) {
|
|
18
|
+
return {
|
|
19
|
+
schemaVersion: "1.0.0",
|
|
20
|
+
mode: "off",
|
|
21
|
+
anonymousProjectId: randomUUID(),
|
|
22
|
+
consent: {
|
|
23
|
+
accepted: false,
|
|
24
|
+
policyVersion: "1.0.0",
|
|
25
|
+
acceptedAt: null,
|
|
26
|
+
},
|
|
27
|
+
detectedStacks: detectProjectStacks(targetDir),
|
|
28
|
+
taskTimings: {},
|
|
29
|
+
extensions: {},
|
|
30
|
+
models: {},
|
|
31
|
+
summary: {
|
|
32
|
+
totalCommits: 0,
|
|
33
|
+
totalLinesAdded: 0,
|
|
34
|
+
totalLinesDeleted: 0,
|
|
35
|
+
totalSubtasksCompleted: 0,
|
|
36
|
+
gitNotesCoveragePct: 100,
|
|
37
|
+
reviewGateBlocksPrevented: 0,
|
|
38
|
+
estimatedBaselineCostUsd: 0,
|
|
39
|
+
estimatedActualCostUsd: 0,
|
|
40
|
+
estimatedCostSavingsUsd: 0,
|
|
41
|
+
estimatedCostSavingsPct: 0,
|
|
42
|
+
},
|
|
43
|
+
lastUpdated: new Date().toISOString(),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export function loadTelemetry(targetDir = process.cwd()) {
|
|
47
|
+
if (isTelemetryGloballyDisabled()) {
|
|
48
|
+
const store = createDefaultTelemetryStore(targetDir);
|
|
49
|
+
store.mode = "off";
|
|
50
|
+
return store;
|
|
51
|
+
}
|
|
52
|
+
const filePath = getTelemetryPath(targetDir);
|
|
53
|
+
if (!existsSync(filePath)) {
|
|
54
|
+
return createDefaultTelemetryStore(targetDir);
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const raw = readFileSync(filePath, "utf8");
|
|
58
|
+
const json = JSON.parse(raw);
|
|
59
|
+
const parsed = TelemetryStoreSchema.safeParse(json);
|
|
60
|
+
if (parsed.success) {
|
|
61
|
+
return parsed.data;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Ignore corrupt files and return default
|
|
66
|
+
}
|
|
67
|
+
return createDefaultTelemetryStore(targetDir);
|
|
68
|
+
}
|
|
69
|
+
export function saveTelemetry(store, targetDir = process.cwd()) {
|
|
70
|
+
const dirPath = join(targetDir, ".lognexus");
|
|
71
|
+
if (!existsSync(dirPath)) {
|
|
72
|
+
mkdirSync(dirPath, { recursive: true });
|
|
73
|
+
}
|
|
74
|
+
store.lastUpdated = new Date().toISOString();
|
|
75
|
+
store.detectedStacks = detectProjectStacks(targetDir);
|
|
76
|
+
const filePath = getTelemetryPath(targetDir);
|
|
77
|
+
writeFileSync(filePath, JSON.stringify(store, null, 2), "utf8");
|
|
78
|
+
}
|
|
79
|
+
export function isTelemetryActive(targetDir = process.cwd()) {
|
|
80
|
+
if (isTelemetryGloballyDisabled())
|
|
81
|
+
return false;
|
|
82
|
+
const store = loadTelemetry(targetDir);
|
|
83
|
+
return store.mode === "local" || store.mode === "community";
|
|
84
|
+
}
|
|
85
|
+
export function enableTelemetry(options) {
|
|
86
|
+
const cwd = options.cwd ?? process.cwd();
|
|
87
|
+
const store = loadTelemetry(cwd);
|
|
88
|
+
if (options.share) {
|
|
89
|
+
if (!options.acceptTerms) {
|
|
90
|
+
throw new Error("To enable anonymous community telemetry (--share), you must explicitly accept the terms using '--accept-terms'. View terms at: docs/TELEMETRY_PRIVACY.md");
|
|
91
|
+
}
|
|
92
|
+
store.mode = "community";
|
|
93
|
+
store.consent.accepted = true;
|
|
94
|
+
store.consent.acceptedAt = new Date().toISOString();
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
store.mode = "local";
|
|
98
|
+
}
|
|
99
|
+
saveTelemetry(store, cwd);
|
|
100
|
+
return { mode: store.mode, anonymousProjectId: store.anonymousProjectId };
|
|
101
|
+
}
|
|
102
|
+
export function disableTelemetry(targetDir = process.cwd()) {
|
|
103
|
+
const store = loadTelemetry(targetDir);
|
|
104
|
+
store.mode = "off";
|
|
105
|
+
saveTelemetry(store, targetDir);
|
|
106
|
+
}
|
|
107
|
+
export function clearTelemetry(targetDir = process.cwd()) {
|
|
108
|
+
const store = createDefaultTelemetryStore(targetDir);
|
|
109
|
+
store.mode = "off";
|
|
110
|
+
saveTelemetry(store, targetDir);
|
|
111
|
+
}
|
|
112
|
+
export function recordTaskStart(taskId, targetDir = process.cwd()) {
|
|
113
|
+
if (!isTelemetryActive(targetDir))
|
|
114
|
+
return;
|
|
115
|
+
const store = loadTelemetry(targetDir);
|
|
116
|
+
store.taskTimings[taskId] = {
|
|
117
|
+
taskId,
|
|
118
|
+
startedAt: new Date().toISOString(),
|
|
119
|
+
completedAt: null,
|
|
120
|
+
durationSec: 0,
|
|
121
|
+
};
|
|
122
|
+
saveTelemetry(store, targetDir);
|
|
123
|
+
}
|
|
124
|
+
export function recordTaskFinish(taskId, targetDir = process.cwd()) {
|
|
125
|
+
if (!isTelemetryActive(targetDir))
|
|
126
|
+
return 0;
|
|
127
|
+
const store = loadTelemetry(targetDir);
|
|
128
|
+
const entry = store.taskTimings[taskId];
|
|
129
|
+
let durationSec = 0;
|
|
130
|
+
if (entry?.startedAt) {
|
|
131
|
+
const started = new Date(entry.startedAt).getTime();
|
|
132
|
+
const now = Date.now();
|
|
133
|
+
durationSec = Math.max(1, Math.round((now - started) / 1000));
|
|
134
|
+
entry.completedAt = new Date(now).toISOString();
|
|
135
|
+
entry.durationSec = durationSec;
|
|
136
|
+
}
|
|
137
|
+
store.summary.totalSubtasksCompleted += 1;
|
|
138
|
+
saveTelemetry(store, targetDir);
|
|
139
|
+
return durationSec;
|
|
140
|
+
}
|
|
141
|
+
export function recordReviewGateBlock(targetDir = process.cwd()) {
|
|
142
|
+
if (!isTelemetryActive(targetDir))
|
|
143
|
+
return;
|
|
144
|
+
const store = loadTelemetry(targetDir);
|
|
145
|
+
store.summary.reviewGateBlocksPrevented += 1;
|
|
146
|
+
saveTelemetry(store, targetDir);
|
|
147
|
+
}
|
|
148
|
+
export function updateCostSavingsEstimate(store) {
|
|
149
|
+
// Economic model:
|
|
150
|
+
// Monolithic Tier-1 (Frontier) Baseline: Assumes 100% of tasks done by frontier model without file scoping
|
|
151
|
+
// Heuristic average cost: $0.05 per commit / diff unit
|
|
152
|
+
// LogNexus Multi-Tier actual cost:
|
|
153
|
+
// tier-1 (Arch/Review): $0.04
|
|
154
|
+
// tier-2 (Orchestration): $0.015
|
|
155
|
+
// tier-3 (Execution with Flash / DeepSeek V3 / Haiku / Kimi): $0.002
|
|
156
|
+
const totalCommits = store.summary.totalCommits;
|
|
157
|
+
if (totalCommits === 0) {
|
|
158
|
+
store.summary.estimatedBaselineCostUsd = 0;
|
|
159
|
+
store.summary.estimatedActualCostUsd = 0;
|
|
160
|
+
store.summary.estimatedCostSavingsUsd = 0;
|
|
161
|
+
store.summary.estimatedCostSavingsPct = 0;
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const baselineCost = totalCommits * 0.05;
|
|
165
|
+
let actualCost = 0;
|
|
166
|
+
for (const model of Object.values(store.models)) {
|
|
167
|
+
const unitCost = model.tier === "tier-1" ? 0.04 : model.tier === "tier-2" ? 0.015 : 0.002;
|
|
168
|
+
actualCost += model.commits * unitCost;
|
|
169
|
+
}
|
|
170
|
+
const savingsUsd = Math.max(0, baselineCost - actualCost);
|
|
171
|
+
const savingsPct = baselineCost > 0 ? (savingsUsd / baselineCost) * 100 : 0;
|
|
172
|
+
store.summary.estimatedBaselineCostUsd = Number(baselineCost.toFixed(3));
|
|
173
|
+
store.summary.estimatedActualCostUsd = Number(actualCost.toFixed(3));
|
|
174
|
+
store.summary.estimatedCostSavingsUsd = Number(savingsUsd.toFixed(3));
|
|
175
|
+
store.summary.estimatedCostSavingsPct = Number(savingsPct.toFixed(1));
|
|
176
|
+
}
|
|
177
|
+
export function recordCommitTelemetry(options) {
|
|
178
|
+
const cwd = options.targetDir ?? process.cwd();
|
|
179
|
+
if (!isTelemetryActive(cwd))
|
|
180
|
+
return;
|
|
181
|
+
const store = loadTelemetry(cwd);
|
|
182
|
+
const diffItems = extractCommitDiffStats(options.sha, cwd);
|
|
183
|
+
let commitAdded = 0;
|
|
184
|
+
let commitDeleted = 0;
|
|
185
|
+
for (const item of diffItems) {
|
|
186
|
+
commitAdded += item.linesAdded;
|
|
187
|
+
commitDeleted += item.linesDeleted;
|
|
188
|
+
const existing = store.extensions[item.ext] ?? {
|
|
189
|
+
ext: item.ext,
|
|
190
|
+
commits: 0,
|
|
191
|
+
linesAdded: 0,
|
|
192
|
+
linesDeleted: 0,
|
|
193
|
+
};
|
|
194
|
+
existing.commits += 1;
|
|
195
|
+
existing.linesAdded += item.linesAdded;
|
|
196
|
+
existing.linesDeleted += item.linesDeleted;
|
|
197
|
+
store.extensions[item.ext] = existing;
|
|
198
|
+
}
|
|
199
|
+
store.summary.totalCommits += 1;
|
|
200
|
+
store.summary.totalLinesAdded += commitAdded;
|
|
201
|
+
store.summary.totalLinesDeleted += commitDeleted;
|
|
202
|
+
const modelKey = extractModelFamilyCategory(options.author);
|
|
203
|
+
const tier = options.tier ?? "tier-3";
|
|
204
|
+
const existingModel = store.models[modelKey] ?? {
|
|
205
|
+
family: modelKey,
|
|
206
|
+
tier,
|
|
207
|
+
commits: 0,
|
|
208
|
+
totalDurationSec: 0,
|
|
209
|
+
avgSubtaskDurationSec: 0,
|
|
210
|
+
};
|
|
211
|
+
existingModel.commits += 1;
|
|
212
|
+
store.models[modelKey] = existingModel;
|
|
213
|
+
updateCostSavingsEstimate(store);
|
|
214
|
+
saveTelemetry(store, cwd);
|
|
215
|
+
// Dispatch community payload asynchronously if in community mode
|
|
216
|
+
if (store.mode === "community" && store.consent.accepted) {
|
|
217
|
+
dispatchCommunityTelemetry(store).catch(() => {
|
|
218
|
+
// Non-blocking silent catch
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
export function buildAnonymousCommunityPayload(store) {
|
|
223
|
+
return {
|
|
224
|
+
schemaVersion: "1.0.0",
|
|
225
|
+
anonymousProjectId: store.anonymousProjectId,
|
|
226
|
+
consent: store.consent,
|
|
227
|
+
environment: {
|
|
228
|
+
os: process.platform,
|
|
229
|
+
nodeVersion: process.version,
|
|
230
|
+
lognexusVersion: getCliVersion(),
|
|
231
|
+
detectedStacks: store.detectedStacks,
|
|
232
|
+
},
|
|
233
|
+
summary: store.summary,
|
|
234
|
+
languageBreakdown: Object.values(store.extensions),
|
|
235
|
+
modelBreakdown: Object.values(store.models),
|
|
236
|
+
dispatchedAt: new Date().toISOString(),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
export async function dispatchCommunityTelemetry(store, endpoint = process.env.LOGNEXUS_TELEMETRY_URL || DEFAULT_TELEMETRY_ENDPOINT) {
|
|
240
|
+
if (isTelemetryGloballyDisabled() || store.mode !== "community" || !store.consent.accepted) {
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
const payload = buildAnonymousCommunityPayload(store);
|
|
244
|
+
try {
|
|
245
|
+
const res = await fetch(endpoint, {
|
|
246
|
+
method: "POST",
|
|
247
|
+
headers: { "Content-Type": "application/json" },
|
|
248
|
+
body: JSON.stringify(payload),
|
|
249
|
+
signal: AbortSignal.timeout(1500),
|
|
250
|
+
});
|
|
251
|
+
return res.ok;
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=collector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collector.js","sourceRoot":"","sources":["../../src/telemetry/collector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface DiffStatItem {
|
|
2
|
+
ext: string;
|
|
3
|
+
linesAdded: number;
|
|
4
|
+
linesDeleted: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function detectProjectStacks(targetDir?: string): string[];
|
|
7
|
+
/**
|
|
8
|
+
* Extracts line change metrics by extension from a Git commit SHA without storing any file names or paths.
|
|
9
|
+
*/
|
|
10
|
+
export declare function extractCommitDiffStats(sha: string, targetDir?: string): DiffStatItem[];
|
|
11
|
+
/**
|
|
12
|
+
* Normalizes author/reviewer strings into generic model family categories (e.g. 'gemini/flash', 'claude/sonnet').
|
|
13
|
+
*/
|
|
14
|
+
export declare function extractModelFamilyCategory(identityStr: string | null | undefined): string;
|
|
15
|
+
//# sourceMappingURL=detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/telemetry/detector.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,mBAAmB,CAAC,SAAS,GAAE,MAAsB,GAAG,MAAM,EAAE,CA6C/E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,EACX,SAAS,GAAE,MAAsB,GAChC,YAAY,EAAE,CA2ChB;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CA8BzF"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { extname, join } from "node:path";
|
|
4
|
+
export function detectProjectStacks(targetDir = process.cwd()) {
|
|
5
|
+
const stacks = new Set();
|
|
6
|
+
try {
|
|
7
|
+
if (existsSync(join(targetDir, "package.json"))) {
|
|
8
|
+
stacks.add("nodejs");
|
|
9
|
+
if (existsSync(join(targetDir, "tsconfig.json"))) {
|
|
10
|
+
stacks.add("typescript");
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
stacks.add("javascript");
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
if (existsSync(join(targetDir, "pyproject.toml")) ||
|
|
17
|
+
existsSync(join(targetDir, "requirements.txt")) ||
|
|
18
|
+
existsSync(join(targetDir, "setup.py"))) {
|
|
19
|
+
stacks.add("python");
|
|
20
|
+
}
|
|
21
|
+
if (existsSync(join(targetDir, "Cargo.toml"))) {
|
|
22
|
+
stacks.add("rust");
|
|
23
|
+
}
|
|
24
|
+
if (existsSync(join(targetDir, "go.mod"))) {
|
|
25
|
+
stacks.add("go");
|
|
26
|
+
}
|
|
27
|
+
if (existsSync(join(targetDir, "pom.xml")) ||
|
|
28
|
+
existsSync(join(targetDir, "build.gradle")) ||
|
|
29
|
+
existsSync(join(targetDir, "build.gradle.kts"))) {
|
|
30
|
+
stacks.add("java");
|
|
31
|
+
}
|
|
32
|
+
if (existsSync(join(targetDir, "CMakeLists.txt")) || existsSync(join(targetDir, "Makefile"))) {
|
|
33
|
+
stacks.add("c/cpp");
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Ignore read errors
|
|
38
|
+
}
|
|
39
|
+
return Array.from(stacks).sort();
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Extracts line change metrics by extension from a Git commit SHA without storing any file names or paths.
|
|
43
|
+
*/
|
|
44
|
+
export function extractCommitDiffStats(sha, targetDir = process.cwd()) {
|
|
45
|
+
const extensionMap = new Map();
|
|
46
|
+
try {
|
|
47
|
+
const raw = execSync(`git diff-tree --numstat --no-commit-id -r ${sha}`, {
|
|
48
|
+
cwd: targetDir,
|
|
49
|
+
encoding: "utf8",
|
|
50
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
51
|
+
});
|
|
52
|
+
for (const line of raw.split("\n")) {
|
|
53
|
+
const trimmed = line.trim();
|
|
54
|
+
if (!trimmed)
|
|
55
|
+
continue;
|
|
56
|
+
const parts = trimmed.split(/\s+/);
|
|
57
|
+
if (parts.length < 3)
|
|
58
|
+
continue;
|
|
59
|
+
const added = Number.parseInt(parts[0], 10);
|
|
60
|
+
const deleted = Number.parseInt(parts[1], 10);
|
|
61
|
+
const filePath = parts.slice(2).join(" ");
|
|
62
|
+
// Ignore binary files where numstat outputs '-'
|
|
63
|
+
const linesAdded = Number.isNaN(added) ? 0 : added;
|
|
64
|
+
const linesDeleted = Number.isNaN(deleted) ? 0 : deleted;
|
|
65
|
+
// Extract ONLY extension (e.g. '.ts', '.py', '.md'). Zero path or filename is recorded.
|
|
66
|
+
const rawExt = extname(filePath).toLowerCase();
|
|
67
|
+
const ext = rawExt === "" ? "(no-ext)" : rawExt;
|
|
68
|
+
const existing = extensionMap.get(ext) ?? { linesAdded: 0, linesDeleted: 0 };
|
|
69
|
+
existing.linesAdded += linesAdded;
|
|
70
|
+
existing.linesDeleted += linesDeleted;
|
|
71
|
+
extensionMap.set(ext, existing);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Non-git or commit without parents
|
|
76
|
+
}
|
|
77
|
+
return Array.from(extensionMap.entries()).map(([ext, stats]) => ({
|
|
78
|
+
ext,
|
|
79
|
+
linesAdded: stats.linesAdded,
|
|
80
|
+
linesDeleted: stats.linesDeleted,
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Normalizes author/reviewer strings into generic model family categories (e.g. 'gemini/flash', 'claude/sonnet').
|
|
85
|
+
*/
|
|
86
|
+
export function extractModelFamilyCategory(identityStr) {
|
|
87
|
+
if (!identityStr)
|
|
88
|
+
return "unknown/other";
|
|
89
|
+
const trimmed = identityStr.trim().toLowerCase();
|
|
90
|
+
// Well-known model family heuristics
|
|
91
|
+
if (trimmed.includes("gemini") && trimmed.includes("flash"))
|
|
92
|
+
return "gemini/flash";
|
|
93
|
+
if (trimmed.includes("gemini") && trimmed.includes("pro"))
|
|
94
|
+
return "gemini/pro";
|
|
95
|
+
if (trimmed.includes("claude") && trimmed.includes("sonnet"))
|
|
96
|
+
return "claude/sonnet";
|
|
97
|
+
if (trimmed.includes("claude") && trimmed.includes("haiku"))
|
|
98
|
+
return "claude/haiku";
|
|
99
|
+
if (trimmed.includes("claude") && trimmed.includes("opus"))
|
|
100
|
+
return "claude/opus";
|
|
101
|
+
if (trimmed.includes("gpt") ||
|
|
102
|
+
trimmed.includes("openai") ||
|
|
103
|
+
trimmed.includes("o1") ||
|
|
104
|
+
trimmed.includes("o3")) {
|
|
105
|
+
return "openai/gpt";
|
|
106
|
+
}
|
|
107
|
+
if (trimmed.includes("deepseek"))
|
|
108
|
+
return "deepseek/v3";
|
|
109
|
+
if (trimmed.includes("kimi") || trimmed.includes("moonshot"))
|
|
110
|
+
return "moonshot/kimi";
|
|
111
|
+
if (trimmed.includes("qwen"))
|
|
112
|
+
return "qwen/coder";
|
|
113
|
+
const slashMatch = trimmed.match(/^([a-z0-9_-]+\/[a-z0-9_.-]+)/i);
|
|
114
|
+
if (slashMatch) {
|
|
115
|
+
return slashMatch[1];
|
|
116
|
+
}
|
|
117
|
+
const firstWord = trimmed.split(/\s+/)[0];
|
|
118
|
+
return firstWord || "unknown/other";
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=detector.js.map
|