(args: InstallArgs)
| 51 | const deps: SchtasksManagerDeps = { ...DEFAULT_DEPS, ...overrides }; |
| 52 | |
| 53 | async function install(args: InstallArgs): Promise<InstallResult> { |
| 54 | const program = deps.resolveProgram(); |
| 55 | const logPath = deps.logPath(); |
| 56 | const plan = buildInstallPlan({ ...args, program, logPath }); |
| 57 | |
| 58 | const alreadyInstalled = await deps.taskExists(); |
| 59 | if (alreadyInstalled && args.force !== true) { |
| 60 | return { |
| 61 | status: 'already-installed', |
| 62 | message: `Scheduled task "${KIMI_SERVER_TASK_NAME}" already exists. Rerun with --force to replace it.`, |
| 63 | taskName: KIMI_SERVER_TASK_NAME, |
| 64 | }; |
| 65 | } |
| 66 | |
| 67 | const argString = serializeArguments(plan); |
| 68 | const xml = buildScheduledTaskXml({ |
| 69 | description: 'Kimi Code local server (managed by `kimi server install`)', |
| 70 | command: plan.program, |
| 71 | ...(argString.length > 0 ? { arguments: argString } : {}), |
| 72 | }); |
| 73 | const xmlPath = deps.writeTaskXml(xml); |
| 74 | |
| 75 | try { |
| 76 | const createArgs = ['/Create', '/TN', KIMI_SERVER_TASK_NAME, '/XML', xmlPath]; |
| 77 | if (alreadyInstalled) { |
| 78 | createArgs.push('/F'); |
| 79 | } |
| 80 | const create = await deps.execSchtasks(createArgs); |
| 81 | if (create.code !== 0) { |
| 82 | throw new Error( |
| 83 | `schtasks /Create failed (code ${create.code}): ${detail(create) ?? 'unknown error'}`, |
| 84 | ); |
| 85 | } |
| 86 | } finally { |
| 87 | |
| 88 | try { |
| 89 | rmSync(xmlPath, { force: true }); |
| 90 | } catch { |
| 91 | |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | writeInstallPlan(plan); |
| 96 | |
| 97 | |
| 98 | const run = await deps.execSchtasks(['/Run', '/TN', KIMI_SERVER_TASK_NAME]); |
| 99 | if (run.code !== 0) { |
| 100 | |
| 101 | return { |
| 102 | status: alreadyInstalled ? 'replaced' : 'installed', |
| 103 | message: `Task ${alreadyInstalled ? 'replaced' : 'installed'} but /Run failed: ${detail(run) ?? 'unknown error'}.`, |
| 104 | taskName: KIMI_SERVER_TASK_NAME, |
| 105 | }; |
| 106 | } |
| 107 | |
| 108 | return { |
| 109 | status: alreadyInstalled ? 'replaced' : 'installed', |
| 110 | message: `Kimi server scheduled task ${alreadyInstalled ? 'replaced' : 'installed'} (${KIMI_SERVER_TASK_NAME}, port ${plan.port}).`, |
nothing calls this directly
no test coverage detected