claude-soul-server 0.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.
Files changed (97) hide show
  1. package/dist/engine/context-assembler.d.ts +3 -0
  2. package/dist/engine/context-assembler.js +161 -0
  3. package/dist/engine/context-assembler.js.map +1 -0
  4. package/dist/engine/exemplar-selector.d.ts +6 -0
  5. package/dist/engine/exemplar-selector.js +21 -0
  6. package/dist/engine/exemplar-selector.js.map +1 -0
  7. package/dist/engine/framework-engine.d.ts +61 -0
  8. package/dist/engine/framework-engine.js +351 -0
  9. package/dist/engine/framework-engine.js.map +1 -0
  10. package/dist/engine/framework-renderer.d.ts +17 -0
  11. package/dist/engine/framework-renderer.js +161 -0
  12. package/dist/engine/framework-renderer.js.map +1 -0
  13. package/dist/engine/framework-seeds.d.ts +2 -0
  14. package/dist/engine/framework-seeds.js +265 -0
  15. package/dist/engine/framework-seeds.js.map +1 -0
  16. package/dist/engine/lesson-store.d.ts +8 -0
  17. package/dist/engine/lesson-store.js +40 -0
  18. package/dist/engine/lesson-store.js.map +1 -0
  19. package/dist/engine/meta-optimizer.d.ts +37 -0
  20. package/dist/engine/meta-optimizer.js +140 -0
  21. package/dist/engine/meta-optimizer.js.map +1 -0
  22. package/dist/engine/prompt-builder.d.ts +31 -0
  23. package/dist/engine/prompt-builder.js +385 -0
  24. package/dist/engine/prompt-builder.js.map +1 -0
  25. package/dist/engine/reflection-runner.d.ts +18 -0
  26. package/dist/engine/reflection-runner.js +313 -0
  27. package/dist/engine/reflection-runner.js.map +1 -0
  28. package/dist/engine/shadow-transform.d.ts +1 -0
  29. package/dist/engine/shadow-transform.js +41 -0
  30. package/dist/engine/shadow-transform.js.map +1 -0
  31. package/dist/engine/signal-extractor.d.ts +14 -0
  32. package/dist/engine/signal-extractor.js +204 -0
  33. package/dist/engine/signal-extractor.js.map +1 -0
  34. package/dist/engine/signal-store.d.ts +5 -0
  35. package/dist/engine/signal-store.js +56 -0
  36. package/dist/engine/signal-store.js.map +1 -0
  37. package/dist/engine/snapshot-manager.d.ts +3 -0
  38. package/dist/engine/snapshot-manager.js +52 -0
  39. package/dist/engine/snapshot-manager.js.map +1 -0
  40. package/dist/engine/state-engine.d.ts +34 -0
  41. package/dist/engine/state-engine.js +127 -0
  42. package/dist/engine/state-engine.js.map +1 -0
  43. package/dist/engine/tension-detector.d.ts +10 -0
  44. package/dist/engine/tension-detector.js +77 -0
  45. package/dist/engine/tension-detector.js.map +1 -0
  46. package/dist/engine/token-budget.d.ts +12 -0
  47. package/dist/engine/token-budget.js +44 -0
  48. package/dist/engine/token-budget.js.map +1 -0
  49. package/dist/hooks/on-stop.d.ts +11 -0
  50. package/dist/hooks/on-stop.js +153 -0
  51. package/dist/hooks/on-stop.js.map +1 -0
  52. package/dist/index.d.ts +2 -0
  53. package/dist/index.js +171 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/tools/soul-activate.d.ts +1 -0
  56. package/dist/tools/soul-activate.js +149 -0
  57. package/dist/tools/soul-activate.js.map +1 -0
  58. package/dist/tools/soul-context.d.ts +1 -0
  59. package/dist/tools/soul-context.js +31 -0
  60. package/dist/tools/soul-context.js.map +1 -0
  61. package/dist/tools/soul-evaluate.d.ts +8 -0
  62. package/dist/tools/soul-evaluate.js +97 -0
  63. package/dist/tools/soul-evaluate.js.map +1 -0
  64. package/dist/tools/soul-framework.d.ts +1 -0
  65. package/dist/tools/soul-framework.js +66 -0
  66. package/dist/tools/soul-framework.js.map +1 -0
  67. package/dist/tools/soul-read.d.ts +1 -0
  68. package/dist/tools/soul-read.js +24 -0
  69. package/dist/tools/soul-read.js.map +1 -0
  70. package/dist/tools/soul-reflect.d.ts +1 -0
  71. package/dist/tools/soul-reflect.js +82 -0
  72. package/dist/tools/soul-reflect.js.map +1 -0
  73. package/dist/tools/soul-signal.d.ts +8 -0
  74. package/dist/tools/soul-signal.js +119 -0
  75. package/dist/tools/soul-signal.js.map +1 -0
  76. package/dist/tools/soul-status.d.ts +1 -0
  77. package/dist/tools/soul-status.js +130 -0
  78. package/dist/tools/soul-status.js.map +1 -0
  79. package/dist/tools/soul-write.d.ts +1 -0
  80. package/dist/tools/soul-write.js +26 -0
  81. package/dist/tools/soul-write.js.map +1 -0
  82. package/dist/types/config-types.d.ts +45 -0
  83. package/dist/types/config-types.js +21 -0
  84. package/dist/types/config-types.js.map +1 -0
  85. package/dist/types/learning-types.d.ts +166 -0
  86. package/dist/types/learning-types.js +2 -0
  87. package/dist/types/learning-types.js.map +1 -0
  88. package/dist/util/files.d.ts +20 -0
  89. package/dist/util/files.js +54 -0
  90. package/dist/util/files.js.map +1 -0
  91. package/dist/util/llm.d.ts +6 -0
  92. package/dist/util/llm.js +76 -0
  93. package/dist/util/llm.js.map +1 -0
  94. package/dist/util/tokens.d.ts +1 -0
  95. package/dist/util/tokens.js +4 -0
  96. package/dist/util/tokens.js.map +1 -0
  97. package/package.json +44 -0
@@ -0,0 +1,56 @@
1
+ import fs from "node:fs/promises";
2
+ import { SESSION_LOG_PATH, DATA_DIR } from "../util/files.js";
3
+ const MAX_FILE_SIZE = 50 * 1024; // 50KB
4
+ export async function appendSignals(signals) {
5
+ if (signals.length === 0)
6
+ return;
7
+ await fs.mkdir(DATA_DIR, { recursive: true });
8
+ const newLines = signals.map((s) => JSON.stringify(s)).join("\n") + "\n";
9
+ await fs.appendFile(SESSION_LOG_PATH, newLines, "utf8");
10
+ // Check file size and truncate if over 50KB
11
+ try {
12
+ const stat = await fs.stat(SESSION_LOG_PATH);
13
+ if (stat.size > MAX_FILE_SIZE) {
14
+ const content = await fs.readFile(SESSION_LOG_PATH, "utf8");
15
+ const lines = content.split("\n").filter((l) => l.trim().length > 0);
16
+ let truncated = lines;
17
+ while (truncated.length > 0) {
18
+ const joined = truncated.join("\n") + "\n";
19
+ if (Buffer.byteLength(joined, "utf8") <= MAX_FILE_SIZE) {
20
+ await fs.writeFile(SESSION_LOG_PATH, joined, "utf8");
21
+ break;
22
+ }
23
+ truncated = truncated.slice(1);
24
+ }
25
+ if (truncated.length === 0) {
26
+ await fs.writeFile(SESSION_LOG_PATH, "", "utf8");
27
+ }
28
+ }
29
+ }
30
+ catch {
31
+ // File doesn't exist yet, that's fine
32
+ }
33
+ }
34
+ export async function readSignals() {
35
+ try {
36
+ const content = await fs.readFile(SESSION_LOG_PATH, "utf8");
37
+ const lines = content.split("\n").filter((l) => l.trim().length > 0);
38
+ return lines.map((l) => JSON.parse(l));
39
+ }
40
+ catch {
41
+ return [];
42
+ }
43
+ }
44
+ export async function clearSignals() {
45
+ try {
46
+ await fs.writeFile(SESSION_LOG_PATH, "", "utf8");
47
+ }
48
+ catch {
49
+ // Ignore
50
+ }
51
+ }
52
+ export async function getSignalCount() {
53
+ const signals = await readSignals();
54
+ return signals.length;
55
+ }
56
+ //# sourceMappingURL=signal-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signal-store.js","sourceRoot":"","sources":["../../src/engine/signal-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function createSnapshot(): Promise<string>;
2
+ export declare function listSnapshots(): Promise<string[]>;
3
+ export declare function rollbackToSnapshot(snapshotName: string): Promise<boolean>;
@@ -0,0 +1,52 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { FRAMEWORKS_PATH, SNAPSHOTS_DIR } from "../util/files.js";
4
+ const MAX_SNAPSHOTS = 20;
5
+ export async function createSnapshot() {
6
+ await fs.mkdir(SNAPSHOTS_DIR, { recursive: true });
7
+ const timestamp = Date.now();
8
+ const snapshotName = `frameworks.v${timestamp}.json`;
9
+ const snapshotPath = path.join(SNAPSHOTS_DIR, snapshotName);
10
+ try {
11
+ await fs.copyFile(FRAMEWORKS_PATH, snapshotPath);
12
+ }
13
+ catch {
14
+ // frameworks.json might not exist yet
15
+ return "";
16
+ }
17
+ // Prune old snapshots — keep last MAX_SNAPSHOTS
18
+ const files = await fs.readdir(SNAPSHOTS_DIR);
19
+ const snapshots = files
20
+ .filter((f) => f.startsWith("frameworks.v") && f.endsWith(".json"))
21
+ .sort();
22
+ if (snapshots.length > MAX_SNAPSHOTS) {
23
+ const toDelete = snapshots.slice(0, snapshots.length - MAX_SNAPSHOTS);
24
+ for (const file of toDelete) {
25
+ await fs.unlink(path.join(SNAPSHOTS_DIR, file)).catch(() => { });
26
+ }
27
+ }
28
+ return snapshotPath;
29
+ }
30
+ export async function listSnapshots() {
31
+ try {
32
+ const files = await fs.readdir(SNAPSHOTS_DIR);
33
+ return files
34
+ .filter((f) => f.startsWith("frameworks.v") && f.endsWith(".json"))
35
+ .sort()
36
+ .reverse();
37
+ }
38
+ catch {
39
+ return [];
40
+ }
41
+ }
42
+ export async function rollbackToSnapshot(snapshotName) {
43
+ const snapshotPath = path.join(SNAPSHOTS_DIR, snapshotName);
44
+ try {
45
+ await fs.copyFile(snapshotPath, FRAMEWORKS_PATH);
46
+ return true;
47
+ }
48
+ catch {
49
+ return false;
50
+ }
51
+ }
52
+ //# sourceMappingURL=snapshot-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-manager.js","sourceRoot":"","sources":["../../src/engine/snapshot-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAElE,MAAM,aAAa,GAAG,EAAE,CAAC;AAEzB,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,EAAE,CAAC,KAAK,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEnD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,YAAY,GAAG,eAAe,SAAS,OAAO,CAAC;IACrD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IAE5D,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,sCAAsC;QACtC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,gDAAgD;IAChD,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,KAAK;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;SAClE,IAAI,EAAE,CAAC;IAEV,IAAI,SAAS,CAAC,MAAM,GAAG,aAAa,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,aAAa,CAAC,CAAC;QACtE,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAC9C,OAAO,KAAK;aACT,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;aAClE,IAAI,EAAE;aACN,OAAO,EAAE,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,YAAoB;IAC3D,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IAC5D,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { InternalState } from "../types/learning-types.js";
2
+ export type StateEvent = {
3
+ type: "session_start";
4
+ } | {
5
+ type: "time_elapsed";
6
+ hoursActive: number;
7
+ } | {
8
+ type: "positive_interaction";
9
+ delta: number;
10
+ } | {
11
+ type: "negative_interaction";
12
+ delta: number;
13
+ } | {
14
+ type: "correction";
15
+ } | {
16
+ type: "tool_failure";
17
+ } | {
18
+ type: "successful_task";
19
+ complexity: "simple" | "complex";
20
+ } | {
21
+ type: "novel_topic";
22
+ } | {
23
+ type: "idle";
24
+ hours: number;
25
+ };
26
+ export declare class StateEngine {
27
+ private state;
28
+ constructor();
29
+ load(): Promise<void>;
30
+ save(): Promise<void>;
31
+ recordEvent(event: StateEvent): void;
32
+ tick(): Promise<void>;
33
+ getState(): Readonly<InternalState>;
34
+ }
@@ -0,0 +1,127 @@
1
+ import { STATE_PATH, META_PATH, FRAMEWORKS_PATH, SESSION_LOG_PATH, DATA_DIR, soulFilePath, } from "../util/files.js";
2
+ import { readJsonSafe, writeJsonAtomic } from "../util/files.js";
3
+ import fs from "node:fs/promises";
4
+ import path from "node:path";
5
+ const DEFAULTS = {
6
+ energy: 1.0,
7
+ mood: 0.6,
8
+ confidence: 0.6,
9
+ socialCharge: 0.5,
10
+ curiosity: 0.5,
11
+ frustration: 0.0,
12
+ hoursActive: 0,
13
+ lastSuccessMinAgo: -1,
14
+ lastFailureMinAgo: -1,
15
+ lastTickAt: Date.now(),
16
+ };
17
+ const MOOD_BASELINE = 0.6;
18
+ const MOOD_REGRESSION_RATE = 0.02;
19
+ function clamp(value, min = 0, max = 1) {
20
+ return Math.max(min, Math.min(max, value));
21
+ }
22
+ function trendWord(value, baseline) {
23
+ const diff = value - baseline;
24
+ if (diff > 0.05)
25
+ return "rising";
26
+ if (diff < -0.05)
27
+ return "falling";
28
+ return "steady";
29
+ }
30
+ export class StateEngine {
31
+ state;
32
+ constructor() {
33
+ this.state = { ...DEFAULTS };
34
+ }
35
+ async load() {
36
+ this.state = await readJsonSafe(STATE_PATH, { ...DEFAULTS });
37
+ }
38
+ async save() {
39
+ await writeJsonAtomic(STATE_PATH, this.state);
40
+ }
41
+ recordEvent(event) {
42
+ this.state.lastTickAt = Date.now();
43
+ switch (event.type) {
44
+ case "session_start":
45
+ this.state.confidence = 0.6;
46
+ this.state.frustration = 0.0;
47
+ this.state.curiosity = 0.5;
48
+ this.state.mood = MOOD_BASELINE;
49
+ break;
50
+ case "positive_interaction":
51
+ this.state.mood = clamp(this.state.mood + event.delta);
52
+ break;
53
+ case "negative_interaction":
54
+ this.state.mood = clamp(this.state.mood - event.delta);
55
+ break;
56
+ case "correction":
57
+ this.state.confidence = clamp(this.state.confidence - 0.1);
58
+ this.state.lastFailureMinAgo = 0;
59
+ break;
60
+ case "tool_failure":
61
+ this.state.frustration = clamp(this.state.frustration + 0.05);
62
+ break;
63
+ case "successful_task":
64
+ this.state.confidence = clamp(this.state.confidence + 0.05);
65
+ this.state.mood = clamp(this.state.mood + (event.complexity === "complex" ? 0.12 : 0.05));
66
+ this.state.lastSuccessMinAgo = 0;
67
+ break;
68
+ case "novel_topic":
69
+ this.state.curiosity = clamp(this.state.curiosity + 0.15);
70
+ break;
71
+ default:
72
+ break;
73
+ }
74
+ this.state.mood += (MOOD_BASELINE - this.state.mood) * MOOD_REGRESSION_RATE;
75
+ this.state.frustration = clamp(this.state.frustration * 0.95);
76
+ }
77
+ async tick() {
78
+ const now = new Date().toISOString().replace("T", " ").slice(0, 19) + " UTC";
79
+ const s = this.state;
80
+ const meta = await readJsonSafe(META_PATH, {});
81
+ const store = await readJsonSafe(FRAMEWORKS_PATH, {
82
+ version: 1,
83
+ frameworks: [],
84
+ meta: { totalDiscovered: 0, totalRetired: 0, totalMerged: 0, lastReflectionAt: 0, reflectionCount: 0 },
85
+ });
86
+ const followUpsPath = path.join(DATA_DIR, "follow-ups.json");
87
+ const followUps = await readJsonSafe(followUpsPath, []);
88
+ let signalCount = 0;
89
+ let correctionCount = 0;
90
+ try {
91
+ const logContent = await fs.readFile(SESSION_LOG_PATH, "utf8");
92
+ const lines = logContent.split("\n").filter((l) => l.trim());
93
+ signalCount = lines.length;
94
+ correctionCount = lines.filter((l) => l.includes('"correction"')).length;
95
+ }
96
+ catch {
97
+ // no signals yet
98
+ }
99
+ const active = store.frameworks.filter((f) => f.status === "active").length;
100
+ const questioning = store.frameworks.filter((f) => f.status === "questioning").length;
101
+ const retired = store.frameworks.filter((f) => f.status === "retired").length;
102
+ const unresolvedFollowUps = followUps.filter((f) => f.status !== "resolved");
103
+ const content = `# State — ${now}
104
+
105
+ ## Session
106
+ - Confidence: ${s.confidence.toFixed(2)} (${trendWord(s.confidence, 0.6)})
107
+ - Mood: ${s.mood.toFixed(2)} (${trendWord(s.mood, MOOD_BASELINE)})
108
+ - Curiosity: ${s.curiosity.toFixed(2)} (${trendWord(s.curiosity, 0.5)})
109
+ - Frustration: ${s.frustration.toFixed(2)}
110
+
111
+ ## System
112
+ - Learning phase: ${meta.phase ?? "apprentice"} (${meta.reflectionCount ?? 0} reflections)
113
+ - Frameworks: ${active} active, ${questioning} questioning, ${retired} retired
114
+ - Signals recorded: ${signalCount} (${correctionCount} corrections)
115
+ - Unresolved follow-ups: ${unresolvedFollowUps.length}${unresolvedFollowUps.length > 0 ? "\n" + unresolvedFollowUps.map((f) => ` - ${f.summary ?? "(no summary)"}`).join("\n") : ""}
116
+ `;
117
+ const statePath = soulFilePath("STATE.md");
118
+ const tmpPath = `${statePath}.tmp-${process.pid}`;
119
+ await fs.writeFile(tmpPath, content, "utf-8");
120
+ await fs.rename(tmpPath, statePath);
121
+ await this.save();
122
+ }
123
+ getState() {
124
+ return { ...this.state };
125
+ }
126
+ }
127
+ //# sourceMappingURL=state-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-engine.js","sourceRoot":"","sources":["../../src/engine/state-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { Framework, Tension } from "../types/learning-types.js";
2
+ /**
3
+ * Detect contradictions between active frameworks based on their domains,
4
+ * descriptions, and evidence patterns.
5
+ */
6
+ export declare function detectTensions(frameworks: Framework[]): Promise<Tension[]>;
7
+ /**
8
+ * Record a context preference for a tension.
9
+ */
10
+ export declare function recordTensionPreference(tensionId: string, context: string, preferredFrameworkId: string, evidence: string): Promise<void>;
@@ -0,0 +1,77 @@
1
+ import { TENSIONS_PATH } from "../util/files.js";
2
+ import { readJsonSafe, writeJsonAtomic } from "../util/files.js";
3
+ /**
4
+ * Detect contradictions between active frameworks based on their domains,
5
+ * descriptions, and evidence patterns.
6
+ */
7
+ export async function detectTensions(frameworks) {
8
+ const active = frameworks.filter((f) => f.status === "active" || f.status === "questioning");
9
+ const tensionState = await readJsonSafe(TENSIONS_PATH, { tensions: [] });
10
+ const existingPairs = new Set(tensionState.tensions.map((t) => [t.frameworkA, t.frameworkB].sort().join("|")));
11
+ const newTensions = [];
12
+ // Check for contradictions based on framework metadata
13
+ for (let i = 0; i < active.length; i++) {
14
+ for (let j = i + 1; j < active.length; j++) {
15
+ const a = active[i];
16
+ const b = active[j];
17
+ const pairKey = [a.id, b.id].sort().join("|");
18
+ if (existingPairs.has(pairKey))
19
+ continue;
20
+ // Check if explicitly marked as contradicting
21
+ if (a.contradicts.includes(b.id) || b.contradicts.includes(a.id)) {
22
+ newTensions.push(makeTension(a, b));
23
+ existingPairs.add(pairKey);
24
+ continue;
25
+ }
26
+ // Heuristic: frameworks in the same domain with divergent evidence patterns
27
+ if (a.domain === b.domain && a.evidence.length >= 3 && b.evidence.length >= 3) {
28
+ const aConfirmed = a.evidence.filter((e) => e.type === "confirmed").length;
29
+ const bContradicted = b.evidence.filter((e) => e.type === "contradicted").length;
30
+ const bConfirmed = b.evidence.filter((e) => e.type === "confirmed").length;
31
+ const aContradicted = a.evidence.filter((e) => e.type === "contradicted").length;
32
+ // If one is mostly confirmed when the other is contradicted (or vice versa)
33
+ if ((aConfirmed > aContradicted && bContradicted > bConfirmed) ||
34
+ (bConfirmed > bContradicted && aContradicted > aConfirmed)) {
35
+ newTensions.push(makeTension(a, b));
36
+ existingPairs.add(pairKey);
37
+ }
38
+ }
39
+ }
40
+ }
41
+ if (newTensions.length > 0) {
42
+ tensionState.tensions.push(...newTensions);
43
+ await writeJsonAtomic(TENSIONS_PATH, tensionState);
44
+ }
45
+ return newTensions;
46
+ }
47
+ function makeTension(a, b) {
48
+ return {
49
+ id: `ten-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
50
+ frameworkA: a.id,
51
+ frameworkB: b.id,
52
+ description: `"${a.name}" vs "${b.name}"`,
53
+ preferredInContext: {},
54
+ status: "detected",
55
+ detectedAt: Date.now(),
56
+ };
57
+ }
58
+ /**
59
+ * Record a context preference for a tension.
60
+ */
61
+ export async function recordTensionPreference(tensionId, context, preferredFrameworkId, evidence) {
62
+ const state = await readJsonSafe(TENSIONS_PATH, { tensions: [] });
63
+ const tension = state.tensions.find((t) => t.id === tensionId);
64
+ if (!tension)
65
+ return;
66
+ const pref = tension.preferredInContext[context] ?? {
67
+ preferred: preferredFrameworkId,
68
+ confirmedCount: 0,
69
+ evidence: [],
70
+ };
71
+ pref.preferred = preferredFrameworkId;
72
+ pref.confirmedCount++;
73
+ pref.evidence = [...pref.evidence, evidence].slice(-5);
74
+ tension.preferredInContext[context] = pref;
75
+ await writeJsonAtomic(TENSIONS_PATH, state);
76
+ }
77
+ //# sourceMappingURL=tension-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tension-detector.js","sourceRoot":"","sources":["../../src/engine/tension-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export type ContentBlock = {
2
+ content: string;
3
+ tier: 1 | 2 | 3;
4
+ label: string;
5
+ fallback?: string;
6
+ };
7
+ /**
8
+ * Apply the 3-tier token budget. Tier 1 is always included.
9
+ * Tier 2 fills to budget (with fallback support). Tier 3 if room remains.
10
+ * Returns the assembled content within the budget.
11
+ */
12
+ export declare function applyTokenBudget(blocks: ContentBlock[], maxTokens: number): string;
@@ -0,0 +1,44 @@
1
+ import { estimateTokens } from "../util/tokens.js";
2
+ /**
3
+ * Apply the 3-tier token budget. Tier 1 is always included.
4
+ * Tier 2 fills to budget (with fallback support). Tier 3 if room remains.
5
+ * Returns the assembled content within the budget.
6
+ */
7
+ export function applyTokenBudget(blocks, maxTokens) {
8
+ const tier1 = blocks.filter((b) => b.tier === 1);
9
+ const tier2 = blocks.filter((b) => b.tier === 2);
10
+ const tier3 = blocks.filter((b) => b.tier === 3);
11
+ const result = [];
12
+ let usedTokens = 0;
13
+ // Tier 1: always include
14
+ for (const block of tier1) {
15
+ const tokens = estimateTokens(block.content);
16
+ result.push(block.content);
17
+ usedTokens += tokens;
18
+ }
19
+ // Tier 2: fill to budget, try fallback if primary doesn't fit
20
+ for (const block of tier2) {
21
+ const tokens = estimateTokens(block.content);
22
+ if (usedTokens + tokens <= maxTokens) {
23
+ result.push(block.content);
24
+ usedTokens += tokens;
25
+ }
26
+ else if (block.fallback) {
27
+ const fallbackTokens = estimateTokens(block.fallback);
28
+ if (usedTokens + fallbackTokens <= maxTokens) {
29
+ result.push(block.fallback);
30
+ usedTokens += fallbackTokens;
31
+ }
32
+ }
33
+ }
34
+ // Tier 3: if room remains
35
+ for (const block of tier3) {
36
+ const tokens = estimateTokens(block.content);
37
+ if (usedTokens + tokens <= maxTokens) {
38
+ result.push(block.content);
39
+ usedTokens += tokens;
40
+ }
41
+ }
42
+ return result.join("\n\n---\n\n");
43
+ }
44
+ //# sourceMappingURL=token-budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-budget.js","sourceRoot":"","sources":["../../src/engine/token-budget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AASnD;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAsB,EACtB,SAAiB;IAEjB,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;IAEjD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,yBAAyB;IACzB,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3B,UAAU,IAAI,MAAM,CAAC;IACvB,CAAC;IAED,8DAA8D;IAC9D,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,UAAU,GAAG,MAAM,IAAI,SAAS,EAAE,CAAC;YACrC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC3B,UAAU,IAAI,MAAM,CAAC;QACvB,CAAC;aAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC1B,MAAM,cAAc,GAAG,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACtD,IAAI,UAAU,GAAG,cAAc,IAAI,SAAS,EAAE,CAAC;gBAC7C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC5B,UAAU,IAAI,cAAc,CAAC;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IAED,0BAA0B;IAC1B,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,UAAU,GAAG,MAAM,IAAI,SAAS,EAAE,CAAC;YACrC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC3B,UAAU,IAAI,MAAM,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Soul System Stop Hook
4
+ *
5
+ * Runs after every Claude Code conversation. Reads the transcript,
6
+ * extracts signals, updates state, and checks if reflection is due.
7
+ *
8
+ * Input (stdin): JSON with session_id, transcript_path, etc.
9
+ * Output (stdout): JSON with optional decision to block stopping.
10
+ */
11
+ export {};
@@ -0,0 +1,153 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Soul System Stop Hook
4
+ *
5
+ * Runs after every Claude Code conversation. Reads the transcript,
6
+ * extracts signals, updates state, and checks if reflection is due.
7
+ *
8
+ * Input (stdin): JSON with session_id, transcript_path, etc.
9
+ * Output (stdout): JSON with optional decision to block stopping.
10
+ */
11
+ import fs from "node:fs/promises";
12
+ import { parseTranscript, extractSignalsFromMessages } from "../engine/signal-extractor.js";
13
+ import { appendSignals, getSignalCount } from "../engine/signal-store.js";
14
+ import { StateEngine } from "../engine/state-engine.js";
15
+ import { ensureDirs, loadConfig, FRAMEWORKS_PATH } from "../util/files.js";
16
+ import { readJsonSafe } from "../util/files.js";
17
+ import { runReflection } from "../engine/reflection-runner.js";
18
+ import { loadMeta, getReflectionThresholds } from "../engine/meta-optimizer.js";
19
+ async function main() {
20
+ // Read hook input from stdin
21
+ // Use a Promise-based approach for reliable stdin reading
22
+ const input = await new Promise((resolve) => {
23
+ const chunks = [];
24
+ process.stdin.on("data", (chunk) => chunks.push(chunk));
25
+ process.stdin.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8")));
26
+ process.stdin.on("error", () => resolve(""));
27
+ // If stdin is already ended (no pipe), resolve after short timeout
28
+ setTimeout(() => resolve(Buffer.concat(chunks).toString("utf-8")), 500);
29
+ });
30
+ if (!input.trim()) {
31
+ process.exit(0);
32
+ }
33
+ let hookInput;
34
+ try {
35
+ hookInput = JSON.parse(input);
36
+ }
37
+ catch {
38
+ // Not valid JSON, exit silently
39
+ process.exit(0);
40
+ }
41
+ if (!hookInput.transcript_path) {
42
+ process.exit(0);
43
+ }
44
+ try {
45
+ await ensureDirs();
46
+ // Read the transcript
47
+ let transcriptContent;
48
+ try {
49
+ transcriptContent = await fs.readFile(hookInput.transcript_path, "utf-8");
50
+ }
51
+ catch {
52
+ // Transcript file doesn't exist or can't be read
53
+ process.exit(0);
54
+ }
55
+ if (!transcriptContent.trim()) {
56
+ process.exit(0);
57
+ }
58
+ // Parse transcript into messages
59
+ const messages = parseTranscript(transcriptContent);
60
+ if (messages.length < 2) {
61
+ // Need at least one user and one assistant message
62
+ process.exit(0);
63
+ }
64
+ // Extract signals using regex heuristics
65
+ const sessionKey = hookInput.session_id?.slice(0, 8) ?? "unknown";
66
+ const signals = extractSignalsFromMessages(messages, sessionKey);
67
+ if (signals.length === 0) {
68
+ process.exit(0);
69
+ }
70
+ // Store signals
71
+ await appendSignals(signals);
72
+ // Update state engine based on signals
73
+ const stateEngine = new StateEngine();
74
+ await stateEngine.load();
75
+ for (const signal of signals) {
76
+ switch (signal.type) {
77
+ case "correction":
78
+ stateEngine.recordEvent({ type: "correction" });
79
+ break;
80
+ case "gratitude":
81
+ stateEngine.recordEvent({ type: "positive_interaction", delta: 0.1 });
82
+ break;
83
+ case "success":
84
+ stateEngine.recordEvent({ type: "successful_task", complexity: "complex" });
85
+ break;
86
+ case "confusion":
87
+ stateEngine.recordEvent({ type: "negative_interaction", delta: 0.05 });
88
+ break;
89
+ case "topic_shift":
90
+ stateEngine.recordEvent({ type: "novel_topic" });
91
+ break;
92
+ case "disengagement":
93
+ stateEngine.recordEvent({ type: "negative_interaction", delta: 0.03 });
94
+ break;
95
+ }
96
+ }
97
+ await stateEngine.tick();
98
+ // Check if reflection is due (phase-adaptive thresholds + time-based fallback)
99
+ const config = await loadConfig();
100
+ const totalSignals = await getSignalCount();
101
+ const meta = await loadMeta();
102
+ const thresholds = getReflectionThresholds(meta);
103
+ // Get last reflection time
104
+ const store = await readJsonSafe(FRAMEWORKS_PATH, {
105
+ version: 1, frameworks: [], meta: { totalDiscovered: 0, totalRetired: 0, totalMerged: 0, lastReflectionAt: 0, reflectionCount: 0 },
106
+ });
107
+ const timeSinceReflection = Date.now() - store.meta.lastReflectionAt;
108
+ // Log signal extraction
109
+ const logMsg = `[soul] ${signals.length} signal(s) extracted (${signals.map((s) => s.type).join(", ")}). Total: ${totalSignals}. Phase: ${meta.phase}. Thresholds: quick=${thresholds.quickSignals}, deep=${thresholds.deepSignals}.\n`;
110
+ await fs.appendFile("/tmp/soul-hook.log", logMsg, "utf-8").catch(() => { });
111
+ if (!config.reflection.enabled || totalSignals < thresholds.minSignals) {
112
+ // Not enough signals for any reflection
113
+ }
114
+ else {
115
+ // Determine which tier to run
116
+ let tier = null;
117
+ // Deep reflection: signal threshold OR time threshold
118
+ if (totalSignals >= thresholds.deepSignals ||
119
+ (timeSinceReflection >= thresholds.deepTimeMs && totalSignals >= thresholds.minSignals)) {
120
+ tier = "deep";
121
+ }
122
+ // Quick reflection: signal threshold OR time threshold
123
+ else if (totalSignals >= thresholds.quickSignals ||
124
+ (timeSinceReflection >= thresholds.quickTimeMs && totalSignals >= thresholds.minSignals)) {
125
+ tier = "quick";
126
+ }
127
+ if (tier) {
128
+ const reason = totalSignals >= (tier === "deep" ? thresholds.deepSignals : thresholds.quickSignals)
129
+ ? `${totalSignals} signals >= ${tier === "deep" ? thresholds.deepSignals : thresholds.quickSignals} threshold`
130
+ : `time-based: ${Math.round(timeSinceReflection / 60000)}min since last reflection`;
131
+ const reflectLog = `[soul] Triggering ${tier} reflection (${reason}). Phase: ${meta.phase}.\n`;
132
+ await fs.appendFile("/tmp/soul-hook.log", reflectLog, "utf-8").catch(() => { });
133
+ try {
134
+ const result = await runReflection(tier);
135
+ const resultLog = `[soul] ${tier} reflection complete: ${result.frameworksUpdated} updated, ${result.newFrameworks} new, ${result.retired} retired, ${result.lessonsGenerated} lessons.\n`;
136
+ await fs.appendFile("/tmp/soul-hook.log", resultLog, "utf-8").catch(() => { });
137
+ }
138
+ catch (reflectErr) {
139
+ const errLog = `[soul] ${tier} reflection failed: ${reflectErr}\n`;
140
+ await fs.appendFile("/tmp/soul-hook.log", errLog, "utf-8").catch(() => { });
141
+ }
142
+ }
143
+ }
144
+ }
145
+ catch (err) {
146
+ // Log errors but don't crash — hooks should be resilient
147
+ const errMsg = `[soul] Stop hook error: ${err}\n`;
148
+ await fs.appendFile("/tmp/soul-hook.log", errMsg, "utf-8").catch(() => { });
149
+ }
150
+ process.exit(0);
151
+ }
152
+ main();
153
+ //# sourceMappingURL=on-stop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"on-stop.js","sourceRoot":"","sources":["../../src/hooks/on-stop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};