preflight-dev 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +172 -0
- package/bin/cli.js +11 -0
- package/dist/cli/init.d.ts +2 -0
- package/dist/cli/init.js +154 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +122 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +34 -0
- package/dist/lib/config.js +118 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/embeddings.d.ts +11 -0
- package/dist/lib/embeddings.js +88 -0
- package/dist/lib/embeddings.js.map +1 -0
- package/dist/lib/files.d.ts +15 -0
- package/dist/lib/files.js +60 -0
- package/dist/lib/files.js.map +1 -0
- package/dist/lib/git-extractor.d.ts +9 -0
- package/dist/lib/git-extractor.js +116 -0
- package/dist/lib/git-extractor.js.map +1 -0
- package/dist/lib/git.d.ts +29 -0
- package/dist/lib/git.js +86 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/session-parser.d.ts +45 -0
- package/dist/lib/session-parser.js +267 -0
- package/dist/lib/session-parser.js.map +1 -0
- package/dist/lib/state.d.ts +21 -0
- package/dist/lib/state.js +86 -0
- package/dist/lib/state.js.map +1 -0
- package/dist/lib/timeline-db.d.ts +67 -0
- package/dist/lib/timeline-db.js +380 -0
- package/dist/lib/timeline-db.js.map +1 -0
- package/dist/lib/triage.d.ts +29 -0
- package/dist/lib/triage.js +193 -0
- package/dist/lib/triage.js.map +1 -0
- package/dist/profiles.d.ts +3 -0
- package/dist/profiles.js +65 -0
- package/dist/profiles.js.map +1 -0
- package/dist/tools/audit-workspace.d.ts +2 -0
- package/dist/tools/audit-workspace.js +86 -0
- package/dist/tools/audit-workspace.js.map +1 -0
- package/dist/tools/checkpoint.d.ts +2 -0
- package/dist/tools/checkpoint.js +108 -0
- package/dist/tools/checkpoint.js.map +1 -0
- package/dist/tools/clarify-intent.d.ts +2 -0
- package/dist/tools/clarify-intent.js +180 -0
- package/dist/tools/clarify-intent.js.map +1 -0
- package/dist/tools/enrich-agent-task.d.ts +2 -0
- package/dist/tools/enrich-agent-task.js +97 -0
- package/dist/tools/enrich-agent-task.js.map +1 -0
- package/dist/tools/generate-scorecard.d.ts +2 -0
- package/dist/tools/generate-scorecard.js +617 -0
- package/dist/tools/generate-scorecard.js.map +1 -0
- package/dist/tools/log-correction.d.ts +2 -0
- package/dist/tools/log-correction.js +76 -0
- package/dist/tools/log-correction.js.map +1 -0
- package/dist/tools/onboard-project.d.ts +2 -0
- package/dist/tools/onboard-project.js +179 -0
- package/dist/tools/onboard-project.js.map +1 -0
- package/dist/tools/preflight-check.d.ts +2 -0
- package/dist/tools/preflight-check.js +229 -0
- package/dist/tools/preflight-check.js.map +1 -0
- package/dist/tools/prompt-score.d.ts +2 -0
- package/dist/tools/prompt-score.js +132 -0
- package/dist/tools/prompt-score.js.map +1 -0
- package/dist/tools/scan-sessions.d.ts +2 -0
- package/dist/tools/scan-sessions.js +182 -0
- package/dist/tools/scan-sessions.js.map +1 -0
- package/dist/tools/scope-work.d.ts +2 -0
- package/dist/tools/scope-work.js +214 -0
- package/dist/tools/scope-work.js.map +1 -0
- package/dist/tools/search-history.d.ts +2 -0
- package/dist/tools/search-history.js +130 -0
- package/dist/tools/search-history.js.map +1 -0
- package/dist/tools/sequence-tasks.d.ts +2 -0
- package/dist/tools/sequence-tasks.js +165 -0
- package/dist/tools/sequence-tasks.js.map +1 -0
- package/dist/tools/session-handoff.d.ts +2 -0
- package/dist/tools/session-handoff.js +113 -0
- package/dist/tools/session-handoff.js.map +1 -0
- package/dist/tools/session-health.d.ts +2 -0
- package/dist/tools/session-health.js +111 -0
- package/dist/tools/session-health.js.map +1 -0
- package/dist/tools/session-stats.d.ts +2 -0
- package/dist/tools/session-stats.js +112 -0
- package/dist/tools/session-stats.js.map +1 -0
- package/dist/tools/sharpen-followup.d.ts +2 -0
- package/dist/tools/sharpen-followup.js +192 -0
- package/dist/tools/sharpen-followup.js.map +1 -0
- package/dist/tools/timeline-view.d.ts +2 -0
- package/dist/tools/timeline-view.js +165 -0
- package/dist/tools/timeline-view.js.map +1 -0
- package/dist/tools/token-audit.d.ts +2 -0
- package/dist/tools/token-audit.js +227 -0
- package/dist/tools/token-audit.js.map +1 -0
- package/dist/tools/verify-completion.d.ts +2 -0
- package/dist/tools/verify-completion.js +154 -0
- package/dist/tools/verify-completion.js.map +1 -0
- package/dist/tools/what-changed.d.ts +2 -0
- package/dist/tools/what-changed.js +40 -0
- package/dist/tools/what-changed.js.map +1 -0
- package/dist/types.d.ts +78 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +52 -0
- package/src/cli/init.ts +133 -0
- package/src/index.ts +135 -0
- package/src/lib/config.ts +157 -0
- package/src/lib/embeddings.ts +118 -0
- package/src/lib/files.ts +59 -0
- package/src/lib/git-extractor.ts +137 -0
- package/src/lib/git.ts +89 -0
- package/src/lib/session-parser.ts +325 -0
- package/src/lib/state.ts +86 -0
- package/src/lib/timeline-db.ts +490 -0
- package/src/lib/triage.ts +255 -0
- package/src/profiles.ts +70 -0
- package/src/templates/config.yml +23 -0
- package/src/templates/triage.yml +27 -0
- package/src/tools/audit-workspace.ts +97 -0
- package/src/tools/checkpoint.ts +119 -0
- package/src/tools/clarify-intent.ts +191 -0
- package/src/tools/enrich-agent-task.ts +108 -0
- package/src/tools/generate-scorecard.ts +673 -0
- package/src/tools/log-correction.ts +89 -0
- package/src/tools/onboard-project.ts +214 -0
- package/src/tools/preflight-check.ts +263 -0
- package/src/tools/prompt-score.ts +150 -0
- package/src/tools/scan-sessions.ts +209 -0
- package/src/tools/scope-work.ts +238 -0
- package/src/tools/search-history.ts +145 -0
- package/src/tools/sequence-tasks.ts +182 -0
- package/src/tools/session-handoff.ts +125 -0
- package/src/tools/session-health.ts +107 -0
- package/src/tools/session-stats.ts +134 -0
- package/src/tools/sharpen-followup.ts +200 -0
- package/src/tools/timeline-view.ts +181 -0
- package/src/tools/token-audit.ts +259 -0
- package/src/tools/verify-completion.ts +159 -0
- package/src/tools/what-changed.ts +48 -0
- package/src/types.ts +87 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface EmbeddingProvider {
|
|
2
|
+
embed(text: string): Promise<number[]>;
|
|
3
|
+
embedBatch(texts: string[]): Promise<number[][]>;
|
|
4
|
+
dimensions: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function preprocessText(text: string): string;
|
|
7
|
+
export interface EmbeddingConfig {
|
|
8
|
+
provider: "local" | "openai";
|
|
9
|
+
apiKey?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function createEmbeddingProvider(config: EmbeddingConfig): EmbeddingProvider;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { pipeline } from "@xenova/transformers";
|
|
2
|
+
// --- Text Preprocessing ---
|
|
3
|
+
export function preprocessText(text) {
|
|
4
|
+
let t = text;
|
|
5
|
+
// Strip markdown formatting
|
|
6
|
+
t = t.replace(/```[\s\S]*?```/g, " "); // code blocks
|
|
7
|
+
t = t.replace(/`[^`]+`/g, " "); // inline code
|
|
8
|
+
t = t.replace(/[#*_~>\[\]()!]/g, ""); // markdown chars
|
|
9
|
+
t = t.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1"); // links
|
|
10
|
+
// Normalize whitespace
|
|
11
|
+
t = t.replace(/\s+/g, " ").trim();
|
|
12
|
+
// Truncate to ~512 tokens (~2048 chars as rough approximation)
|
|
13
|
+
if (t.length > 2048)
|
|
14
|
+
t = t.slice(0, 2048);
|
|
15
|
+
return t;
|
|
16
|
+
}
|
|
17
|
+
// --- Local Provider (Xenova/transformers) ---
|
|
18
|
+
let extractor = null;
|
|
19
|
+
async function getExtractor() {
|
|
20
|
+
if (!extractor) {
|
|
21
|
+
extractor = await pipeline("feature-extraction", "Xenova/all-MiniLM-L6-v2");
|
|
22
|
+
}
|
|
23
|
+
return extractor;
|
|
24
|
+
}
|
|
25
|
+
class LocalEmbeddingProvider {
|
|
26
|
+
dimensions = 384;
|
|
27
|
+
async embed(text) {
|
|
28
|
+
const ext = await getExtractor();
|
|
29
|
+
const processed = preprocessText(text);
|
|
30
|
+
const output = await ext(processed, { pooling: "mean", normalize: true });
|
|
31
|
+
return Array.from(output.data);
|
|
32
|
+
}
|
|
33
|
+
async embedBatch(texts) {
|
|
34
|
+
const results = [];
|
|
35
|
+
for (const text of texts) {
|
|
36
|
+
results.push(await this.embed(text));
|
|
37
|
+
}
|
|
38
|
+
return results;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// --- OpenAI Provider ---
|
|
42
|
+
class OpenAIEmbeddingProvider {
|
|
43
|
+
dimensions = 1536;
|
|
44
|
+
apiKey;
|
|
45
|
+
constructor(apiKey) {
|
|
46
|
+
this.apiKey = apiKey;
|
|
47
|
+
}
|
|
48
|
+
async embed(text) {
|
|
49
|
+
const [result] = await this.embedBatch([text]);
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
async embedBatch(texts) {
|
|
53
|
+
const results = [];
|
|
54
|
+
const processed = texts.map(preprocessText);
|
|
55
|
+
// Batch up to 100 at a time
|
|
56
|
+
for (let i = 0; i < processed.length; i += 100) {
|
|
57
|
+
const batch = processed.slice(i, i + 100);
|
|
58
|
+
const resp = await fetch("https://api.openai.com/v1/embeddings", {
|
|
59
|
+
method: "POST",
|
|
60
|
+
headers: {
|
|
61
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
62
|
+
"Content-Type": "application/json",
|
|
63
|
+
},
|
|
64
|
+
body: JSON.stringify({ model: "text-embedding-3-small", input: batch }),
|
|
65
|
+
});
|
|
66
|
+
if (!resp.ok) {
|
|
67
|
+
const err = await resp.text();
|
|
68
|
+
throw new Error(`OpenAI embeddings API error ${resp.status}: ${err}`);
|
|
69
|
+
}
|
|
70
|
+
const data = await resp.json();
|
|
71
|
+
// Sort by index to preserve order
|
|
72
|
+
const sorted = data.data.sort((a, b) => a.index - b.index);
|
|
73
|
+
for (const item of sorted) {
|
|
74
|
+
results.push(item.embedding);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return results;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export function createEmbeddingProvider(config) {
|
|
81
|
+
if (config.provider === "openai") {
|
|
82
|
+
if (!config.apiKey)
|
|
83
|
+
throw new Error("OpenAI API key required for openai embedding provider");
|
|
84
|
+
return new OpenAIEmbeddingProvider(config.apiKey);
|
|
85
|
+
}
|
|
86
|
+
return new LocalEmbeddingProvider();
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=embeddings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embeddings.js","sourceRoot":"","sources":["../../src/lib/embeddings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { DocInfo } from "../types.js";
|
|
2
|
+
/** Single source of truth for the project directory. */
|
|
3
|
+
export declare const PROJECT_DIR: string;
|
|
4
|
+
/**
|
|
5
|
+
* Read a file relative to PROJECT_DIR, returning at most `maxLines` lines.
|
|
6
|
+
* Returns null if the file doesn't exist or can't be read as UTF-8.
|
|
7
|
+
*/
|
|
8
|
+
export declare function readIfExists(relPath: string, maxLines?: number): string | null;
|
|
9
|
+
/**
|
|
10
|
+
* Scan .claude/ for markdown docs. Returns content + metadata by default.
|
|
11
|
+
* Pass `metadataOnly: true` to skip reading file content.
|
|
12
|
+
*/
|
|
13
|
+
export declare function findWorkspaceDocs(opts?: {
|
|
14
|
+
metadataOnly?: boolean;
|
|
15
|
+
}): Record<string, DocInfo>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { readFileSync, existsSync, readdirSync, statSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
/** Single source of truth for the project directory. */
|
|
4
|
+
export const PROJECT_DIR = process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
5
|
+
const MAX_SCAN_DEPTH = 10;
|
|
6
|
+
/**
|
|
7
|
+
* Read a file relative to PROJECT_DIR, returning at most `maxLines` lines.
|
|
8
|
+
* Returns null if the file doesn't exist or can't be read as UTF-8.
|
|
9
|
+
*/
|
|
10
|
+
export function readIfExists(relPath, maxLines = 50) {
|
|
11
|
+
const full = join(PROJECT_DIR, relPath);
|
|
12
|
+
if (!existsSync(full))
|
|
13
|
+
return null;
|
|
14
|
+
try {
|
|
15
|
+
const buf = readFileSync(full);
|
|
16
|
+
// Reject likely-binary files: check for null bytes in first 8KB
|
|
17
|
+
if (buf.subarray(0, 8192).includes(0))
|
|
18
|
+
return null;
|
|
19
|
+
const lines = buf.toString("utf-8").split("\n");
|
|
20
|
+
return lines.slice(0, maxLines).join("\n");
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Scan .claude/ for markdown docs. Returns content + metadata by default.
|
|
28
|
+
* Pass `metadataOnly: true` to skip reading file content.
|
|
29
|
+
*/
|
|
30
|
+
export function findWorkspaceDocs(opts) {
|
|
31
|
+
const docs = {};
|
|
32
|
+
const claudeDir = join(PROJECT_DIR, ".claude");
|
|
33
|
+
if (!existsSync(claudeDir))
|
|
34
|
+
return docs;
|
|
35
|
+
const scanDir = (dir, prefix = "", depth = 0) => {
|
|
36
|
+
if (depth > MAX_SCAN_DEPTH)
|
|
37
|
+
return;
|
|
38
|
+
try {
|
|
39
|
+
for (const entry of readdirSync(dir)) {
|
|
40
|
+
const full = join(dir, entry);
|
|
41
|
+
const rel = prefix ? `${prefix}/${entry}` : entry;
|
|
42
|
+
const stat = statSync(full);
|
|
43
|
+
if (stat.isDirectory() && !entry.startsWith(".") && !entry.includes("node_modules") && entry !== "preflight-state") {
|
|
44
|
+
scanDir(full, rel, depth + 1);
|
|
45
|
+
}
|
|
46
|
+
else if (entry.endsWith(".md") && stat.size < 50000) {
|
|
47
|
+
docs[rel] = {
|
|
48
|
+
content: opts?.metadataOnly ? "" : readFileSync(full, "utf-8").split("\n").slice(0, 40).join("\n"),
|
|
49
|
+
mtime: stat.mtime,
|
|
50
|
+
size: stat.size,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch { /* permission errors, etc. */ }
|
|
56
|
+
};
|
|
57
|
+
scanDir(claudeDir);
|
|
58
|
+
return docs;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/lib/files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TimelineEvent } from "./session-parser.js";
|
|
2
|
+
/**
|
|
3
|
+
* Extract git commits as TimelineEvent[].
|
|
4
|
+
*/
|
|
5
|
+
export declare function extractGitHistory(projectDir: string, opts?: {
|
|
6
|
+
since?: Date;
|
|
7
|
+
branch?: string;
|
|
8
|
+
maxCount?: number;
|
|
9
|
+
}): TimelineEvent[];
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* git-extractor.ts — Extract git commit history as timeline events.
|
|
3
|
+
*/
|
|
4
|
+
import { execSync } from "child_process";
|
|
5
|
+
import { existsSync } from "fs";
|
|
6
|
+
import { join } from "path";
|
|
7
|
+
import { randomUUID } from "crypto";
|
|
8
|
+
// In git --format, %% produces a literal %. So we use %%…%% in the format
|
|
9
|
+
// string, but the actual output contains %…%. We need separate constants.
|
|
10
|
+
const COMMIT_SEP_FMT = "%%COMMIT_START%%";
|
|
11
|
+
const COMMIT_END_FMT = "%%COMMIT_END%%";
|
|
12
|
+
const FIELD_SEP_FMT = "%%F%%";
|
|
13
|
+
// What appears in the output after git processes the format:
|
|
14
|
+
const COMMIT_SEP = "%COMMIT_START%";
|
|
15
|
+
const COMMIT_END = "%COMMIT_END%";
|
|
16
|
+
const FIELD_SEP = "%F%";
|
|
17
|
+
/**
|
|
18
|
+
* Extract git commits as TimelineEvent[].
|
|
19
|
+
*/
|
|
20
|
+
export function extractGitHistory(projectDir, opts) {
|
|
21
|
+
if (!existsSync(join(projectDir, ".git"))) {
|
|
22
|
+
// Try bare dir or parent — but most likely just not a repo
|
|
23
|
+
try {
|
|
24
|
+
execSync("git rev-parse --git-dir", { cwd: projectDir, stdio: "pipe" });
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const args = ["git", "log"];
|
|
31
|
+
if (opts?.branch) {
|
|
32
|
+
args.push(opts.branch);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
args.push("--all");
|
|
36
|
+
}
|
|
37
|
+
const maxCount = opts?.maxCount ?? 10000;
|
|
38
|
+
args.push(`--max-count=${maxCount}`);
|
|
39
|
+
if (opts?.since) {
|
|
40
|
+
args.push(`--since=${opts.since.toISOString()}`);
|
|
41
|
+
}
|
|
42
|
+
// Format: structured fields separated by known delimiters
|
|
43
|
+
args.push(`--format=${COMMIT_SEP_FMT}${FIELD_SEP_FMT}%H${FIELD_SEP_FMT}%aI${FIELD_SEP_FMT}%an${FIELD_SEP_FMT}%s${FIELD_SEP_FMT}%b${FIELD_SEP_FMT}${COMMIT_END_FMT}`, "--stat");
|
|
44
|
+
let output;
|
|
45
|
+
try {
|
|
46
|
+
output = execSync(args.join(" "), {
|
|
47
|
+
cwd: projectDir,
|
|
48
|
+
encoding: "utf-8",
|
|
49
|
+
maxBuffer: 50 * 1024 * 1024,
|
|
50
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
// No commits or other git error
|
|
55
|
+
if (err.stdout)
|
|
56
|
+
output = err.stdout;
|
|
57
|
+
else
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
if (!output.trim())
|
|
61
|
+
return [];
|
|
62
|
+
const projectName = projectDir.split("/").filter(Boolean).pop() ?? projectDir;
|
|
63
|
+
return parseGitOutput(output, projectDir, projectName);
|
|
64
|
+
}
|
|
65
|
+
// ── Internal ───────────────────────────────────────────────────────────────
|
|
66
|
+
function parseGitOutput(raw, project, projectName) {
|
|
67
|
+
const events = [];
|
|
68
|
+
// Split on COMMIT_START markers
|
|
69
|
+
const blocks = raw.split(COMMIT_SEP).filter((b) => b.includes(COMMIT_END));
|
|
70
|
+
for (const block of blocks) {
|
|
71
|
+
try {
|
|
72
|
+
const endIdx = block.indexOf(COMMIT_END);
|
|
73
|
+
const headerPart = block.slice(0, endIdx);
|
|
74
|
+
const statPart = block.slice(endIdx + COMMIT_END.length).trim();
|
|
75
|
+
const fields = headerPart.split(FIELD_SEP);
|
|
76
|
+
// fields: ["", hash, date, author, subject, body, ""]
|
|
77
|
+
const hash = fields[1]?.trim() ?? "";
|
|
78
|
+
const dateStr = fields[2]?.trim() ?? "";
|
|
79
|
+
const author = fields[3]?.trim() ?? "";
|
|
80
|
+
const subject = fields[4]?.trim() ?? "";
|
|
81
|
+
const body = fields[5]?.trim() ?? "";
|
|
82
|
+
if (!hash)
|
|
83
|
+
continue;
|
|
84
|
+
const commitMsg = body ? `${subject}\n\n${body}` : subject;
|
|
85
|
+
const content = statPart ? `${commitMsg}\n\n${statPart}` : commitMsg;
|
|
86
|
+
// Parse diffstat summary (last line like " 3 files changed, 10 insertions(+), 2 deletions(-)")
|
|
87
|
+
const statMatch = statPart.match(/(\d+) files? changed(?:,\s*(\d+) insertions?\(\+\))?(?:,\s*(\d+) deletions?\(-\))?/);
|
|
88
|
+
const metadata = JSON.stringify({
|
|
89
|
+
hash,
|
|
90
|
+
author,
|
|
91
|
+
files_changed: statMatch ? parseInt(statMatch[1], 10) : 0,
|
|
92
|
+
insertions: statMatch?.[2] ? parseInt(statMatch[2], 10) : 0,
|
|
93
|
+
deletions: statMatch?.[3] ? parseInt(statMatch[3], 10) : 0,
|
|
94
|
+
});
|
|
95
|
+
events.push({
|
|
96
|
+
id: randomUUID(),
|
|
97
|
+
timestamp: new Date(dateStr).toISOString(),
|
|
98
|
+
type: "commit",
|
|
99
|
+
project,
|
|
100
|
+
project_name: projectName,
|
|
101
|
+
branch: "all",
|
|
102
|
+
session_id: "",
|
|
103
|
+
source_file: `git:${hash}`,
|
|
104
|
+
source_line: 0,
|
|
105
|
+
content,
|
|
106
|
+
content_preview: subject.length > 120 ? subject.slice(0, 120) + "…" : subject,
|
|
107
|
+
metadata,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
process.stderr.write(`[git-extractor] failed to parse commit block: ${err}\n`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return events;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=git-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-extractor.js","sourceRoot":"","sources":["../../src/lib/git-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run a git command safely using execFileSync (no shell injection).
|
|
3
|
+
* Accepts an array of args (preferred) or a string (split on whitespace for backward compat).
|
|
4
|
+
* Returns stdout on success. On failure, returns a descriptive error string.
|
|
5
|
+
*/
|
|
6
|
+
export declare function run(argsOrCmd: string | string[], opts?: {
|
|
7
|
+
timeout?: number;
|
|
8
|
+
}): string;
|
|
9
|
+
/** Get the current branch name. */
|
|
10
|
+
export declare function getBranch(): string;
|
|
11
|
+
/** Get short git status. */
|
|
12
|
+
export declare function getStatus(): string;
|
|
13
|
+
/** Get recent commits as oneline. */
|
|
14
|
+
export declare function getRecentCommits(count?: number): string;
|
|
15
|
+
/** Get the last commit as oneline. */
|
|
16
|
+
export declare function getLastCommit(): string;
|
|
17
|
+
/** Get the last commit timestamp. */
|
|
18
|
+
export declare function getLastCommitTime(): string;
|
|
19
|
+
/**
|
|
20
|
+
* Get files changed since `ref`. Falls back to HEAD~1, then "no commits".
|
|
21
|
+
* Uses explicit fallback steps instead of shell chaining.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getDiffFiles(ref?: string): string;
|
|
24
|
+
/** Get staged files. */
|
|
25
|
+
export declare function getStagedFiles(): string;
|
|
26
|
+
/**
|
|
27
|
+
* Get diff stat since `ref`. Falls back to HEAD~3.
|
|
28
|
+
*/
|
|
29
|
+
export declare function getDiffStat(ref?: string): string;
|
package/dist/lib/git.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { execFileSync } from "child_process";
|
|
2
|
+
import { PROJECT_DIR } from "./files.js";
|
|
3
|
+
/**
|
|
4
|
+
* Run a git command safely using execFileSync (no shell injection).
|
|
5
|
+
* Accepts an array of args (preferred) or a string (split on whitespace for backward compat).
|
|
6
|
+
* Returns stdout on success. On failure, returns a descriptive error string.
|
|
7
|
+
*/
|
|
8
|
+
export function run(argsOrCmd, opts = {}) {
|
|
9
|
+
const args = typeof argsOrCmd === "string" ? argsOrCmd.split(/\s+/) : argsOrCmd;
|
|
10
|
+
try {
|
|
11
|
+
return execFileSync("git", args, {
|
|
12
|
+
cwd: PROJECT_DIR,
|
|
13
|
+
encoding: "utf-8",
|
|
14
|
+
timeout: opts.timeout || 10000,
|
|
15
|
+
maxBuffer: 1024 * 1024,
|
|
16
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
17
|
+
}).trim();
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
const timedOut = e.killed === true || e.signal === "SIGTERM";
|
|
21
|
+
if (timedOut) {
|
|
22
|
+
return `[timed out after ${opts.timeout || 10000}ms]`;
|
|
23
|
+
}
|
|
24
|
+
// Return stderr/stdout if available, otherwise the error message
|
|
25
|
+
const output = e.stdout?.trim() || e.stderr?.trim();
|
|
26
|
+
if (output)
|
|
27
|
+
return output;
|
|
28
|
+
if (e.code === "ENOENT")
|
|
29
|
+
return "[git not found]";
|
|
30
|
+
return `[command failed: git ${args.join(" ")} (exit ${e.status ?? "?"})]`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** Convenience: run a raw command string (split on spaces). Only for simple, known-safe commands. */
|
|
34
|
+
function gitCmd(cmdStr, opts) {
|
|
35
|
+
return run(cmdStr.split(/\s+/), opts);
|
|
36
|
+
}
|
|
37
|
+
/** Get the current branch name. */
|
|
38
|
+
export function getBranch() {
|
|
39
|
+
return run(["branch", "--show-current"]);
|
|
40
|
+
}
|
|
41
|
+
/** Get short git status. */
|
|
42
|
+
export function getStatus() {
|
|
43
|
+
return run(["status", "--short"]);
|
|
44
|
+
}
|
|
45
|
+
/** Get recent commits as oneline. */
|
|
46
|
+
export function getRecentCommits(count = 5) {
|
|
47
|
+
return run(["log", "--oneline", `-${count}`]);
|
|
48
|
+
}
|
|
49
|
+
/** Get the last commit as oneline. */
|
|
50
|
+
export function getLastCommit() {
|
|
51
|
+
return run(["log", "--oneline", "-1"]);
|
|
52
|
+
}
|
|
53
|
+
/** Get the last commit timestamp. */
|
|
54
|
+
export function getLastCommitTime() {
|
|
55
|
+
return run(["log", "-1", "--format=%ci"]);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get files changed since `ref`. Falls back to HEAD~1, then "no commits".
|
|
59
|
+
* Uses explicit fallback steps instead of shell chaining.
|
|
60
|
+
*/
|
|
61
|
+
export function getDiffFiles(ref = "HEAD~3") {
|
|
62
|
+
const result = run(["diff", "--name-only", ref]);
|
|
63
|
+
if (!result.startsWith("["))
|
|
64
|
+
return result;
|
|
65
|
+
const fallback = run(["diff", "--name-only", "HEAD~1"]);
|
|
66
|
+
if (!fallback.startsWith("["))
|
|
67
|
+
return fallback;
|
|
68
|
+
return "no commits";
|
|
69
|
+
}
|
|
70
|
+
/** Get staged files. */
|
|
71
|
+
export function getStagedFiles() {
|
|
72
|
+
return run(["diff", "--staged", "--name-only"]);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get diff stat since `ref`. Falls back to HEAD~3.
|
|
76
|
+
*/
|
|
77
|
+
export function getDiffStat(ref = "HEAD~5") {
|
|
78
|
+
const result = run(["diff", ref, "--stat"]);
|
|
79
|
+
if (!result.startsWith("["))
|
|
80
|
+
return result;
|
|
81
|
+
const fallback = run(["diff", "HEAD~3", "--stat"]);
|
|
82
|
+
if (!fallback.startsWith("["))
|
|
83
|
+
return fallback;
|
|
84
|
+
return "no diff stats available";
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGzC;;;;GAIG;AACH,MAAM,UAAU,GAAG,CAAC,SAA4B,EAAE,OAA6B,EAAE;IAC/E,MAAM,IAAI,GAAG,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAChF,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE;YAC/B,GAAG,EAAE,WAAW;YAChB,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,KAAK;YAC9B,SAAS,EAAE,IAAI,GAAG,IAAI;YACtB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC,IAAI,EAAE,CAAC;IACZ,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC;QAC7D,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,oBAAoB,IAAI,CAAC,OAAO,IAAI,KAAK,KAAK,CAAC;QACxD,CAAC;QACD,iEAAiE;QACjE,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;QACpD,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAC1B,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,iBAAiB,CAAC;QAClD,OAAO,wBAAwB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC;IAC7E,CAAC;AACH,CAAC;AAED,qGAAqG;AACrG,SAAS,MAAM,CAAC,MAAc,EAAE,IAA2B;IACzD,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,SAAS;IACvB,OAAO,GAAG,CAAC,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,4BAA4B;AAC5B,MAAM,UAAU,SAAS;IACvB,OAAO,GAAG,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,gBAAgB,CAAC,KAAK,GAAG,CAAC;IACxC,OAAO,GAAG,CAAC,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,aAAa;IAC3B,OAAO,GAAG,CAAC,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,iBAAiB;IAC/B,OAAO,GAAG,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,GAAG,GAAG,QAAQ;IACzC,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC,CAAC;IACjD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC;IAC3C,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC;IACxD,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC/C,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,wBAAwB;AACxB,MAAM,UAAU,cAAc;IAC5B,OAAO,GAAG,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC;AAClD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,GAAG,GAAG,QAAQ;IACxC,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC;IAC3C,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IACnD,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC/C,OAAO,yBAAyB,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export interface TimelineEvent {
|
|
2
|
+
id: string;
|
|
3
|
+
timestamp: string;
|
|
4
|
+
type: string;
|
|
5
|
+
project: string;
|
|
6
|
+
project_name: string;
|
|
7
|
+
branch: string;
|
|
8
|
+
session_id: string;
|
|
9
|
+
source_file: string;
|
|
10
|
+
source_line: number;
|
|
11
|
+
content: string;
|
|
12
|
+
content_preview: string;
|
|
13
|
+
metadata: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Discover all Claude project session directories.
|
|
17
|
+
*/
|
|
18
|
+
export declare function findSessionDirs(): {
|
|
19
|
+
project: string;
|
|
20
|
+
projectName: string;
|
|
21
|
+
sessionDir: string;
|
|
22
|
+
}[];
|
|
23
|
+
/**
|
|
24
|
+
* List JSONL session files in a project directory (including subagent files).
|
|
25
|
+
*/
|
|
26
|
+
export declare function findSessionFiles(projectDir: string): {
|
|
27
|
+
sessionId: string;
|
|
28
|
+
path: string;
|
|
29
|
+
mtime: Date;
|
|
30
|
+
}[];
|
|
31
|
+
/**
|
|
32
|
+
* Parse a single JSONL session file into timeline events.
|
|
33
|
+
* For files >10MB, streams line-by-line.
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseSession(filePath: string, project: string, projectName: string): TimelineEvent[];
|
|
36
|
+
/**
|
|
37
|
+
* Async streaming parser for large files.
|
|
38
|
+
*/
|
|
39
|
+
export declare function parseSessionAsync(filePath: string, project: string, projectName: string): Promise<TimelineEvent[]>;
|
|
40
|
+
/**
|
|
41
|
+
* Parse all sessions for a project directory, optionally filtering by mtime.
|
|
42
|
+
*/
|
|
43
|
+
export declare function parseAllSessions(projectDir: string, opts?: {
|
|
44
|
+
since?: Date;
|
|
45
|
+
}): TimelineEvent[];
|