tillerhand 3.48.1 → 3.49.1
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/agents/board-chair.md +1 -1
- package/.claude/agents/security-auditor.md +1 -1
- package/.claude/agents/test-writer.md +1 -1
- package/.claude/board/board-product.md +1 -1
- package/.claude/board/council.md +1 -1
- package/.claude/board/rules.md +6 -6
- package/.claude/commands/adopt.md +3 -3
- package/.claude/commands/ask-mode.md +4 -4
- package/.claude/commands/board.md +1 -1
- package/.claude/commands/build.md +1 -1
- package/.claude/commands/design.md +4 -4
- package/.claude/commands/findings-business.md +1 -1
- package/.claude/commands/findings-legal.md +1 -1
- package/.claude/commands/findings-perf.md +1 -1
- package/.claude/commands/findings-security.md +2 -2
- package/.claude/commands/findings-tech.md +1 -1
- package/.claude/commands/findings-ux.md +1 -1
- package/.claude/commands/fix-bug.md +2 -2
- package/.claude/commands/handoff.md +2 -2
- package/.claude/commands/kit-update.md +2 -2
- package/.claude/commands/qa.md +1 -1
- package/.claude/commands/release.md +2 -2
- package/.claude/commands/research.md +3 -3
- package/.claude/commands/retro.md +1 -1
- package/.claude/commands/rollback.md +3 -3
- package/.claude/commands/start.md +4 -4
- package/.claude/commands/tools.md +1 -1
- package/.claude/commands/user-feedback.md +1 -1
- package/.claude/findings/lenses/business.md +1 -1
- package/.claude/findings/protocol.md +2 -2
- package/.claude/hooks/budget.mjs +1 -1
- package/.claude/hooks/checkpoint.mjs +2 -2
- package/.claude/hooks/commit-gate.mjs +18 -17
- package/.claude/hooks/council.mjs +37 -52
- package/.claude/hooks/dashboard-data.mjs +34 -42
- package/.claude/hooks/dashboard.mjs +18 -20
- package/.claude/hooks/destructive-guard.mjs +2 -2
- package/.claude/hooks/flow.mjs +1 -1
- package/.claude/hooks/freeze-guard.mjs +2 -2
- package/.claude/hooks/gate.mjs +21 -13
- package/.claude/hooks/labels.mjs +92 -152
- package/.claude/hooks/lang.mjs +25 -9
- package/.claude/hooks/messages.mjs +497 -494
- package/.claude/hooks/notify.mjs +1 -1
- package/.claude/hooks/prefs.mjs +10 -18
- package/.claude/hooks/preview.mjs +1 -1
- package/.claude/hooks/progress.mjs +7 -9
- package/.claude/hooks/qa-report.mjs +1 -3
- package/.claude/hooks/session-start.mjs +2 -3
- package/.claude/hooks/status-read.mjs +5 -5
- package/.claude/hooks/statusline.mjs +4 -4
- package/.claude/hooks/tools.mjs +3 -7
- package/.claude/hooks/usage.mjs +2 -2
- package/.claude/i18n/tr.json +496 -0
- package/.claude/security-patterns.json +1 -1
- package/.claude/skills/logo-design/SKILL.md +2 -2
- package/.claude/skills/motion-video/SKILL.md +1 -1
- package/.claude/skills/source-research/SKILL.md +1 -1
- package/.claude/skills/ui-motion/SKILL.md +1 -1
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +1 -1
- package/README.md +2 -2
- package/README.tr.md +2 -2
- package/docs/architecture/overview.md +1 -1
- package/docs/decisions/log.md +1 -1
- package/docs/legal/privacy-kvkk.md +35 -35
- package/docs/operations/deploy-setup.md +1 -1
- package/docs/operations/feature-flags.md +1 -1
- package/docs/product/glossary.md +3 -3
- package/docs/product/launch.md +1 -1
- package/docs/product/prd.md +2 -2
- package/docs/product/roadmap.md +1 -1
- package/docs/product/specs/_template.md +1 -1
- package/docs/product/unit-economics.md +1 -1
- package/docs/quality/test-plan.md +5 -5
- package/docs/workflow/decision-protocol.md +1 -2
- package/docs/workflow/mcp-catalog.md +1 -1
- package/docs/workflow/skills.md +2 -2
- package/docs/workflow/usage-limits.md +1 -1
- package/kit/CHANGELOG.md +34 -0
- package/kit/VERSION +1 -1
- package/kit/guide.html +56 -56
- package/kit/guide.tr.html +10 -10
- package/kit/kit.mjs +7 -42
- package/kit/templates/addons/ai/.env.example.append +3 -3
- package/kit/templates/addons/tr/docs/legal/turkiye.md +55 -55
- package/kit/templates/addons/tr/types/backend/.env.example.append +2 -2
- package/kit/templates/addons/tr/types/backend/app/shared/payments.py +1 -1
- package/kit/templates/addons/tr/types/backend/tests/security/test_payment_webhook.py +3 -3
- package/kit/templates/addons/tr/types/web-saas/.env.example.append +2 -2
- package/kit/templates/addons/tr/types/web-saas/.github/workflows/payment-webhook.yml +3 -3
- package/kit/templates/addons/tr/types/web-saas/src/lib/payments/webhook-signature.ts +1 -1
- package/kit/templates/addons/tr/types/web-saas/tests/security/payment-webhook.mjs +4 -4
- package/kit/templates/backend/.github/dependabot.yml +1 -1
- package/kit/templates/backend/.github/workflows/live-monitoring.yml +1 -1
- package/kit/templates/backend/docs/architecture/stack.md +3 -3
- package/kit/templates/mobile/.github/dependabot.yml +1 -1
- package/kit/templates/mobile/.github/workflows/ci.yml +2 -2
- package/kit/templates/mobile/docs/architecture/stack.md +4 -4
- package/kit/templates/mobile/docs/architecture/structure.md +1 -1
- package/kit/templates/mobile/docs/design/design-guide.md +1 -1
- package/kit/templates/web-saas/.github/dependabot.yml +1 -1
- package/kit/templates/web-saas/.github/workflows/ci.yml +2 -2
- package/kit/templates/web-saas/.github/workflows/live-monitoring.yml +1 -1
- package/kit/templates/web-saas/docs/architecture/stack.md +4 -4
- package/kit/templates/web-saas/docs/design/design-guide.md +1 -1
- package/kit/tools/antigravity/.agents/hooks.json +5 -5
- package/package.json +1 -1
package/.claude/hooks/lang.mjs
CHANGED
|
@@ -23,14 +23,14 @@ const stateFile = (root) => path.join(root, '.claude', 'state', 'lang.json');
|
|
|
23
23
|
const i18nFile = (root, lang) => path.join(root, '.claude', 'i18n', `${lang}.json`);
|
|
24
24
|
const placeholders = (s) => [...new Set([...s.matchAll(PLACEHOLDER)].map((m) => m[1]))].sort().join(',');
|
|
25
25
|
|
|
26
|
-
// null: not set up and not chosen yet (/start asks).
|
|
26
|
+
// null: not set up and not chosen yet (/start asks). A set-up project without a choice is English.
|
|
27
27
|
export function readLang(root = findRoot()) {
|
|
28
28
|
const kit = readJson(kitFile(root));
|
|
29
29
|
const chosen = validCode(kit?.lang) ?? validCode(readJson(stateFile(root))?.lang);
|
|
30
30
|
if (chosen) return chosen;
|
|
31
31
|
// same rule as status-read kitPending: a broken .kit.json counts as missing
|
|
32
32
|
const notSetUp = kit ? kit.type === null : fs.existsSync(path.join(root, 'kit', 'kit.mjs'));
|
|
33
|
-
return notSetUp ? null : '
|
|
33
|
+
return notSetUp ? null : 'en';
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
export function setLang(root, code) {
|
|
@@ -51,18 +51,34 @@ const translation = (root, lang) => {
|
|
|
51
51
|
return j && typeof j === 'object' && !Array.isArray(j) ? j : {};
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
+
// Per process: the dashboard calls t() hundreds of times; the modification time keeps a rewritten file visible
|
|
55
|
+
const cache = new Map();
|
|
56
|
+
const cachedTranslation = (root, lang) => {
|
|
57
|
+
const file = i18nFile(root, lang);
|
|
58
|
+
let stamp = 0;
|
|
59
|
+
try { stamp = fs.statSync(file).mtimeMs; } catch { /* no file: English */ }
|
|
60
|
+
const hit = cache.get(file);
|
|
61
|
+
if (hit?.stamp === stamp) return hit.own;
|
|
62
|
+
const own = translation(root, lang);
|
|
63
|
+
cache.set(file, { stamp, own });
|
|
64
|
+
return own;
|
|
65
|
+
};
|
|
66
|
+
|
|
54
67
|
export function t(root, key, vars = {}) {
|
|
55
68
|
if (!Object.hasOwn(MESSAGES, key)) return key;
|
|
56
69
|
const lang = readLang(root) ?? 'en';
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
70
|
+
const own = lang === 'en' ? {} : cachedTranslation(root, lang);
|
|
71
|
+
const en = MESSAGES[key].en;
|
|
72
|
+
// A hand-edited text that drops or adds a placeholder could hide what an approval dialog asks: English instead
|
|
73
|
+
const text = Object.hasOwn(own, key) && typeof own[key] === 'string' && placeholders(own[key]) === placeholders(en) ? own[key] : en;
|
|
62
74
|
return text.replace(PLACEHOLDER, (m, name) => Object.hasOwn(vars, name) ? String(vars[name]) : m);
|
|
63
75
|
}
|
|
64
76
|
|
|
65
|
-
|
|
77
|
+
// Date and number locale for a language code (English when the runtime does not know the code)
|
|
78
|
+
export const locale = (lang) => { try { return Intl.DateTimeFormat.supportedLocalesOf(lang ?? 'en')[0] ?? 'en'; } catch { return 'en'; } };
|
|
79
|
+
|
|
80
|
+
// Every language but English reads .claude/i18n/<lang>.json (tr ships with the kit)
|
|
81
|
+
const needsTranslation = (lang) => Boolean(lang) && lang !== 'en';
|
|
66
82
|
|
|
67
83
|
export function missingKeys(root = findRoot()) {
|
|
68
84
|
const lang = readLang(root);
|
|
@@ -73,7 +89,7 @@ export function missingKeys(root = findRoot()) {
|
|
|
73
89
|
|
|
74
90
|
export function writeTranslation(root, obj) {
|
|
75
91
|
const lang = readLang(root);
|
|
76
|
-
if (!needsTranslation(lang)) throw new Error(`No translation file for language ${lang ?? 'none'}:
|
|
92
|
+
if (!needsTranslation(lang)) throw new Error(`No translation file for language ${lang ?? 'none'}: en is built in.`);
|
|
77
93
|
if (!obj || typeof obj !== 'object' || Array.isArray(obj) || Object.getPrototypeOf(obj) !== Object.prototype) throw new Error('Translation must be a JSON object { key: text }.');
|
|
78
94
|
for (const [k, v] of Object.entries(obj)) {
|
|
79
95
|
if (!Object.hasOwn(MESSAGES, k)) throw new Error(`Unknown key: ${k}`);
|