tillerhand 3.49.8 → 3.49.10

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.
@@ -27,6 +27,8 @@ const DESTRUCTIVE = [
27
27
  [/\bgit\s+clean\b(?=[^;]*\s--?[a-z]*f)(?=[^;]*\s-[a-z]*d)/i, 'git clean permanently deletes untracked files'],
28
28
  [/\bredis-cli\b[^;]*\b(flushall|flushdb)\b/i, 'Redis data is being deleted'],
29
29
  [/\bfirebase\s+firestore:delete\b/i, 'Firestore data is being deleted'],
30
+ [/\bheroku\s+pg:reset\b|\bdrop(Database|Collection)\s*\(|\bdeleteMany\s*\(\s*\{\s*\}\s*\)|\bartisan\s+migrate:(fresh|refresh|reset)\b|\btypeorm\b[^;]*\bschema:drop\b|\bknex\b[^;]*\bmigrate:rollback\b[^;]*--all\b|\bprisma\s+db\s+push\b[^;]*--accept-data-loss\b/i, 'Database data is being deleted or reset'],
31
+ [/\b(terraform|tofu|pulumi)\s+destroy\b/i, 'Cloud infrastructure is being destroyed'],
30
32
  ];
31
33
 
32
34
  // Database addresses other than localhost count as prod (or a shared environment)
@@ -45,8 +47,9 @@ const NEEDS_APPROVAL = [
45
47
  // The subcommand can also come after flags: vercel --scope team promote <url>
46
48
  [/\b(vercel|vc)(@[\w.-]+)?\b[^;&|]*\s(promote|rollback)\b/i, 'guard.destructive.promoteRollback'],
47
49
  [UNCLEAR_ENV, 'guard.destructive.unclearEnv'],
48
- [/\b(fly|flyctl)\s+deploy\b|\brailway\s+up\b|\bnetlify\s+deploy\b[^;]*--prod/i, 'guard.destructive.serverDeploy'],
49
- [/\beas(-cli(@[\w.-]+)?)?\s+(submit\b|update:(rollback|republish)\b|update\b(?=[^;\n]*--(branch|channel|environment)(=|\s+)['"]?prod(uction)?\b)|deploy\b(?=[^;\n]*--prod\b))/i, 'guard.destructive.storeSubmit'],
50
+ // A package spelling (npx netlify-cli, firebase-tools, wrangler@3) deploys the same way
51
+ [/\b(fly|flyctl)\s+deploy\b|\brailway\s+up\b|\bnetlify(-cli)?(@[\w.-]+)?\s+deploy\b[^;]*--prod|\bfirebase(-tools)?(@[\w.-]+)?\s+deploy\b|\bwrangler(@[\w.-]+)?\s+(deploy|publish|pages\s+deploy)\b|\bgcloud\s+app\s+deploy\b|\b(serverless|sls)\s+deploy\b|\bcdk\s+deploy\b|\bpulumi\s+up\b|\bamplify\s+(push|publish)\b|\b(terraform|tofu)\s+apply\b|\bexpo\s+publish\b/i, 'guard.destructive.serverDeploy'],
52
+ [/\beas(-cli(@[\w.-]+)?)?\s+(submit\b|build\b(?=[^;\n]*--auto-submit\b)|update:(rollback|republish)\b|update\b(?=[^;\n]*--(branch|channel|environment)(=|\s+)['"]?prod(uction)?\b)|deploy\b(?=[^;\n]*--prod\b))/i, 'guard.destructive.storeSubmit'],
50
53
  [/\bgit\s+push\b[^;]*\b(main|master|production)\b/i, 'guard.destructive.pushMain'],
51
54
  [/\bgit\s+(rebase|filter-branch|filter-repo)\b/i, 'guard.destructive.rewriteHistory'],
52
55
  [/\b(alembic\s+upgrade|prisma\s+migrate\s+deploy|supabase\s+db\s+push)\b/i, 'guard.destructive.migration'],
@@ -304,6 +307,8 @@ const PERMISSION_EQUIVALENT = [
304
307
  ['deny', /\bgit\s+reset\s+[^;&|]*--hard\b/i, 'git reset --hard deletes uncommitted work'],
305
308
  ['deny', /\bgit\s+push\b[^;&|]*\s(--force\S*|-\w*f\w*|\+\S+)(?=\s|$)/i, 'git push --force overwrites the remote history'],
306
309
  ['deny', ENV_ACCESS, 'Access to .env or secrets/ (the AI does not read or write them)'],
310
+ // Claude asks every push through settings.json (Bash(git push:*)); a push to any branch can deploy (Vercel's prod branch)
311
+ ['ask', /\bgit\s+push\b/i, 'guard.destructive.perm.push'],
307
312
  ['ask', /freeze-guard\.mjs['"]?\s+['"]?--off\b/i, 'guard.destructive.perm.freezeOff'],
308
313
  ['ask', /tools\.mjs['"]?\s+['"]?--commands\b/i, 'guard.destructive.perm.toolsCommands'],
309
314
  ['ask', /freeze-guard\.mjs['"]?\s+['"]?--plan-add\b/i, 'guard.destructive.perm.planAdd'],
@@ -400,6 +400,7 @@ export const MESSAGES = {
400
400
  'guard.destructive.envShell': { en: 'The command names a .env file (secrets). The AI does not read or write it; if needed, the user does it. User approval required.' },
401
401
  'guard.destructive.gitOutput': { en: 'git writes its output to a file the command chooses (--output / format-patch -o); it can overwrite a guard, test or settings file. User approval required.' },
402
402
  'guard.destructive.boardShell': { en: 'docs/workflow/board.md (board members, commit review switch) is changed from the shell. Use the file tools; otherwise user approval required.' },
403
+ 'guard.destructive.perm.push': { en: 'Pushing to the remote repository (a pushed branch can deploy)' },
403
404
  'guard.destructive.perm.freezeOff': { en: 'The edit lock is being removed' },
404
405
  'guard.destructive.perm.toolsCommands': { en: 'The shared .claude/settings.json → skillOverrides is changing (command list)' },
405
406
  'guard.destructive.perm.planAdd': { en: 'The approved plan\'s file list is widening (scope shield)' },
@@ -26,9 +26,20 @@ const POPULAR = {
26
26
 
27
27
  // Case-insensitive (the Windows shell is); npm's install aliases (in, ins, isntall, it…) count as install
28
28
  const COMMANDS = [
29
- [/^(npm|pnpm|bun)\s+(i|in|ins|inst|insta|instal|install|isnt|isnta|isntal|isntall|it|add)\b/i, 'npm'], [/^yarn\s+(global\s+)?add\b/i, 'npm'], [/^npx\s+expo\s+install\b/i, 'npm'],
30
- [/^uv\s+(add|pip\s+install)\b/i, 'pypi'], [/^(python3?\s+-m\s+)?pip3?\s+install\b/i, 'pypi'], [/^poetry\s+add\b/i, 'pypi'],
29
+ [/^(npm|pnpm|bun)\s+(i|in|ins|inst|insta|instal|install|isnt|isnta|isntal|isntall|it|add)\b/i, 'npm'], [/^yarn\s+(global\s+)?add\b/i, 'npm'], [/^(npx\s+)?expo\s+install\b/i, 'npm'],
30
+ // create/init <name> downloads and runs create-<name>; deno takes npm:<name> specifiers
31
+ [/^(npm|pnpm|yarn|bun)\s+(create|init)\b/i, 'npm', 'create'], [/^deno\s+(add|install|run|x)\b/i, 'npm', 'deno'],
32
+ [/^uv\s+(add|pip\s+install|tool\s+install)\b/i, 'pypi'], [/^((python[\d.]*|py)(\s+-\d[\d.]*)?\s+-m\s+)?pip[\d.]*(\s+-\S+)*\s+install\b/i, 'pypi'],
33
+ [/^(poetry|pdm)\s+add\b|^(pipenv|pipx)\s+install\b/i, 'pypi'],
31
34
  ];
35
+ // create-vite for vite, @scope/create for @scope, @scope/create-x for @scope/x (npm's own mapping)
36
+ function createName(arg) {
37
+ const n = npmName(arg);
38
+ if (!n) return null;
39
+ if (!n.startsWith('@')) return `create-${n}`;
40
+ const [scope, rest] = n.split('/');
41
+ return rest ? `${scope}/create-${rest}` : `${scope}/create`;
42
+ }
32
43
 
33
44
  // Download-and-run: the first positional is the package (the rest are its arguments), or the values of the package flags.
34
45
  // local: the runner uses a bin the project already has before downloading (npx, npm exec, bunx); pnpm/yarn dlx always download.
@@ -72,6 +83,7 @@ function execArgs(args, eco, positional) {
72
83
  // Also timeout/nice/stdbuf, shell keywords (then, do, else, !) and combined shell flags (bash -lc).
73
84
  const WRAPPER = /^(?:\(|\{|!\s*|[A-Za-z_]\w*=\S*\s+|(?:sudo|env|time|nohup|exec|command|xargs|corepack|call|start|then|do|else|ionice|stdbuf)\s+|timeout\s+(?:-\S+\s+)*\S+\s+|nice\s+(?:-n\s*\S+\s+|-\d+\s+)?|(?:bash|sh|zsh|dash|cmd|pwsh|powershell)(?:\.exe)?\s+(?:-\w*c|\/c|\/k|-Command)\s+["']?)/i;
74
85
  const SUBCOMMAND = /^(install|i|add|exec|x|dlx|tool|pip|run|global)$/;
86
+ const VALUE_FLAG = /^(--prefix|-C|--dir|--cwd|--workspace|--filter|--registry|--cache|--userconfig)$/i;
75
87
  export function normalize(part) {
76
88
  let s = part.trim(), prev;
77
89
  do { prev = s; s = s.replace(WRAPPER, '').trim(); } while (s !== prev);
@@ -81,7 +93,10 @@ export function normalize(part) {
81
93
  const t = s.split(/\s+/);
82
94
  if (/^(npm|pnpm|yarn|bun|uv)$/i.test(t[0])) {
83
95
  let i = 1;
84
- while (i < t.length && t[i].startsWith('-')) i += !t[i].includes('=') && t[i + 1] && !t[i + 1].startsWith('-') && !SUBCOMMAND.test(t[i + 1]) ? 2 : 1;
96
+ // A flag known to take a value always skips it (npm --prefix x i: x is a folder, not the exec subcommand)
97
+ while (i < t.length && t[i].startsWith('-')) i += VALUE_FLAG.test(t[i]) || (!t[i].includes('=') && t[i + 1] && !t[i + 1].startsWith('-') && !SUBCOMMAND.test(t[i + 1])) ? 2 : 1;
98
+ // yarn workspace <name> add x: the workspace name is not the subcommand
99
+ if (/^yarn$/i.test(t[0]) && /^workspace$/i.test(t[i] ?? '')) i += 2;
85
100
  s = [t[0], ...t.slice(i)].join(' ');
86
101
  }
87
102
  return s;
@@ -124,6 +139,15 @@ export function findPackages(command) {
124
139
  }
125
140
  continue;
126
141
  }
142
+ if (match[2] === 'create') {
143
+ const name = createName(args.find((a) => !a.startsWith('-')) ?? '');
144
+ if (name) result.push({ eco, name });
145
+ continue;
146
+ }
147
+ if (match[2] === 'deno') {
148
+ for (const a of args) if (/^npm:/i.test(a)) { const name = npmName(a.slice(4)); if (name) result.push({ eco, name }); }
149
+ continue;
150
+ }
127
151
  for (let i = 0; i < args.length; i++) {
128
152
  const a = args[i];
129
153
  if (a.startsWith('-')) {
@@ -397,6 +397,7 @@
397
397
  "guard.destructive.envShell": "Komut bir .env dosyasını (sırlar) anıyor. AI onu okumaz, yazmaz; gerekirse kullanıcı yapar. Kullanıcı onayı gerekli.",
398
398
  "guard.destructive.gitOutput": "git çıktısını komutun seçtiği bir dosyaya yazıyor (--output / format-patch -o); bir koruma, test ya da ayar dosyasını ezebilir. Kullanıcı onayı gerekli.",
399
399
  "guard.destructive.boardShell": "docs/workflow/board.md (kurul üyeleri, commit incelemesi anahtarı) kabuktan değiştiriliyor. Dosya araçlarını kullan; yoksa kullanıcı onayı gerekli.",
400
+ "guard.destructive.perm.push": "Uzak depoya gönderiliyor (gönderilen dal yayına çıkabilir)",
400
401
  "guard.destructive.perm.freezeOff": "Düzenleme kilidi kaldırılıyor",
401
402
  "guard.destructive.perm.toolsCommands": "Paylaşılan .claude/settings.json → skillOverrides değişiyor (komut listesi)",
402
403
  "guard.destructive.perm.planAdd": "Onaylı planın dosya listesi genişliyor (kapsam kalkanı)",
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="Version" src="https://img.shields.io/badge/version-3.49.8-2a78d6?style=flat-square"></a>
9
+ <a href="kit/CHANGELOG.md"><img alt="Version" src="https://img.shields.io/badge/version-3.49.10-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">
package/README.tr.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.49.8-2a78d6?style=flat-square"></a>
9
+ <a href="kit/CHANGELOG.md"><img alt="Sürüm" src="https://img.shields.io/badge/s%C3%BCr%C3%BCm-3.49.10-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">
package/kit/CHANGELOG.md CHANGED
@@ -3,6 +3,20 @@
3
3
  The kit version is in `kit/VERSION`. To update a project, run `/kit-update` in it.
4
4
  Items with an "Adapt by hand" note concern files owned by the project; the update does not touch them.
5
5
 
6
+ ## [3.49.10] - 2026-10-30
7
+
8
+ ### Security
9
+ - **The package gate checks more install commands:** `npm create <x>` / `npm init <x>` (and the pnpm, yarn, bun versions) check the `create-<x>` package they download and run; `pipx install`, `uv tool install`, `pdm add`, `pipenv install`, a bare `expo install` and Deno `npm:` specifiers are checked too.
10
+ - Flags before the subcommand no longer hide the package: `npm --prefix x i`, `pnpm -C x add`, `yarn --cwd x add`, `yarn workspace web add`, `pip --quiet install`, `py -m pip install`, `python3.12 -m pip install`.
11
+
12
+ ## [3.49.9] - 2026-10-30
13
+
14
+ ### Security
15
+ - **More production deploys ask you:** `firebase deploy`, `wrangler deploy`/`publish`/`pages deploy`, `gcloud app deploy`, `serverless deploy`, `cdk deploy`, `pulumi up`, `amplify push`, `terraform apply`, `expo publish`, `eas build --auto-submit`, and `netlify deploy --prod` through `npx netlify-cli`.
16
+ - **More data deletion is blocked:** `heroku pg:reset`, MongoDB `dropDatabase()`/`dropCollection()`/`deleteMany({})`, Laravel `migrate:fresh`/`refresh`/`reset`, TypeORM `schema:drop`, Knex `migrate:rollback --all`, `prisma db push --accept-data-loss`, and `terraform`/`tofu`/`pulumi destroy`.
17
+ - On Codex and Antigravity every `git push` asks, as it already did in Claude Code: a pushed branch can deploy.
18
+ - The structure guard blocks more clutter names in new projects: `a.old.ts`, `a.bak.ts`, `a.backup.ts`, `a-copy.ts`, `a (1).ts`, `Copy of a.ts`, `old/`, `backup/`, editor swap files (`.swp`, `.rej`, `.sav`) and OS files (`.DS_Store`, `Thumbs.db`).
19
+
6
20
  ## [3.49.8] - 2026-10-30
7
21
 
8
22
  ### Security
package/kit/VERSION CHANGED
@@ -1 +1 @@
1
- 3.49.8
1
+ 3.49.10
package/kit/guide.html CHANGED
@@ -361,7 +361,7 @@ footer .container { display: flex; flex-wrap: wrap; gap: 16px; justify-content:
361
361
  <section class="hero">
362
362
  <div class="container">
363
363
  <div>
364
- <span class="pill"><b>v3.49.8</b> Starter kit for Claude Code · MIT</span>
364
+ <span class="pill"><b>v3.49.10</b> Starter kit for Claude Code · MIT</span>
365
365
  <h1>The AI builds.<br><em>You steer.</em></h1>
366
366
  <p class="sub">TillerHand takes a product from idea to production and maintenance with Claude Code. At every important decision the AI gives you the options, its recommendation and the cost of each option. An expert board reviews the work, and guardrails stop mistakes before they happen.</p>
367
367
  <div class="setup">
@@ -1241,7 +1241,7 @@ Next: G-013 password reset · pending decision: email service</pre>
1241
1241
  <footer>
1242
1242
  <div class="container">
1243
1243
  <a class="brand" href="#top" style="font-size:16px"><svg class="mark" style="width:22px;height:22px"><use href="#mark"/></svg>TillerHand</a>
1244
- <span>Version 3.49.8 · <a href="https://github.com/burakdogrul/TillerHand">GitHub</a> · <a href="https://github.com/burakdogrul/TillerHand/blob/main/LICENSE">MIT license</a> · The KVKK section is a checklist, not legal advice.</span>
1244
+ <span>Version 3.49.10 · <a href="https://github.com/burakdogrul/TillerHand">GitHub</a> · <a href="https://github.com/burakdogrul/TillerHand/blob/main/LICENSE">MIT license</a> · The KVKK section is a checklist, not legal advice.</span>
1245
1245
  </div>
1246
1246
  </footer>
1247
1247
 
package/kit/guide.tr.html CHANGED
@@ -361,7 +361,7 @@ footer .container { display: flex; flex-wrap: wrap; gap: 16px; justify-content:
361
361
  <section class="hero">
362
362
  <div class="container">
363
363
  <div>
364
- <span class="pill"><b>v3.49.8</b> Claude Code için başlangıç kiti · MIT</span>
364
+ <span class="pill"><b>v3.49.10</b> Claude Code için başlangıç kiti · MIT</span>
365
365
  <h1>Kodu AI yazar.<br><em>Dümen sende.</em></h1>
366
366
  <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>
367
367
  <div class="setup">
@@ -1245,7 +1245,7 @@ Sıradaki: G-013 şifre sıfırlama · bekleyen karar: e-posta servisi</pre>
1245
1245
  <footer>
1246
1246
  <div class="container">
1247
1247
  <a class="brand" href="#top" style="font-size:16px"><svg class="mark" style="width:22px;height:22px"><use href="#mark"/></svg>TillerHand</a>
1248
- <span>Sürüm 3.49.8 · <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>
1248
+ <span>Sürüm 3.49.10 · <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>
1249
1249
  </div>
1250
1250
  </footer>
1251
1251
 
@@ -55,7 +55,6 @@
55
55
  "CLAUDE-SECURITY-*/**"
56
56
  ],
57
57
  "deny": [
58
- "**/*.bak",
59
58
  "**/*.orig",
60
59
  "**/*.tmp",
61
60
  "**/*~",
@@ -69,6 +68,25 @@
69
68
  "**/tmp/**",
70
69
  "**/untitled*",
71
70
  "**/test.*",
72
- "**/deneme*"
71
+ "**/deneme*",
72
+ "**/*.bak*",
73
+ "**/*.old",
74
+ "**/*.old.*",
75
+ "**/*_bak.*",
76
+ "**/*.backup.*",
77
+ "**/*-backup.*",
78
+ "**/*_backup.*",
79
+ "**/*-copy.*",
80
+ "**/*-copy?.*",
81
+ "**/*_copy.*",
82
+ "**/* (?).*",
83
+ "**/Copy of *",
84
+ "**/old/**",
85
+ "**/backup/**",
86
+ "**/*.sav",
87
+ "**/*.swp",
88
+ "**/*.rej",
89
+ "**/.DS_Store",
90
+ "**/Thumbs.db"
73
91
  ]
74
92
  }
@@ -66,7 +66,6 @@
66
66
  "CLAUDE-SECURITY-*/**"
67
67
  ],
68
68
  "deny": [
69
- "**/*.bak",
70
69
  "**/*.orig",
71
70
  "**/*.tmp",
72
71
  "**/*~",
@@ -80,6 +79,25 @@
80
79
  "**/tmp/**",
81
80
  "**/untitled*",
82
81
  "**/test.*",
83
- "**/deneme*"
82
+ "**/deneme*",
83
+ "**/*.bak*",
84
+ "**/*.old",
85
+ "**/*.old.*",
86
+ "**/*_bak.*",
87
+ "**/*.backup.*",
88
+ "**/*-backup.*",
89
+ "**/*_backup.*",
90
+ "**/*-copy.*",
91
+ "**/*-copy?.*",
92
+ "**/*_copy.*",
93
+ "**/* (?).*",
94
+ "**/Copy of *",
95
+ "**/old/**",
96
+ "**/backup/**",
97
+ "**/*.sav",
98
+ "**/*.swp",
99
+ "**/*.rej",
100
+ "**/.DS_Store",
101
+ "**/Thumbs.db"
84
102
  ]
85
103
  }
@@ -71,7 +71,6 @@
71
71
  "CLAUDE-SECURITY-*/**"
72
72
  ],
73
73
  "deny": [
74
- "**/*.bak",
75
74
  "**/*.orig",
76
75
  "**/*.tmp",
77
76
  "**/*~",
@@ -85,6 +84,25 @@
85
84
  "**/tmp/**",
86
85
  "**/untitled*",
87
86
  "**/test.*",
88
- "**/deneme*"
87
+ "**/deneme*",
88
+ "**/*.bak*",
89
+ "**/*.old",
90
+ "**/*.old.*",
91
+ "**/*_bak.*",
92
+ "**/*.backup.*",
93
+ "**/*-backup.*",
94
+ "**/*_backup.*",
95
+ "**/*-copy.*",
96
+ "**/*-copy?.*",
97
+ "**/*_copy.*",
98
+ "**/* (?).*",
99
+ "**/Copy of *",
100
+ "**/old/**",
101
+ "**/backup/**",
102
+ "**/*.sav",
103
+ "**/*.swp",
104
+ "**/*.rej",
105
+ "**/.DS_Store",
106
+ "**/Thumbs.db"
89
107
  ]
90
108
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tillerhand",
3
- "version": "3.49.8",
3
+ "version": "3.49.10",
4
4
  "description": "Vibe coding kit for Claude Code, Codex and Antigravity: rules, commands, guards and project templates.",
5
5
  "license": "MIT",
6
6
  "type": "module",