agent-profiler 0.1.0 → 1.0.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 +66 -0
- package/dist/cli.js +5 -4
- package/dist/commands/init.js +4 -0
- package/dist/commands/status.js +36 -9
- package/dist/core/db.js +164 -28
- package/dist/core/gitWorkspace.js +46 -5
- package/dist/core/packageMeta.js +20 -0
- package/dist/core/schema.sql +8 -0
- package/package.json +57 -3
- package/agent-profiler-0.1.0.tgz +0 -0
- package/docs/agent-profiler-mvp-handoff.md +0 -980
- package/google-home.png +0 -0
- package/src/adapters/codex.ts +0 -131
- package/src/adapters/cursor.ts +0 -115
- package/src/cli.ts +0 -109
- package/src/commands/auditContext.ts +0 -62
- package/src/commands/hook.ts +0 -104
- package/src/commands/init.ts +0 -324
- package/src/commands/last.ts +0 -326
- package/src/commands/status.ts +0 -345
- package/src/core/contextAudit.ts +0 -102
- package/src/core/db.ts +0 -491
- package/src/core/eventMetadata.ts +0 -184
- package/src/core/gitWorkspace.ts +0 -92
- package/src/core/normalize.ts +0 -29
- package/src/core/profile.ts +0 -35
- package/src/core/schema.sql +0 -56
- package/src/core/tokens.ts +0 -4
- package/src/types/better-sqlite3.d.ts +0 -26
- package/tsconfig.json +0 -15
package/src/core/gitWorkspace.ts
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { spawnSync } from "node:child_process";
|
|
3
|
-
|
|
4
|
-
export type WorkspaceGitMeta = {
|
|
5
|
-
/** Absolute working directory for this hook (session / payload cwd). */
|
|
6
|
-
workspacePath: string;
|
|
7
|
-
/** `git rev-parse --show-toplevel` when inside a repo, else null. */
|
|
8
|
-
gitRepoRoot: string | null;
|
|
9
|
-
/** Short label: basename of repo root (and git present); else null. */
|
|
10
|
-
gitRepoName: string | null;
|
|
11
|
-
/** `git rev-parse --abbrev-ref HEAD` (may be `HEAD` when detached); null if not a git repo. */
|
|
12
|
-
gitBranch: string | null;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
function trimmedOrNull(value: unknown): string | undefined {
|
|
16
|
-
if (typeof value !== "string") return undefined;
|
|
17
|
-
const t = value.trim();
|
|
18
|
-
return t.length > 0 ? t : undefined;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function asRecord(value: unknown): Record<string, unknown> {
|
|
22
|
-
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
23
|
-
return value as Record<string, unknown>;
|
|
24
|
-
}
|
|
25
|
-
return {};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Absolute path for “where this event ran”: adapter repoPath, then common payload cwd keys, then process.cwd().
|
|
30
|
-
*/
|
|
31
|
-
export function resolveHookWorkspacePath(
|
|
32
|
-
normalizedRepoPath: string | undefined,
|
|
33
|
-
rawPayload: unknown,
|
|
34
|
-
): string {
|
|
35
|
-
const payload = asRecord(rawPayload);
|
|
36
|
-
const candidates = [
|
|
37
|
-
trimmedOrNull(normalizedRepoPath),
|
|
38
|
-
trimmedOrNull(payload.cwd),
|
|
39
|
-
trimmedOrNull(payload.workspacePath),
|
|
40
|
-
trimmedOrNull(payload.workspace),
|
|
41
|
-
trimmedOrNull(payload.projectPath),
|
|
42
|
-
trimmedOrNull(payload.rootPath),
|
|
43
|
-
];
|
|
44
|
-
for (const c of candidates) {
|
|
45
|
-
if (!c) continue;
|
|
46
|
-
return path.isAbsolute(c) ? path.normalize(c) : path.resolve(process.cwd(), c);
|
|
47
|
-
}
|
|
48
|
-
return path.resolve(process.cwd());
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function gitOutput(workspacePath: string, args: string[]): string | null {
|
|
52
|
-
try {
|
|
53
|
-
const r = spawnSync("git", ["-C", workspacePath, ...args], {
|
|
54
|
-
encoding: "utf8",
|
|
55
|
-
timeout: 2500,
|
|
56
|
-
maxBuffer: 2 * 1024 * 1024,
|
|
57
|
-
});
|
|
58
|
-
if (r.error || r.status !== 0) return null;
|
|
59
|
-
const out = (r.stdout ?? "").trim();
|
|
60
|
-
return out.length > 0 ? out : null;
|
|
61
|
-
} catch {
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Best-effort git context for `workspacePath`. Non-repo → git* fields null; `workspacePath` still set.
|
|
68
|
-
*/
|
|
69
|
-
export function resolveWorkspaceGitMeta(workspacePath: string): WorkspaceGitMeta {
|
|
70
|
-
const inside = gitOutput(workspacePath, ["rev-parse", "--is-inside-work-tree"]);
|
|
71
|
-
if (inside !== "true") {
|
|
72
|
-
return {
|
|
73
|
-
workspacePath,
|
|
74
|
-
gitRepoRoot: null,
|
|
75
|
-
gitRepoName: null,
|
|
76
|
-
gitBranch: null,
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const root = gitOutput(workspacePath, ["rev-parse", "--show-toplevel"]);
|
|
81
|
-
const branch = gitOutput(workspacePath, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
82
|
-
|
|
83
|
-
const gitRepoRoot = root ? path.normalize(root) : null;
|
|
84
|
-
const gitRepoName = gitRepoRoot ? path.basename(gitRepoRoot) : null;
|
|
85
|
-
|
|
86
|
-
return {
|
|
87
|
-
workspacePath,
|
|
88
|
-
gitRepoRoot,
|
|
89
|
-
gitRepoName,
|
|
90
|
-
gitBranch: branch,
|
|
91
|
-
};
|
|
92
|
-
}
|
package/src/core/normalize.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
export type AgentEventSource = "cursor" | "claude-code" | "codex" | "generic";
|
|
2
|
-
|
|
3
|
-
export type AgentEventRole =
|
|
4
|
-
| "user_prompt"
|
|
5
|
-
| "assistant_output"
|
|
6
|
-
| "tool_call"
|
|
7
|
-
| "tool_result"
|
|
8
|
-
| "tool_failure"
|
|
9
|
-
| "shell_command"
|
|
10
|
-
| "shell_output"
|
|
11
|
-
| "file_edit"
|
|
12
|
-
| "session_start"
|
|
13
|
-
| "session_stop"
|
|
14
|
-
| "unknown";
|
|
15
|
-
|
|
16
|
-
export type NormalizedAgentEvent = {
|
|
17
|
-
source: AgentEventSource;
|
|
18
|
-
sourceEvent: string;
|
|
19
|
-
repoPath?: string;
|
|
20
|
-
sessionId?: string;
|
|
21
|
-
turnId?: string;
|
|
22
|
-
model?: string;
|
|
23
|
-
role: AgentEventRole;
|
|
24
|
-
observableText: string;
|
|
25
|
-
estimatedInputTokens: number;
|
|
26
|
-
estimatedOutputTokens: number;
|
|
27
|
-
estimatedTotalTokens: number;
|
|
28
|
-
rawPayload: unknown;
|
|
29
|
-
};
|
package/src/core/profile.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import os from "node:os";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
|
|
5
|
-
type AgentProfilerConfig = {
|
|
6
|
-
databasePath?: string;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
function readJsonFile<T>(filePath: string): T | null {
|
|
10
|
-
try {
|
|
11
|
-
return JSON.parse(fs.readFileSync(filePath, "utf8")) as T;
|
|
12
|
-
} catch {
|
|
13
|
-
return null;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function getLocalProfileDir(cwd = process.cwd()): string {
|
|
18
|
-
return path.join(cwd, ".agent-profiler");
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function getHomeProfileDir(): string {
|
|
22
|
-
return path.join(os.homedir(), ".agent-profiler");
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function getPreferredConfigPath(cwd = process.cwd()): string {
|
|
26
|
-
const localConfig = path.join(getLocalProfileDir(cwd), "config.json");
|
|
27
|
-
if (fs.existsSync(localConfig)) return localConfig;
|
|
28
|
-
return path.join(getHomeProfileDir(), "config.json");
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function getConfiguredDatabasePath(cwd = process.cwd()): string | null {
|
|
32
|
-
const configPath = getPreferredConfigPath(cwd);
|
|
33
|
-
const config = readJsonFile<AgentProfilerConfig>(configPath);
|
|
34
|
-
return config?.databasePath ?? null;
|
|
35
|
-
}
|
package/src/core/schema.sql
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
CREATE TABLE IF NOT EXISTS events (
|
|
2
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
3
|
-
created_at TEXT NOT NULL,
|
|
4
|
-
source TEXT NOT NULL,
|
|
5
|
-
source_event TEXT NOT NULL,
|
|
6
|
-
repo_path TEXT,
|
|
7
|
-
session_id TEXT,
|
|
8
|
-
turn_id TEXT,
|
|
9
|
-
model TEXT,
|
|
10
|
-
role TEXT NOT NULL,
|
|
11
|
-
estimated_input_tokens INTEGER DEFAULT 0,
|
|
12
|
-
estimated_output_tokens INTEGER DEFAULT 0,
|
|
13
|
-
estimated_total_tokens INTEGER DEFAULT 0,
|
|
14
|
-
payload_hash TEXT NOT NULL,
|
|
15
|
-
raw_payload TEXT NOT NULL,
|
|
16
|
-
workspace_path TEXT,
|
|
17
|
-
git_repo_root TEXT,
|
|
18
|
-
git_repo_name TEXT,
|
|
19
|
-
git_branch TEXT,
|
|
20
|
-
interaction_kind TEXT,
|
|
21
|
-
correlation_id TEXT,
|
|
22
|
-
tool_canonical_name TEXT,
|
|
23
|
-
mcp_server TEXT,
|
|
24
|
-
mcp_tool TEXT,
|
|
25
|
-
payload_byte_length INTEGER,
|
|
26
|
-
prompt_fingerprint TEXT
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
CREATE TABLE IF NOT EXISTS interaction_spans (
|
|
30
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
31
|
-
session_key TEXT NOT NULL,
|
|
32
|
-
source TEXT NOT NULL,
|
|
33
|
-
correlation_id TEXT NOT NULL,
|
|
34
|
-
turn_id TEXT,
|
|
35
|
-
tool_canonical_name TEXT,
|
|
36
|
-
mcp_server TEXT,
|
|
37
|
-
mcp_tool TEXT,
|
|
38
|
-
pre_event_id INTEGER,
|
|
39
|
-
post_event_id INTEGER,
|
|
40
|
-
failure_event_id INTEGER,
|
|
41
|
-
arg_token_estimate INTEGER DEFAULT 0,
|
|
42
|
-
result_token_estimate INTEGER DEFAULT 0,
|
|
43
|
-
workspace_path TEXT,
|
|
44
|
-
git_repo_root TEXT,
|
|
45
|
-
git_repo_name TEXT,
|
|
46
|
-
git_branch TEXT,
|
|
47
|
-
started_at TEXT,
|
|
48
|
-
completed_at TEXT,
|
|
49
|
-
UNIQUE(session_key, source, correlation_id)
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
CREATE INDEX IF NOT EXISTS idx_events_session
|
|
53
|
-
ON events(session_id, created_at);
|
|
54
|
-
|
|
55
|
-
CREATE INDEX IF NOT EXISTS idx_events_source
|
|
56
|
-
ON events(source, created_at);
|
package/src/core/tokens.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
declare module "better-sqlite3" {
|
|
2
|
-
namespace Database {
|
|
3
|
-
type RunResult = { changes: number; lastInsertRowid: number | bigint };
|
|
4
|
-
|
|
5
|
-
interface Statement {
|
|
6
|
-
run(...params: unknown[]): RunResult;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
interface Database {
|
|
10
|
-
exec(sql: string): this;
|
|
11
|
-
pragma(source: string): unknown;
|
|
12
|
-
prepare(sql: string): Statement;
|
|
13
|
-
close(): void;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
class DatabaseImpl {
|
|
18
|
-
constructor(filename: string);
|
|
19
|
-
exec(sql: string): this;
|
|
20
|
-
pragma(source: string): unknown;
|
|
21
|
-
prepare(sql: string): Database.Statement;
|
|
22
|
-
close(): void;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export = DatabaseImpl;
|
|
26
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "NodeNext",
|
|
5
|
-
"moduleResolution": "NodeNext",
|
|
6
|
-
"outDir": "dist",
|
|
7
|
-
"rootDir": "src",
|
|
8
|
-
"strict": true,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"forceConsistentCasingInFileNames": true,
|
|
11
|
-
"skipLibCheck": true,
|
|
12
|
-
"types": ["node"]
|
|
13
|
-
},
|
|
14
|
-
"include": ["src"]
|
|
15
|
-
}
|