@hegel-dev/companion 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 +84 -0
- package/dist/analyzers/prompt-analyzer.d.ts +7 -0
- package/dist/analyzers/prompt-analyzer.d.ts.map +1 -0
- package/dist/analyzers/prompt-analyzer.js +224 -0
- package/dist/analyzers/prompt-analyzer.js.map +1 -0
- package/dist/analyzers/response-analyzer.d.ts +6 -0
- package/dist/analyzers/response-analyzer.d.ts.map +1 -0
- package/dist/analyzers/response-analyzer.js +218 -0
- package/dist/analyzers/response-analyzer.js.map +1 -0
- package/dist/analyzers/session-analyzer.d.ts +10 -0
- package/dist/analyzers/session-analyzer.d.ts.map +1 -0
- package/dist/analyzers/session-analyzer.js +194 -0
- package/dist/analyzers/session-analyzer.js.map +1 -0
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +27 -0
- package/dist/config.js.map +1 -0
- package/dist/debug-wrapper.d.ts +2 -0
- package/dist/debug-wrapper.d.ts.map +1 -0
- package/dist/debug-wrapper.js +55 -0
- package/dist/debug-wrapper.js.map +1 -0
- package/dist/dev-watch.d.ts +10 -0
- package/dist/dev-watch.d.ts.map +1 -0
- package/dist/dev-watch.js +55 -0
- package/dist/dev-watch.js.map +1 -0
- package/dist/format.d.ts +4 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +38 -0
- package/dist/format.js.map +1 -0
- package/dist/hook.d.ts +8 -0
- package/dist/hook.d.ts.map +1 -0
- package/dist/hook.js +320 -0
- package/dist/hook.js.map +1 -0
- package/dist/hooks-generator.d.ts +45 -0
- package/dist/hooks-generator.d.ts.map +1 -0
- package/dist/hooks-generator.js +120 -0
- package/dist/hooks-generator.js.map +1 -0
- package/dist/mcp.d.ts +10 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +173 -0
- package/dist/mcp.js.map +1 -0
- package/dist/prompts.d.ts +11 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +85 -0
- package/dist/prompts.js.map +1 -0
- package/dist/setup.d.ts +28 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +247 -0
- package/dist/setup.js.map +1 -0
- package/dist/state.d.ts +14 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +77 -0
- package/dist/state.js.map +1 -0
- package/dist/transcript.d.ts +32 -0
- package/dist/transcript.d.ts.map +1 -0
- package/dist/transcript.js +156 -0
- package/dist/transcript.js.map +1 -0
- package/dist/types.d.ts +137 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/hegel-vscode/hegel-companion-1.0.0.vsix +0 -0
- package/hegel.config.schema.json +63 -0
- package/package.json +59 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { sessionDurationMinutes, totalFilesEdited, totalLinesChanged, } from "../state.js";
|
|
2
|
+
import { recentUserTurns } from "../transcript.js";
|
|
3
|
+
const ACTIVE_STEERING_PATTERN = /\b(test|verify|verification|review|audit|security|coverage|commit|push|fix|implement|update|plan|analy[sz]e|enhancement|tune)\b/i;
|
|
4
|
+
const PASSIVE_DELEGATION_PATTERN = /^(continue|go on|go ahead|do it|same|yes|ok|okay|sure|proceed|carry on)[.!]?$/i;
|
|
5
|
+
const CONCERN_CONFIDENCE = {
|
|
6
|
+
"context-loss": "high",
|
|
7
|
+
"no-checkpoint": "high",
|
|
8
|
+
"self-contradiction": "high",
|
|
9
|
+
"scope-creep": "medium",
|
|
10
|
+
"prompt-degradation": "medium",
|
|
11
|
+
"missing-verification": "medium",
|
|
12
|
+
"session-trend": "medium",
|
|
13
|
+
"over-delegation": "low",
|
|
14
|
+
"non-responsive": "low",
|
|
15
|
+
"repeated-rephrase": "low",
|
|
16
|
+
};
|
|
17
|
+
function confidenceForCategory(category) {
|
|
18
|
+
return CONCERN_CONFIDENCE[category] ?? "medium";
|
|
19
|
+
}
|
|
20
|
+
function shouldShowInSessionSummary(concern) {
|
|
21
|
+
return concern.severity !== "info" || confidenceForCategory(concern.category) !== "low";
|
|
22
|
+
}
|
|
23
|
+
const LATER_VERIFICATION_PATTERN = /\b(test|tests|testing|build|verify|verification|validated?|coverage|suite|passed|green|security review|audit)\b/i;
|
|
24
|
+
function concernSupersededByLaterEvidence(concern, state, transcript) {
|
|
25
|
+
if (concern.category !== "untested-changes" && concern.category !== "missing-verification") {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
const recentPromptEvidence = state.prompts
|
|
29
|
+
.slice(-4)
|
|
30
|
+
.some((prompt) => LATER_VERIFICATION_PATTERN.test(prompt.prompt));
|
|
31
|
+
const recentResponseEvidence = state.responses
|
|
32
|
+
.slice(-4)
|
|
33
|
+
.some((response) => !response.concerns.some((c) => c.category === concern.category));
|
|
34
|
+
let transcriptEvidence = false;
|
|
35
|
+
if (transcript) {
|
|
36
|
+
transcriptEvidence = recentUserTurns(transcript, 4)
|
|
37
|
+
.some((turn) => LATER_VERIFICATION_PATTERN.test(turn.text));
|
|
38
|
+
}
|
|
39
|
+
return recentPromptEvidence || (transcriptEvidence && recentResponseEvidence);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Produces a human-readable session summary with accumulated concerns.
|
|
43
|
+
* Called at the stop hook — this is Hegel's "end of turn" dialectical review.
|
|
44
|
+
*/
|
|
45
|
+
export function analyzeSession(state, transcript) {
|
|
46
|
+
const concerns = [];
|
|
47
|
+
const minutes = sessionDurationMinutes(state);
|
|
48
|
+
const files = totalFilesEdited(state);
|
|
49
|
+
const lines = totalLinesChanged(state);
|
|
50
|
+
const ctx = transcript ?? null;
|
|
51
|
+
// ── Accumulated pattern analysis ──
|
|
52
|
+
// Prompt quality trend — prefer transcript data when available for a
|
|
53
|
+
// more accurate picture of the full conversation, not just hook-tracked turns.
|
|
54
|
+
const median = (counts) => {
|
|
55
|
+
const sorted = [...counts].sort((a, b) => a - b);
|
|
56
|
+
const mid = Math.floor(sorted.length / 2);
|
|
57
|
+
return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
|
|
58
|
+
};
|
|
59
|
+
if (ctx && ctx.userTurnCount >= 6) {
|
|
60
|
+
const allUserTurns = recentUserTurns(ctx, ctx.userTurnCount);
|
|
61
|
+
const half = Math.floor(allUserTurns.length / 2);
|
|
62
|
+
const firstCounts = allUserTurns.slice(0, half).map((t) => t.wordCount);
|
|
63
|
+
const secondCounts = allUserTurns.slice(half).map((t) => t.wordCount);
|
|
64
|
+
const medFirst = median(firstCounts);
|
|
65
|
+
const medSecond = median(secondCounts);
|
|
66
|
+
if (medSecond < medFirst * 0.4 && medSecond < 10) {
|
|
67
|
+
concerns.push({
|
|
68
|
+
severity: "warning",
|
|
69
|
+
category: "session-trend",
|
|
70
|
+
message: `Prompt quality declined (transcript): first half median ${Math.round(medFirst)} words, second half median ${Math.round(medSecond)} words`,
|
|
71
|
+
suggestion: "In future sessions, maintain detailed prompts throughout. Consider setting a personal rule: every prompt should have at least one concrete reference (file, function, behavior).",
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else if (state.prompts.length >= 6) {
|
|
76
|
+
const half = Math.floor(state.prompts.length / 2);
|
|
77
|
+
const firstCounts = state.prompts.slice(0, half).map((p) => p.wordCount);
|
|
78
|
+
const secondCounts = state.prompts.slice(half).map((p) => p.wordCount);
|
|
79
|
+
const medFirst = median(firstCounts);
|
|
80
|
+
const medSecond = median(secondCounts);
|
|
81
|
+
if (medSecond < medFirst * 0.4 && medSecond < 10) {
|
|
82
|
+
concerns.push({
|
|
83
|
+
severity: "warning",
|
|
84
|
+
category: "session-trend",
|
|
85
|
+
message: `Prompt quality declined: first half median ${Math.round(medFirst)} words, second half median ${Math.round(medSecond)} words`,
|
|
86
|
+
suggestion: "In future sessions, maintain detailed prompts throughout. Consider setting a personal rule: every prompt should have at least one concrete reference (file, function, behavior).",
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Concern frequency
|
|
91
|
+
const allConcerns = state.concerns.filter((concern) => !concernSupersededByLaterEvidence(concern, state, ctx));
|
|
92
|
+
const categoryCounts = new Map();
|
|
93
|
+
for (const c of allConcerns) {
|
|
94
|
+
categoryCounts.set(c.category, (categoryCounts.get(c.category) ?? 0) + 1);
|
|
95
|
+
}
|
|
96
|
+
const repeatedCategories = [...categoryCounts.entries()]
|
|
97
|
+
.filter(([category]) => confidenceForCategory(category) !== "low")
|
|
98
|
+
.filter(([, count]) => count >= 3)
|
|
99
|
+
.sort((a, b) => b[1] - a[1]);
|
|
100
|
+
if (repeatedCategories.length > 0) {
|
|
101
|
+
const details = repeatedCategories
|
|
102
|
+
.map(([cat, count]) => `${cat} (${count}x)`)
|
|
103
|
+
.join(", ");
|
|
104
|
+
concerns.push({
|
|
105
|
+
severity: "info",
|
|
106
|
+
category: "recurring-patterns",
|
|
107
|
+
message: `Recurring concern patterns this session: ${details}`,
|
|
108
|
+
suggestion: "These patterns suggest areas for your development workflow to improve. Consider creating personal rules or checklists for the frequent categories.",
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
// Long session without commits — check both state prompts and transcript
|
|
112
|
+
let mentionsCommit = state.prompts.some((p) => /\b(commit|push|save|checkpoint)\b/i.test(p.prompt));
|
|
113
|
+
if (!mentionsCommit && ctx) {
|
|
114
|
+
const userTurns = recentUserTurns(ctx, ctx.userTurnCount);
|
|
115
|
+
mentionsCommit = userTurns.some((t) => /\b(commit|push|save|checkpoint)\b/i.test(t.text));
|
|
116
|
+
}
|
|
117
|
+
if (minutes > 30 && lines > 100 && !mentionsCommit) {
|
|
118
|
+
concerns.push({
|
|
119
|
+
severity: "warning",
|
|
120
|
+
category: "no-checkpoint",
|
|
121
|
+
message: `${Math.round(minutes)} min session with ${lines} lines changed and no commit/checkpoint mentioned`,
|
|
122
|
+
suggestion: "Commit working changes frequently. It's much easier to review and revert small increments than large batches.",
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
// [Transcript-only] Conversation depth ratio — if the assistant is producing
|
|
126
|
+
// significantly more text than the user is providing, the user may be
|
|
127
|
+
// over-delegating without steering.
|
|
128
|
+
if (ctx && ctx.userTurnCount >= 3 && ctx.assistantTurnCount >= 3) {
|
|
129
|
+
const userTurns = recentUserTurns(ctx, ctx.userTurnCount);
|
|
130
|
+
const totalUserWords = ctx.turns
|
|
131
|
+
.filter((t) => t.role === "user")
|
|
132
|
+
.reduce((s, t) => s + t.wordCount, 0);
|
|
133
|
+
const totalAssistantWords = ctx.turns
|
|
134
|
+
.filter((t) => t.role === "assistant")
|
|
135
|
+
.reduce((s, t) => s + t.wordCount, 0);
|
|
136
|
+
const recentUserText = userTurns.slice(-4).map((t) => t.text).join("\n");
|
|
137
|
+
const hasActiveSteering = ACTIVE_STEERING_PATTERN.test(recentUserText);
|
|
138
|
+
const passiveTurnCount = userTurns.filter((t) => t.wordCount <= 3 || PASSIVE_DELEGATION_PATTERN.test(t.text.trim())).length;
|
|
139
|
+
if (totalAssistantWords > 0 && totalUserWords > 0) {
|
|
140
|
+
const ratio = totalAssistantWords / totalUserWords;
|
|
141
|
+
if (ratio > 20 && ctx.userTurnCount >= 5 && passiveTurnCount >= 3 && !hasActiveSteering) {
|
|
142
|
+
concerns.push({
|
|
143
|
+
severity: "info",
|
|
144
|
+
category: "over-delegation",
|
|
145
|
+
message: `AI output is ${Math.round(ratio)}x the volume of your input. You may be auto-accepting without enough steering.`,
|
|
146
|
+
suggestion: "Review the AI's outputs more critically. Are you checking the code changes, or just saying 'continue'?",
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// High compaction count — early context is degraded
|
|
152
|
+
if (state.compactionCount >= 2) {
|
|
153
|
+
concerns.push({
|
|
154
|
+
severity: state.compactionCount >= 3 ? "warning" : "info",
|
|
155
|
+
category: "context-loss",
|
|
156
|
+
message: `Context was compacted ${state.compactionCount} times this session. Early instructions and decisions may be lost.`,
|
|
157
|
+
suggestion: "Start a fresh chat with a summary of key decisions so far. Continuing in a heavily compacted session increases the risk of contradictory or off-track changes.",
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
// ── Build summary ──
|
|
161
|
+
const warningCount = allConcerns.filter((c) => c.severity === "warning").length;
|
|
162
|
+
const criticalCount = allConcerns.filter((c) => c.severity === "critical").length;
|
|
163
|
+
const models = state.modelsUsed?.join(", ") ?? "unknown";
|
|
164
|
+
const summaryConcerns = concerns.filter(shouldShowInSessionSummary);
|
|
165
|
+
const summaryParts = [
|
|
166
|
+
`📊 Hegel Session Review`,
|
|
167
|
+
`─────────────────────────`,
|
|
168
|
+
`Duration: ${Math.round(minutes)} min | Turns: ${state.turnCount} | Files: ${files} | Lines: ${lines} | Compactions: ${state.compactionCount} | Model: ${models}`,
|
|
169
|
+
];
|
|
170
|
+
if (ctx) {
|
|
171
|
+
summaryParts.push(`Transcript: ${ctx.userTurnCount} user turns, ${ctx.assistantTurnCount} assistant turns`);
|
|
172
|
+
}
|
|
173
|
+
if (criticalCount > 0 || warningCount > 0) {
|
|
174
|
+
summaryParts.push(`Concerns: ${criticalCount} critical, ${warningCount} warnings`);
|
|
175
|
+
}
|
|
176
|
+
if (summaryConcerns.length > 0) {
|
|
177
|
+
summaryParts.push("", "Session-level observations:");
|
|
178
|
+
for (const c of summaryConcerns) {
|
|
179
|
+
const icon = c.severity === "critical" ? "🔴" : c.severity === "warning" ? "🟡" : "🔵";
|
|
180
|
+
summaryParts.push(`${icon} ${c.message}`);
|
|
181
|
+
if (c.suggestion) {
|
|
182
|
+
summaryParts.push(` → ${c.suggestion}`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (concerns.length === 0 && warningCount === 0) {
|
|
187
|
+
summaryParts.push("", "✅ Clean session — no significant concerns detected.");
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
summary: summaryParts.join("\n"),
|
|
191
|
+
concerns,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=session-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-analyzer.js","sourceRoot":"","sources":["../../src/analyzers/session-analyzer.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface HegelConfig {
|
|
2
|
+
model: string;
|
|
3
|
+
enableLlmAnalysis: boolean;
|
|
4
|
+
timeoutSeconds: number;
|
|
5
|
+
strictness: "relaxed" | "balanced" | "strict";
|
|
6
|
+
/** When true, both layers still run full analysis and collect stats, but the user never sees intervention in the chat (no blocking, no user_message). */
|
|
7
|
+
observeOnly: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function configPath(workspaceRoot?: string): string;
|
|
10
|
+
export declare function loadConfig(workspaceRoot?: string): Promise<HegelConfig>;
|
|
11
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,OAAO,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;IAC9C,yJAAyJ;IACzJ,WAAW,EAAE,OAAO,CAAC;CACtB;AAcD,wBAAgB,UAAU,CAAC,aAAa,GAAE,MAAsB,GAAG,MAAM,CAExE;AAED,wBAAsB,UAAU,CAAC,aAAa,GAAE,MAAsB,GAAG,OAAO,CAAC,WAAW,CAAC,CAQ5F"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { join, dirname } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
const DEFAULTS = {
|
|
5
|
+
model: "auto",
|
|
6
|
+
enableLlmAnalysis: true,
|
|
7
|
+
timeoutSeconds: 15,
|
|
8
|
+
strictness: "balanced",
|
|
9
|
+
observeOnly: false,
|
|
10
|
+
};
|
|
11
|
+
function hegelRoot() {
|
|
12
|
+
return join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
13
|
+
}
|
|
14
|
+
export function configPath(workspaceRoot = process.cwd()) {
|
|
15
|
+
return join(workspaceRoot, "hegel.config.json");
|
|
16
|
+
}
|
|
17
|
+
export async function loadConfig(workspaceRoot = process.cwd()) {
|
|
18
|
+
try {
|
|
19
|
+
const raw = await readFile(configPath(workspaceRoot), "utf-8");
|
|
20
|
+
const parsed = JSON.parse(raw);
|
|
21
|
+
return { ...DEFAULTS, ...parsed };
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return { ...DEFAULTS };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAWzC,MAAM,QAAQ,GAAgB;IAC5B,KAAK,EAAE,MAAM;IACb,iBAAiB,EAAE,IAAI;IACvB,cAAc,EAAE,EAAE;IAClB,UAAU,EAAE,UAAU;IACtB,WAAW,EAAE,KAAK;CACnB,CAAC;AAEF,SAAS,SAAS;IAChB,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,gBAAwB,OAAO,CAAC,GAAG,EAAE;IAC9D,OAAO,IAAI,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,gBAAwB,OAAO,CAAC,GAAG,EAAE;IACpE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAyB,CAAC;QACvD,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC;IACzB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug-wrapper.d.ts","sourceRoot":"","sources":["../src/debug-wrapper.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { stdin } from "node:process";
|
|
2
|
+
import { appendFile, mkdir } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
const LOG_DIR = ".hegel-state";
|
|
5
|
+
const DEBUG_LOG = join(LOG_DIR, "debug-raw.log");
|
|
6
|
+
async function main() {
|
|
7
|
+
await mkdir(LOG_DIR, { recursive: true });
|
|
8
|
+
const chunks = [];
|
|
9
|
+
for await (const chunk of stdin) {
|
|
10
|
+
chunks.push(chunk);
|
|
11
|
+
}
|
|
12
|
+
const raw = Buffer.concat(chunks).toString("utf-8").replace(/^\uFEFF/, "");
|
|
13
|
+
const ts = new Date().toISOString();
|
|
14
|
+
await appendFile(DEBUG_LOG, `\n=== ${ts} ===\nSTDIN (${raw.length} bytes):\n${raw}\n`, "utf-8");
|
|
15
|
+
let input;
|
|
16
|
+
try {
|
|
17
|
+
input = JSON.parse(raw);
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
21
|
+
await appendFile(DEBUG_LOG, `PARSE ERROR: ${errMsg}\n`, "utf-8");
|
|
22
|
+
process.stdout.write(JSON.stringify({ continue: true }) + "\n");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
await appendFile(DEBUG_LOG, `PARSED event: ${input.hook_event_name}\n`, "utf-8");
|
|
26
|
+
const event = input.hook_event_name;
|
|
27
|
+
if (event === "beforeSubmitPrompt") {
|
|
28
|
+
const prompt = input.prompt ?? "";
|
|
29
|
+
const isLazy = /^(fix it|fix this|do it|make it work)\.?$/i.test(prompt.trim());
|
|
30
|
+
const output = isLazy
|
|
31
|
+
? { continue: false, user_message: `⚖️ Hegel: Lazy prompt detected — "${prompt}". Please be more specific.` }
|
|
32
|
+
: { continue: true };
|
|
33
|
+
const json = JSON.stringify(output);
|
|
34
|
+
await appendFile(DEBUG_LOG, `STDOUT: ${json}\n`, "utf-8");
|
|
35
|
+
process.stdout.write(json + "\n");
|
|
36
|
+
}
|
|
37
|
+
else if (event === "stop") {
|
|
38
|
+
const output = { followup_message: "📊 Hegel: Session review — debug wrapper active." };
|
|
39
|
+
const json = JSON.stringify(output);
|
|
40
|
+
await appendFile(DEBUG_LOG, `STDOUT: ${json}\n`, "utf-8");
|
|
41
|
+
process.stdout.write(json + "\n");
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
process.stdout.write(JSON.stringify({}) + "\n");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
main().catch(async (err) => {
|
|
48
|
+
try {
|
|
49
|
+
await mkdir(LOG_DIR, { recursive: true });
|
|
50
|
+
await appendFile(DEBUG_LOG, `FATAL: ${err instanceof Error ? err.stack : String(err)}\n`, "utf-8");
|
|
51
|
+
}
|
|
52
|
+
catch { /* */ }
|
|
53
|
+
process.stdout.write(JSON.stringify({ continue: true }) + "\n");
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=debug-wrapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug-wrapper.js","sourceRoot":"","sources":["../src/debug-wrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,OAAO,GAAG,cAAc,CAAC;AAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;AAEjD,KAAK,UAAU,IAAI;IACjB,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,KAAe,CAAC,CAAC;IAC/B,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAE3E,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,MAAM,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,gBAAgB,GAAG,CAAC,MAAM,aAAa,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAEhG,IAAI,KAA8B,CAAC;IACnC,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChE,MAAM,UAAU,CAAC,SAAS,EAAE,gBAAgB,MAAM,IAAI,EAAE,OAAO,CAAC,CAAC;QACjE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IAED,MAAM,UAAU,CAAC,SAAS,EAAE,iBAAiB,KAAK,CAAC,eAAe,IAAI,EAAE,OAAO,CAAC,CAAC;IAEjF,MAAM,KAAK,GAAG,KAAK,CAAC,eAAe,CAAC;IAEpC,IAAI,KAAK,KAAK,oBAAoB,EAAE,CAAC;QACnC,MAAM,MAAM,GAAI,KAAK,CAAC,MAAiB,IAAI,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,4CAA4C,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAChF,MAAM,MAAM,GAAG,MAAM;YACnB,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,qCAAqC,MAAM,6BAA6B,EAAE;YAC7G,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,UAAU,CAAC,SAAS,EAAE,WAAW,IAAI,IAAI,EAAE,OAAO,CAAC,CAAC;QAC1D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IACpC,CAAC;SAAM,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,EAAE,gBAAgB,EAAE,kDAAkD,EAAE,CAAC;QACxF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,UAAU,CAAC,SAAS,EAAE,WAAW,IAAI,IAAI,EAAE,OAAO,CAAC,CAAC;QAC1D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IACpC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAClD,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACzB,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,MAAM,UAAU,CAAC,SAAS,EAAE,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACrG,CAAC;IAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;IACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;AAClE,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Development watcher — runs after tsc --watch rebuilds.
|
|
3
|
+
* Watches dist/ for changes, then regenerates hooks.json for the
|
|
4
|
+
* target project specified as the first CLI argument.
|
|
5
|
+
*
|
|
6
|
+
* Usage: node dist/dev-watch.js <project-path>
|
|
7
|
+
* Typically run via: npm run dev -- <project-path>
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=dev-watch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-watch.d.ts","sourceRoot":"","sources":["../src/dev-watch.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Development watcher — runs after tsc --watch rebuilds.
|
|
3
|
+
* Watches dist/ for changes, then regenerates hooks.json for the
|
|
4
|
+
* target project specified as the first CLI argument.
|
|
5
|
+
*
|
|
6
|
+
* Usage: node dist/dev-watch.js <project-path>
|
|
7
|
+
* Typically run via: npm run dev -- <project-path>
|
|
8
|
+
*/
|
|
9
|
+
import { watch } from "node:fs";
|
|
10
|
+
import { resolve, join } from "node:path";
|
|
11
|
+
import { loadConfig } from "./config.js";
|
|
12
|
+
import { writeHooksFile, configHash } from "./hooks-generator.js";
|
|
13
|
+
const targetDir = process.argv[2];
|
|
14
|
+
if (!targetDir) {
|
|
15
|
+
console.log("Usage: node dist/dev-watch.js <project-path>");
|
|
16
|
+
console.log("Watches for rebuilds and regenerates hooks.json automatically.");
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
const projectPath = resolve(targetDir);
|
|
20
|
+
let debounceTimer = null;
|
|
21
|
+
async function regenerate() {
|
|
22
|
+
try {
|
|
23
|
+
const config = await loadConfig();
|
|
24
|
+
const updated = await writeHooksFile(projectPath, config);
|
|
25
|
+
const ts = new Date().toLocaleTimeString();
|
|
26
|
+
if (updated) {
|
|
27
|
+
console.log(`[${ts}] ♻️ hooks.json regenerated (hash: ${configHash(config)})`);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
console.log(`[${ts}] ✓ rebuild detected, hooks.json unchanged`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
console.error("Regeneration failed:", err instanceof Error ? err.message : err);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
console.log(`Watching dist/ and hegel.config.json for changes...`);
|
|
38
|
+
console.log(`Target: ${join(projectPath, ".cursor", "hooks.json")}`);
|
|
39
|
+
console.log("");
|
|
40
|
+
// Watch the compiled output directory
|
|
41
|
+
watch("dist", { recursive: true }, (_event, filename) => {
|
|
42
|
+
if (!filename?.endsWith(".js"))
|
|
43
|
+
return;
|
|
44
|
+
if (debounceTimer)
|
|
45
|
+
clearTimeout(debounceTimer);
|
|
46
|
+
debounceTimer = setTimeout(regenerate, 300);
|
|
47
|
+
});
|
|
48
|
+
// Also watch the config file
|
|
49
|
+
watch("hegel.config.json", () => {
|
|
50
|
+
if (debounceTimer)
|
|
51
|
+
clearTimeout(debounceTimer);
|
|
52
|
+
debounceTimer = setTimeout(regenerate, 300);
|
|
53
|
+
});
|
|
54
|
+
regenerate();
|
|
55
|
+
//# sourceMappingURL=dev-watch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-watch.js","sourceRoot":"","sources":["../src/dev-watch.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElE,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClC,IAAI,CAAC,SAAS,EAAE,CAAC;IACf,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC;IAC9E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;AACvC,IAAI,aAAa,GAAyC,IAAI,CAAC;AAE/D,KAAK,UAAU,UAAU;IACvB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC1D,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC;QAC3C,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,uCAAuC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAClF,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,6CAA6C,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAClF,CAAC;AACH,CAAC;AAED,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;AACnE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC;AACrE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAEhB,sCAAsC;AACtC,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;IACtD,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO;IACvC,IAAI,aAAa;QAAE,YAAY,CAAC,aAAa,CAAC,CAAC;IAC/C,aAAa,GAAG,UAAU,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;AAC9C,CAAC,CAAC,CAAC;AAEH,6BAA6B;AAC7B,KAAK,CAAC,mBAAmB,EAAE,GAAG,EAAE;IAC9B,IAAI,aAAa;QAAE,YAAY,CAAC,aAAa,CAAC,CAAC;IAC/C,aAAa,GAAG,UAAU,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;AAC9C,CAAC,CAAC,CAAC;AAEH,UAAU,EAAE,CAAC"}
|
package/dist/format.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAQ1C,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAY1D;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAqB9D"}
|
package/dist/format.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const SEVERITY_ICON = {
|
|
2
|
+
critical: "🔴",
|
|
3
|
+
warning: "🟡",
|
|
4
|
+
info: "🔵",
|
|
5
|
+
};
|
|
6
|
+
export function formatConcerns(concerns) {
|
|
7
|
+
if (concerns.length === 0)
|
|
8
|
+
return "";
|
|
9
|
+
const lines = ["⚖️ Hegel:"];
|
|
10
|
+
for (const c of concerns) {
|
|
11
|
+
const icon = SEVERITY_ICON[c.severity] ?? "•";
|
|
12
|
+
lines.push(`${icon} [${c.category}] ${c.message}`);
|
|
13
|
+
if (c.suggestion) {
|
|
14
|
+
lines.push(` → ${c.suggestion}`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return lines.join("\n");
|
|
18
|
+
}
|
|
19
|
+
export function formatBlockMessage(concerns) {
|
|
20
|
+
const actionable = concerns.filter((c) => c.severity === "critical" || c.severity === "warning");
|
|
21
|
+
if (actionable.length === 0)
|
|
22
|
+
return formatConcerns(concerns);
|
|
23
|
+
const hasCritical = actionable.some((c) => c.severity === "critical");
|
|
24
|
+
const header = hasCritical
|
|
25
|
+
? "⛔ Hegel blocked this prompt:"
|
|
26
|
+
: "⚖️ Hegel paused this prompt — please review:";
|
|
27
|
+
const lines = [header, ""];
|
|
28
|
+
for (const c of actionable) {
|
|
29
|
+
const icon = SEVERITY_ICON[c.severity] ?? "•";
|
|
30
|
+
lines.push(`${icon} ${c.message}`);
|
|
31
|
+
if (c.suggestion) {
|
|
32
|
+
lines.push(` → ${c.suggestion}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
lines.push("", "Revise your prompt, or resubmit the same text to proceed anyway.");
|
|
36
|
+
return lines.join("\n");
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAEA,MAAM,aAAa,GAA2B;IAC5C,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,IAAI;IACb,IAAI,EAAE,IAAI;CACX,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,QAAmB;IAChD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAErC,MAAM,KAAK,GAAa,CAAC,WAAW,CAAC,CAAC;IACtC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC;QAC9C,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;YACjB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,QAAmB;IACpD,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAChC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,CAC7D,CAAC;IACF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,cAAc,CAAC,QAAQ,CAAC,CAAC;IAE7D,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG,WAAW;QACxB,CAAC,CAAC,8BAA8B;QAChC,CAAC,CAAC,8CAA8C,CAAC;IAEnD,MAAM,KAAK,GAAa,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC;QAC9C,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;YACjB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,kEAAkE,CAAC,CAAC;IACnF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
package/dist/hook.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { HookBaseInput } from "./types.js";
|
|
2
|
+
type OutputWriter = (obj: Record<string, unknown>) => void;
|
|
3
|
+
type InputReader = () => Promise<string>;
|
|
4
|
+
export declare function processHookInput(input: HookBaseInput, output?: OutputWriter): Promise<void>;
|
|
5
|
+
export declare function processHookJson(raw: string, output?: OutputWriter): Promise<void>;
|
|
6
|
+
export declare function runHook(readInput?: InputReader, output?: OutputWriter): Promise<void>;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=hook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../src/hook.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EACV,aAAa,EAOd,MAAM,YAAY,CAAC;AAEpB,KAAK,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;AAC3D,KAAK,WAAW,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;AAwSzC,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,aAAa,EACpB,MAAM,GAAE,YAA0B,GACjC,OAAO,CAAC,IAAI,CAAC,CAsCf;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,YAA0B,GACjC,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,wBAAsB,OAAO,CAC3B,SAAS,GAAE,WAAuB,EAClC,MAAM,GAAE,YAA0B,GACjC,OAAO,CAAC,IAAI,CAAC,CAGf"}
|