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.
package/.claude/settings.json
CHANGED
package/package.json
CHANGED
|
@@ -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
|