Skip to content

Commit 8a1be72

Browse files
author
1bcMax
committed
chore: rename runcode-* files to franklin-* with legacy migration
- ~/.blockrun/runcode-stats.json → franklin-stats.json (auto-migrate) - ~/.blockrun/runcode-debug.log → franklin-debug.log (auto-migrate) - ~/.blockrun/runcode.pid → franklin.pid (daemon) - User-facing text updated from 'runcode' → 'franklin' in logs/stats/proxy - LaunchAgent plist now writes to franklin-debug.log - Panel server reads franklin-stats.json, falls back to runcode-stats.json
1 parent de5d0ae commit 8a1be72

21 files changed

Lines changed: 233 additions & 91 deletions

File tree

.claude/scheduled_tasks.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"sessionId":"822af36b-a3ff-49d8-b899-331d2bb0b744","pid":76601,"acquiredAt":1776177674939}

dist/agent/commands.js

Lines changed: 130 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ const DIRECT_COMMANDS = {
290290
const hasWallet = fs.existsSync(path.join(BLOCKRUN_DIR, 'wallet.json'))
291291
|| fs.existsSync(path.join(BLOCKRUN_DIR, 'solana-wallet.json'));
292292
checks.push(hasWallet ? '✓ wallet configured' : '⚠ no wallet — run: runcode setup');
293-
checks.push(fs.existsSync(path.join(BLOCKRUN_DIR, 'runcode-config.json')) ? '✓ config file exists' : '⚠ no config — using defaults');
293+
checks.push(fs.existsSync(path.join(BLOCKRUN_DIR, 'franklin-config.json')) || fs.existsSync(path.join(BLOCKRUN_DIR, 'runcode-config.json')) ? '✓ config file exists' : '⚠ no config — using defaults');
294294
// Check MCP
295295
const { listMcpServers } = await import('../mcp/client.js');
296296
const mcpServers = listMcpServers();
@@ -398,49 +398,6 @@ const DIRECT_COMMANDS = {
398398
ctx.onEvent({ kind: 'text_delta', text });
399399
emitDone(ctx);
400400
},
401-
'/wallet': async (ctx) => {
402-
const chain = (await import('../config.js')).loadChain();
403-
try {
404-
let address;
405-
let balance;
406-
const fetchTimeout = (ms) => new Promise((_, rej) => setTimeout(() => rej(new Error('timeout')), ms));
407-
if (chain === 'solana') {
408-
const { getOrCreateSolanaWallet, setupAgentSolanaWallet } = await import('@blockrun/llm');
409-
const w = await getOrCreateSolanaWallet();
410-
address = w.address;
411-
try {
412-
const client = await setupAgentSolanaWallet({ silent: true });
413-
const bal = await Promise.race([client.getBalance(), fetchTimeout(5000)]);
414-
balance = `$${bal.toFixed(2)} USDC`;
415-
}
416-
catch {
417-
balance = '(unavailable)';
418-
}
419-
}
420-
else {
421-
const { getOrCreateWallet, setupAgentWallet } = await import('@blockrun/llm');
422-
const w = getOrCreateWallet();
423-
address = w.address;
424-
try {
425-
const client = setupAgentWallet({ silent: true });
426-
const bal = await Promise.race([client.getBalance(), fetchTimeout(5000)]);
427-
balance = `$${bal.toFixed(2)} USDC`;
428-
}
429-
catch {
430-
balance = '(unavailable)';
431-
}
432-
}
433-
ctx.onEvent({ kind: 'text_delta', text: `**Wallet**\n` +
434-
` Chain: ${chain}\n` +
435-
` Address: ${address}\n` +
436-
` Balance: ${balance}\n`
437-
});
438-
}
439-
catch (err) {
440-
ctx.onEvent({ kind: 'text_delta', text: `Wallet error: ${err.message}\n` });
441-
}
442-
emitDone(ctx);
443-
},
444401
'/clear': (ctx) => {
445402
ctx.history.length = 0;
446403
resetTokenAnchor();
@@ -693,6 +650,135 @@ export async function handleSlashCommand(input, ctx) {
693650
emitDone(ctx);
694651
return { handled: true };
695652
}
653+
// /wallet — show wallet info, import, or export
654+
if (input === '/wallet' || input.startsWith('/wallet ')) {
655+
const chain = (await import('../config.js')).loadChain();
656+
const args = input.slice(7).trim();
657+
// /wallet export — show private key
658+
if (args === 'export') {
659+
try {
660+
if (chain === 'solana') {
661+
const { loadSolanaWallet, getOrCreateSolanaWallet } = await import('@blockrun/llm');
662+
const key = loadSolanaWallet();
663+
if (!key) {
664+
ctx.onEvent({ kind: 'text_delta', text: 'No Solana wallet found. Run `/wallet` first.\n' });
665+
emitDone(ctx);
666+
return { handled: true };
667+
}
668+
const w = await getOrCreateSolanaWallet();
669+
ctx.onEvent({ kind: 'text_delta', text: `**Wallet Export (Solana)**\n` +
670+
` Address: ${w.address}\n` +
671+
` Private Key: ${key}\n\n` +
672+
`⚠️ Keep this key safe. Anyone with it controls your funds.\n`
673+
});
674+
}
675+
else {
676+
const { loadWallet, getOrCreateWallet } = await import('@blockrun/llm');
677+
const key = loadWallet();
678+
if (!key) {
679+
ctx.onEvent({ kind: 'text_delta', text: 'No wallet found. Run `/wallet` first.\n' });
680+
emitDone(ctx);
681+
return { handled: true };
682+
}
683+
const w = getOrCreateWallet();
684+
ctx.onEvent({ kind: 'text_delta', text: `**Wallet Export (Base)**\n` +
685+
` Address: ${w.address}\n` +
686+
` Private Key: ${key}\n\n` +
687+
`⚠️ Keep this key safe. Anyone with it controls your funds.\n`
688+
});
689+
}
690+
}
691+
catch (err) {
692+
ctx.onEvent({ kind: 'text_delta', text: `Export error: ${err.message}\n` });
693+
}
694+
emitDone(ctx);
695+
return { handled: true };
696+
}
697+
// /wallet import <private-key>
698+
if (args.startsWith('import')) {
699+
const key = args.slice(6).trim();
700+
if (!key) {
701+
ctx.onEvent({ kind: 'text_delta', text: `**Usage:** \`/wallet import <private-key>\`\n\n` +
702+
` Base: \`/wallet import 0x...\` (hex, 66 chars)\n` +
703+
` Solana: \`/wallet import <bs58-key>\` (base58 encoded)\n`
704+
});
705+
emitDone(ctx);
706+
return { handled: true };
707+
}
708+
try {
709+
if (chain === 'solana') {
710+
const { saveSolanaWallet, solanaPublicKey } = await import('@blockrun/llm');
711+
const address = await solanaPublicKey(key);
712+
saveSolanaWallet(key);
713+
ctx.onEvent({ kind: 'text_delta', text: `**Wallet Imported (Solana)**\n` +
714+
` Address: ${address}\n` +
715+
` Saved to: ~/.blockrun/\n\n` +
716+
`Restart Franklin to use the new wallet.\n`
717+
});
718+
}
719+
else {
720+
const { privateKeyToAccount } = await import('viem/accounts');
721+
const { saveWallet } = await import('@blockrun/llm');
722+
const account = privateKeyToAccount(key);
723+
saveWallet(key);
724+
ctx.onEvent({ kind: 'text_delta', text: `**Wallet Imported (Base)**\n` +
725+
` Address: ${account.address}\n` +
726+
` Saved to: ~/.blockrun/\n\n` +
727+
`Restart Franklin to use the new wallet.\n`
728+
});
729+
}
730+
}
731+
catch (err) {
732+
ctx.onEvent({ kind: 'text_delta', text: `Import error: ${err.message}\n` });
733+
}
734+
emitDone(ctx);
735+
return { handled: true };
736+
}
737+
// /wallet (no args) — show wallet info
738+
try {
739+
let address;
740+
let balance;
741+
const fetchTimeout = (ms) => new Promise((_, rej) => setTimeout(() => rej(new Error('timeout')), ms));
742+
if (chain === 'solana') {
743+
const { getOrCreateSolanaWallet, setupAgentSolanaWallet } = await import('@blockrun/llm');
744+
const w = await getOrCreateSolanaWallet();
745+
address = w.address;
746+
try {
747+
const client = await setupAgentSolanaWallet({ silent: true });
748+
const bal = await Promise.race([client.getBalance(), fetchTimeout(5000)]);
749+
balance = `$${bal.toFixed(2)} USDC`;
750+
}
751+
catch {
752+
balance = '(unavailable)';
753+
}
754+
}
755+
else {
756+
const { getOrCreateWallet, setupAgentWallet } = await import('@blockrun/llm');
757+
const w = getOrCreateWallet();
758+
address = w.address;
759+
try {
760+
const client = setupAgentWallet({ silent: true });
761+
const bal = await Promise.race([client.getBalance(), fetchTimeout(5000)]);
762+
balance = `$${bal.toFixed(2)} USDC`;
763+
}
764+
catch {
765+
balance = '(unavailable)';
766+
}
767+
}
768+
ctx.onEvent({ kind: 'text_delta', text: `**Wallet**\n` +
769+
` Chain: ${chain}\n` +
770+
` Address: ${address}\n` +
771+
` Balance: ${balance}\n\n` +
772+
` \`/wallet import <key>\` — import a personal wallet\n` +
773+
` \`/wallet export\` — show private key\n`
774+
});
775+
}
776+
catch (err) {
777+
ctx.onEvent({ kind: 'text_delta', text: `Wallet error: ${err.message}\n` });
778+
}
779+
emitDone(ctx);
780+
return { handled: true };
781+
}
696782
// /delete <...>
697783
if (input.startsWith('/delete ')) {
698784
const arg = input.slice('/delete '.length).trim();

dist/commands/config.js

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import fs from 'node:fs';
22
import path from 'node:path';
33
import chalk from 'chalk';
44
import { BLOCKRUN_DIR } from '../config.js';
5-
const CONFIG_FILE = path.join(BLOCKRUN_DIR, 'runcode-config.json');
5+
const CONFIG_FILE = path.join(BLOCKRUN_DIR, 'franklin-config.json');
6+
const LEGACY_CONFIG_FILE = path.join(BLOCKRUN_DIR, 'runcode-config.json');
67
const VALID_KEYS = [
78
'default-model',
89
'sonnet-model',
@@ -21,7 +22,14 @@ export function loadConfig() {
2122
return JSON.parse(content);
2223
}
2324
catch {
24-
return {};
25+
// Fall back to legacy config file
26+
try {
27+
const legacy = fs.readFileSync(LEGACY_CONFIG_FILE, 'utf-8');
28+
return JSON.parse(legacy);
29+
}
30+
catch {
31+
return {};
32+
}
2533
}
2634
}
2735
function saveConfig(config) {
@@ -47,7 +55,7 @@ export function configCommand(action, keyOrUndefined, value) {
4755
console.log(chalk.dim(`\nConfig file: ${CONFIG_FILE}`));
4856
return;
4957
}
50-
console.log(chalk.bold('runcode config\n'));
58+
console.log(chalk.bold('franklin config\n'));
5159
for (const [k, v] of entries) {
5260
console.log(` ${chalk.cyan(k)} = ${chalk.green(v)}`);
5361
}
@@ -56,7 +64,7 @@ export function configCommand(action, keyOrUndefined, value) {
5664
}
5765
if (action === 'get') {
5866
if (!keyOrUndefined) {
59-
console.log(chalk.red('Usage: runcode config get <key>'));
67+
console.log(chalk.red('Usage: franklin config get <key>'));
6068
process.exit(1);
6169
}
6270
const config = loadConfig();
@@ -71,7 +79,7 @@ export function configCommand(action, keyOrUndefined, value) {
7179
}
7280
if (action === 'set') {
7381
if (!keyOrUndefined || value === undefined) {
74-
console.log(chalk.red('Usage: runcode config set <key> <value>'));
82+
console.log(chalk.red('Usage: franklin config set <key> <value>'));
7583
process.exit(1);
7684
}
7785
if (!isValidKey(keyOrUndefined)) {
@@ -87,7 +95,7 @@ export function configCommand(action, keyOrUndefined, value) {
8795
}
8896
if (action === 'unset') {
8997
if (!keyOrUndefined) {
90-
console.log(chalk.red('Usage: runcode config unset <key>'));
98+
console.log(chalk.red('Usage: franklin config unset <key>'));
9199
process.exit(1);
92100
}
93101
if (!isValidKey(keyOrUndefined)) {
@@ -102,6 +110,6 @@ export function configCommand(action, keyOrUndefined, value) {
102110
return;
103111
}
104112
console.log(chalk.red(`Unknown action: ${action}`));
105-
console.log('Usage: runcode config <set|get|unset|list> [key] [value]');
113+
console.log('Usage: franklin config <set|get|unset|list> [key] [value]');
106114
process.exit(1);
107115
}

dist/commands/daemon.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import fs from 'node:fs';
33
import path from 'node:path';
44
import chalk from 'chalk';
55
import { BLOCKRUN_DIR, DEFAULT_PROXY_PORT } from '../config.js';
6-
const PID_FILE = path.join(BLOCKRUN_DIR, 'runcode.pid');
7-
const LOG_FILE = path.join(BLOCKRUN_DIR, 'runcode-debug.log');
6+
const PID_FILE = path.join(BLOCKRUN_DIR, 'franklin.pid');
7+
const LOG_FILE = path.join(BLOCKRUN_DIR, 'franklin-debug.log');
88
function readPid() {
99
try {
1010
const raw = fs.readFileSync(PID_FILE, 'utf-8').trim();

dist/commands/init.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ export async function initCommand(options) {
6363
<key>KeepAlive</key>
6464
<false/>
6565
<key>StandardOutPath</key>
66-
<string>${os.homedir()}/.blockrun/runcode-debug.log</string>
66+
<string>${os.homedir()}/.blockrun/franklin-debug.log</string>
6767
<key>StandardErrorPath</key>
68-
<string>${os.homedir()}/.blockrun/runcode-debug.log</string>
68+
<string>${os.homedir()}/.blockrun/franklin-debug.log</string>
6969
</dict>
7070
</plist>`;
7171
fs.mkdirSync(LAUNCH_AGENT_DIR, { recursive: true });

dist/commands/logs.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import fs from 'node:fs';
22
import path from 'node:path';
33
import chalk from 'chalk';
44
import { BLOCKRUN_DIR } from '../config.js';
5-
const LOG_FILE = path.join(BLOCKRUN_DIR, 'runcode-debug.log');
5+
const LOG_FILE = path.join(BLOCKRUN_DIR, 'franklin-debug.log');
6+
const LEGACY_LOG_FILE = path.join(BLOCKRUN_DIR, 'runcode-debug.log');
67
const MAX_LOG_SIZE = 10 * 1024 * 1024; // 10MB auto-rotate threshold
78
export function logsCommand(options) {
89
if (options.clear) {
@@ -15,9 +16,16 @@ export function logsCommand(options) {
1516
}
1617
return;
1718
}
19+
// Migrate legacy log file
20+
if (!fs.existsSync(LOG_FILE) && fs.existsSync(LEGACY_LOG_FILE)) {
21+
try {
22+
fs.renameSync(LEGACY_LOG_FILE, LOG_FILE);
23+
}
24+
catch { /* best effort */ }
25+
}
1826
if (!fs.existsSync(LOG_FILE)) {
19-
console.log(chalk.dim('No logs yet. Start runcode with --debug to enable logging:'));
20-
console.log(chalk.bold(' runcode start --debug'));
27+
console.log(chalk.dim('No logs yet. Start franklin with --debug to enable logging:'));
28+
console.log(chalk.bold(' franklin start --debug'));
2129
return;
2230
}
2331
// Auto-rotate: if file is over threshold, keep only last half

dist/commands/proxy.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@ function launchProxy(server, port, debug) {
8787
});
8888
server.listen(port, () => {
8989
console.log(chalk.green(`✓ Proxy running on port ${port}`));
90-
console.log(chalk.dim(` Usage tracking: ~/.blockrun/runcode-stats.json`));
90+
console.log(chalk.dim(` Usage tracking: ~/.blockrun/franklin-stats.json`));
9191
if (debug)
92-
console.log(chalk.dim(` Debug log: ~/.blockrun/runcode-debug.log`));
93-
console.log(chalk.dim(` Run 'runcode stats' to view statistics\n`));
92+
console.log(chalk.dim(` Debug log: ~/.blockrun/franklin-debug.log`));
93+
console.log(chalk.dim(` Run 'franklin stats' to view statistics\n`));
9494
console.log('Set this in your shell to use with Claude Code:\n');
9595
console.log(chalk.bold(` export ANTHROPIC_BASE_URL=http://localhost:${port}/api`));
9696
console.log(chalk.bold(` export ANTHROPIC_AUTH_TOKEN=x402-proxy-handles-auth`));

dist/commands/setup.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ export async function setupCommand(chainArg) {
99
console.log(chalk.yellow('Solana wallet already exists.'));
1010
console.log(`Address: ${chalk.cyan(wallets[0].publicKey)}`);
1111
console.log(chalk.dim('\nNext steps:'));
12-
console.log(chalk.dim(' runcode start — start coding'));
13-
console.log(chalk.dim(' runcode balance — check USDC balance'));
14-
console.log(chalk.dim(' runcode start -m free — use free models (no USDC needed)'));
12+
console.log(chalk.dim(' franklin start — start coding'));
13+
console.log(chalk.dim(' franklin balance — check USDC balance'));
14+
console.log(chalk.dim(' franklin start -m free — use free models (no USDC needed)'));
1515
saveChain('solana');
1616
return;
1717
}
@@ -29,9 +29,9 @@ export async function setupCommand(chainArg) {
2929
console.log(chalk.yellow('Wallet already exists.'));
3030
console.log(`Address: ${chalk.cyan(wallets[0].address)}`);
3131
console.log(chalk.dim('\nNext steps:'));
32-
console.log(chalk.dim(' runcode start — start coding'));
33-
console.log(chalk.dim(' runcode balance — check USDC balance'));
34-
console.log(chalk.dim(' runcode start -m free — use free models (no USDC needed)'));
32+
console.log(chalk.dim(' franklin start — start coding'));
33+
console.log(chalk.dim(' franklin balance — check USDC balance'));
34+
console.log(chalk.dim(' franklin start -m free — use free models (no USDC needed)'));
3535
saveChain('base');
3636
return;
3737
}
@@ -44,6 +44,6 @@ export async function setupCommand(chainArg) {
4444
console.log(`\nSend USDC on Base to this address to fund your account.`);
4545
}
4646
saveChain(chain);
47-
console.log(`Then run ${chalk.bold('runcode start')} to begin.\n`);
47+
console.log(`Then run ${chalk.bold('franklin start')} to begin.\n`);
4848
console.log(chalk.dim(`Chain: ${chain} — saved to ~/.blockrun/`));
4949
}

dist/panel/server.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,9 @@ export function createPanelServer(port) {
158158
}
159159
});
160160
// Watch stats file for changes → push to SSE clients
161-
const statsFile = path.join(BLOCKRUN_DIR, 'runcode-stats.json');
161+
const statsFile = fs.existsSync(path.join(BLOCKRUN_DIR, 'franklin-stats.json'))
162+
? path.join(BLOCKRUN_DIR, 'franklin-stats.json')
163+
: path.join(BLOCKRUN_DIR, 'runcode-stats.json');
162164
if (fs.existsSync(statsFile)) {
163165
fs.watchFile(statsFile, { interval: 2000 }, () => {
164166
try {

0 commit comments

Comments
 (0)