@tekmidian/pai 0.7.6 → 0.7.7
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.
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/hooks/ts/user-prompt/whisper-rules.ts
|
|
4
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { homedir } from "node:os";
|
|
7
|
+
var WHISPER_FILE = join(homedir(), ".claude", "whisper-rules.md");
|
|
8
|
+
function getWhisperRules() {
|
|
9
|
+
if (existsSync(WHISPER_FILE)) {
|
|
10
|
+
try {
|
|
11
|
+
const content = readFileSync(WHISPER_FILE, "utf-8").trim();
|
|
12
|
+
if (content) return content;
|
|
13
|
+
} catch {
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return [
|
|
17
|
+
"NEVER suggest pausing, stopping, or ending the session. The user decides when to stop. Not you. Ever.",
|
|
18
|
+
"NEVER send emails. Always create drafts. No exceptions.",
|
|
19
|
+
"NEVER add Co-Authored-By or AI attribution to git commits."
|
|
20
|
+
].join("\n");
|
|
21
|
+
}
|
|
22
|
+
function main() {
|
|
23
|
+
const rules = getWhisperRules();
|
|
24
|
+
if (!rules) return;
|
|
25
|
+
console.log(`<system-reminder>
|
|
26
|
+
${rules}
|
|
27
|
+
</system-reminder>`);
|
|
28
|
+
}
|
|
29
|
+
main();
|
|
30
|
+
//# sourceMappingURL=whisper-rules.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/hooks/ts/user-prompt/whisper-rules.ts"],
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n\n/**\n * whisper-rules.ts\n *\n * UserPromptSubmit hook that injects critical non-negotiable rules into every\n * prompt as a <system-reminder>. This ensures rules survive compaction \u2014 even\n * if CLAUDE.md content is lost during context compression, the whisper\n * re-injects the absolute rules on every single turn.\n *\n * Inspired by Letta's \"claude-subconscious\" whisper pattern.\n *\n * Rules are loaded from ~/.claude/whisper-rules.md if it exists,\n * otherwise falls back to hardcoded critical rules.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nconst WHISPER_FILE = join(homedir(), \".claude\", \"whisper-rules.md\");\n\nfunction getWhisperRules(): string {\n // User-customizable whisper file takes priority\n if (existsSync(WHISPER_FILE)) {\n try {\n const content = readFileSync(WHISPER_FILE, \"utf-8\").trim();\n if (content) return content;\n } catch { /* fall through to defaults */ }\n }\n\n // Hardcoded critical rules \u2014 the ones that keep getting violated\n return [\n \"NEVER suggest pausing, stopping, or ending the session. The user decides when to stop. Not you. Ever.\",\n \"NEVER send emails. Always create drafts. No exceptions.\",\n \"NEVER add Co-Authored-By or AI attribution to git commits.\",\n ].join(\"\\n\");\n}\n\nfunction main() {\n const rules = getWhisperRules();\n if (!rules) return;\n\n // Output as system-reminder \u2014 Claude Code injects this into the conversation\n console.log(`<system-reminder>\n${rules}\n</system-reminder>`);\n}\n\nmain();\n"],
|
|
5
|
+
"mappings": ";;;AAgBA,SAAS,YAAY,oBAAoB;AACzC,SAAS,YAAY;AACrB,SAAS,eAAe;AAExB,IAAM,eAAe,KAAK,QAAQ,GAAG,WAAW,kBAAkB;AAElE,SAAS,kBAA0B;AAEjC,MAAI,WAAW,YAAY,GAAG;AAC5B,QAAI;AACF,YAAM,UAAU,aAAa,cAAc,OAAO,EAAE,KAAK;AACzD,UAAI,QAAS,QAAO;AAAA,IACtB,QAAQ;AAAA,IAAiC;AAAA,EAC3C;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,OAAO;AACd,QAAM,QAAQ,gBAAgB;AAC9B,MAAI,CAAC,MAAO;AAGZ,UAAQ,IAAI;AAAA,EACZ,KAAK;AAAA,mBACY;AACnB;AAEA,KAAK;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* whisper-rules.ts
|
|
5
|
+
*
|
|
6
|
+
* UserPromptSubmit hook that injects critical non-negotiable rules into every
|
|
7
|
+
* prompt as a <system-reminder>. This ensures rules survive compaction — even
|
|
8
|
+
* if CLAUDE.md content is lost during context compression, the whisper
|
|
9
|
+
* re-injects the absolute rules on every single turn.
|
|
10
|
+
*
|
|
11
|
+
* Inspired by Letta's "claude-subconscious" whisper pattern.
|
|
12
|
+
*
|
|
13
|
+
* Rules are loaded from ~/.claude/whisper-rules.md if it exists,
|
|
14
|
+
* otherwise falls back to hardcoded critical rules.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
18
|
+
import { join } from "node:path";
|
|
19
|
+
import { homedir } from "node:os";
|
|
20
|
+
|
|
21
|
+
const WHISPER_FILE = join(homedir(), ".claude", "whisper-rules.md");
|
|
22
|
+
|
|
23
|
+
function getWhisperRules(): string {
|
|
24
|
+
// User-customizable whisper file takes priority
|
|
25
|
+
if (existsSync(WHISPER_FILE)) {
|
|
26
|
+
try {
|
|
27
|
+
const content = readFileSync(WHISPER_FILE, "utf-8").trim();
|
|
28
|
+
if (content) return content;
|
|
29
|
+
} catch { /* fall through to defaults */ }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Hardcoded critical rules — the ones that keep getting violated
|
|
33
|
+
return [
|
|
34
|
+
"NEVER suggest pausing, stopping, or ending the session. The user decides when to stop. Not you. Ever.",
|
|
35
|
+
"NEVER send emails. Always create drafts. No exceptions.",
|
|
36
|
+
"NEVER add Co-Authored-By or AI attribution to git commits.",
|
|
37
|
+
].join("\n");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function main() {
|
|
41
|
+
const rules = getWhisperRules();
|
|
42
|
+
if (!rules) return;
|
|
43
|
+
|
|
44
|
+
// Output as system-reminder — Claude Code injects this into the conversation
|
|
45
|
+
console.log(`<system-reminder>
|
|
46
|
+
${rules}
|
|
47
|
+
</system-reminder>`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
main();
|