hebbian 0.5.3 → 0.6.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/dist/bin/hebbian.js +61 -5
- package/dist/bin/hebbian.js.map +1 -1
- package/dist/digest.d.ts +42 -0
- package/dist/digest.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +59 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/digest.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export interface DigestResult {
|
|
2
2
|
corrections: number;
|
|
3
3
|
skipped: number;
|
|
4
|
+
toolFailures: number;
|
|
4
5
|
transcriptPath: string;
|
|
5
6
|
sessionId: string;
|
|
6
7
|
}
|
|
@@ -10,6 +11,30 @@ export interface ExtractedCorrection {
|
|
|
10
11
|
prefix: 'NO' | 'DO' | 'MUST' | 'WARN';
|
|
11
12
|
keywords: string[];
|
|
12
13
|
}
|
|
14
|
+
interface TranscriptLine {
|
|
15
|
+
type?: string;
|
|
16
|
+
message?: {
|
|
17
|
+
role?: string;
|
|
18
|
+
content?: string | Array<{
|
|
19
|
+
type: string;
|
|
20
|
+
text?: string;
|
|
21
|
+
tool_use_id?: string;
|
|
22
|
+
is_error?: boolean;
|
|
23
|
+
}>;
|
|
24
|
+
};
|
|
25
|
+
toolUseResult?: {
|
|
26
|
+
stdout?: string;
|
|
27
|
+
stderr?: string;
|
|
28
|
+
status?: string;
|
|
29
|
+
};
|
|
30
|
+
sessionId?: string;
|
|
31
|
+
uuid?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface ToolFailure {
|
|
34
|
+
toolName: string;
|
|
35
|
+
exitCode: number;
|
|
36
|
+
errorText: string;
|
|
37
|
+
}
|
|
13
38
|
/**
|
|
14
39
|
* Parse hook input from stdin to extract transcript path and session ID.
|
|
15
40
|
*/
|
|
@@ -22,9 +47,26 @@ export declare function readHookInput(stdin: string): {
|
|
|
22
47
|
* Auto-processes inbox and writes audit log.
|
|
23
48
|
*/
|
|
24
49
|
export declare function digestTranscript(brainRoot: string, transcriptPath: string, sessionId?: string): DigestResult;
|
|
50
|
+
/**
|
|
51
|
+
* Parse tool_result blocks from a Claude Code transcript.
|
|
52
|
+
* Returns detected failures (exit code ≠ 0, is_error = true).
|
|
53
|
+
*/
|
|
54
|
+
export declare function parseToolResults(transcriptPath: string): ToolFailure[];
|
|
55
|
+
/**
|
|
56
|
+
* Detect a tool failure from a tool_result block.
|
|
57
|
+
* Returns failure info if exit code ≠ 0, null otherwise.
|
|
58
|
+
*/
|
|
59
|
+
export declare function detectToolFailure(block: {
|
|
60
|
+
content?: string | Array<{
|
|
61
|
+
type: string;
|
|
62
|
+
text?: string;
|
|
63
|
+
}>;
|
|
64
|
+
is_error?: boolean;
|
|
65
|
+
}, toolUseResult?: TranscriptLine['toolUseResult']): ToolFailure | null;
|
|
25
66
|
/**
|
|
26
67
|
* Extract corrections from user messages using pattern matching.
|
|
27
68
|
* Returns up to MAX_CORRECTIONS_PER_SESSION corrections.
|
|
28
69
|
*/
|
|
29
70
|
export declare function extractCorrections(messages: string[]): ExtractedCorrection[];
|
|
71
|
+
export {};
|
|
30
72
|
//# sourceMappingURL=digest.d.ts.map
|
package/dist/digest.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"digest.d.ts","sourceRoot":"","sources":["../src/digest.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,YAAY;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;IACtC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACnB;
|
|
1
|
+
{"version":3,"file":"digest.d.ts","sourceRoot":"","sources":["../src/digest.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,YAAY;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;IACtC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,UAAU,cAAc;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;KACpG,CAAC;IACF,aAAa,CAAC,EAAE;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CAClB;AA+CD;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAYjG;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,CAsE5G;AAiDD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,WAAW,EAAE,CA4BtE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAChC,KAAK,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,EACxF,aAAa,CAAC,EAAE,cAAc,CAAC,eAAe,CAAC,GAC7C,WAAW,GAAG,IAAI,CA8BpB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,mBAAmB,EAAE,CAiC5E"}
|
package/dist/index.d.ts
CHANGED
|
@@ -24,8 +24,8 @@ export { processInbox, ensureInbox, appendCorrection } from './inbox';
|
|
|
24
24
|
export type { Correction, InboxResult } from './inbox';
|
|
25
25
|
export { installHooks, uninstallHooks, checkHooks } from './hooks';
|
|
26
26
|
export type { HookStatus } from './hooks';
|
|
27
|
-
export { digestTranscript, extractCorrections, readHookInput } from './digest';
|
|
28
|
-
export type { DigestResult, ExtractedCorrection } from './digest';
|
|
27
|
+
export { digestTranscript, extractCorrections, readHookInput, parseToolResults, detectToolFailure } from './digest';
|
|
28
|
+
export type { DigestResult, ExtractedCorrection, ToolFailure } from './digest';
|
|
29
29
|
export { resolveBrainRoot } from './constants';
|
|
30
30
|
export { growCandidate, promoteCandidates, listCandidates, toCandidatePath, fromCandidatePath } from './candidates';
|
|
31
31
|
export type { CandidateInfo, PromoteResult } from './candidates';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,YAAY,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAG3G,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AACnF,YAAY,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACrD,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACtE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,YAAY,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAG3G,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AACnF,YAAY,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACrD,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACtE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,aAAa,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACpH,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACpH,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG3D,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACrG,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1746,14 +1746,25 @@ function digestTranscript(brainRoot, transcriptPath, sessionId) {
|
|
|
1746
1746
|
const logPath = join15(logDir, `${resolvedSessionId}.jsonl`);
|
|
1747
1747
|
if (existsSync14(logPath)) {
|
|
1748
1748
|
console.log(`\u23ED already digested session ${resolvedSessionId}, skip`);
|
|
1749
|
-
return { corrections: 0, skipped: 0, transcriptPath, sessionId: resolvedSessionId };
|
|
1749
|
+
return { corrections: 0, skipped: 0, toolFailures: 0, transcriptPath, sessionId: resolvedSessionId };
|
|
1750
1750
|
}
|
|
1751
1751
|
const messages = parseTranscript(transcriptPath);
|
|
1752
|
+
const toolFailures = parseToolResults(transcriptPath);
|
|
1753
|
+
for (const failure of toolFailures) {
|
|
1754
|
+
logEpisode(brainRoot, "tool-failure", failure.toolName, failure.errorText);
|
|
1755
|
+
}
|
|
1756
|
+
if (toolFailures.length > 0) {
|
|
1757
|
+
console.log(`\u{1F527} digest: ${toolFailures.length} tool failure(s) logged as episodes`);
|
|
1758
|
+
}
|
|
1752
1759
|
const corrections = extractCorrections(messages);
|
|
1753
|
-
if (corrections.length === 0) {
|
|
1760
|
+
if (corrections.length === 0 && toolFailures.length === 0) {
|
|
1754
1761
|
console.log(`\u{1F4DD} digest: no corrections found in session ${resolvedSessionId}`);
|
|
1755
1762
|
writeAuditLog(brainRoot, resolvedSessionId, []);
|
|
1756
|
-
return { corrections: 0, skipped: messages.length, transcriptPath, sessionId: resolvedSessionId };
|
|
1763
|
+
return { corrections: 0, skipped: messages.length, toolFailures: toolFailures.length, transcriptPath, sessionId: resolvedSessionId };
|
|
1764
|
+
}
|
|
1765
|
+
if (corrections.length === 0) {
|
|
1766
|
+
writeAuditLog(brainRoot, resolvedSessionId, []);
|
|
1767
|
+
return { corrections: 0, skipped: messages.length, toolFailures: toolFailures.length, transcriptPath, sessionId: resolvedSessionId };
|
|
1757
1768
|
}
|
|
1758
1769
|
let applied = 0;
|
|
1759
1770
|
const auditEntries = [];
|
|
@@ -1773,6 +1784,7 @@ function digestTranscript(brainRoot, transcriptPath, sessionId) {
|
|
|
1773
1784
|
return {
|
|
1774
1785
|
corrections: applied,
|
|
1775
1786
|
skipped: messages.length - corrections.length,
|
|
1787
|
+
toolFailures: toolFailures.length,
|
|
1776
1788
|
transcriptPath,
|
|
1777
1789
|
sessionId: resolvedSessionId
|
|
1778
1790
|
};
|
|
@@ -1804,6 +1816,48 @@ function extractText(content) {
|
|
|
1804
1816
|
}
|
|
1805
1817
|
return null;
|
|
1806
1818
|
}
|
|
1819
|
+
var MAX_FAILURES_PER_SESSION = 20;
|
|
1820
|
+
function parseToolResults(transcriptPath) {
|
|
1821
|
+
const content = readFileSync6(transcriptPath, "utf8");
|
|
1822
|
+
const lines = content.split("\n").filter(Boolean);
|
|
1823
|
+
const failures = [];
|
|
1824
|
+
for (const line of lines) {
|
|
1825
|
+
if (failures.length >= MAX_FAILURES_PER_SESSION) break;
|
|
1826
|
+
let entry;
|
|
1827
|
+
try {
|
|
1828
|
+
entry = JSON.parse(line);
|
|
1829
|
+
} catch {
|
|
1830
|
+
continue;
|
|
1831
|
+
}
|
|
1832
|
+
if (entry.type !== "user") continue;
|
|
1833
|
+
if (!entry.message || !Array.isArray(entry.message.content)) continue;
|
|
1834
|
+
for (const block of entry.message.content) {
|
|
1835
|
+
if (block.type !== "tool_result") continue;
|
|
1836
|
+
if (!block.is_error) continue;
|
|
1837
|
+
const failure = detectToolFailure(block, entry.toolUseResult);
|
|
1838
|
+
if (failure) failures.push(failure);
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
return failures;
|
|
1842
|
+
}
|
|
1843
|
+
function detectToolFailure(block, toolUseResult) {
|
|
1844
|
+
if (!block.is_error) return null;
|
|
1845
|
+
let errorText = "";
|
|
1846
|
+
if (typeof block.content === "string") {
|
|
1847
|
+
errorText = block.content;
|
|
1848
|
+
} else if (Array.isArray(block.content)) {
|
|
1849
|
+
errorText = block.content.filter((b) => b.type === "text" && b.text).map((b) => b.text).join("\n");
|
|
1850
|
+
}
|
|
1851
|
+
if (!errorText && typeof toolUseResult === "string") {
|
|
1852
|
+
errorText = toolUseResult;
|
|
1853
|
+
}
|
|
1854
|
+
if (!errorText) return null;
|
|
1855
|
+
const exitMatch = errorText.match(/^Exit code (\d+)/);
|
|
1856
|
+
const exitCode = exitMatch ? parseInt(exitMatch[1], 10) : 1;
|
|
1857
|
+
const firstLine = errorText.split("\n").find((l) => l.trim() && !l.startsWith("Exit code")) || "unknown";
|
|
1858
|
+
const toolName = firstLine.trim().slice(0, 80);
|
|
1859
|
+
return { toolName, exitCode, errorText: errorText.slice(0, 500) };
|
|
1860
|
+
}
|
|
1807
1861
|
function extractCorrections(messages) {
|
|
1808
1862
|
const corrections = [];
|
|
1809
1863
|
for (const text of messages) {
|
|
@@ -2509,6 +2563,7 @@ export {
|
|
|
2509
2563
|
clearReports,
|
|
2510
2564
|
contraNeuron,
|
|
2511
2565
|
detectOutcome,
|
|
2566
|
+
detectToolFailure,
|
|
2512
2567
|
digestTranscript,
|
|
2513
2568
|
emitBootstrap,
|
|
2514
2569
|
emitIndex,
|
|
@@ -2529,6 +2584,7 @@ export {
|
|
|
2529
2584
|
jaccardSimilarity,
|
|
2530
2585
|
listCandidates,
|
|
2531
2586
|
logEpisode,
|
|
2587
|
+
parseToolResults,
|
|
2532
2588
|
printDiag,
|
|
2533
2589
|
processInbox,
|
|
2534
2590
|
promoteCandidates,
|