tillerhand 3.28.6 → 3.29.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/.claude/commands/adopt.md +1 -1
- package/.claude/commands/kit-update.md +1 -1
- package/.claude/commands/retro.md +1 -1
- package/.claude/commands/start.md +2 -2
- package/.claude/hooks/gate.mjs +51 -0
- package/AGENTS.md +1 -0
- package/README.en.md +2 -2
- package/README.md +2 -2
- package/kit/CHANGELOG.md +14 -0
- package/kit/VERSION +1 -1
- package/kit/guide.html +3 -3
- package/kit/kit.mjs +21 -4
- package/kit/project/gitignore +2 -0
- package/kit/templates/backend/docs/architecture/stack.md +1 -0
- package/kit/templates/mobile/docs/architecture/stack.md +1 -0
- package/kit/templates/web-saas/docs/architecture/stack.md +1 -0
- package/package.json +1 -1
|
@@ -41,7 +41,7 @@ Bulguları kısa bir tablo halinde göster. Hızlı taramada kodun içine dalma:
|
|
|
41
41
|
## Adım 2: Tip ve kurulum
|
|
42
42
|
|
|
43
43
|
1. Taramaya göre tipi öner ve onaylat (web-saas / mobile / backend; AI özelliği var mı; Türkiye'de satış veya Türk kullanıcı varsa Türkiye eki `tr`, ayrıntı `/start` Adım 2).
|
|
44
|
-
2. Kur: `node <kit klasörü>/kit/kit.mjs install --type <tip> [--addons ai,tr] --project .` (kit klasörü `.kit.json` → `kit` alanında; alan `npx:tillerhand@<sürüm>` ise `npx -y tillerhand@<sürüm> install ...`; sürüm tam olarak `1.2.3` biçiminde ve `.kit.json` → `version` ile aynı değilse dur ve sor). Araç `init`'te seçilmediyse Adım 0'daki seçimi `--tool <liste>` olarak ekle.
|
|
44
|
+
2. Kur: `node <kit klasörü>/kit/kit.mjs install --type <tip> [--addons ai,tr] --project .` (kit klasörü `.kit.json` → `kit` alanında; alan `local` ise klasör git dışı `.kit.local.json` → `kit`'te, o dosya yoksa proje başka makinede açılmıştır: kullanıcıya kit klasörünü sor ya da `npx -y tillerhand@<.kit.json → version>` kullan; alan `npx:tillerhand@<sürüm>` ise `npx -y tillerhand@<sürüm> install ...`; sürüm tam olarak `1.2.3` biçiminde ve `.kit.json` → `version` ile aynı değilse dur ve sor). Araç `init`'te seçilmediyse Adım 0'daki seçimi `--tool <liste>` olarak ekle.
|
|
45
45
|
3. **`.kit-new` dosyaları:** Her biri için (`CLAUDE.md` ve `AGENTS.md` hariç, onlar Adım 4'te) farkı özetle ve karar olarak sor: kitinkini al / projeninkini koru / birleştir. Örnekler: `.env.example` genelde birleştirilir; `ci.yml` için mevcut CI'ın yaptıklarını kitinkiyle karşılaştır. Sonra `.kit-new` dosyasını sil.
|
|
46
46
|
|
|
47
47
|
## Adım 3: Belgeleri koddan çıkar
|
|
@@ -5,7 +5,7 @@ argument-hint: [boş | --addons ai,tr | --tool claude,codex,antigravity]
|
|
|
5
5
|
|
|
6
6
|
Ek argüman: $ARGUMENTS
|
|
7
7
|
|
|
8
|
-
1. `.kit.json`'u oku: mevcut sürüm, `
|
|
8
|
+
1. `.kit.json`'u oku: mevcut sürüm, `source` (kit repo adresi), tip, ekler.
|
|
9
9
|
2. Commit edilmemiş değişiklik varsa dur ve önce commit etmeyi öner (güncelleme dosya yazar).
|
|
10
10
|
3. Kiti geçici bir klasöre klonla ve güncellemeyi çalıştır:
|
|
11
11
|
|
|
@@ -28,7 +28,7 @@ Amaç: Bu projede öğrendiklerini kaybetmemek ve kiti (bundan sonraki tüm proj
|
|
|
28
28
|
- Kural ekleme > kural değiştirme > kural silme sırasıyla tercih et; kiti şişirme. Aynı amaçlı mevcut kural varsa onu güçlendir. Metni `mattpocock-skills:writing-for-agents` ilkeleriyle yaz.
|
|
29
29
|
- Önerileri **çoklu seçimle** onaylat.
|
|
30
30
|
6. Onaylananları kite uygula:
|
|
31
|
-
1. `.kit.json` → `
|
|
31
|
+
1. `.kit.json` → `source` reposunu geçici klasöre klonla.
|
|
32
32
|
2. `retro/<proje>-<tarih>` dalı aç.
|
|
33
33
|
3. Değişiklikleri yap, `kit/CHANGELOG.md` → "[Yayınlanmamış]" bölümüne ekle.
|
|
34
34
|
4. `node --test "kit/tests/*.test.mjs"` çalıştır, commit at.
|
|
@@ -40,7 +40,7 @@ Bu bir **9 adımlı sihirbaz** (0-9). Kullanıcı hiçbir şeyi bilmiyormuş gib
|
|
|
40
40
|
- **Kapalı (Önerilen):** Projenin hafızası `AGENTS.md`, `progress.md` ve karar günlüğünde; görünür ve git'te. Tekrarlayan hatalar `/fix-bug` ile "Öğrenilen kurallar"a önerilir. `.claude/settings.json`'a `"autoMemoryEnabled": false` ekle (dosyayı birleştir).
|
|
41
41
|
- **Açık:** Tercihlerin oturumlar arasında kendiliğinden hatırlanır; notlar `AGENTS.md` ile çelişebilir. Ayara dokunma.
|
|
42
42
|
Seçimi `**Profil:**` satırına ekle (örn. `hafıza: kapalı`). Kaynak: code.claude.com/docs/en/memory (2026-10-25).
|
|
43
|
-
1. Ortamı kontrol et ve tek satırla raporla: `node --version`, `git --version` ve kitin yeri. İki kurulum yolu var: kökte `kit/kit.mjs` (template yolu) ya da `.kit.json` → `kit` alanındaki klasör (`init` ile kurulmuş, `type` boş). `kit` alanı `npx:tillerhand@<sürüm>` ise kit npm paketinden kurulmuştur. Klasörde zaten uygulama kodu varsa (`package.json`, `pyproject.toml`, `src/` vb.) dur ve `/adopt` öner.
|
|
43
|
+
1. Ortamı kontrol et ve tek satırla raporla: `node --version`, `git --version` ve kitin yeri. İki kurulum yolu var: kökte `kit/kit.mjs` (template yolu) ya da `.kit.json` → `kit` alanındaki klasör (`init` ile kurulmuş, `type` boş). `kit` alanı `npx:tillerhand@<sürüm>` ise kit npm paketinden kurulmuştur. `local` ise klasörün bu makinedeki yolu git dışı `.kit.local.json` → `kit`'tedir; o dosya yoksa kullanıcıya kit klasörünü sor ya da `npx -y tillerhand@<.kit.json → version>` kullan. Klasörde zaten uygulama kodu varsa (`package.json`, `pyproject.toml`, `src/` vb.) dur ve `/adopt` öner.
|
|
44
44
|
2. `docs/workflow/skills.md`'deki plugin'lerin skill'leri senin skill listende var mı bak. LSP eklentisi dil sunucusu ister: web ve mobil için `npm i -g typescript-language-server typescript`, backend için `npm i -g pyright` (global kurulum; kullanıcı onayıyla). **Eklentiler:** Proje ayarı eklentileri açar ama indirmez; kurulmamış olanlar yükleme hatası verir ve skill'leri gelmez. Kullanıcıya listeyi göster ve sor: "Proje ayarındaki eklentiler kurulsun mu?" Önce `node .claude/hooks/plugins-sync.mjs` ile eksikleri listele; onay gelirse `node .claude/hooks/plugins-sync.mjs --install` çalıştır. Betik eksikleri proje kapsamında kurar, `false` olanları (paket eklentileri: tasarım, güvenlik, yayın, video) kurup kapatır. Kullanıcıya tek cümleyle söyle: "Paketler kapalı gelir, ilgili komut gerektiğinde açmayı sorar; durum için `/tools`." Sonra kullanıcıdan `/reload-plugins` çalıştırmasını iste. claude CLI yoksa eksik eklentilerin `/plugin install x@y` komutlarını ver ve "Kurup devam edelim mi, eksik skill olmadan mı?" diye sor.
|
|
45
45
|
3. `caveman:caveman` skill'ini yükle (rapor dili).
|
|
46
46
|
4. **Limit:** Limiti oku (`docs/workflow/usage-limits.md` §1) ve raporla. Seçilen derinliğin tahmini maliyetini kalan limitle karşılaştır; adımlar arasında durup sonra devam edilebileceğini söyle. Seviye sarı veya kırmızıysa bunu tek satırla söyle; durdurma.
|
|
@@ -88,7 +88,7 @@ Kullanıcıya ne yapılacağını tek cümleyle söyle, sonra çalıştır:
|
|
|
88
88
|
```bash
|
|
89
89
|
# template yolu (kökte kit/ var): kit/ kurulumdan sonra silinir
|
|
90
90
|
node kit/kit.mjs install --type <web-saas|mobile|backend> [--addons ai,tr] [--tool claude,codex,antigravity]
|
|
91
|
-
# init yolu (.kit.json → kit): kit klasörüne dokunulmaz; araç init'te seçildiyse --tool gerekmez
|
|
91
|
+
# init yolu (.kit.json → kit; "local" ise .kit.local.json → kit, o dosya yoksa kullanıcıya sor): kit klasörüne dokunulmaz; araç init'te seçildiyse --tool gerekmez
|
|
92
92
|
node <kit>/kit/kit.mjs install --type <web-saas|mobile|backend> [--addons ai,tr] --project .
|
|
93
93
|
# npm yolu (.kit.json → kit = npx:tillerhand@<sürüm>): aynı sürümle. Sürüm tam olarak 1.2.3 biçiminde ve .kit.json → version ile aynı değilse dur, kullanıcıya sor
|
|
94
94
|
npx -y tillerhand@<sürüm> install --type <web-saas|mobile|backend> [--addons ai,tr] --project .
|
package/.claude/hooks/gate.mjs
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
// The result goes to .claude/state/gate.json with the same change signature as the commit gate; the commit gate stops
|
|
8
8
|
// the commit on a red or stale result. A green check's output is not written, the last 30 lines of a red one are.
|
|
9
9
|
// If no check passed (commands empty, no Semgrep) the result is EMPTY: the commit gate stays closed.
|
|
10
|
+
// "Mutlak yol": an added line with this machine's project or home path is red; a generic C:\Users\<name>, /home/<name> is a note.
|
|
10
11
|
// node .claude/hooks/gate.mjs --approve saves the commands with user approval. A new or changed command does not run unapproved:
|
|
11
12
|
// an untrusted repo's AGENTS.md must not run code through the gate. The approval lives in the user folder (~/.vibe-kit/).
|
|
12
13
|
import fs from 'node:fs';
|
|
@@ -95,6 +96,55 @@ function semgrep(root, files) {
|
|
|
95
96
|
return { name, status: 'failed', sec, output: tail(`${r.error ? `${r.error.message}\n` : ''}${r.stdout ?? ''}${r.stderr ?? ''}`) };
|
|
96
97
|
}
|
|
97
98
|
|
|
99
|
+
// A path that only exists on this machine in a changed line breaks the code, tests and docs on every other machine.
|
|
100
|
+
// Red: this project's folder or the home folder (at least two levels, so /app or /root alone is not matched; a path
|
|
101
|
+
// boundary after it; any slash style, JSON-escaped too; case-insensitive only on Windows).
|
|
102
|
+
// Note only: a generic C:\Users\<name>, /home/<name>/, /Users/<name>/ (a container path like /home/node/app or a route
|
|
103
|
+
// is not a machine path, so it never blocks).
|
|
104
|
+
// "kit:yol-izinli" on the line or the line above allows a deliberate one (Dockerfile and JSON take no inline comment).
|
|
105
|
+
// Only added lines of tracked files are read (an old path elsewhere in the file is not this change's); a new file is
|
|
106
|
+
// read whole. Paths are read from the git top level, so a project in a monorepo subfolder is checked too.
|
|
107
|
+
const ESCAPE = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
108
|
+
export function absPathCheck(root, files) {
|
|
109
|
+
const name = 'Mutlak yol';
|
|
110
|
+
const git = (...a) => spawnSync('git', a, { cwd: root, encoding: 'utf8', maxBuffer: BUFFER });
|
|
111
|
+
const top = git('rev-parse', '--show-toplevel').stdout?.trim() || root;
|
|
112
|
+
const variants = (p) => { const f = p.replace(/\\/g, '/').replace(/\/+$/, ''); return [f, f.replace(/\//g, '\\'), f.replace(/\//g, '\\\\')]; };
|
|
113
|
+
const deep = (p) => p.replace(/\\/g, '/').replace(/^[A-Za-z]:/, '').split('/').filter(Boolean).length >= 2;
|
|
114
|
+
const own = [...new Set([root, top, os.homedir()].filter((p) => p && deep(p)).flatMap(variants))].map(ESCAPE);
|
|
115
|
+
const mine = own.length ? new RegExp(`(?:${own.join('|')})(?=[\\\\/'"\`\\s,;:)\\]}]|$)`, process.platform === 'win32' ? 'i' : '') : null;
|
|
116
|
+
const generic = /\b[A-Za-z]:(?:\\\\|\\|\/)Users(?:\\\\|\\|\/)[^\\/\s'"<>:]+|(?<![\w.-])\/(?:Users|home)\/[^/\s'"<>:]+\//;
|
|
117
|
+
// Added line numbers per file from one diff against HEAD (staged and unstaged); a file not in it is new: read whole
|
|
118
|
+
const added = new Map();
|
|
119
|
+
let file = null;
|
|
120
|
+
for (const l of (git('diff', 'HEAD', '-U0', '--no-color', '--no-renames', '--no-ext-diff').stdout ?? '').split('\n')) {
|
|
121
|
+
const f = l.match(/^\+\+\+ b\/(.+)$/);
|
|
122
|
+
if (f) { file = f[1]; added.set(file, new Set()); continue; }
|
|
123
|
+
const h = file && l.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/);
|
|
124
|
+
if (h) for (let n = +h[1]; n < +h[1] + +(h[2] ?? 1); n++) added.get(file).add(n);
|
|
125
|
+
}
|
|
126
|
+
const red = [], notes = [];
|
|
127
|
+
for (const f of files) {
|
|
128
|
+
if (/^\.claude\/state\/|(^|\/)\.kit\.local\.json$/.test(f)) continue;
|
|
129
|
+
let lines;
|
|
130
|
+
try {
|
|
131
|
+
const b = fs.readFileSync(path.join(top, f));
|
|
132
|
+
if (b.length > 2e6 || b.subarray(0, 8000).includes(0)) continue;
|
|
133
|
+
lines = b.toString('utf8').split(/\r?\n/);
|
|
134
|
+
} catch { continue; }
|
|
135
|
+
lines.forEach((l, i) => {
|
|
136
|
+
if (added.has(f) && !added.get(f).has(i + 1)) return;
|
|
137
|
+
if (l.includes('kit:yol-izinli') || lines[i - 1]?.includes('kit:yol-izinli')) return;
|
|
138
|
+
const at = `${f}:${i + 1}: ${l.trim().slice(0, 120)}`;
|
|
139
|
+
if (mine?.test(l)) red.push(at); else if (generic.test(l)) notes.push(at);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
const list = (a) => [...a.slice(0, 15), a.length > 15 ? `… ve ${a.length - 15} satır daha` : ''].filter(Boolean).join('\n');
|
|
143
|
+
if (red.length) return { name, status: 'failed', note: 'bu makineye özel yol; import.meta.url, __dirname, path.join(kök, …), os.tmpdir() kullan. Bilinçliyse satıra ya da üstüne kit:yol-izinli yaz',
|
|
144
|
+
output: list(red) };
|
|
145
|
+
return { name, status: 'passed', ...(notes.length && { note: `${notes.length} satırda kullanıcı klasörüne benzeyen yol var; makineye özelse düzelt (engellemez)`, output: list(notes) }) };
|
|
146
|
+
}
|
|
147
|
+
|
|
98
148
|
export const approvalNeeded = (list) => `komut onayı gerekli\nAGENTS.md → Komutlar yeni veya değişmiş; bu komutlar onaysız çalışmaz:\n${commandList(list)}\n` +
|
|
99
149
|
'Komutları kullanıcıya göster ve sor. Onaylarsa: node .claude/hooks/gate.mjs --approve, sonra komutu tekrar çalıştır.';
|
|
100
150
|
|
|
@@ -128,6 +178,7 @@ export function runGate(root) {
|
|
|
128
178
|
const empty = !checks.some((k) => k.status === 'passed');
|
|
129
179
|
const spec = specCheck(root, start); // after the test command, which may have refreshed the JUnit report; it does not fill an empty gate
|
|
130
180
|
if (spec) checks.push(spec);
|
|
181
|
+
checks.push(absPathCheck(root, files)); // after "empty": it does not fill a gate with no lint/test either
|
|
131
182
|
const passed = !empty && checks.every((k) => k.status !== 'failed');
|
|
132
183
|
const file = path.join(root, '.claude', 'state', 'gate.json');
|
|
133
184
|
fs.mkdirSync(path.dirname(file), { recursive: true });
|
package/AGENTS.md
CHANGED
|
@@ -81,6 +81,7 @@ build: [ ]
|
|
|
81
81
|
- Onay almadan (soru modundan bağımsız): veri silme/sıfırlama, `git push --force`, `git reset --hard`, toplu dosya silme, prod deploy, para harcatan işlem.
|
|
82
82
|
- Testi geçirmek için testi silme veya zayıflatma (test koruması hook'u sorar). Var olmayan API veya paket uydurma.
|
|
83
83
|
- Hook'ları (sır engeli, commit kapısı) atlatmaya çalışma. Kullanıcı adına karar verip sonradan bildirme.
|
|
84
|
+
- Koda, teste veya belgeye bu makineye özel mutlak yol yazma (`C:\Users\<ad>\…`, `/home/<ad>/…`, proje klasörünün tam yolu). Yolu proje kökünden, betiğin konumundan veya geçici klasörden türet; kapı yakalar. Bilinçli bir örnekse satıra `kit:yol-izinli` yaz.
|
|
84
85
|
|
|
85
86
|
## Git
|
|
86
87
|
|
package/README.en.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
</p>
|
|
7
7
|
|
|
8
8
|
<p align="center">
|
|
9
|
-
<a href="kit/CHANGELOG.md"><img alt="Version" src="https://img.shields.io/badge/version-3.
|
|
9
|
+
<a href="kit/CHANGELOG.md"><img alt="Version" src="https://img.shields.io/badge/version-3.29.0-2a78d6?style=flat-square"></a>
|
|
10
10
|
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-2a78d6?style=flat-square"></a>
|
|
11
11
|
<img alt="Claude Code" src="https://img.shields.io/badge/Claude%20Code-ready-d97757?style=flat-square">
|
|
12
12
|
<img alt="Also Codex and Antigravity" src="https://img.shields.io/badge/also-Codex%20%C2%B7%20Antigravity-5b6577?style=flat-square">
|
|
@@ -201,7 +201,7 @@ A new file outside the map is asked about, clutter like `*.bak` and `*-old.*` is
|
|
|
201
201
|
| Package gate | Blocks packages that don't exist (on install and on `npx`, `uvx` runs); asks about very new ones or lookalikes of popular ones |
|
|
202
202
|
| Structure guard | Asks about files outside the map, blocks clutter files |
|
|
203
203
|
| Test guard | Asks before a test is deleted, skipped or weakened |
|
|
204
|
-
| Deterministic gate | No commit until lint, type check, tests and Semgrep have run |
|
|
204
|
+
| Deterministic gate | No commit until lint, type check, tests and Semgrep have run; catches machine-specific paths written into code |
|
|
205
205
|
| Commit gate | No commit without a board review and a green gate |
|
|
206
206
|
| Edit lock | With `/freeze <folder>` on, the AI writes only inside that folder |
|
|
207
207
|
| Scope shield | Asks before writing to a file outside the approved plan |
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
</p>
|
|
7
7
|
|
|
8
8
|
<p align="center">
|
|
9
|
-
<a href="kit/CHANGELOG.md"><img alt="Sürüm" src="https://img.shields.io/badge/s%C3%BCr%C3%BCm-3.
|
|
9
|
+
<a href="kit/CHANGELOG.md"><img alt="Sürüm" src="https://img.shields.io/badge/s%C3%BCr%C3%BCm-3.29.0-2a78d6?style=flat-square"></a>
|
|
10
10
|
<a href="LICENSE"><img alt="Lisans: MIT" src="https://img.shields.io/badge/lisans-MIT-2a78d6?style=flat-square"></a>
|
|
11
11
|
<img alt="Claude Code" src="https://img.shields.io/badge/Claude%20Code-haz%C4%B1r-d97757?style=flat-square">
|
|
12
12
|
<img alt="Codex ve Antigravity" src="https://img.shields.io/badge/ayr%C4%B1ca-Codex%20%C2%B7%20Antigravity-5b6577?style=flat-square">
|
|
@@ -199,7 +199,7 @@ Harita dışı yeni dosya sorulur, `*.bak` ve `*-old.*` gibi dağınıklık dosy
|
|
|
199
199
|
| Paket kapısı | Var olmayan paketi engeller (kurulumda ve `npx`, `uvx` ile çalıştırmada); çok yeni veya popüler bir pakete benzeyeni sorar |
|
|
200
200
|
| Yapı koruyucu | Harita dışı dosyayı sorar, dağınıklık dosyalarını engeller |
|
|
201
201
|
| Test koruması | Silinen, atlanan veya gevşetilen testi sorar |
|
|
202
|
-
| Deterministik kapı | Lint, tip, test ve Semgrep çalışmadan commit açılmaz |
|
|
202
|
+
| Deterministik kapı | Lint, tip, test ve Semgrep çalışmadan commit açılmaz; koda yazılmış makineye özel yolu yakalar |
|
|
203
203
|
| Commit kapısı | Kurul denetimi ve yeşil kapı olmadan commit atılmaz |
|
|
204
204
|
| Düzenleme kilidi | `/freeze <klasör>` açıkken AI sadece o klasöre yazar |
|
|
205
205
|
| Kapsam kalkanı | Onaylı planın dışındaki dosyaya yazım sorulur |
|
package/kit/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,20 @@
|
|
|
3
3
|
Kit sürümü `kit/VERSION` dosyasında. Bir projeyi güncellemek: projede `/kit-update`.
|
|
4
4
|
"Elle uyarla" notu olan maddeler projeye ait dosyalardadır; güncelleme bunlara dokunmaz.
|
|
5
5
|
|
|
6
|
+
## [3.29.0] - 2026-10-26
|
|
7
|
+
|
|
8
|
+
### Yeni
|
|
9
|
+
- **Deterministik kapıda "Mutlak yol" kontrolü.** Eklenen bir satırda bu makinenin proje klasörünün ya da ev klasörünün tam yolu varsa kapı kırmızı olur; yol düz, ters bölü ya da kaçışlı yazılmış olabilir. Böyle bir yol başka makinede çalışmaz. Kapı satırları listeler ve yolun nasıl türetileceğini söyler.
|
|
10
|
+
- `C:\Users\<ad>`, `/home/<ad>/` gibi genel kullanıcı klasörü kalıpları yalnız not olarak listelenir, commit'i engellemez. `/home/node/app` gibi konteyner yolları ve `/users/42` gibi route'lar bu yüzden sorun çıkarmaz.
|
|
11
|
+
- Yalnız eklenen satırlar taranır, yeni dosyalar baştan sona taranır. Git'e girmeyen dosyalara bakılmaz.
|
|
12
|
+
- Bilinçli bir örnek (belgede örnek yol, test girdisi) satıra ya da bir üst satıra `kit:yol-izinli` yazarak geçer. Üst satır seçeneği Dockerfile ve JSON gibi satır içi yorum alamayan dosyalar içindir.
|
|
13
|
+
- AGENTS.md (Asla) ve üç tipin stack belgesine (Sık yapılan AI hataları) aynı kural eklendi.
|
|
14
|
+
|
|
15
|
+
### Düzeltilen
|
|
16
|
+
- **Kit, projenin dışındaki yerel bir klondan kurulunca kit klasörünün bu makinedeki tam yolu `.kit.json`'a yazılıyordu.** `.kit.json` commit edildiği için projeyi başka makinede açan kişi var olmayan bir yolu görüyordu. Yol artık git dışı `.kit.local.json` dosyasında; `.kit.json` → `kit` alanı `local` yazar. Eski kayıtlar `/kit-update` sırasında kendiliğinden taşınır. Kayıttaki yol bu makinede yoksa (başka makinede yazılmışsa) taşınmaz, yalnız kaldırılır. `/start` ve `/adopt` dosya yoksa kit klasörünü sorar ya da npm paketini kullanır.
|
|
17
|
+
- Rehberin alt bilgisindeki sürüm numarası eskide kalmıştı. Rehberdeki ve README rozetlerindeki sürüm artık testle denetleniyor.
|
|
18
|
+
- Elle uyarla: `docs/architecture/stack.md` projeye ait. Yeni madde "Sık yapılan AI hataları" bölümünde; istersen kendi stack belgene ekle. `.gitignore`'a `.kit.local.json` satırı güncellemede eklenir.
|
|
19
|
+
|
|
6
20
|
## [3.28.6] - 2026-10-26
|
|
7
21
|
|
|
8
22
|
### Düzeltilen
|
package/kit/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.29.0
|
package/kit/guide.html
CHANGED
|
@@ -287,7 +287,7 @@ footer .container { display: flex; flex-wrap: wrap; gap: 16px; justify-content:
|
|
|
287
287
|
<section class="hero">
|
|
288
288
|
<div class="container">
|
|
289
289
|
<div>
|
|
290
|
-
<span class="pill"><b>v3.
|
|
290
|
+
<span class="pill"><b>v3.29.0</b> Claude Code için başlangıç kiti · MIT</span>
|
|
291
291
|
<h1>Kodu AI yazar.<br><em>Dümen sende.</em></h1>
|
|
292
292
|
<p class="sub">TillerHand, Claude Code ile bir ürünü fikirden canlıya ve bakıma kadar götürür. Her önemli kararda AI sana seçenekleri, önerisini ve her seçeneğin bedelini sunar. Bir uzman kurulu işi denetler, korumalar hatayı daha olmadan durdurur.</p>
|
|
293
293
|
<div class="install"><span id="cmd">npx tillerhand init</span><button class="copy" type="button" data-copy="cmd">Kopyala</button></div>
|
|
@@ -764,7 +764,7 @@ node vibe-kit/kit/kit.mjs init
|
|
|
764
764
|
<tr><td>Yapı koruyucu</td><td>Harita dışı yeni dosya sorulur; <code>*.bak</code>, <code>*-old.*</code>, kopya ve <code>temp/</code> gibi dağınıklıklar engellenir</td></tr>
|
|
765
765
|
<tr><td>Yapılandırma onayı</td><td><code>CLAUDE.md</code>, <code>AGENTS.md</code>, <code>.claude/</code>, <code>.codex/</code>, <code>.mcp.json</code> ve iş akışı dosyaları onayın olmadan değişmez</td></tr>
|
|
766
766
|
<tr><td>Test koruması</td><td>Beklenti silmek veya yoruma almak, <code>.skip</code>/<code>.only</code>, gevşek beklenti, test dosyasını silmek veya taşımak ve test ayarında kapsamı daraltmak sorulur; kabukla test dosyasına yazmak da</td></tr>
|
|
767
|
-
<tr><td>Deterministik kapı</td><td><code>gate.mjs --run</code>: lint, tip kontrolü, test ve Semgrep çalışır; çıktı kurula girdi olur, kırmızı kontrol RET sayılır. Spec'teki "değişmemesi gereken" davranışların testi yoksa veya kırmızıysa kapı kırmızıdır. Yeni veya değişen komut önce sana gösterilip onaylatılır</td></tr>
|
|
767
|
+
<tr><td>Deterministik kapı</td><td><code>gate.mjs --run</code>: lint, tip kontrolü, test ve Semgrep çalışır; çıktı kurula girdi olur, kırmızı kontrol RET sayılır. Spec'teki "değişmemesi gereken" davranışların testi yoksa veya kırmızıysa kapı kırmızıdır. Eklenen bir satırda bu makineye özel bir yol (proje klasörünün ya da ev klasörünün tam yolu) varsa da kırmızıdır. Yeni veya değişen komut önce sana gösterilip onaylatılır</td></tr>
|
|
768
768
|
<tr><td>Commit kapısı</td><td>Kurul denetimi ve aynı değişiklikler için yeşil kapı olmadan commit atılmaz; denetimi atlamak (<code>--skip</code>) her seferinde sorulur</td></tr>
|
|
769
769
|
<tr><td>Düzenleme kilidi</td><td><code>/freeze <klasör></code> açıkken AI sadece o klasöre yazar; kabukla dışarı yazmak sorulur, sembolik bağdan kaçılamaz</td></tr>
|
|
770
770
|
<tr><td>Kapsam kalkanı</td><td><code>/plan-task</code> onayından sonra planın dosya listesi kaydedilir; listede olmayan mevcut dosyaya yazım sorulur. Kalkanı açmak ve kapatmak da sorulur</td></tr>
|
|
@@ -1053,7 +1053,7 @@ Sıradaki: G-013 şifre sıfırlama · bekleyen karar: e-posta servisi</pre>
|
|
|
1053
1053
|
<footer>
|
|
1054
1054
|
<div class="container">
|
|
1055
1055
|
<a class="brand" href="#top" style="font-size:16px"><svg class="mark" style="width:22px;height:22px"><use href="#mark"/></svg>TillerHand</a>
|
|
1056
|
-
<span>Sürüm 3.
|
|
1056
|
+
<span>Sürüm 3.29.0 · <a href="https://github.com/burakdogrul/TillerHand">GitHub</a> · <a href="https://github.com/burakdogrul/TillerHand/blob/main/LICENSE">MIT lisansı</a> · KVKK bölümü kontrol listesidir, hukuki görüş değildir.</span>
|
|
1057
1057
|
</div>
|
|
1058
1058
|
</footer>
|
|
1059
1059
|
|
package/kit/kit.mjs
CHANGED
|
@@ -31,7 +31,7 @@ const ADDONS = fs.readdirSync(path.join(TEMPLATES, 'addons'));
|
|
|
31
31
|
const TOOLS = ['claude', 'codex', 'antigravity'];
|
|
32
32
|
// Root entries that are not part of the common layer (the kit itself, generated and temporary files)
|
|
33
33
|
// CLAUDE.local.md is personal (in .gitignore); it must not be carried into a project installed from a local folder
|
|
34
|
-
const COMMON_EXCLUDE = new Set(['.git', 'kit', 'node_modules', '.kit.json', 'README.md', 'dashboard.html', '.previews', 'sandbox', '.calisma', '.impeccable', 'CLAUDE.local.md', 'LICENSE', 'README.en.md', 'package.json']);
|
|
34
|
+
const COMMON_EXCLUDE = new Set(['.git', 'kit', 'node_modules', '.kit.json', '.kit.local.json', 'README.md', 'dashboard.html', '.previews', 'sandbox', '.calisma', '.impeccable', 'CLAUDE.local.md', 'LICENSE', 'README.en.md', 'package.json']);
|
|
35
35
|
// Files that only make sense in the kit repo and are not carried into projects
|
|
36
36
|
const KIT_ONLY = ['.github/workflows/kit-tests.yml', '.github/workflows/npm-publish.yml'];
|
|
37
37
|
// Run from the npm package (npx tillerhand): the kit lives in the npx cache, which can be cleared, so the record names
|
|
@@ -202,6 +202,19 @@ function writeRecord(projectDir, data) {
|
|
|
202
202
|
fs.writeFileSync(path.join(projectDir, '.kit.json'), JSON.stringify(data, null, 2) + '\n');
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
// A local kit clone outside the project is a folder on this machine only: its path goes to the git-ignored
|
|
206
|
+
// .kit.local.json and .kit.json says "local", so a clone of the project on another machine never points at this one.
|
|
207
|
+
// Returns the value for .kit.json → kit; an old record with an absolute path is moved the same way on install/update.
|
|
208
|
+
// A path written on another OS (D:\Kit read on Linux) counts too; one that does not exist here is not copied into
|
|
209
|
+
// .kit.local.json: /start and /adopt then ask for the kit folder instead of using another machine's path.
|
|
210
|
+
export function portableKit(projectDir, kit) {
|
|
211
|
+
if (typeof kit !== 'string' || !(path.win32.isAbsolute(kit) || path.posix.isAbsolute(kit))) return kit;
|
|
212
|
+
if (!fs.existsSync(kit)) return 'local';
|
|
213
|
+
fs.writeFileSync(path.join(projectDir, '.kit.local.json'), JSON.stringify({ kit }, null, 2) + '\n');
|
|
214
|
+
appendLine(path.join(projectDir, '.gitignore'), '.kit.local.json');
|
|
215
|
+
return 'local';
|
|
216
|
+
}
|
|
217
|
+
|
|
205
218
|
function validateTools(tools) {
|
|
206
219
|
for (const a of tools) if (!TOOLS.includes(a)) throw new Error(`Geçersiz araç: ${a}. Seçenekler: ${TOOLS.join(', ')}`);
|
|
207
220
|
return tools.length ? tools : ['claude'];
|
|
@@ -319,7 +332,7 @@ function init({ project, tool }) {
|
|
|
319
332
|
installTools(projectDir, tools, files, conflicts);
|
|
320
333
|
const today = new Date().toISOString().slice(0, 10);
|
|
321
334
|
// type: null = kit installed, no type chosen yet (/start step 3 or /adopt)
|
|
322
|
-
writeRecord(projectDir, { version: VERSION, source: SOURCE, kit: VIA_NPX ? `npx:tillerhand@${VERSION}` : inside ? kitRel : ROOT, type: null, addons: [], tool: tool.length ? tools : null, created: today, updated: today, files });
|
|
335
|
+
writeRecord(projectDir, { version: VERSION, source: SOURCE, kit: VIA_NPX ? `npx:tillerhand@${VERSION}` : inside ? kitRel : portableKit(projectDir, ROOT), type: null, addons: [], tool: tool.length ? tools : null, created: today, updated: today, files });
|
|
323
336
|
|
|
324
337
|
console.log(`Kit ${VERSION} kuruldu: ${projectDir} · araç: ${tool.length ? tools.join(', ') : 'seçilmedi (Claude Code dosyaları kuruldu; /start ve /adopt sorar, Codex/Antigravity için --tool)'}`);
|
|
325
338
|
console.log(`Kit klasörü: ${VIA_NPX ? `npm paketi tillerhand@${VERSION}` : inside ? `${kitRel} (.gitignore'a eklendi)` : ROOT} · git deposu: ${git}`);
|
|
@@ -347,7 +360,7 @@ function installIntoProject(projectDir, type, addons, tool) {
|
|
|
347
360
|
for (const p of patches) applyPatch(projectDir, p);
|
|
348
361
|
const tools = tool.length ? validateTools(tool) : (j.tool ?? ['claude']);
|
|
349
362
|
installTools(projectDir, tools, files, conflicts);
|
|
350
|
-
writeRecord(projectDir, { ...j, version: VERSION, type, addons, tool: tool.length ? tools : (j.tool ?? null), updated: new Date().toISOString().slice(0, 10), files });
|
|
363
|
+
writeRecord(projectDir, { ...j, kit: portableKit(projectDir, j.kit), version: VERSION, type, addons, tool: tool.length ? tools : (j.tool ?? null), updated: new Date().toISOString().slice(0, 10), files });
|
|
351
364
|
console.log(`Kuruldu: ${type}${addons.length ? ' + ' + addons.join(', ') : ''} (kit ${VERSION}) · ${projectDir}`);
|
|
352
365
|
conflictReport(conflicts);
|
|
353
366
|
}
|
|
@@ -442,7 +455,11 @@ function update({ project, addons: newAddons, tool }) {
|
|
|
442
455
|
const tools = tool.length ? validateTools(tool) : (j.tool ?? ['claude']);
|
|
443
456
|
installTools(project, tools, record, report.conflicts);
|
|
444
457
|
|
|
445
|
-
|
|
458
|
+
const kit = portableKit(project, j.kit);
|
|
459
|
+
if (kit !== j.kit) console.log(fs.existsSync(path.join(project, '.kit.local.json'))
|
|
460
|
+
? 'Kit klasörünün bu makinedeki yolu .kit.json\'dan .kit.local.json\'a taşındı (git dışı).'
|
|
461
|
+
: '.kit.json\'daki kit klasörü yolu bu makinede yok (başka makinede yazılmış); kaldırıldı. /start ve /adopt kit klasörünü sorar.');
|
|
462
|
+
writeRecord(project, { ...j, kit, version: VERSION, addons: allAddons, tool: tool.length ? tools : (j.tool ?? null), updated: new Date().toISOString().slice(0, 10), files: record });
|
|
446
463
|
|
|
447
464
|
console.log(`Kit ${j.version} -> ${VERSION}`);
|
|
448
465
|
const printList = (title, list) => list.length && console.log(`${title} (${list.length}):\n ${list.join('\n ')}`);
|
package/kit/project/gitignore
CHANGED
|
@@ -122,6 +122,7 @@ uv run pytest --junitxml=test-results/junit.xml
|
|
|
122
122
|
|
|
123
123
|
## Sık yapılan AI hataları (bunlara dikkat)
|
|
124
124
|
|
|
125
|
+
- Koda, teste veya ayara bu makineye özel mutlak yol yazmak (`C:\Users\<ad>\…`, `/home/<ad>/…`, proje klasörünün tam yolu): başka makinede çalışmaz. Yolu `Path(__file__).parent`, ayardan gelen kök veya testte `tmp_path` ile türet. Deterministik kapı bunu yakalar.
|
|
125
126
|
- Pydantic v1 sözdizimini (`class Config`, `.dict()`) v2 ile karıştırmak.
|
|
126
127
|
- Dış API çağrısında timeout koymamak, hatayı yutmak (`except: pass`).
|
|
127
128
|
- CORS'u `allow_origins=["*"]` ile kimlik bilgisiyle birlikte açmak.
|
|
@@ -128,6 +128,7 @@ maestro test .maestro/ --format junit --output test-results/junit-e2e.xml
|
|
|
128
128
|
|
|
129
129
|
## Sık yapılan AI hataları (bunlara dikkat)
|
|
130
130
|
|
|
131
|
+
- Koda, teste veya ayara bu makineye özel mutlak yol yazmak (`C:\Users\<ad>\…`, `/home/<ad>/…`, proje klasörünün tam yolu): başka makinede çalışmaz. Yolu `import.meta.url` / `__dirname`, `path.join(process.cwd(), …)` veya `os.tmpdir()` ile türet. Deterministik kapı bunu yakalar.
|
|
131
132
|
- Web'e özel API veya paket kullanmak (DOM, `window`, sadece web çalışan kütüphaneler).
|
|
132
133
|
- `npm install` ile SDK ile uyumsuz sürüm kurmak.
|
|
133
134
|
- Token'ı AsyncStorage'a yazmak.
|
|
@@ -134,6 +134,7 @@ npx vitest run --reporter=default --reporter=junit --outputFile.junit=test-resul
|
|
|
134
134
|
|
|
135
135
|
## Sık yapılan AI hataları (bunlara dikkat)
|
|
136
136
|
|
|
137
|
+
- Koda, teste veya ayara bu makineye özel mutlak yol yazmak (`C:\Users\<ad>\…`, `/home/<ad>/…`, proje klasörünün tam yolu): başka makinede çalışmaz. Yolu `import.meta.url` / `__dirname`, `path.join(process.cwd(), …)` veya `os.tmpdir()` ile türet. Deterministik kapı bunu yakalar.
|
|
137
138
|
- Client component içinde Supabase admin istemcisi veya sır kullanmak.
|
|
138
139
|
- Sayfayı middleware ile koruyup server action'ı korumasız bırakmak.
|
|
139
140
|
- RLS'i "çalışmıyor" diye kapatmak.
|
package/package.json
CHANGED