Skip to content

Commit 91b8d87

Browse files
RusDynclaude
andcommitted
Fix code review issues: file perms, key rotate .mcp.json, deactivate match
- atomicWriteJson: write tmp file with mode 0o600 (was world-readable) - key rotate: also update .mcp.json Authorization header (was left stale) - key deactivate: use includes() not startsWith() for key_prefix match (key_prefix is 8 hex chars from the secret, not a prefix of fullKey) - Warn when hooks/ not found in package during init Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2ac00d4 commit 91b8d87

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

cli/src/commands/key.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,26 @@ export async function keyRotateCommand(nameOrId: string) {
347347
}
348348
}
349349

350+
// Update .mcp.json if present
351+
const mcpPath = join(process.cwd(), '.mcp.json');
352+
if (existsSync(mcpPath)) {
353+
try {
354+
const mcpConfig = JSON.parse(readFileSync(mcpPath, 'utf-8'));
355+
if (mcpConfig.mcpServers?.writbase?.headers?.Authorization || mcpConfig.writbase?.headers?.Authorization) {
356+
const entry = mcpConfig.mcpServers?.writbase ?? mcpConfig.writbase;
357+
if (entry?.headers) {
358+
entry.headers.Authorization = `Bearer ${fullKey}`;
359+
const mcpTmpPath = mcpPath + '.tmp';
360+
writeFileSync(mcpTmpPath, JSON.stringify(mcpConfig, null, 2) + '\n', { mode: 0o600 });
361+
renameSync(mcpTmpPath, mcpPath);
362+
success('Updated agent key in .mcp.json');
363+
}
364+
}
365+
} catch {
366+
// Non-critical — skip
367+
}
368+
}
369+
350370
console.log();
351371
warn('Save this new key — it cannot be retrieved later:');
352372
console.log();
@@ -676,7 +696,7 @@ export async function keyDeactivateCommand(nameOrId: string) {
676696
if (existsSync(localSettingsPath)) {
677697
try {
678698
const ls = JSON.parse(readFileSync(localSettingsPath, 'utf-8'));
679-
if (ls.env?.WRITBASE_AGENT_KEY?.startsWith(key.key_prefix)) {
699+
if (ls.env?.WRITBASE_AGENT_KEY?.includes(key.key_prefix)) {
680700
removeLocalEnv('WRITBASE_AGENT_KEY');
681701
warn('Removed deactivated key from .claude/settings.local.json — create a new key for hooks to work');
682702
}

cli/src/lib/claude-code.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { WRITBASE_HOME } from './config.js';
66

77
export function atomicWriteJson(filePath: string, content: string) {
88
const tmpPath = filePath + '.tmp';
9-
writeFileSync(tmpPath, content);
9+
writeFileSync(tmpPath, content, { mode: 0o600 });
1010
renameSync(tmpPath, filePath);
1111
}
1212

@@ -22,8 +22,12 @@ export function installSkills(supabaseUrl?: string) {
2222
const skillsSource = join(packageRoot, 'skills');
2323
cpSync(skillsSource, join(WRITBASE_HOME, 'skills'), { recursive: true });
2424

25-
// Copy hooks from package (if present)
25+
// Copy hooks from package
2626
const hooksSource = join(packageRoot, 'hooks');
27+
if (!existsSync(hooksSource)) {
28+
// eslint-disable-next-line no-console
29+
console.warn('⚠ Hooks not found in package — PostToolUse and SubagentStop hooks will not be registered');
30+
}
2731
if (existsSync(hooksSource)) {
2832
mkdirSync(join(WRITBASE_HOME, 'hooks'), { recursive: true });
2933
cpSync(hooksSource, join(WRITBASE_HOME, 'hooks'), { recursive: true });

0 commit comments

Comments
 (0)