@r1z4x/tezgah 1.5.1 → 1.7.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.
- package/CHANGELOG.md +126 -1
- package/MANIFEST +11 -0
- package/README.md +6 -3
- package/bin/consult +13 -10
- package/bin/tezgah-docs +18 -16
- package/bin/tezgah-doctor +152 -0
- package/bin/tezgah-research +286 -12
- package/bin/tezgah-route +48 -1
- package/bin/tezgah-setup +27 -14
- package/bin/tezgah-task +771 -46
- package/bin/tezgah-taste +48 -10
- package/docs/architecture.md +7 -4
- package/docs/citations-baseline.json +1 -1
- package/docs/clarity-baseline.json +5 -5
- package/docs/contract.md +112 -25
- package/docs/evidence.md +201 -28
- package/docs/feature-audit.md +25 -4
- package/docs/gate.md +70 -33
- package/docs/glossary.md +4 -4
- package/docs/hosts.md +8 -8
- package/docs/index.json +30 -10
- package/docs/judge.md +9 -3
- package/docs/models.md +35 -2
- package/docs/operations.md +103 -3
- package/docs/research.md +392 -13
- package/docs/skills.md +24 -6
- package/docs/status-line.md +5 -5
- package/docs/testing.md +2 -2
- 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-posttooluse.py +24 -5
- package/hooks/projects-pretooluse.py +9 -4
- package/hooks/projects-stop.py +28 -16
- package/hooks/tezgah_agents.py +29 -9
- package/hooks/tezgah_clarity.py +7 -3
- package/hooks/tezgah_components.py +2 -1
- package/hooks/tezgah_context.py +460 -390
- package/hooks/tezgah_gate.py +640 -104
- package/hooks/tezgah_integrity.py +1480 -197
- package/hooks/tezgah_models.py +337 -15
- package/hooks/tezgah_paths.py +103 -10
- package/hooks/tezgah_policy.py +286 -130
- package/hooks/tezgah_product.py +107 -0
- package/hooks/tezgah_rank.py +29 -27
- package/hooks/tezgah_replay.py +200 -30
- package/hooks/tezgah_research.py +1297 -12
- package/hooks/tezgah_skill_pick.py +58 -17
- package/hooks/tezgah_stopspec.py +7 -0
- package/hooks/tezgah_store.py +74 -27
- package/hooks/tezgah_task.py +917 -8
- package/hosts/codex/hook.py +9 -10
- package/hosts/cursor/hook.py +21 -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 +119 -39
- package/output-styles/tezgah.md +76 -42
- package/package.json +1 -1
- package/skills/analyze-app/SKILL.md +57 -0
- package/skills/design-contract/EVALS.md +24 -1
- package/skills/design-contract/SKILL.md +17 -1
- package/skills/design-contract/data-views.md +86 -0
- package/skills/feature-audit/SKILL.md +32 -3
- package/skills/i-have-adhd/EVALS.md +22 -2
- package/skills/i-have-adhd/SKILL.md +12 -5
- package/skills/plan-add/EVALS.md +8 -8
- package/skills/plan-add/SKILL.md +22 -21
- package/skills/plan-sync/EVALS.md +2 -2
- package/skills/plan-sync/SKILL.md +14 -8
- package/skills/pm-frameworks/SKILL.md +6 -0
- package/skills/ponytail/EVALS.md +21 -2
- package/skills/ponytail/SKILL.md +4 -4
- package/skills/product-analysis/EVALS.md +23 -1
- package/skills/product-analysis/SKILL.md +50 -11
- package/skills/product-flow/EVALS.md +81 -0
- package/skills/product-flow/SKILL.md +91 -0
- package/skills/research/SKILL.md +99 -2
- package/skills/tezgah-contract/EVALS.md +52 -7
- package/skills/tezgah-contract/SKILL.md +204 -85
|
@@ -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
|
+
}
|
|
@@ -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
|
|
package/hooks/tezgah_agents.py
CHANGED
|
@@ -37,7 +37,7 @@ import subprocess
|
|
|
37
37
|
|
|
38
38
|
import tezgah_models as tm
|
|
39
39
|
from tezgah_paths import (CONFIG_DIR, HOME, codegraph_bin, host_installed, off,
|
|
40
|
-
root_for)
|
|
40
|
+
root_for, say)
|
|
41
41
|
from tezgah_paths import HOST_DIRS as HOST_HOMES
|
|
42
42
|
|
|
43
43
|
MARKER = "# tezgah: managed by tezgah-agents; do not edit"
|
|
@@ -186,6 +186,7 @@ def detect_infra(root):
|
|
|
186
186
|
# ------------------------------------------------------------------ roles ----
|
|
187
187
|
|
|
188
188
|
def _reviewer_body(host):
|
|
189
|
+
decision = say()["decision"]
|
|
189
190
|
return (
|
|
190
191
|
"You are tezgah-reviewer, an adversarial code reviewer. Review a change,\n"
|
|
191
192
|
"not the whole repo, with the code graph as below.\n\n"
|
|
@@ -221,9 +222,11 @@ def _reviewer_body(host):
|
|
|
221
222
|
"provisional. Disclose the order you read the files in.\n\n"
|
|
222
223
|
"Scope and budget. One review per plan, over its whole diff in the\n"
|
|
223
224
|
"verification phase; at most two rounds - only a confirmed critical or\n"
|
|
224
|
-
"major finding opens round two
|
|
225
|
-
"
|
|
226
|
-
"
|
|
225
|
+
"major finding opens round two; a minor or suggestion one is fixed in the\n"
|
|
226
|
+
"session without a new round, or recorded fix-later only when it waits\n"
|
|
227
|
+
"on a user decision (%s); after round two what is left is fixed by\n"
|
|
228
|
+
"the session and closed with `--resolved`, or recorded fix-later only\n"
|
|
229
|
+
"with %s, never a third round. A round may be a fan-out of\n"
|
|
227
230
|
"reviewers spawned at once, one per dimension (correctness and contract,\n"
|
|
228
231
|
"security, tests and performance) or per file group: when your brief\n"
|
|
229
232
|
"names a dimension or files, review only those - a sibling owns the rest.\n"
|
|
@@ -236,7 +239,7 @@ def _reviewer_body(host):
|
|
|
236
239
|
"specific accusation needs it. The same defect family confirmed in both\n"
|
|
237
240
|
"rounds is a sign the design needs a pivot, not another patch.\n\n"
|
|
238
241
|
"%s" % (_graph_howto(host), _blast_radius(host), EMPTY_IS_NOT_PROOF,
|
|
239
|
-
_may_use(host)))
|
|
242
|
+
decision, decision, _may_use(host)))
|
|
240
243
|
|
|
241
244
|
|
|
242
245
|
def _worker_body(tier):
|
|
@@ -418,9 +421,26 @@ def _orch_body(names):
|
|
|
418
421
|
"--name <slug> --parent-worktree active --json` when the session runs\n"
|
|
419
422
|
"inside Orca, else `git worktree add -b <branch> <absolute path>` - and\n"
|
|
420
423
|
"brief it with absolute paths under that checkout only, never the main\n"
|
|
421
|
-
"checkout.
|
|
422
|
-
"
|
|
423
|
-
"
|
|
424
|
+
"checkout. Every writing brief names its `Owns:` globs (the files only\n"
|
|
425
|
+
"that slice writes; the gate holds its siblings to them) and declares\n"
|
|
426
|
+
"its checkout on a `Worktree: <abs path>` line, and siblings\n"
|
|
427
|
+
"message each other only on an interface or ownership change - status\n"
|
|
428
|
+
"goes to you. Serialize only a real\n"
|
|
429
|
+
"dependency. Your todo list is the step queue: each open item is ready\n"
|
|
430
|
+
"or blocked on something named (a slice id, %s).\n"
|
|
431
|
+
"After every spawn and every landed slice, dispatch every ready\n"
|
|
432
|
+
"item at once, before any `wait`, and mark each dispatched item blocked\n"
|
|
433
|
+
"on its slice id. Never `wait` while a ready step exists. Once every\n"
|
|
434
|
+
"open item is blocked on a running slice, `wait` or end the turn - the\n"
|
|
435
|
+
"host wakes you on the result. You integrate the branches in the order\n"
|
|
436
|
+
"`tezgah-task slice merge-plan` prints, and own CHANGELOG.md, MANIFEST\n"
|
|
437
|
+
"and the citation baseline. The per-turn\n"
|
|
438
|
+
"checks of what changed still run in the turn, in the background; only\n"
|
|
439
|
+
"the heavy tier (full suite, neuter, e2e) is joined at merge.\n"
|
|
440
|
+
"A slice commits `wip: <step>` after each step. A stopped slice is\n"
|
|
441
|
+
"resumed (`tezgah-task slice resume <id>`) or re-dispatched, never\n"
|
|
442
|
+
"silently absorbed inline; run `tezgah-task slice reconcile --prune`\n"
|
|
443
|
+
"before the turn that merged slices ends.\n\n"
|
|
424
444
|
"Route reviews to tezgah-reviewer, with the changed files and symbols in\n"
|
|
425
445
|
"the brief: where it has no shell it cannot run `git diff` itself. Checks\n"
|
|
426
446
|
"go to tezgah-tester, docs and citations to tezgah-docs, a security review\n"
|
|
@@ -432,7 +452,7 @@ def _orch_body(names):
|
|
|
432
452
|
"tezgah-frontier); an ESCALATE answer is restarted on tezgah-frontier with\n"
|
|
433
453
|
"the same brief. Never delegate a task a specialist is not\n"
|
|
434
454
|
"listed for, and never let a subagent spawn its own subagents. Verify each\n"
|
|
435
|
-
"returned claim against the code before acting." % listed)
|
|
455
|
+
"returned claim against the code before acting." % (listed, say()["blocker_tokens"]))
|
|
436
456
|
|
|
437
457
|
|
|
438
458
|
# ---------------------------------------------------------------- renderers --
|
package/hooks/tezgah_clarity.py
CHANGED
|
@@ -4,7 +4,8 @@ Four rules are counted per file over docs/*.md and CHANGELOG.md: sentences over
|
|
|
4
4
|
25 words, semicolons, a short list of words with a plainer replacement, and
|
|
5
5
|
passive voice. Only English prose written for people is read: fenced code,
|
|
6
6
|
code spans (including one broken across lines), link targets, HTML comments,
|
|
7
|
-
tables, headings and any line holding
|
|
7
|
+
tables, headings and any line holding another language's marker letter (a
|
|
8
|
+
language pack's `markers.letters`, hooks/lang/) are blanked first, with
|
|
8
9
|
their newlines kept so a hit still names its line.
|
|
9
10
|
|
|
10
11
|
The counts are a ratchet, not a style gate: `docs/clarity-baseline.json` holds
|
|
@@ -19,6 +20,8 @@ import json
|
|
|
19
20
|
import os
|
|
20
21
|
import re
|
|
21
22
|
|
|
23
|
+
from tezgah_paths import packs
|
|
24
|
+
|
|
22
25
|
RULES = ("long_sentences", "semicolons", "replace_words", "passive")
|
|
23
26
|
LONG = 25
|
|
24
27
|
REPLACE = ("commence", "initiate", "utilize", "prior to", "in order to", "ensure",
|
|
@@ -33,7 +36,8 @@ FENCE = re.compile(r"^\s*(```|~~~)")
|
|
|
33
36
|
SPAN = re.compile(r"(?<!`)(`+)(?!`)(.+?)(?<!`)\1(?!`)", re.S)
|
|
34
37
|
COMMENT = re.compile(r"<!--.*?-->", re.S)
|
|
35
38
|
LINK_TARGET = re.compile(r"\]\([^)]*\)|\]\[[^\]]*\]|<https?://[^>]*>|https?://\S+")
|
|
36
|
-
|
|
39
|
+
OTHER_LANGUAGE = re.compile("[%s]" % "".join(
|
|
40
|
+
c for p in packs().values() for c in p["markers"]["letters"]))
|
|
37
41
|
SKIP_LINE = re.compile(r"^\s*(?:#|\||\[[^\]]+\]:\s)")
|
|
38
42
|
ITEM = re.compile(r"^\s*(?:[-*+]|\d+[.)])\s+")
|
|
39
43
|
BASELINE = os.path.join("docs", "clarity-baseline.json")
|
|
@@ -58,7 +62,7 @@ def prose(text):
|
|
|
58
62
|
out.append(SPAN.sub(lambda m: _blank(m, " CODE "), para))
|
|
59
63
|
text = LINK_TARGET.sub(lambda m: "]" if m.group(0)[0] == "]" else "",
|
|
60
64
|
COMMENT.sub(_blank, "".join(out)))
|
|
61
|
-
return "\n".join("" if SKIP_LINE.match(line) or
|
|
65
|
+
return "\n".join("" if SKIP_LINE.match(line) or OTHER_LANGUAGE.search(line) else line
|
|
62
66
|
for line in text.split("\n"))
|
|
63
67
|
|
|
64
68
|
|
|
@@ -103,7 +103,8 @@ COMPONENTS = [
|
|
|
103
103
|
"switch": "research-off", "editable": False, "revert": "git"},
|
|
104
104
|
{"key": "product", "label": "product",
|
|
105
105
|
"files": ["hooks/tezgah_policy.py", "skills/product-analysis/SKILL.md",
|
|
106
|
-
"skills/feature-audit/SKILL.md"
|
|
106
|
+
"skills/feature-audit/SKILL.md", "skills/product-flow/SKILL.md",
|
|
107
|
+
"hooks/tezgah_product.py"],
|
|
107
108
|
"switch": "research-off", "editable": True, "revert": "git"},
|
|
108
109
|
{"key": "attribution", "label": "attribution",
|
|
109
110
|
"files": ["hooks/tezgah_policy.py", "hooks/tezgah_gate.py"],
|