@r1z4x/tezgah 1.6.0 → 1.8.2
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/CHANGELOG.md +140 -1
- package/MANIFEST +7 -0
- package/README.md +6 -3
- package/bin/tezgah-decisions +6 -14
- package/bin/tezgah-design +21 -5
- package/bin/tezgah-docs +18 -16
- package/bin/tezgah-doctor +152 -0
- package/bin/tezgah-lessons +4 -1
- package/bin/tezgah-research +249 -17
- package/bin/tezgah-route +70 -8
- package/bin/tezgah-setup +26 -13
- package/bin/tezgah-task +877 -60
- package/bin/tezgah-taste +56 -15
- package/docs/architecture.md +28 -11
- package/docs/clarity-baseline.json +2 -2
- package/docs/contract.md +108 -24
- package/docs/environment.md +3 -1
- package/docs/evidence.md +209 -28
- package/docs/feature-audit.md +1 -1
- package/docs/gate.md +78 -23
- package/docs/glossary.md +4 -4
- package/docs/hosts.md +8 -8
- package/docs/index.json +11 -5
- package/docs/judge.md +9 -3
- package/docs/models.md +75 -14
- package/docs/operations.md +133 -3
- package/docs/research.md +349 -15
- package/docs/skills.md +1 -1
- package/docs/status-line.md +5 -5
- package/docs/testing.md +20 -13
- package/docs/vision.md +12 -4
- package/hooks/hooks.json +2 -2
- package/hooks/lang/en.json +323 -0
- package/hooks/lang/tr.json +344 -0
- package/hooks/projects-auto-init.py +29 -1
- package/hooks/projects-posttooluse.py +24 -5
- package/hooks/projects-pretooluse.py +9 -4
- package/hooks/projects-stop.py +28 -16
- package/hooks/tezgah_agents.py +53 -17
- package/hooks/tezgah_clarity.py +7 -3
- package/hooks/tezgah_context.py +489 -438
- package/hooks/tezgah_gate.py +996 -80
- package/hooks/tezgah_integrity.py +1547 -197
- package/hooks/tezgah_models.py +427 -45
- package/hooks/tezgah_paths.py +147 -16
- package/hooks/tezgah_policy.py +261 -129
- package/hooks/tezgah_rank.py +29 -27
- package/hooks/tezgah_replay.py +200 -30
- package/hooks/tezgah_research.py +1303 -14
- package/hooks/tezgah_stopspec.py +7 -0
- package/hooks/tezgah_store.py +74 -27
- package/hooks/tezgah_task.py +1201 -40
- package/hooks/tezgah_taste.py +8 -4
- package/hosts/codex/hook.py +32 -13
- package/hosts/cursor/hook.py +32 -14
- package/hosts/dsh/hooks.json +2 -2
- package/hosts/omp/hook.py +44 -23
- package/hosts/omp/tezgah-hook.ts.in +93 -7
- package/hosts/opencode/plugins/tezgah.js +273 -6
- package/output-styles/tezgah.md +76 -42
- package/package.json +1 -1
- package/skills/i-have-adhd/EVALS.md +22 -2
- package/skills/i-have-adhd/SKILL.md +12 -5
- package/skills/plan-add/SKILL.md +27 -11
- package/skills/plan-add/render_table.py +8 -3
- package/skills/plan-sync/SKILL.md +5 -3
- package/skills/ponytail/EVALS.md +21 -2
- package/skills/ponytail/SKILL.md +4 -4
- package/skills/research/SKILL.md +89 -1
- package/skills/tezgah-contract/EVALS.md +52 -7
- package/skills/tezgah-contract/SKILL.md +154 -59
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Turkish",
|
|
3
|
+
"done": [
|
|
4
|
+
"yaptım|tamamladım|tamamlandı|bitirdim|bitirildi|ekledim|eklendi|düzelttim|düzeltildi|hallettim|güncellendi|kuruldu|uygulandı|yayına girdi|kapatıldı|yüklendi|tüm testler geçti|testler geçti|testler yeşil|çalışıyor"
|
|
5
|
+
],
|
|
6
|
+
"verified": [
|
|
7
|
+
"doğruladım|test ettim|kontrol ettim|denetledim|doğrulandı|test edildi"
|
|
8
|
+
],
|
|
9
|
+
"negated": [
|
|
10
|
+
"doğrulanmadı|doğrulamadım|kontrol edilmedi|test edilmedi"
|
|
11
|
+
],
|
|
12
|
+
"admitted": [
|
|
13
|
+
"çeliş|geçemez|imk[aâ]nsız"
|
|
14
|
+
],
|
|
15
|
+
"sycophant": {
|
|
16
|
+
"interjection": [
|
|
17
|
+
"evet"
|
|
18
|
+
],
|
|
19
|
+
"opener": [
|
|
20
|
+
"haklısın|haklısınız|iyi yakaladın|detaylı bakmadım"
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
"closer": [],
|
|
24
|
+
"next_action": [
|
|
25
|
+
"sıradaki adım|sonraki adım"
|
|
26
|
+
],
|
|
27
|
+
"preamble": [
|
|
28
|
+
"aşağıda|şöyle\\b|öncelikle\\b|şimdi\\b"
|
|
29
|
+
],
|
|
30
|
+
"markers": {
|
|
31
|
+
"letters": [
|
|
32
|
+
"ç",
|
|
33
|
+
"ğ",
|
|
34
|
+
"ı",
|
|
35
|
+
"ö",
|
|
36
|
+
"ş",
|
|
37
|
+
"ü",
|
|
38
|
+
"Ç",
|
|
39
|
+
"Ğ",
|
|
40
|
+
"İ",
|
|
41
|
+
"Ö",
|
|
42
|
+
"Ş",
|
|
43
|
+
"Ü"
|
|
44
|
+
],
|
|
45
|
+
"words": [
|
|
46
|
+
"ve",
|
|
47
|
+
"bir",
|
|
48
|
+
"bu",
|
|
49
|
+
"şu",
|
|
50
|
+
"için",
|
|
51
|
+
"ile",
|
|
52
|
+
"ama",
|
|
53
|
+
"fakat",
|
|
54
|
+
"veya",
|
|
55
|
+
"mı",
|
|
56
|
+
"mu",
|
|
57
|
+
"mü",
|
|
58
|
+
"çok",
|
|
59
|
+
"daha",
|
|
60
|
+
"gibi",
|
|
61
|
+
"kadar",
|
|
62
|
+
"sonra",
|
|
63
|
+
"önce",
|
|
64
|
+
"var",
|
|
65
|
+
"yok",
|
|
66
|
+
"değil",
|
|
67
|
+
"olarak",
|
|
68
|
+
"olan",
|
|
69
|
+
"hem",
|
|
70
|
+
"ise",
|
|
71
|
+
"ki",
|
|
72
|
+
"artık",
|
|
73
|
+
"hâlâ",
|
|
74
|
+
"hala",
|
|
75
|
+
"şimdi",
|
|
76
|
+
"yani",
|
|
77
|
+
"diye",
|
|
78
|
+
"tüm",
|
|
79
|
+
"bütün",
|
|
80
|
+
"kalan",
|
|
81
|
+
"neden",
|
|
82
|
+
"nasıl",
|
|
83
|
+
"yeni",
|
|
84
|
+
"eski",
|
|
85
|
+
"evet",
|
|
86
|
+
"hayır"
|
|
87
|
+
]
|
|
88
|
+
},
|
|
89
|
+
"negation_before": [
|
|
90
|
+
"\\bdeğil"
|
|
91
|
+
],
|
|
92
|
+
"question_particle": [
|
|
93
|
+
"m[ıiuü]|değil"
|
|
94
|
+
],
|
|
95
|
+
"question_end": [
|
|
96
|
+
"m[ıiuü]"
|
|
97
|
+
],
|
|
98
|
+
"clause_join": [
|
|
99
|
+
"ama|ve"
|
|
100
|
+
],
|
|
101
|
+
"external_state": [
|
|
102
|
+
"yok|eksik|yayımlan|yayınlan"
|
|
103
|
+
],
|
|
104
|
+
"external_ci_state": [
|
|
105
|
+
"geçti|başarısız"
|
|
106
|
+
],
|
|
107
|
+
"publish_state": [
|
|
108
|
+
"yok|eksik|yayımlan|yayınlan"
|
|
109
|
+
],
|
|
110
|
+
"residual_label": [
|
|
111
|
+
"açık (?:kalan|iş|madde|nokta|soru)|eksik(?!siz)|yapılama|yapılma(?:yan|dı)|yapılacak|bekleyen|bakıla?ma|bitme(?:yen|di)|tamamlanma|kısmen|doğrulan(?:a)?ma|test edile?me|çalıştırıla?ma|koşula?ma|dokunula?ma|sonraki adım|sıradaki|sırada\\b|kapsam dışı|atlan(?:an|dı)|ertelen|bilinen (?:hata|sınırlama|sorun)|teknik borç|ileride|gelecek (?:iş|çalışma)|önerilen (?:iyileştirme|adım)|manuel doğrulama|elle doğrula|engel(?:ler)?\\b|engelleyenler\\b|erişilemeyen|fix-?later|\\w+m[ae]d[ıiuü](?:m|kl[ae]r(?:[ıi]m)?)\\b|kontrol edil(?:e)?me|incelen(?:e)?me|ölçül(?:e)?me|çözül(?:e)?me|denen(?:e)?me|ulaşılama|(?:yarım|askıda|sonraya) kalan|sonra bakılacak"
|
|
112
|
+
],
|
|
113
|
+
"residual_first": [
|
|
114
|
+
"kalan(?:lar)?(?=\\s*(?:\\(|$))|kalan\\s+(?:tek\\s+)?(?:iş|işler|adım|adımlar|madde|maddeler|görev|görevler|şey)\\b"
|
|
115
|
+
],
|
|
116
|
+
"label_done": [
|
|
117
|
+
"giderildi|çözüldü|yazıldı|bitti|ölçüldü|yapıldı|halledildi|kapandı|kalmadı|tamamlanan|düzeltilen|giderilen|kapatılan|çözülen|artık (?:var|mevcut)"
|
|
118
|
+
],
|
|
119
|
+
"partial": [
|
|
120
|
+
"kısmen"
|
|
121
|
+
],
|
|
122
|
+
"nothing_left": [
|
|
123
|
+
"\\byok"
|
|
124
|
+
],
|
|
125
|
+
"nothing_lead": [],
|
|
126
|
+
"empty_item": [
|
|
127
|
+
"yok|hiç(?:biri|bir şey)?"
|
|
128
|
+
],
|
|
129
|
+
"blockers": {
|
|
130
|
+
"decision": {
|
|
131
|
+
"pattern": "KARAR"
|
|
132
|
+
},
|
|
133
|
+
"irreversible": {
|
|
134
|
+
"pattern": "GER[İI] ALINAMAZ"
|
|
135
|
+
},
|
|
136
|
+
"access": {
|
|
137
|
+
"pattern": "YETK[İI][A-ZÇĞİIÖŞÜ]*"
|
|
138
|
+
},
|
|
139
|
+
"env": {
|
|
140
|
+
"pattern": "ORTAM[A-ZÇĞİIÖŞÜ]*"
|
|
141
|
+
},
|
|
142
|
+
"said_not": [
|
|
143
|
+
"gerek(?:mi|mez|tirm|li\\s+değil)|istem|yok\\b|değil\\b"
|
|
144
|
+
],
|
|
145
|
+
"tried_not": [
|
|
146
|
+
"değil\\b|gerek(?:mi|mez|tirm)|istem"
|
|
147
|
+
],
|
|
148
|
+
"absent": [
|
|
149
|
+
"yok"
|
|
150
|
+
]
|
|
151
|
+
},
|
|
152
|
+
"blocker_labels": [
|
|
153
|
+
"engel"
|
|
154
|
+
],
|
|
155
|
+
"blockers_only": [
|
|
156
|
+
"engel(?:ler)?"
|
|
157
|
+
],
|
|
158
|
+
"env_error": [
|
|
159
|
+
"bulunamad|kurulu değil|yüklü değil|mevcut değil"
|
|
160
|
+
],
|
|
161
|
+
"access_error": [
|
|
162
|
+
"izin|reddedil|erişim"
|
|
163
|
+
],
|
|
164
|
+
"spawn_words": [
|
|
165
|
+
"ajan|sağlayıcı"
|
|
166
|
+
],
|
|
167
|
+
"was_exclude": [
|
|
168
|
+
"şimdi|kendi|ileri|geri"
|
|
169
|
+
],
|
|
170
|
+
"was": [
|
|
171
|
+
"\\w+(?<!m[ae])(?:yordu|[dt][ıiuü])"
|
|
172
|
+
],
|
|
173
|
+
"now": [
|
|
174
|
+
"^artık\\b.*(?:\\bvar\\b|\\bmevcut\\b|\\w+yor\\b)"
|
|
175
|
+
],
|
|
176
|
+
"future": [
|
|
177
|
+
"\\w+(?:acak|ecek)"
|
|
178
|
+
],
|
|
179
|
+
"word_order": "object_first",
|
|
180
|
+
"ui_objects": [
|
|
181
|
+
"akış|adım|ekran|sayfa|arayüz|form|menü|buton|düğme|panel|tasarım|görünüm|kart|bileşen|sekme|pencere"
|
|
182
|
+
],
|
|
183
|
+
"ui_quality": [],
|
|
184
|
+
"hints": {
|
|
185
|
+
"spec": [
|
|
186
|
+
"düzgün çalış\\w*|düzgün görün\\w*|güzel görün\\w*|daha iyi (ol|görün)\\w*|kullanıcı dostu|modern görün\\w*|şık (ol|görün)\\w*|profesyonel görün\\w*|temiz (bir )?(arayüz|görün)\\w*|anlaşılır\\w*|kullanılabilirlik\\w*",
|
|
187
|
+
{
|
|
188
|
+
"ui_ask": "basitleştir\\w*|sadeleştir\\w*"
|
|
189
|
+
},
|
|
190
|
+
"yeniden tasarla\\w*|baştan tasarla\\w*|tasarım\\w*|focus[- ]durum\\w*|tipografi\\w*|bileşen\\w*|tema\\w*|animasyon\\w*|erişilebilir\\w*|prototip\\w*|hizala\\w*|hiza\\w*|boşluk\\w*|satır aral\\w*|gölge\\w*|kenarlık\\w*|yazı tipi\\w*|punto\\w*|renk\\w*|palet\\w*|devre dışı\\w*|boş durum\\w*|kırılma nokta\\w*|mobil (uyumlu|görünüm)|karanlık mod\\w*|aydınlık mod\\w*|renk şema\\w*|stil rehber\\w*|tasarım sistemi|tasarım token\\w*|ekran okuyucu\\w*|kontrast\\w*|ekran görüntü\\w*|görsel (incele|kontrol|karşılaştır)\\w*"
|
|
191
|
+
],
|
|
192
|
+
"consult": [
|
|
193
|
+
"mimari\\w*|kök neden\\w*|geri dönüşü olmayan|kırıcı değişiklik\\w*|geriye dönük uyum\\w*|api sürüm\\w*|sürümleme\\w*|versiyonlama\\w*|şema\\w*|göç\\w*|migrasyon\\w*|veri (taşı|göç)\\w*|geri al\\w*|geri (alınamaz|dönüşü (yok|olmaz|olmayan))|performans bütçe\\w*|gecikme bütçe\\w*|güvenlik\\w*|zafiyet\\w*|bağımlılık(ları)? güncelle\\w*|paket güncelle\\w*|sürüm yükselt\\w*|tedarik zincir\\w*|eş ?zamanlı\\w*|yarış (durumu|koşulu)\\w*|kapasite (plan|hesab|test|sınır)\\w*|ölçeklen\\w*|yük test\\w*|mimari karar\\w*|tasarım karar\\w*|politika değiş\\w*|sözleşme (değiş|yenile)\\w*|yayına al\\w*|canlıya al\\w*|sürüm çıkar\\w*|ödün (ver|vermey)\\w*"
|
|
194
|
+
],
|
|
195
|
+
"research": [
|
|
196
|
+
"araştır\\w*|literatür\\w*|hipotez\\w*|deney|karşılaştır\\w*|karşılaştırmalı analiz|kıyaslama\\w*|varyant\\w*|a/b testi|(kullanıcı|müşteri) (interview\\w*|görüşme\\w*|mülakat\\w*)|user (görüşme\\w*|mülakat\\w*)|anket\\w*|kök neden (analiz|araştır)\\w*|kaynak tarama\\w*|referans tarama\\w*|(yöntem|yaklaşım|kütüphane|varyant|seçenek)\\w* karşılaştır\\w*|ölçüm\\w*|deneysel\\w*|deneyler\\w*|makale\\w*|veri (seti|kümesi)|olay sonrası (analiz|değerlendirme)\\w*|hata bütçe\\w*|gerçekten (doğru|öyle) mu|kanıt\\w*|test kapsam\\w*|kapsam oran\\w*|kapsamı (artır|yükselt)\\w*|doküman(tasyon)?\\w* (yetersiz|eksik|kötü|zayıf)"
|
|
197
|
+
],
|
|
198
|
+
"product": [
|
|
199
|
+
"ürün\\w*|yol harita\\w*|kuzey yıldız\\w*|aktivasyon\\w*|dönüşüm\\w*|fiyatlandır\\w*|önceliklendir\\w*|kullanıcı araştırma\\w*|ürün keşf\\w*|müşteri geri bildirim\\w*|benimsen\\w*|konumlandır\\w*|segmentasyon\\w*|hedef kitle\\w*|(kullanıcı|müşteri) discovery|keşif (görüşme|çalışma)\\w*|fırsat\\w*|memnuniyet\\w*|anket\\w*|(kullanıcı|müşteri)[ -]?(feedback|geri bildirim)\\w*|(customer|user)[ -]?geri bildirim\\w*|şikayet\\w*|rakip\\w*|rekabet\\w*|pazar pay\\w*|terk oran\\w*|elde tutma\\w*|abonelik\\w*|gelir model\\w*|özellik\\w*|sayfa(?! numara)\\w*|ekran(?! kart)(?!a\\b[^.!?\\n]{0,40}\\b(?:yaz|bas)\\w*)\\w*|arayüz\\w*|arama kutu\\w*|filtre\\w*|tablo(?![^.!?\\n]{0,60}\\b(?:sütun|kolon|sql|index|indeks)\\w*)\\w*|adım(?! sayı)\\w*|kullanıcı liste\\w*|form(u|un|da|daki|lar|ları|unu)\\w*"
|
|
200
|
+
],
|
|
201
|
+
"graph": [
|
|
202
|
+
"kim çağır\\w*|çağrı yerleri|nerede tanımlı|nasıl bağlan\\w*|etkilenir\\w*|hangi dosyalar etkilen\\w*|etki (analiz|alan)\\w*|neyi etkile\\w*|neleri etkile\\w*|etkilen\\w*|bağımlı\\w*|kullanılmayan\\w*|kullanılmıyor|ölü kod|döngüsel (bağımlılık|import)\\w*|giriş nokta\\w*|uygulama (nerede|nereden) başl\\w*|kim import ed\\w*|(fonksiyon|metod|sınıf|modül|api)\\w* (kim|nerede) kullan\\w*|nerede (kullanıl|çağrıl)\\w*|tanım\\w* nerede|kullanım yerleri|çağrı (zinciri|grafiği)|bağımlılık (grafiği|ağacı)|yeniden adlandır\\w*"
|
|
203
|
+
]
|
|
204
|
+
},
|
|
205
|
+
"fan_verbs": [
|
|
206
|
+
"düzelt|güncelle|ekle|yaz|sil|kaldır|taşı|bitir|tamamla|incele|oluştur|değiştir"
|
|
207
|
+
],
|
|
208
|
+
"fan_join": [
|
|
209
|
+
"ve"
|
|
210
|
+
],
|
|
211
|
+
"fan_ordinals": [
|
|
212
|
+
"birinci(?:si)?",
|
|
213
|
+
"ikinci(?:si)?"
|
|
214
|
+
],
|
|
215
|
+
"fan_directives": [
|
|
216
|
+
"paralel\\w*|alt ?ajan\\w*|orkestra\\w*"
|
|
217
|
+
],
|
|
218
|
+
"data_ask": [
|
|
219
|
+
"(?:metri[ck]s?|kpis?|data|sales|revenue) (?:\\w+ ){0,2}pano|(?:veri\\w*|satış\\w*|gelir\\w*) (?:\\w+ ){0,2}(?:dashboard|pano)|(?:dashboard|gösterge panel)\\w* (?:\\w+ ){0,4}(?:tasarla|oluştur|hazırla|yap|göster)\\w*|öner\\w* (?:\\w+ ){0,3}grafi\\w*|hangi (?:metri[ck]\\w*|kpi\\w*|grafi\\w*|göstergeleri?)|(?:metri[ck]\\w*|kpi\\w*) (?:\\w+ ){0,3}(?:tasarla|seç|tanımla|belirle|takip|izle)\\w*|gösterge panel\\w*|visuali[sz]\\w* (?:\\w+ ){0,3}veri\\w*|veri\\w* (?:\\w+ ){0,3}görselleştir\\w*"
|
|
220
|
+
],
|
|
221
|
+
"code_sense": [
|
|
222
|
+
"\\b(?:indeks\\w*|veri yapı\\w*|fonksiyon\\w*|bileşen\\w*|modül\\w*|dosya\\w*|kopyala\\w*|seçici\\w*|yükleme|ilerleme|paket\\w*)\\b"
|
|
223
|
+
],
|
|
224
|
+
"constraint": {
|
|
225
|
+
"dont": [
|
|
226
|
+
"(?P<obj>[\\w./@~-]+?)(?:'\\w+)?\\s+(?:sakın\\s+)?dokunma(?:yın|yınız)?\\b(?!\\s+(?:hedef|alan|olay|duyar)\\w*)"
|
|
227
|
+
],
|
|
228
|
+
"ask": [
|
|
229
|
+
"(?:bana\\s+)?sormadan\\s+(?P<ask>\\w+)\\s+(?:etme|yapma)\\w*"
|
|
230
|
+
],
|
|
231
|
+
"grant": [
|
|
232
|
+
"(?:bana\\s+)?sormadan(?!\\s+(?:\\w+\\s+)?(?:etme|yapma|ilerleme|gitme)\\w*)|onay(?:ı|ımı)?\\s+ver(?:iyorum|dim)|izin\\s+ver(?:iyorum|dim)|onaylıyorum|sormana gerek yok"
|
|
233
|
+
],
|
|
234
|
+
"lift": [
|
|
235
|
+
"(?:artık|bundan sonra|tekrar|yine)\\s+(?:bana\\s+)?sor\\b|onay\\w*\\s+geri\\s+al\\w*|izn\\w*\\s+geri\\s+al\\w*"
|
|
236
|
+
],
|
|
237
|
+
"lift_outward": [
|
|
238
|
+
"(?:pr\\b|push\\w*|release\\w*|yayınla\\w*|yayımla\\w*|sürüm\\b|versiyonla\\w*|etiketle\\w*|tag\\w*)(?:\\s+\\S+){0,2}?\\s+(?:et|yap|çıkar)(?:ma|me)(?:y[ıi]n\\w*)?\\b",
|
|
239
|
+
"(?:push|yay[ıi]nla|yayımla|etiketle|versiyonla|tag)(?:la|le)?m[ae](?:y[ıi]n\\w*)?\\b"
|
|
240
|
+
],
|
|
241
|
+
"grant_not": [
|
|
242
|
+
"\\b(?!bütün\\b)\\w+[dt][ıiuü]n(?:[ıi]z)?\\b|\\bneden\\b|\\bniye\\b"
|
|
243
|
+
],
|
|
244
|
+
"grant_not_verb": [
|
|
245
|
+
"\\w{2,}m[ae](?:y[ıi]n(?:[ıi]z)?)?"
|
|
246
|
+
],
|
|
247
|
+
"grant_not_soft": [
|
|
248
|
+
"durma|bekleme|sorma|unutma"
|
|
249
|
+
]
|
|
250
|
+
},
|
|
251
|
+
"ask": {
|
|
252
|
+
"process": [
|
|
253
|
+
"\\b(?:başlayayım|devam edeyim|ilerleyeyim|geçeyim|sürdüreyim|uygulayayım|yapayım|açayım|kapatayım|birleştireyim|merge edeyim|commit(?:le)?(?:yeyim|eyim| atayım)|koşayım|çalıştırayım)\\b|\\b(?:devam etmemi|başlamamı|ilerlememi|commit atmamı|merge etmemi|uygulamamı|yapmamı) ister mis\\w*|\\bhangisi(?:nden|yle|ni)? (?:önce|ile başla|başla\\w*)|\\bnereden başla\\w*"
|
|
254
|
+
],
|
|
255
|
+
"never_default": [
|
|
256
|
+
"zorla|geçmiş\\w* (?:yeniden yaz|değiştir)\\w*|\\bsil\\w*|kaldır\\w*|yok et\\w*|üretim\\w*|\\bcanlı\\w*|\\bprod\\w*|göç\\w*|kimlik bilgi\\w*|şifre\\w*|parola\\w*|\\bhesa[bp]\\w*|e-?posta\\w*|gönder\\w*"
|
|
257
|
+
],
|
|
258
|
+
"spend": [
|
|
259
|
+
"ücret\\w*|ödeme\\w*|harca\\w*|bütçe\\w*|maliyet\\w*|\\bpara\\b|dolar\\w*|\\$\\s?\\d"
|
|
260
|
+
],
|
|
261
|
+
"default_mark": [
|
|
262
|
+
"öneri\\w*|önerilen|önerim|varsayılan\\w*|tavsiye\\w*"
|
|
263
|
+
],
|
|
264
|
+
"options": [
|
|
265
|
+
"\\bveya\\b|\\bya da\\b|\\byoksa\\b|seçenek\\w*|alternatif\\w*|\\bm[ıiuü]\\b.+\\bm[ıiuü]\\b|\\b(?:a|1)\\)?\\s.+?,\\s*(?:b|2)\\)?\\s"
|
|
266
|
+
],
|
|
267
|
+
"cheap_answer": [
|
|
268
|
+
"evet|tamam|olur|devam(?: et)?|yap|başla|ilerle|okey|onay(?:lıyorum)?"
|
|
269
|
+
],
|
|
270
|
+
"outward": {
|
|
271
|
+
"push": "\\bpush\\w*",
|
|
272
|
+
"release": "versiyon\\w*|sürüm\\w*|\\brelease\\w*|etiket\\w*",
|
|
273
|
+
"publish": "yayınla\\w*|yayımla\\w*|\\bnpm\\b|homebrew",
|
|
274
|
+
"pr": "\\bpr\\b|pull request"
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
"needle_stop": [
|
|
278
|
+
"ve",
|
|
279
|
+
"veya",
|
|
280
|
+
"ile"
|
|
281
|
+
],
|
|
282
|
+
"rank_stopwords": [
|
|
283
|
+
"bir",
|
|
284
|
+
"bunu",
|
|
285
|
+
"buna",
|
|
286
|
+
"bunlar",
|
|
287
|
+
"şunu",
|
|
288
|
+
"için",
|
|
289
|
+
"ile",
|
|
290
|
+
"ama",
|
|
291
|
+
"gibi",
|
|
292
|
+
"daha",
|
|
293
|
+
"çok",
|
|
294
|
+
"kadar",
|
|
295
|
+
"veya",
|
|
296
|
+
"değil",
|
|
297
|
+
"her",
|
|
298
|
+
"hem",
|
|
299
|
+
"olan",
|
|
300
|
+
"olarak",
|
|
301
|
+
"sonra",
|
|
302
|
+
"önce",
|
|
303
|
+
"ise",
|
|
304
|
+
"yani",
|
|
305
|
+
"nasil",
|
|
306
|
+
"neden"
|
|
307
|
+
],
|
|
308
|
+
"fold": [
|
|
309
|
+
"ıi",
|
|
310
|
+
"âa",
|
|
311
|
+
"îi",
|
|
312
|
+
"ûu"
|
|
313
|
+
],
|
|
314
|
+
"say": {
|
|
315
|
+
"unverified": "doğrulanmadı",
|
|
316
|
+
"reply_lang": "Turkish",
|
|
317
|
+
"reply_in": "in Turkish, even when the user\nwrites English",
|
|
318
|
+
"reply_split": "in Turkish, ALWAYS, even when the user writes English",
|
|
319
|
+
"reply_short": "reply Turkish",
|
|
320
|
+
"gap_example": "\"deploy öncesi doğrulamadım; riski şöyle değerlendirdim: ...\"",
|
|
321
|
+
"blocker_tokens": "KARAR, YETKİ, GERİ ALINAMAZ, ORTAM",
|
|
322
|
+
"agree_word": "\"haklısın\"",
|
|
323
|
+
"opener_short": "\"haklısın\", \"you're right\", \"good catch\", \"detaylı bakmadım\", \"I didn't look closely\"",
|
|
324
|
+
"decision_gloss": "DECISION: ",
|
|
325
|
+
"access_gloss": "ACCESS: ",
|
|
326
|
+
"irreversible_gloss": "IRREVERSIBLE: ",
|
|
327
|
+
"env_gloss": "ENV: ",
|
|
328
|
+
"blockers_heading": "Engeller",
|
|
329
|
+
"decision": "KARAR",
|
|
330
|
+
"access": "YETKİ",
|
|
331
|
+
"irreversible": "GERİ ALINAMAZ",
|
|
332
|
+
"env": "ORTAM",
|
|
333
|
+
"done_claim": "yaptım",
|
|
334
|
+
"opener_examples": "\"haklısın\", \"you're right\", \"absolutely right\", \"good catch\", \"iyi yakaladın\", \"detaylı bakmadım\", \"I didn't look closely\", \"I should have checked\"",
|
|
335
|
+
"opener_ban": "never \"haklısın\" / \"you're right\" / \"detaylı bakmadım\" / an apology",
|
|
336
|
+
"residual_lead": "Bu maddeleri şimdi yap veya engel türü ve kanıtla yaz. ",
|
|
337
|
+
"slice_lead": "Durmuş bir dilim var. ",
|
|
338
|
+
"ready_lead": "Hazır adımlar bekliyor. ",
|
|
339
|
+
"ask_lead": "Bu soruyu sorma: kararı ver ya da önerili onay sorusuna çevir. ",
|
|
340
|
+
"approval_heading": "Onay için sorular",
|
|
341
|
+
"recommended": "Öneri",
|
|
342
|
+
"grant_examples": "\"bana sormadan pushla\", \"onay veriyorum\""
|
|
343
|
+
}
|
|
344
|
+
}
|
|
@@ -14,7 +14,7 @@ sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
|
|
|
14
14
|
from tezgah_guard import attest_session, import_failed, safe # noqa: E402
|
|
15
15
|
try:
|
|
16
16
|
from tezgah_context import context_for, record # noqa: E402
|
|
17
|
-
from tezgah_paths import HOST_DIRS # noqa: E402
|
|
17
|
+
from tezgah_paths import HOST_DIRS, root_for # noqa: E402
|
|
18
18
|
except Exception as exc:
|
|
19
19
|
import_failed(exc)
|
|
20
20
|
|
|
@@ -62,6 +62,20 @@ def core_is_in_a_file():
|
|
|
62
62
|
return False
|
|
63
63
|
|
|
64
64
|
|
|
65
|
+
def export_session(env_file, session_id):
|
|
66
|
+
"""Append `export TEZGAH_SESSION=<id>` to Claude's CLAUDE_ENV_FILE, appended
|
|
67
|
+
because other hooks write the same file."""
|
|
68
|
+
import shlex
|
|
69
|
+
with open(env_file, "a", encoding="utf-8") as fh:
|
|
70
|
+
fh.write("export TEZGAH_SESSION=%s\n" % shlex.quote(session_id))
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def note_child(session_id, agent_id, agent_type):
|
|
74
|
+
"""The child's lineage row in its parent's ledger (`tezgah-route --report`)."""
|
|
75
|
+
from tezgah_integrity import note
|
|
76
|
+
note(session_id, "subagent_start", agent_type, agent=agent_id)
|
|
77
|
+
|
|
78
|
+
|
|
65
79
|
def main():
|
|
66
80
|
try:
|
|
67
81
|
payload = json.load(sys.stdin)
|
|
@@ -74,6 +88,14 @@ def main():
|
|
|
74
88
|
# tezgah wires, and dsh (which runs it too) has no transcript to derive
|
|
75
89
|
# the kind from, so the store is the only channel its line has.
|
|
76
90
|
safe(payload.get("session_id"), record, payload.get("session_id"), "orch")
|
|
91
|
+
# The child's lineage row: a Claude subagent runs under its parent's
|
|
92
|
+
# session id, its calls carrying `agent_id`, so this row in the parent's
|
|
93
|
+
# ledger is what types it for `tezgah-route --report` (hooks reference,
|
|
94
|
+
# SubagentStart input: agent_id, agent_type).
|
|
95
|
+
aid, kind = payload.get("agent_id"), payload.get("agent_type")
|
|
96
|
+
if isinstance(aid, str) and aid and isinstance(kind, str) and root_for(cwd):
|
|
97
|
+
safe(payload.get("session_id"), note_child, payload.get("session_id"),
|
|
98
|
+
aid, kind)
|
|
77
99
|
if event == "SessionStart":
|
|
78
100
|
# Claude and dsh run this one script; Claude's manifest declares
|
|
79
101
|
# TEZGAH_CORE_IN_FILE on SessionStart and dsh's does not, so the flag
|
|
@@ -82,6 +104,12 @@ def main():
|
|
|
82
104
|
sid = payload.get("session_id")
|
|
83
105
|
host = "claude" if os.environ.get("TEZGAH_CORE_IN_FILE") == "1" else "dsh"
|
|
84
106
|
safe(sid, attest_session, host, sid, cwd)
|
|
107
|
+
# The session id the route, judge and status CLIs write under: Claude
|
|
108
|
+
# sources this file before every Bash call (CLAUDE_ENV_FILE, SessionStart
|
|
109
|
+
# only), as omp exports TEZGAH_SESSION to its shells
|
|
110
|
+
env_file = os.environ.get("CLAUDE_ENV_FILE")
|
|
111
|
+
if env_file and isinstance(sid, str) and sid:
|
|
112
|
+
safe(sid, export_session, env_file, sid)
|
|
85
113
|
text = safe(payload.get("session_id"), context_for,
|
|
86
114
|
EVENTS.get(event, "session_start"), cwd, payload,
|
|
87
115
|
# the brief is a subagent's own text, never the file's; every
|
|
@@ -31,6 +31,18 @@ try:
|
|
|
31
31
|
except Exception as exc:
|
|
32
32
|
import_failed(exc)
|
|
33
33
|
|
|
34
|
+
|
|
35
|
+
def cross_note(session_id, tool, inp, cwd):
|
|
36
|
+
"""The cross-project write notice (hooks/tezgah_gate.py::cross_project_note),
|
|
37
|
+
imported here and not at the top: a gate module without it costs this one
|
|
38
|
+
line, never the evidence row."""
|
|
39
|
+
try:
|
|
40
|
+
from tezgah_gate import cross_project_note
|
|
41
|
+
except ImportError:
|
|
42
|
+
return None
|
|
43
|
+
return cross_project_note(session_id, tool, inp, cwd)
|
|
44
|
+
|
|
45
|
+
|
|
34
46
|
# The tool-use kinds this hook can see, for the status line's used marks. Claude
|
|
35
47
|
# reads them from its transcript and ignores this store, but dsh runs this same
|
|
36
48
|
# file with no transcript of its own - the store is the only channel its Web
|
|
@@ -139,13 +151,20 @@ def main():
|
|
|
139
151
|
# the Bash result's own stdout/stderr, read on a bounded tail for the
|
|
140
152
|
# empty-run contract (tezgah_integrity.EMPTY_RUN)
|
|
141
153
|
empty_run=ran_nothing(result),
|
|
142
|
-
agent=agent
|
|
154
|
+
agent=agent,
|
|
155
|
+
# a background spawn's result names its child (`agentId`), the
|
|
156
|
+
# `agent_id` that child's own calls carry: its slice record keeps it
|
|
157
|
+
# (hooks/tezgah_gate.py::lease_reason)
|
|
158
|
+
child=(result.get("agentId") if isinstance(result, dict)
|
|
159
|
+
and result.get("status") == "async_launched" else None))
|
|
143
160
|
# the opt-in taste note: the learnings in scope for the first write to this
|
|
144
|
-
# file type in the session (hooks/tezgah_taste.write_note),
|
|
145
|
-
#
|
|
161
|
+
# file type in the session (hooks/tezgah_taste.write_note), and the
|
|
162
|
+
# cross-project write notice (hooks/tezgah_gate.py::cross_project_note),
|
|
163
|
+
# beside the provenance line rather than instead of it
|
|
146
164
|
if event == "PostToolUse" and not failed:
|
|
147
|
-
notice = "\n".join(t for t in (
|
|
148
|
-
|
|
165
|
+
notice = "\n".join(t for t in (
|
|
166
|
+
notice, safe(session_id, write_note, session_id, inp, cwd, tool),
|
|
167
|
+
safe(session_id, cross_note, session_id, tool, inp, cwd)) if t)
|
|
149
168
|
if notice:
|
|
150
169
|
json.dump({"hookSpecificOutput": {
|
|
151
170
|
"hookEventName": event,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""Claude Code PreToolUse hook (matcher Agent|Task|Grep|Bash),
|
|
2
|
+
"""Claude Code PreToolUse hook (matcher Agent|Task|Grep|Bash|...|AskUserQuestion),
|
|
3
|
+
inert outside roots.
|
|
3
4
|
|
|
4
5
|
Claude's envelope around the shared gate (hooks/tezgah_gate.py): refuse the
|
|
5
6
|
grep-only explorer subagent, and nudge the first code-symbol search of a
|
|
@@ -13,15 +14,19 @@ import sys
|
|
|
13
14
|
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
|
|
14
15
|
from tezgah_guard import import_failed, safe # noqa: E402
|
|
15
16
|
try:
|
|
16
|
-
from tezgah_gate import decision, graph_advice # noqa: E402
|
|
17
|
+
from tezgah_gate import ask_advice, decision, graph_advice, spawn_advice # noqa: E402
|
|
17
18
|
except Exception as exc:
|
|
18
19
|
import_failed(exc)
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
def verdict(tool, inp, cwd, session_id, agent):
|
|
22
|
-
"""(deny reason,
|
|
23
|
+
"""(deny reason, advice line): the graph line, the shared-worktree warning
|
|
24
|
+
of a spawn or the ask-policy warning of an AskUserQuestion call, only for a
|
|
25
|
+
call the gate lets through."""
|
|
23
26
|
reason = decision(tool, inp, cwd, session_id, agent=agent)
|
|
24
|
-
return reason, None if reason else graph_advice(tool, inp, cwd, "claude")
|
|
27
|
+
return reason, None if reason else (graph_advice(tool, inp, cwd, "claude")
|
|
28
|
+
or spawn_advice(tool, inp, session_id, cwd)
|
|
29
|
+
or ask_advice(tool, inp, session_id, cwd))
|
|
25
30
|
|
|
26
31
|
|
|
27
32
|
def main():
|
package/hooks/projects-stop.py
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""Claude Code Stop / SubagentStop hook: refuse to end a turn on a false claim.
|
|
3
3
|
|
|
4
|
-
Blocks (decision: "block") when the final message opens by placating,
|
|
4
|
+
Blocks (decision: "block") when the final message opens by placating, claims
|
|
5
5
|
done/tested/passing in a session whose newest turn changed code and left a check
|
|
6
|
-
failing or unproven by a later pass
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
failing or unproven by a later pass, or ends a turn that did work on a list of
|
|
7
|
+
what is left with an item no blocker accounts for (`residual work`). An explicit
|
|
8
|
+
"doğrulanmadı" clears only a claim whose repair is a check, and only after a
|
|
9
|
+
check that ran and failed since the newest change: the word alone used to clear
|
|
10
|
+
every refusal, so writing it was cheaper than verifying (plan 080). With
|
|
11
|
+
`stop_hook_active` set - the reply after a block - the reply is judged again:
|
|
12
|
+
it is refused once more only for a reason class this turn was not refused for
|
|
13
|
+
yet, at most two refusals per turn (`tezgah_integrity._record_only`, counted
|
|
14
|
+
from the ledger), and otherwise recorded as an `after_block` row. Claude Code
|
|
15
|
+
also overrides the hook after its own consecutive-block cap, so this can never
|
|
16
|
+
trap a session. A subagent's end (SubagentStop) is judged record-only: one
|
|
17
|
+
`subagent_end` row, never a block (ADR 011); it also closes the slice record
|
|
18
|
+
of a background child that ended (`tezgah_task.close_child`), so its lease
|
|
19
|
+
goes with it. Inert outside a tezgah root or under the `verify-off` kill
|
|
20
|
+
switch (the record close only under `slices-off`).
|
|
14
21
|
"""
|
|
15
22
|
import json
|
|
16
23
|
import os
|
|
@@ -24,10 +31,13 @@ try:
|
|
|
24
31
|
except Exception as exc:
|
|
25
32
|
import_failed(exc)
|
|
26
33
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
|
|
35
|
+
def close_child(cwd, session_id, agent_id):
|
|
36
|
+
"""The background child's record closes when its SubagentStop arrives:
|
|
37
|
+
Claude sends no other end for a `run_in_background` launch."""
|
|
38
|
+
import tezgah_task
|
|
39
|
+
root = tezgah_task.main_repo(cwd)
|
|
40
|
+
return root and tezgah_task.close_child(root, session_id, agent_id)
|
|
31
41
|
|
|
32
42
|
|
|
33
43
|
def main():
|
|
@@ -39,20 +49,22 @@ def main():
|
|
|
39
49
|
return
|
|
40
50
|
session_id = p.get("session_id")
|
|
41
51
|
safe(session_id, bind_session, session_id) # the switch latch (tezgah_paths.off)
|
|
52
|
+
cwd = p.get("cwd") or os.getcwd()
|
|
53
|
+
if p.get("hook_event_name") == "SubagentStop" and p.get("agent_id") \
|
|
54
|
+
and root_for(cwd) and not off("slices-off"):
|
|
55
|
+
safe(session_id, close_child, cwd, session_id, p.get("agent_id"))
|
|
42
56
|
if off("verify-off"):
|
|
43
57
|
return
|
|
44
|
-
cwd = p.get("cwd") or os.getcwd()
|
|
45
58
|
if not root_for(cwd):
|
|
46
59
|
return
|
|
47
60
|
if p.get("hook_event_name") == "SubagentStop":
|
|
48
61
|
safe(session_id, stop_reason, p.get("last_assistant_message"),
|
|
49
62
|
session_id, cwd=cwd, subagent=True, agent=p.get("agent_id"))
|
|
50
63
|
return
|
|
51
|
-
blocked = 1 if p.get("stop_hook_active") else 0
|
|
52
64
|
# a core that cannot answer has refused nothing, so the turn ends: the rule
|
|
53
65
|
# never traps a session, and that holds for its own failure too
|
|
54
66
|
reason = safe(session_id, stop_reason, p.get("last_assistant_message"),
|
|
55
|
-
session_id, cwd=cwd,
|
|
67
|
+
session_id, cwd=cwd, after_block=bool(p.get("stop_hook_active")))
|
|
56
68
|
if reason:
|
|
57
69
|
json.dump({"decision": "block", "reason": reason}, sys.stdout)
|
|
58
70
|
|