{"repo": "chunqiuyiyu/sekrun", "files": {"lib/main.js": {"a59e9025cd0563d0260643200de4bf4e0a5267b6": {"t": 1785745516.9553242, "n": 5426, "h": "66251e9bfb0c14ce", "c": "import { readFileSync } from 'node:fs';\nimport process from 'node:process';\nimport { Agent } from './agent.js';\nimport { Client } from './deepseek.js';\nimport { runRepl, runWithStepContinuation } from './repl.js';\nimport { enforceUpdate, getUpdateStatus, runUpdate } from './update.js';\n\nconst currentVersion = JSON.parse(\n readFileSync(new URL('../package.json', import.meta.url), 'utf-8'),\n).version;\n\nconst usageText = `sekrun v${currentVersion} - coding agent CLI (DeepSeek V4 Flash)\n\nUsage:\n sekrun [options] Start interactive REPL\n sekrun [options] \"prompt\" REPL with initial task\n\nOptions:\n --cwd Project root (default: current directory)\n --max-output Truncate tool output to n bytes (default: 8192)\n --max-tool-history \n Keep at most n bytes of each tool result in history (default: 4096)\n --max-history-messages \n Compact older conversation history above n messages (default: 40)\n --max-steps Max agent steps per user message (default: 80)\n --caveman Use ultra-concise caveman-style prompts to save tokens (default: on)\n --update Update to the latest version and exit\n --verbose Print token/cache usage each step\n --help Show this help\n\nEnvironment:\n DEEPSEEK_API_KEY Required API key\n DEEPSEEK_API_URL Optional chat completions URL\n`;\n\nexport async function main(argv = process.argv, env = process.env) {\n const parsed = parseArgs(argv.slice(2));\n if (parsed.help) {\n process.stdout.write(usageText);\n return;\n }\n\n if (parsed.update) {\n console.log('Checking for updates...');\n const status = await getUpdateStatus();\n if (!status.ok) {\n console.error(`Update check failed: ${status.error}`);\n console.error('Attempting to install sekrun@latest anyway...');\n } else if (!status.updateAvailable) {\n console.log(`sekrun is already up to date (${status.current}).`);\n return;\n } else {\n console.log(`Updating sekrun from ${status.current} to ${status.latest}...`);\n }\n const result = runUpdate();\n if (result.ok) {\n console.log('Update complete. Restart sekrun to use the new version.');\n } else {\n console.error('Update failed:', result.stderr);\n process.exitCode = 1;\n }\n return;\n }\n\n const { ok: upToDate } = await enforceUpdate();\n if (!upToDate) {\n process.exitCode = 1;\n return;\n }\n\n const apiKey = env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n console.error('DEEPSEEK_API_KEY is not set');\n process.exitCode = 1;\n return;\n }\n\n const workdir = parsed.cwd || process.cwd();\n const client = new Client({\n apiKey,\n baseUrl: env.DEEPSEEK_API_URL,\n });\n const agent = await Agent.create(client, {\n workdir,\n maxOutput: parsed.maxOutput,\n maxToolHistoryBytes: parsed.maxToolHistoryBytes,\n maxHistoryMessages: parsed.maxHistoryMessages,\n maxStepsPerTurn: parsed.maxSteps,\n verbose: parsed.verbose,\n caveman: parsed.caveman,\n });\n\n if (parsed.initialParts.length > 0) {\n await runWithStepContinuation(\n agent,\n () => agent.handleUserMessage(parsed.initialParts.join(' '), false),\n false,\n );\n }\n\n await runRepl(agent, { version: currentVersion });\n}\n\nfunction parseArgs(args) {\n const parsed = {\n cwd: null,\n maxOutput: 8192,\n maxToolHistoryBytes: 4096,\n maxHistoryMessages: 40,\n maxSteps: 80,\n verbose: false,\n caveman: true,\n help: false,\n update: false,\n initialParts: [],\n };\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = args[i];\n if (arg === '--help' || arg === '-h') {\n parsed.help = true;\n return parsed;\n }\n if (arg === '--cwd') {\n i += 1;\n if (i >= args.length) throw new Error('--cwd requires a path');\n parsed.cwd = args[i];\n continue;\n }\n if (arg === '--max-output') {\n i += 1;\n if (i >= args.length) throw new Error('--max-output requires a number');\n parsed.maxOutput = parsePositiveInteger(args[i], '--max-output');\n continue;\n }\n if (arg === '--max-tool-history') {\n i += 1;\n if (i >= args.length) throw new Error('--max-tool-history requires a number');\n parsed.maxToolHistoryBytes = parsePositiveInteger(args[i], '--max-tool-history');\n continue;\n }\n if (arg === '--max-history-messages') {\n i += 1;\n if (i >= args.length) throw new Error('--max-history-messages requires a number');\n parsed.maxHistoryMessages = parsePositiveInteger(args[i], '--max-history-messages');\n continue;\n }\n if (arg === '--max-steps') {\n i += 1;\n if (i >= args.length) throw new Error('--max-steps requires a number');\n parsed.maxSteps = parsePositiveInteger(args[i], '--max-steps');\n continue;\n }\n if (arg === '--caveman') {\n parsed.caveman = true;\n continue;\n }\n if (arg === '--update') {\n parsed.update = true;\n continue;\n }\n if (arg === '--verbose') {\n parsed.verbose = true;\n continue;\n }\n if (arg === '--') {\n parsed.initialParts.push(...args.slice(i + 1));\n break;\n }\n parsed.initialParts.push(arg);\n }\n\n return parsed;\n}\n\nfunction parsePositiveInteger(value, name) {\n const parsed = Number.parseInt(value, 10);\n if (!Number.isSafeInteger(parsed) || parsed < 0) {\n throw new Error(`${name} requires a non-negative integer`);\n }\n return parsed;\n}\n"}, "8372cfba45ea3f971791e8ae559b744148305614": {"t": 1785753769.3069346, "n": 5206, "h": "093748d3133c7cc9", "c": "import { readFileSync } from 'node:fs';\nimport process from 'node:process';\nimport { Agent } from './agent.js';\nimport { Client } from './deepseek.js';\nimport { runRepl, runWithStepContinuation } from './repl.js';\nimport { enforceUpdate, getUpdateStatus, runUpdate } from './update.js';\n\nconst currentVersion = JSON.parse(\n readFileSync(new URL('../package.json', import.meta.url), 'utf-8'),\n).version;\n\nconst usageText = `sekrun v${currentVersion} - coding agent CLI (DeepSeek V4 Flash)\n\nUsage:\n sekrun [options] Start interactive REPL\n sekrun [options] \"prompt\" REPL with initial task\n\nOptions:\n --cwd Project root (default: current directory)\n --max-output Truncate tool output to n bytes (default: 8192)\n --max-tool-history \n Keep at most n bytes of each tool result in history (default: 4096)\n --max-history-messages \n Compact older conversation history above n messages (default: 40)\n --max-steps Max agent steps per user message (default: 80)\n --update Update to the latest version and exit\n --verbose Print token/cache usage each step\n --help Show this help\n\nEnvironment:\n DEEPSEEK_API_KEY Required API key\n DEEPSEEK_API_URL Optional chat completions URL\n`;\n\nexport async function main(argv = process.argv, env = process.env) {\n const parsed = parseArgs(argv.slice(2));\n if (parsed.help) {\n process.stdout.write(usageText);\n return;\n }\n\n if (parsed.update) {\n console.log('Checking for updates...');\n const status = await getUpdateStatus();\n if (!status.ok) {\n console.error(`Update check failed: ${status.error}`);\n console.error('Attempting to install sekrun@latest anyway...');\n } else if (!status.updateAvailable) {\n console.log(`sekrun is already up to date (${status.current}).`);\n return;\n } else {\n console.log(`Updating sekrun from ${status.current} to ${status.latest}...`);\n }\n const result = runUpdate();\n if (result.ok) {\n console.log('Update complete. Restart sekrun to use the new version.');\n } else {\n console.error('Update failed:', result.stderr);\n process.exitCode = 1;\n }\n return;\n }\n\n const { ok: upToDate } = await enforceUpdate();\n if (!upToDate) {\n process.exitCode = 1;\n return;\n }\n\n const apiKey = env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n console.error('DEEPSEEK_API_KEY is not set');\n process.exitCode = 1;\n return;\n }\n\n const workdir = parsed.cwd || process.cwd();\n const client = new Client({\n apiKey,\n baseUrl: env.DEEPSEEK_API_URL,\n });\n const agent = await Agent.create(client, {\n workdir,\n maxOutput: parsed.maxOutput,\n maxToolHistoryBytes: parsed.maxToolHistoryBytes,\n maxHistoryMessages: parsed.maxHistoryMessages,\n maxStepsPerTurn: parsed.maxSteps,\n verbose: parsed.verbose,\n });\n\n if (parsed.initialParts.length > 0) {\n await runWithStepContinuation(\n agent,\n () => agent.handleUserMessage(parsed.initialParts.join(' '), false),\n false,\n );\n }\n\n await runRepl(agent, { version: currentVersion });\n}\n\nfunction parseArgs(args) {\n const parsed = {\n cwd: null,\n maxOutput: 8192,\n maxToolHistoryBytes: 4096,\n maxHistoryMessages: 40,\n maxSteps: 80,\n verbose: false,\n help: false,\n update: false,\n initialParts: [],\n };\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = args[i];\n if (arg === '--help' || arg === '-h') {\n parsed.help = true;\n return parsed;\n }\n if (arg === '--cwd') {\n i += 1;\n if (i >= args.length) throw new Error('--cwd requires a path');\n parsed.cwd = args[i];\n continue;\n }\n if (arg === '--max-output') {\n i += 1;\n if (i >= args.length) throw new Error('--max-output requires a number');\n parsed.maxOutput = parsePositiveInteger(args[i], '--max-output');\n continue;\n }\n if (arg === '--max-tool-history') {\n i += 1;\n if (i >= args.length) throw new Error('--max-tool-history requires a number');\n parsed.maxToolHistoryBytes = parsePositiveInteger(args[i], '--max-tool-history');\n continue;\n }\n if (arg === '--max-history-messages') {\n i += 1;\n if (i >= args.length) throw new Error('--max-history-messages requires a number');\n parsed.maxHistoryMessages = parsePositiveInteger(args[i], '--max-history-messages');\n continue;\n }\n if (arg === '--max-steps') {\n i += 1;\n if (i >= args.length) throw new Error('--max-steps requires a number');\n parsed.maxSteps = parsePositiveInteger(args[i], '--max-steps');\n continue;\n }\n if (arg === '--update') {\n parsed.update = true;\n continue;\n }\n if (arg === '--verbose') {\n parsed.verbose = true;\n continue;\n }\n if (arg === '--') {\n parsed.initialParts.push(...args.slice(i + 1));\n break;\n }\n parsed.initialParts.push(arg);\n }\n\n return parsed;\n}\n\nfunction parsePositiveInteger(value, name) {\n const parsed = Number.parseInt(value, 10);\n if (!Number.isSafeInteger(parsed) || parsed < 0) {\n throw new Error(`${name} requires a non-negative integer`);\n }\n return parsed;\n}\n"}, "150fa0e8a9a9595ffd8fcc7e7b22f4f293e27568": {"t": 1785753770.8718967, "n": 5847, "h": "15edf5b689b2dc3c", "c": "import { readFileSync } from 'node:fs';\nimport process from 'node:process';\nimport { Agent } from './agent.js';\nimport { Client } from './deepseek.js';\nimport { runRepl, runWithStepContinuation } from './repl.js';\nimport { checkForUpdate, enforceUpdate, runUpdate } from './update.js';\n\nconst currentVersion = JSON.parse(\n readFileSync(new URL('../package.json', import.meta.url), 'utf-8'),\n).version;\n\nconst usageText = `sekrun v${currentVersion} — coding agent CLI (DeepSeek V4 Flash)\n\nUsage:\n sekrun [options] Start interactive REPL\n sekrun [options] \"prompt\" REPL with initial task\n\nOptions:\n --cwd Project root (default: current directory)\n --max-output Truncate tool output to n bytes (default: 8192)\n --max-tool-history \n Keep at most n bytes of each tool result in history (default: 4096)\n --max-history-messages \n Compact older conversation history above n messages (default: 40)\n --max-steps Max agent steps per user message (default: 80)\n --update Update to the latest version and exit\n --no-update-check Skip the update version check on startup\n --verbose Print token/cache usage each step\n --help Show this help\n\nEnvironment:\n DEEPSEEK_API_KEY Required API key\n DEEPSEEK_API_URL Optional chat completions URL\n`;\n\nexport async function main(argv = process.argv, env = process.env) {\n const parsed = parseArgs(argv.slice(2));\n if (parsed.help) {\n process.stdout.write(usageText);\n return;\n }\n\n // Handle explicit update request\n if (parsed.update) {\n console.log('Checking for updates...');\n const latest = await checkForUpdate();\n if (!latest) {\n console.log('You are already on the latest version, or the check failed.');\n return;\n }\n console.log(`Updating sekrun from ${currentVersion} to ${latest}...`);\n const result = runUpdate();\n if (result.ok) {\n console.log('Update complete! Restart sek to use the new version.');\n } else {\n console.error('Update failed:', result.stderr);\n process.exitCode = 1;\n }\n return;\n }\n\n // Force update check — blocks startup if not up-to-date\n const { ok: upToDate } = await enforceUpdate();\n if (!upToDate) {\n process.exitCode = 1;\n return;\n }\n\n // Check for update in background (friendly notification only)\n checkForUpdate()\n .then((latest) => {\n if (latest) {\n const line = ` Update available: ${currentVersion} → ${latest}`;\n const border = '─'.repeat(line.length + 2);\n console.error(`\\n ╭${border}╮`);\n console.error(` │ ${line} │`);\n console.error(` │ Run \"sekrun --update\" to upgrade now. │`);\n console.error(` ╰${border}╯\\n`);\n }\n })\n .catch(() => { /* ignore */ });\n\n const apiKey = env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n console.error('DEEPSEEK_API_KEY is not set');\n process.exitCode = 1;\n return;\n }\n\n const workdir = parsed.cwd || process.cwd();\n const client = new Client({\n apiKey,\n baseUrl: env.DEEPSEEK_API_URL,\n });\n const agent = await Agent.create(client, {\n workdir,\n maxOutput: parsed.maxOutput,\n maxToolHistoryBytes: parsed.maxToolHistoryBytes,\n maxHistoryMessages: parsed.maxHistoryMessages,\n maxStepsPerTurn: parsed.maxSteps,\n verbose: parsed.verbose,\n });\n\n console.log(`sekrun v${currentVersion} — coding agent CLI (DeepSeek V4 Flash)`);\n\n if (parsed.initialParts.length > 0) {\n await runWithStepContinuation(\n agent,\n () => agent.handleUserMessage(parsed.initialParts.join(' '), false),\n false,\n );\n }\n\n await runRepl(agent);\n}\n\nfunction parseArgs(args) {\n const parsed = {\n cwd: null,\n maxOutput: 8192,\n maxToolHistoryBytes: 4096,\n maxHistoryMessages: 40,\n maxSteps: 80,\n verbose: false,\n help: false,\n update: false,\n noUpdateCheck: false,\n initialParts: [],\n };\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = args[i];\n if (arg === '--help' || arg === '-h') {\n parsed.help = true;\n return parsed;\n }\n if (arg === '--cwd') {\n i += 1;\n if (i >= args.length) throw new Error('--cwd requires a path');\n parsed.cwd = args[i];\n continue;\n }\n if (arg === '--max-output') {\n i += 1;\n if (i >= args.length) throw new Error('--max-output requires a number');\n parsed.maxOutput = parsePositiveInteger(args[i], '--max-output');\n continue;\n }\n if (arg === '--max-tool-history') {\n i += 1;\n if (i >= args.length) throw new Error('--max-tool-history requires a number');\n parsed.maxToolHistoryBytes = parsePositiveInteger(args[i], '--max-tool-history');\n continue;\n }\n if (arg === '--max-history-messages') {\n i += 1;\n if (i >= args.length) throw new Error('--max-history-messages requires a number');\n parsed.maxHistoryMessages = parsePositiveInteger(args[i], '--max-history-messages');\n continue;\n }\n if (arg === '--max-steps') {\n i += 1;\n if (i >= args.length) throw new Error('--max-steps requires a number');\n parsed.maxSteps = parsePositiveInteger(args[i], '--max-steps');\n continue;\n }\n if (arg === '--update') {\n parsed.update = true;\n continue;\n }\n if (arg === '--no-update-check') {\n parsed.noUpdateCheck = true;\n continue;\n }\n if (arg === '--verbose') {\n parsed.verbose = true;\n continue;\n }\n if (arg === '--') {\n parsed.initialParts.push(...args.slice(i + 1));\n break;\n }\n parsed.initialParts.push(arg);\n }\n\n return parsed;\n}\n\nfunction parsePositiveInteger(value, name) {\n const parsed = Number.parseInt(value, 10);\n if (!Number.isSafeInteger(parsed) || parsed < 0) {\n throw new Error(`${name} requires a non-negative integer`);\n }\n return parsed;\n}\n"}, "99dd33c6d0eca155c9cf33ddb5f3c9180d3e1490": {"t": 1785753772.0514858, "n": 5735, "h": "7397c8a877beef58", "c": "import { readFileSync } from 'node:fs';\nimport process from 'node:process';\nimport { Agent } from './agent.js';\nimport { Client } from './deepseek.js';\nimport { runRepl, runWithStepContinuation } from './repl.js';\nimport { checkForUpdate, enforceUpdate, runUpdate } from './update.js';\n\nconst currentVersion = JSON.parse(\n readFileSync(new URL('../package.json', import.meta.url), 'utf-8'),\n).version;\n\nconst usageText = `sek - coding agent CLI (DeepSeek V4 Flash)\n\nUsage:\n sek [options] Start interactive REPL\n sek [options] \"prompt\" REPL with initial task\n\nOptions:\n --cwd Project root (default: current directory)\n --max-output Truncate tool output to n bytes (default: 8192)\n --max-tool-history \n Keep at most n bytes of each tool result in history (default: 4096)\n --max-history-messages \n Compact older conversation history above n messages (default: 40)\n --max-steps Max agent steps per user message (default: 80)\n --update Update to the latest version and exit\n --no-update-check Skip the update version check on startup\n --verbose Print token/cache usage each step\n --help Show this help\n\nEnvironment:\n DEEPSEEK_API_KEY Required API key\n DEEPSEEK_API_URL Optional chat completions URL\n`;\n\nexport async function main(argv = process.argv, env = process.env) {\n const parsed = parseArgs(argv.slice(2));\n if (parsed.help) {\n process.stdout.write(usageText);\n return;\n }\n\n // Handle explicit update request\n if (parsed.update) {\n console.log('Checking for updates...');\n const latest = await checkForUpdate();\n if (!latest) {\n console.log('You are already on the latest version, or the check failed.');\n return;\n }\n console.log(`Updating sekrun from ${currentVersion} to ${latest}...`);\n const result = runUpdate();\n if (result.ok) {\n console.log('Update complete! Restart sek to use the new version.');\n } else {\n console.error('Update failed:', result.stderr);\n process.exitCode = 1;\n }\n return;\n }\n\n // Force update check — blocks startup if not up-to-date\n const { ok: upToDate } = await enforceUpdate();\n if (!upToDate) {\n process.exitCode = 1;\n return;\n }\n\n // Check for update in background (friendly notification only)\n checkForUpdate()\n .then((latest) => {\n if (latest) {\n const line = ` Update available: ${currentVersion} → ${latest}`;\n const border = '─'.repeat(line.length + 2);\n console.error(`\\n ╭${border}╮`);\n console.error(` │ ${line} │`);\n console.error(` │ Run \"sekrun --update\" to upgrade now. │`);\n console.error(` ╰${border}╯\\n`);\n }\n })\n .catch(() => { /* ignore */ });\n\n const apiKey = env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n console.error('DEEPSEEK_API_KEY is not set');\n process.exitCode = 1;\n return;\n }\n\n const workdir = parsed.cwd || process.cwd();\n const client = new Client({\n apiKey,\n baseUrl: env.DEEPSEEK_API_URL,\n });\n const agent = await Agent.create(client, {\n workdir,\n maxOutput: parsed.maxOutput,\n maxToolHistoryBytes: parsed.maxToolHistoryBytes,\n maxHistoryMessages: parsed.maxHistoryMessages,\n maxStepsPerTurn: parsed.maxSteps,\n verbose: parsed.verbose,\n });\n\n if (parsed.initialParts.length > 0) {\n await runWithStepContinuation(\n agent,\n () => agent.handleUserMessage(parsed.initialParts.join(' '), false),\n false,\n );\n }\n\n await runRepl(agent);\n}\n\nfunction parseArgs(args) {\n const parsed = {\n cwd: null,\n maxOutput: 8192,\n maxToolHistoryBytes: 4096,\n maxHistoryMessages: 40,\n maxSteps: 80,\n verbose: false,\n help: false,\n update: false,\n noUpdateCheck: false,\n initialParts: [],\n };\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = args[i];\n if (arg === '--help' || arg === '-h') {\n parsed.help = true;\n return parsed;\n }\n if (arg === '--cwd') {\n i += 1;\n if (i >= args.length) throw new Error('--cwd requires a path');\n parsed.cwd = args[i];\n continue;\n }\n if (arg === '--max-output') {\n i += 1;\n if (i >= args.length) throw new Error('--max-output requires a number');\n parsed.maxOutput = parsePositiveInteger(args[i], '--max-output');\n continue;\n }\n if (arg === '--max-tool-history') {\n i += 1;\n if (i >= args.length) throw new Error('--max-tool-history requires a number');\n parsed.maxToolHistoryBytes = parsePositiveInteger(args[i], '--max-tool-history');\n continue;\n }\n if (arg === '--max-history-messages') {\n i += 1;\n if (i >= args.length) throw new Error('--max-history-messages requires a number');\n parsed.maxHistoryMessages = parsePositiveInteger(args[i], '--max-history-messages');\n continue;\n }\n if (arg === '--max-steps') {\n i += 1;\n if (i >= args.length) throw new Error('--max-steps requires a number');\n parsed.maxSteps = parsePositiveInteger(args[i], '--max-steps');\n continue;\n }\n if (arg === '--update') {\n parsed.update = true;\n continue;\n }\n if (arg === '--no-update-check') {\n parsed.noUpdateCheck = true;\n continue;\n }\n if (arg === '--verbose') {\n parsed.verbose = true;\n continue;\n }\n if (arg === '--') {\n parsed.initialParts.push(...args.slice(i + 1));\n break;\n }\n parsed.initialParts.push(arg);\n }\n\n return parsed;\n}\n\nfunction parsePositiveInteger(value, name) {\n const parsed = Number.parseInt(value, 10);\n if (!Number.isSafeInteger(parsed) || parsed < 0) {\n throw new Error(`${name} requires a non-negative integer`);\n }\n return parsed;\n}\n"}, "b0fba22b1d69055796d01096011de2b7ddbfa6b2": {"t": 1785753773.5010712, "n": 3905, "h": "0e7470f3a9b429be", "c": "import process from 'node:process';\nimport { Agent } from './agent.js';\nimport { Client } from './deepseek.js';\nimport { runRepl, runWithStepContinuation } from './repl.js';\n\nconst usageText = `sek - coding agent CLI (DeepSeek V4 Flash)\n\nUsage:\n sek [options] Start interactive REPL\n sek [options] \"prompt\" REPL with initial task\n\nOptions:\n --cwd Project root (default: current directory)\n --max-output Truncate tool output to n bytes (default: 8192)\n --max-tool-history \n Keep at most n bytes of each tool result in history (default: 4096)\n --max-history-messages \n Compact older conversation history above n messages (default: 40)\n --max-steps Max agent steps per user message (default: 80)\n --verbose Print token/cache usage each step\n --help Show this help\n\nEnvironment:\n DEEPSEEK_API_KEY Required API key\n DEEPSEEK_API_URL Optional chat completions URL\n`;\n\nexport async function main(argv = process.argv, env = process.env) {\n const parsed = parseArgs(argv.slice(2));\n if (parsed.help) {\n process.stdout.write(usageText);\n return;\n }\n\n const apiKey = env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n console.error('DEEPSEEK_API_KEY is not set');\n process.exitCode = 1;\n return;\n }\n\n const workdir = parsed.cwd || process.cwd();\n const client = new Client({\n apiKey,\n baseUrl: env.DEEPSEEK_API_URL,\n });\n const agent = await Agent.create(client, {\n workdir,\n maxOutput: parsed.maxOutput,\n maxToolHistoryBytes: parsed.maxToolHistoryBytes,\n maxHistoryMessages: parsed.maxHistoryMessages,\n maxStepsPerTurn: parsed.maxSteps,\n verbose: parsed.verbose,\n });\n\n if (parsed.initialParts.length > 0) {\n await runWithStepContinuation(\n agent,\n () => agent.handleUserMessage(parsed.initialParts.join(' '), false),\n false,\n );\n }\n\n await runRepl(agent);\n}\n\nfunction parseArgs(args) {\n const parsed = {\n cwd: null,\n maxOutput: 8192,\n maxToolHistoryBytes: 4096,\n maxHistoryMessages: 40,\n maxSteps: 80,\n verbose: false,\n help: false,\n initialParts: [],\n };\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = args[i];\n if (arg === '--help' || arg === '-h') {\n parsed.help = true;\n return parsed;\n }\n if (arg === '--cwd') {\n i += 1;\n if (i >= args.length) throw new Error('--cwd requires a path');\n parsed.cwd = args[i];\n continue;\n }\n if (arg === '--max-output') {\n i += 1;\n if (i >= args.length) throw new Error('--max-output requires a number');\n parsed.maxOutput = parsePositiveInteger(args[i], '--max-output');\n continue;\n }\n if (arg === '--max-tool-history') {\n i += 1;\n if (i >= args.length) throw new Error('--max-tool-history requires a number');\n parsed.maxToolHistoryBytes = parsePositiveInteger(args[i], '--max-tool-history');\n continue;\n }\n if (arg === '--max-history-messages') {\n i += 1;\n if (i >= args.length) throw new Error('--max-history-messages requires a number');\n parsed.maxHistoryMessages = parsePositiveInteger(args[i], '--max-history-messages');\n continue;\n }\n if (arg === '--max-steps') {\n i += 1;\n if (i >= args.length) throw new Error('--max-steps requires a number');\n parsed.maxSteps = parsePositiveInteger(args[i], '--max-steps');\n continue;\n }\n if (arg === '--verbose') {\n parsed.verbose = true;\n continue;\n }\n if (arg === '--') {\n parsed.initialParts.push(...args.slice(i + 1));\n break;\n }\n parsed.initialParts.push(arg);\n }\n\n return parsed;\n}\n\nfunction parsePositiveInteger(value, name) {\n const parsed = Number.parseInt(value, 10);\n if (!Number.isSafeInteger(parsed) || parsed < 0) {\n throw new Error(`${name} requires a non-negative integer`);\n }\n return parsed;\n}\n"}, "d2d9fe0859a1b2370a614e560611b84bedd9050c": {"t": 1785753774.7146904, "n": 3810, "h": "60197d8a4720991e", "c": "import process from 'node:process';\nimport { Agent } from './agent.js';\nimport { Client } from './deepseek.js';\nimport { runRepl } from './repl.js';\n\nconst usageText = `sek - coding agent CLI (DeepSeek V4 Flash)\n\nUsage:\n sek [options] Start interactive REPL\n sek [options] \"prompt\" REPL with initial task\n\nOptions:\n --cwd Project root (default: current directory)\n --max-output Truncate tool output to n bytes (default: 8192)\n --max-tool-history \n Keep at most n bytes of each tool result in history (default: 4096)\n --max-history-messages \n Compact older conversation history above n messages (default: 40)\n --max-steps Max agent steps per user message (default: 40)\n --verbose Print token/cache usage each step\n --help Show this help\n\nEnvironment:\n DEEPSEEK_API_KEY Required API key\n DEEPSEEK_API_URL Optional chat completions URL\n`;\n\nexport async function main(argv = process.argv, env = process.env) {\n const parsed = parseArgs(argv.slice(2));\n if (parsed.help) {\n process.stdout.write(usageText);\n return;\n }\n\n const apiKey = env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n console.error('DEEPSEEK_API_KEY is not set');\n process.exitCode = 1;\n return;\n }\n\n const workdir = parsed.cwd || process.cwd();\n const client = new Client({\n apiKey,\n baseUrl: env.DEEPSEEK_API_URL,\n });\n const agent = await Agent.create(client, {\n workdir,\n maxOutput: parsed.maxOutput,\n maxToolHistoryBytes: parsed.maxToolHistoryBytes,\n maxHistoryMessages: parsed.maxHistoryMessages,\n maxStepsPerTurn: parsed.maxSteps,\n verbose: parsed.verbose,\n });\n\n if (parsed.initialParts.length > 0) {\n await agent.handleUserMessage(parsed.initialParts.join(' '), false);\n }\n\n await runRepl(agent);\n}\n\nfunction parseArgs(args) {\n const parsed = {\n cwd: null,\n maxOutput: 8192,\n maxToolHistoryBytes: 4096,\n maxHistoryMessages: 40,\n maxSteps: 40,\n verbose: false,\n help: false,\n initialParts: [],\n };\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = args[i];\n if (arg === '--help' || arg === '-h') {\n parsed.help = true;\n return parsed;\n }\n if (arg === '--cwd') {\n i += 1;\n if (i >= args.length) throw new Error('--cwd requires a path');\n parsed.cwd = args[i];\n continue;\n }\n if (arg === '--max-output') {\n i += 1;\n if (i >= args.length) throw new Error('--max-output requires a number');\n parsed.maxOutput = parsePositiveInteger(args[i], '--max-output');\n continue;\n }\n if (arg === '--max-tool-history') {\n i += 1;\n if (i >= args.length) throw new Error('--max-tool-history requires a number');\n parsed.maxToolHistoryBytes = parsePositiveInteger(args[i], '--max-tool-history');\n continue;\n }\n if (arg === '--max-history-messages') {\n i += 1;\n if (i >= args.length) throw new Error('--max-history-messages requires a number');\n parsed.maxHistoryMessages = parsePositiveInteger(args[i], '--max-history-messages');\n continue;\n }\n if (arg === '--max-steps') {\n i += 1;\n if (i >= args.length) throw new Error('--max-steps requires a number');\n parsed.maxSteps = parsePositiveInteger(args[i], '--max-steps');\n continue;\n }\n if (arg === '--verbose') {\n parsed.verbose = true;\n continue;\n }\n if (arg === '--') {\n parsed.initialParts.push(...args.slice(i + 1));\n break;\n }\n parsed.initialParts.push(arg);\n }\n\n return parsed;\n}\n\nfunction parsePositiveInteger(value, name) {\n const parsed = Number.parseInt(value, 10);\n if (!Number.isSafeInteger(parsed) || parsed < 0) {\n throw new Error(`${name} requires a non-negative integer`);\n }\n return parsed;\n}\n"}, "39fe5c92f75d4afc14c3aa5526bad264c9a5479c": {"t": 1785753775.916038, "n": 2908, "h": "247434c47471aefe", "c": "import process from 'node:process';\nimport { Agent } from './agent.js';\nimport { Client } from './deepseek.js';\nimport { runRepl } from './repl.js';\n\nconst usageText = `sek - coding agent CLI (DeepSeek V4 Flash)\n\nUsage:\n sek [options] Start interactive REPL\n sek [options] \"prompt\" REPL with initial task\n\nOptions:\n --cwd Project root (default: current directory)\n --max-output Truncate tool output to n bytes (default: 8192)\n --max-steps Max agent steps per user message (default: 40)\n --verbose Print token/cache usage each step\n --help Show this help\n\nEnvironment:\n DEEPSEEK_API_KEY Required API key\n DEEPSEEK_API_URL Optional chat completions URL\n`;\n\nexport async function main(argv = process.argv, env = process.env) {\n const parsed = parseArgs(argv.slice(2));\n if (parsed.help) {\n process.stdout.write(usageText);\n return;\n }\n\n const apiKey = env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n console.error('DEEPSEEK_API_KEY is not set');\n process.exitCode = 1;\n return;\n }\n\n const workdir = parsed.cwd || process.cwd();\n const client = new Client({\n apiKey,\n baseUrl: env.DEEPSEEK_API_URL,\n });\n const agent = await Agent.create(client, {\n workdir,\n maxOutput: parsed.maxOutput,\n maxStepsPerTurn: parsed.maxSteps,\n verbose: parsed.verbose,\n });\n\n if (parsed.initialParts.length > 0) {\n await agent.handleUserMessage(parsed.initialParts.join(' '), false);\n }\n\n await runRepl(agent);\n}\n\nfunction parseArgs(args) {\n const parsed = {\n cwd: null,\n maxOutput: 8192,\n maxSteps: 40,\n verbose: false,\n help: false,\n initialParts: [],\n };\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = args[i];\n if (arg === '--help' || arg === '-h') {\n parsed.help = true;\n return parsed;\n }\n if (arg === '--cwd') {\n i += 1;\n if (i >= args.length) throw new Error('--cwd requires a path');\n parsed.cwd = args[i];\n continue;\n }\n if (arg === '--max-output') {\n i += 1;\n if (i >= args.length) throw new Error('--max-output requires a number');\n parsed.maxOutput = parsePositiveInteger(args[i], '--max-output');\n continue;\n }\n if (arg === '--max-steps') {\n i += 1;\n if (i >= args.length) throw new Error('--max-steps requires a number');\n parsed.maxSteps = parsePositiveInteger(args[i], '--max-steps');\n continue;\n }\n if (arg === '--verbose') {\n parsed.verbose = true;\n continue;\n }\n if (arg === '--') {\n parsed.initialParts.push(...args.slice(i + 1));\n break;\n }\n parsed.initialParts.push(arg);\n }\n\n return parsed;\n}\n\nfunction parsePositiveInteger(value, name) {\n const parsed = Number.parseInt(value, 10);\n if (!Number.isSafeInteger(parsed) || parsed < 0) {\n throw new Error(`${name} requires a non-negative integer`);\n }\n return parsed;\n}\n"}, "dcc5de933a70bd8a1a6060ced0daf259844f1478": {"t": 1785753777.2840066, "n": 2908, "h": "edf7da3b4c95a8e2", "c": "import process from 'node:process';\nimport { Agent } from './agent.js';\nimport { Client } from './deepseek.js';\nimport { runRepl } from './repl.js';\n\nconst usageText = `zek - coding agent CLI (DeepSeek V4 Flash)\n\nUsage:\n zek [options] Start interactive REPL\n zek [options] \"prompt\" REPL with initial task\n\nOptions:\n --cwd Project root (default: current directory)\n --max-output Truncate tool output to n bytes (default: 8192)\n --max-steps Max agent steps per user message (default: 40)\n --verbose Print token/cache usage each step\n --help Show this help\n\nEnvironment:\n DEEPSEEK_API_KEY Required API key\n DEEPSEEK_API_URL Optional chat completions URL\n`;\n\nexport async function main(argv = process.argv, env = process.env) {\n const parsed = parseArgs(argv.slice(2));\n if (parsed.help) {\n process.stdout.write(usageText);\n return;\n }\n\n const apiKey = env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n console.error('DEEPSEEK_API_KEY is not set');\n process.exitCode = 1;\n return;\n }\n\n const workdir = parsed.cwd || process.cwd();\n const client = new Client({\n apiKey,\n baseUrl: env.DEEPSEEK_API_URL,\n });\n const agent = await Agent.create(client, {\n workdir,\n maxOutput: parsed.maxOutput,\n maxStepsPerTurn: parsed.maxSteps,\n verbose: parsed.verbose,\n });\n\n if (parsed.initialParts.length > 0) {\n await agent.handleUserMessage(parsed.initialParts.join(' '), false);\n }\n\n await runRepl(agent);\n}\n\nfunction parseArgs(args) {\n const parsed = {\n cwd: null,\n maxOutput: 8192,\n maxSteps: 40,\n verbose: false,\n help: false,\n initialParts: [],\n };\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = args[i];\n if (arg === '--help' || arg === '-h') {\n parsed.help = true;\n return parsed;\n }\n if (arg === '--cwd') {\n i += 1;\n if (i >= args.length) throw new Error('--cwd requires a path');\n parsed.cwd = args[i];\n continue;\n }\n if (arg === '--max-output') {\n i += 1;\n if (i >= args.length) throw new Error('--max-output requires a number');\n parsed.maxOutput = parsePositiveInteger(args[i], '--max-output');\n continue;\n }\n if (arg === '--max-steps') {\n i += 1;\n if (i >= args.length) throw new Error('--max-steps requires a number');\n parsed.maxSteps = parsePositiveInteger(args[i], '--max-steps');\n continue;\n }\n if (arg === '--verbose') {\n parsed.verbose = true;\n continue;\n }\n if (arg === '--') {\n parsed.initialParts.push(...args.slice(i + 1));\n break;\n }\n parsed.initialParts.push(arg);\n }\n\n return parsed;\n}\n\nfunction parsePositiveInteger(value, name) {\n const parsed = Number.parseInt(value, 10);\n if (!Number.isSafeInteger(parsed) || parsed < 0) {\n throw new Error(`${name} requires a non-negative integer`);\n }\n return parsed;\n}\n"}}, "README.md": {"a59e9025cd0563d0260643200de4bf4e0a5267b6": {"t": 1785746600.9972258, "n": 1681, "h": "323db8b4cd6810d6", "c": "# Sekrun CLI\n\n**sekrun** is a coding agent CLI powered by **DeepSeek V4 Flash**. It runs entirely on Node.js with **zero npm dependencies** — just the standard library.\n\nIt can read, write, search, and edit files, execute shell commands, and interact with the user across multiple turns, all driven by the DeepSeek function-calling API.\n\n![preview](preview.webp)\n\n## Install\n\n```bash\nnpm install -g sekrun\n```\n\nAfter installation, the command `sekrun` is available globally.\n\n## Requirements\n\n- **Node.js** >= 18 (native `fetch` support required)\n- A **DeepSeek API key**\n\n## Quick start\n\n```bash\n# Set your API key\nexport DEEPSEEK_API_KEY=sk-your-key-here\n\n# Run a one-shot task\nsekrun \"implement a fizzbuzz function in Python\"\n\n# Or start an interactive REPL session\nsekrun\n```\n\n### Options\n\n| Option | Default | Description |\n|---|---|---|\n| `--cwd ` | current directory | Project root directory |\n| `--max-output ` | 8192 | Truncate tool output to n bytes |\n| `--max-tool-history ` | 4096 | Keep at most n bytes of each tool result in conversation history |\n| `--max-history-messages ` | 40 | Compact older history above n messages |\n| `--max-steps ` | 80 | Max agent steps per user message |\n| `--verbose` | false | Print token/cache usage after each step |\n| `--help` | — | Show help |\n\n## How it works\n\n1. The CLI sends your request to the DeepSeek API with a set of available tools.\n2. The model responds with tool calls (read file, write file, search, shell, etc.).\n3. Each tool call is executed locally and the result is fed back to the model.\n4. The loop continues until the model produces a final answer or the step limit is reached.\n\n## License\n\nMIT\n"}, "9cefc83093d89a1430edfd0bf40710111c3b9449": {"t": 1785753771.6487763, "n": 1681, "h": "323db8b4cd6810d6", "c": "# Sekrun CLI\n\n**sekrun** is a coding agent CLI powered by **DeepSeek V4 Flash**. It runs entirely on Node.js with **zero npm dependencies** — just the standard library.\n\nIt can read, write, search, and edit files, execute shell commands, and interact with the user across multiple turns, all driven by the DeepSeek function-calling API.\n\n![preview](preview.webp)\n\n## Install\n\n```bash\nnpm install -g sekrun\n```\n\nAfter installation, the command `sekrun` is available globally.\n\n## Requirements\n\n- **Node.js** >= 18 (native `fetch` support required)\n- A **DeepSeek API key**\n\n## Quick start\n\n```bash\n# Set your API key\nexport DEEPSEEK_API_KEY=sk-your-key-here\n\n# Run a one-shot task\nsekrun \"implement a fizzbuzz function in Python\"\n\n# Or start an interactive REPL session\nsekrun\n```\n\n### Options\n\n| Option | Default | Description |\n|---|---|---|\n| `--cwd ` | current directory | Project root directory |\n| `--max-output ` | 8192 | Truncate tool output to n bytes |\n| `--max-tool-history ` | 4096 | Keep at most n bytes of each tool result in conversation history |\n| `--max-history-messages ` | 40 | Compact older history above n messages |\n| `--max-steps ` | 80 | Max agent steps per user message |\n| `--verbose` | false | Print token/cache usage after each step |\n| `--help` | — | Show help |\n\n## How it works\n\n1. The CLI sends your request to the DeepSeek API with a set of available tools.\n2. The model responds with tool calls (read file, write file, search, shell, etc.).\n3. Each tool call is executed locally and the result is fed back to the model.\n4. The loop continues until the model produces a final answer or the step limit is reached.\n\n## License\n\nMIT\n"}, "387fda8a48bda441b7d5d51506bb66b40f307a1f": {"t": 1785753773.0749125, "n": 1655, "h": "12f9e47bffb28cb1", "c": "# Sekrun CLI\n\n**sekrun** is a coding agent CLI powered by **DeepSeek V4 Flash**. It runs entirely on Node.js with **zero npm dependencies** — just the standard library.\n\nIt can read, write, search, and edit files, execute shell commands, and interact with the user across multiple turns, all driven by the DeepSeek function-calling API.\n\n## Install\n\n```bash\nnpm install -g sekrun\n```\n\nAfter installation, the command `sekrun` is available globally.\n\n## Requirements\n\n- **Node.js** >= 18 (native `fetch` support required)\n- A **DeepSeek API key**\n\n## Quick start\n\n```bash\n# Set your API key\nexport DEEPSEEK_API_KEY=sk-your-key-here\n\n# Run a one-shot task\nsekrun \"implement a fizzbuzz function in Python\"\n\n# Or start an interactive REPL session\nsekrun\n```\n\n### Options\n\n| Option | Default | Description |\n|---|---|---|\n| `--cwd ` | current directory | Project root directory |\n| `--max-output ` | 8192 | Truncate tool output to n bytes |\n| `--max-tool-history ` | 4096 | Keep at most n bytes of each tool result in conversation history |\n| `--max-history-messages ` | 40 | Compact older history above n messages |\n| `--max-steps ` | 80 | Max agent steps per user message |\n| `--verbose` | false | Print token/cache usage after each step |\n| `--help` | — | Show help |\n\n## How it works\n\n1. The CLI sends your request to the DeepSeek API with a set of available tools.\n2. The model responds with tool calls (read file, write file, search, shell, etc.).\n3. Each tool call is executed locally and the result is fed back to the model.\n4. The loop continues until the model produces a final answer or the step limit is reached.\n\n## License\n\nMIT\n"}, "3f0a38a91e3dcb022e36fddaa03b52ee868035f9": {"t": 1785753774.288831, "n": 1653, "h": "23ab13bb01f269b6", "c": "# Sek CLI\n\n**sek-cli** is a coding agent CLI powered by **DeepSeek V4 Flash**. It runs entirely on Node.js with **zero npm dependencies** — just the standard library.\n\nIt can read, write, search, and edit files, execute shell commands, and interact with the user across multiple turns, all driven by the DeepSeek function-calling API.\n\n## Install\n\n```bash\nnpm install -g sek-cli\n```\n\nAfter installation, the command `sek` is available globally.\n\n## Requirements\n\n- **Node.js** >= 18 (native `fetch` support required)\n- A **DeepSeek API key**\n\n## Quick start\n\n```bash\n# Set your API key\nexport DEEPSEEK_API_KEY=sk-your-key-here\n\n# Run a one-shot task\nsek-cli \"implement a fizzbuzz function in Python\"\n\n# Or start an interactive REPL session\nsek-cli\n```\n\n### Options\n\n| Option | Default | Description |\n|---|---|---|\n| `--cwd ` | current directory | Project root directory |\n| `--max-output ` | 8192 | Truncate tool output to n bytes |\n| `--max-tool-history ` | 4096 | Keep at most n bytes of each tool result in conversation history |\n| `--max-history-messages ` | 40 | Compact older history above n messages |\n| `--max-steps ` | 80 | Max agent steps per user message |\n| `--verbose` | false | Print token/cache usage after each step |\n| `--help` | — | Show help |\n\n## How it works\n\n1. The CLI sends your request to the DeepSeek API with a set of available tools.\n2. The model responds with tool calls (read file, write file, search, shell, etc.).\n3. Each tool call is executed locally and the result is fed back to the model.\n4. The loop continues until the model produces a final answer or the step limit is reached.\n\n## License\n\nMIT\n"}, "6503762e4482be10649a9516438eb74a9e9a5a28": {"t": 1785753775.6602902, "n": 1786, "h": "66219d3680a219fa", "c": "# sek\n\n**sek** is a coding agent CLI powered by **DeepSeek V4 Flash**. It runs entirely on Node.js with **zero npm dependencies** — just the standard library.\n\nIt can read, write, search, and edit files, execute shell commands, and interact with the user across multiple turns, all driven by the DeepSeek function-calling API.\n\n## Install\n\n```bash\nnpm install -g sek-cli\n```\n\n## Requirements\n\n- **Node.js** >= 18 (native `fetch` support required)\n- A **DeepSeek API key**\n\n## Quick start\n\n```bash\n# Set your API key\nexport DEEPSEEK_API_KEY=sk-your-key-here\n\n# Run a one-shot task\nsek-cli \"implement a fizzbuzz function in Python\"\n\n# Or start an interactive REPL session\nsek\n```\n\n### Options\n\n| Option | Default | Description |\n|---|---|---|\n| `--cwd ` | current directory | Project root directory |\n| `--max-output ` | 8192 | Truncate tool output to n bytes |\n| `--max-tool-history ` | 4096 | Keep at most n bytes of each tool result in conversation history |\n| `--max-history-messages ` | 40 | Compact older history above n messages |\n| `--max-steps ` | 80 | Max agent steps per user message |\n| `--verbose` | false | Print token/cache usage after each step |\n| `--help` | — | Show help |\n\n### Environment variables\n\n| Variable | Required | Description |\n|---|---|---|\n| `DEEPSEEK_API_KEY` | Yes | Your DeepSeek API key |\n\n## How it works\n\n1. The CLI sends your request to the DeepSeek API with a set of available tools.\n2. The model responds with tool calls (read file, write file, search, shell, etc.).\n3. Each tool call is executed locally and the result is fed back to the model.\n4. The loop continues until the model produces a final answer or the step limit is reached.\n\nsek has no external runtime dependencies — only what ships with Node.js.\n\n## License\n\nMIT\n"}}}}