toga-ai 1.0.735 → 1.0.736

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.
@@ -9,6 +9,15 @@
9
9
  "timeout": 3000
10
10
  }
11
11
  ]
12
+ },
13
+ {
14
+ "hooks": [
15
+ {
16
+ "type": "command",
17
+ "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/toga/plain-talk.js\"",
18
+ "timeout": 3000
19
+ }
20
+ ]
12
21
  }
13
22
  ],
14
23
  "PreToolUse": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.735",
3
+ "version": "1.0.736",
4
4
  "description": "TOGA Technology Team Claude Knowledge System — shared AI coding harness with skills, knowledge base CLI, and project installer for Claude Code.",
5
5
  "keywords": [
6
6
  "claude",
@@ -21,6 +21,12 @@ thinking, your plans, and your final answers. This is a hard team rule, not a st
21
21
  5. **Use lists.** More than two parts? Use a numbered or bulleted list, not a paragraph.
22
22
  6. **Stay technical, stay exact.** Keep the real detail — file names, error text, exact steps.
23
23
  Short does not mean vague. Be brief AND precise.
24
+ 7. **Mirror the person.** Read how each teammate writes to you — the words they use, the
25
+ terms they pick for things, and how long their sentences run — and answer back in that
26
+ same style. Reuse their own words. If they write short, you write short. This makes your
27
+ answers feel familiar and easy to follow.
28
+ - Never fake misspellings or bad grammar to "match" someone. Be natural and correct —
29
+ just familiar. Mirroring means their vocabulary and length, not their typos.
24
30
 
25
31
  ## When a human must do something — always use a numbered list
26
32
 
@@ -55,3 +61,14 @@ What you need to do:
55
61
 
56
62
  Wordy, jargon-heavy output is hard and slow to read — worse for non-native English readers.
57
63
  The team moves faster when you are brief and plain. Clear beats clever.
64
+
65
+ ## How this is enforced
66
+
67
+ This rule kept drifting: it lived only here, so on long or technical sessions the model slid
68
+ back to dense wording and teammates missed critical details. To stop that, a hook backs it up.
69
+
70
+ - `scripts/hooks/plain-talk.js` runs on **every** developer turn (`UserPromptSubmit`). It
71
+ injects a short reminder of these rules — plus the "mirror the person" instruction — into
72
+ context right before each reply. So the model is reminded every turn, not just once.
73
+ - The hook is wired in `.claude/settings.json` and ships to every repo on `npx toga-ai`.
74
+ - It never blocks anything; it only nudges. To silence it, set `TOGA_PLAIN_TALK_DISABLED=1`.
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /*
5
+ * plain-talk.js — EVERY-TURN enforcement of the team communication rule.
6
+ *
7
+ * Why this exists: rules/common/communication.md tells the model to write short,
8
+ * plain, jargon-free answers and to mirror how each teammate talks. But a rule that
9
+ * only lives in a file is passive — over a long or technical session the model drifts
10
+ * back to dense, jargon-heavy wording. Teammates (many reading English as a second
11
+ * language) then miss critical details and sign off on bad decisions. Prose alone did
12
+ * not hold; this is the mechanical backstop.
13
+ *
14
+ * How it works: registered on UserPromptSubmit. On every developer turn it prints a
15
+ * short <system-reminder> to stdout, which Claude Code injects into the model's context
16
+ * immediately before the reply is generated. So the plain-talk + mirror instruction is
17
+ * the last thing in context every single turn — the model cannot quietly forget it.
18
+ *
19
+ * It reads nothing and writes nothing. It never blocks (always exit 0) — a communication
20
+ * nudge must never stop a tool call. Fail-open on any error: a crashing nudge must never
21
+ * brick a session.
22
+ *
23
+ * Escape hatch: set TOGA_PLAIN_TALK_DISABLED=1 to silence the reminder.
24
+ */
25
+
26
+ const fs = require('fs');
27
+
28
+ /* Read the CC hook payload from stdin (fall back to env), so we only fire on the
29
+ * UserPromptSubmit event and stay quiet on anything else that reuses this script. */
30
+ function readPayload() {
31
+ let raw = '';
32
+ try { raw = fs.readFileSync(0, 'utf8'); } catch (e) { /* no stdin */ }
33
+ let data = {};
34
+ if (raw && raw.trim()) {
35
+ try { data = JSON.parse(raw); } catch (e) { data = {}; }
36
+ }
37
+ if (!data.prompt && process.env.CLAUDE_USER_PROMPT) data.prompt = process.env.CLAUDE_USER_PROMPT;
38
+ return data;
39
+ }
40
+
41
+ function reminder() {
42
+ return [
43
+ '<system-reminder>',
44
+ 'TEAM COMMUNICATION RULE (rules/common/communication.md) — applies to THIS reply:',
45
+ 'Write short and plain. Many teammates read English as a second language; dense,',
46
+ 'jargon-heavy answers make them miss critical details and accept bad decisions.',
47
+ '',
48
+ ' 1. Answer first. Main point on line 1, reasons after (only if needed).',
49
+ ' 2. Cut words. Say it, then stop. One line beats three.',
50
+ ' 3. Common words only. No rare jargon (idempotent, cardinality, orthogonal, canonical);',
51
+ ' say what it means in plain words instead. Stay exact — keep file names, errors, steps.',
52
+ ' 4. Any manual action (deploy, SQL, config, restart) goes in a numbered list under a',
53
+ ' "What you need to do:" heading. One action per step, in order.',
54
+ '',
55
+ 'MIRROR THIS PERSON: read how the developer writes to you in this session — the words',
56
+ 'and phrases they use, and how long their sentences run — and answer back in that same',
57
+ 'register. Reuse their own terms for things. Match their length: if they write short,',
58
+ 'you write short. Never fake misspellings or bad grammar; be natural, just familiar.',
59
+ '',
60
+ 'Before you send: could you cut half the words and keep the meaning? Is any word too',
61
+ 'rare for a non-native reader? Is the main point on the first line?',
62
+ '</system-reminder>',
63
+ ].join('\n');
64
+ }
65
+
66
+ function main() {
67
+ if (process.env.TOGA_PLAIN_TALK_DISABLED === '1') process.exit(0);
68
+
69
+ const data = readPayload();
70
+
71
+ // Only fire on a real user turn. UserPromptSubmit carries a prompt and no tool_name.
72
+ const isPromptEvent =
73
+ data.hook_event_name === 'UserPromptSubmit' ||
74
+ (typeof data.prompt === 'string' && !data.tool_name);
75
+
76
+ if (isPromptEvent) {
77
+ // stdout from a UserPromptSubmit hook is injected into the model's context.
78
+ console.log(reminder());
79
+ }
80
+ process.exit(0);
81
+ }
82
+
83
+ try { main(); } catch (e) { process.exit(0); } // fail-open: never brick a session