tellrun 0.0.0-stage → 1.0.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/config.js ADDED
@@ -0,0 +1,62 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { z } from "zod";
5
+ /** CLI 与后台服务共用的用户数据目录,不依赖当前工作目录。 */
6
+ export const appDirectory = join(homedir(), ".tellrun");
7
+ /** 配置向导与运行入口共用校验,不保存终端环境。 */
8
+ export const configSchema = z.object({
9
+ telegram: z.object({
10
+ token: z
11
+ .string()
12
+ .trim()
13
+ .regex(/^\d+:[\w-]+$/),
14
+ ownerId: z
15
+ .union([
16
+ z.number(),
17
+ z
18
+ .string()
19
+ .trim()
20
+ .regex(/^[1-9]\d*$/)
21
+ .transform(Number),
22
+ ])
23
+ .pipe(z.number().int().positive().max(Number.MAX_SAFE_INTEGER)),
24
+ /** 可选代理由用户自行配置;未设置时继承运行环境,空字符串表示直连。 */
25
+ proxyUrl: z
26
+ .string()
27
+ .trim()
28
+ .pipe(z.url({ protocol: /^https?$/ }).or(z.literal("")))
29
+ .optional(),
30
+ }),
31
+ codexPath: z.string().trim().min(1).default("codex"),
32
+ });
33
+ /** 读取用户配置,允许环境变量覆盖 Telegram 与 Codex 入口;诊断不包含配置值。 */
34
+ export function loadConfig(env = process.env) {
35
+ let saved = {};
36
+ try {
37
+ saved = JSON.parse(readFileSync(join(appDirectory, "config.json"), "utf8"));
38
+ if (!saved || typeof saved !== "object" || Array.isArray(saved))
39
+ throw new SyntaxError();
40
+ }
41
+ catch (error) {
42
+ if (!(error instanceof Error && "code" in error && error.code === "ENOENT")) {
43
+ throw new Error(error instanceof SyntaxError
44
+ ? "~/.tellrun/config.json 不是有效的配置对象,请运行 tellrun setup 重新配置"
45
+ : "无法读取 ~/.tellrun/config.json,请检查文件权限");
46
+ }
47
+ }
48
+ const config = configSchema.safeParse({
49
+ ...saved,
50
+ telegram: {
51
+ token: env.TELEGRAM_BOT_TOKEN ?? saved.telegram?.token,
52
+ ownerId: env.TELEGRAM_OWNER_ID ?? saved.telegram?.ownerId,
53
+ proxyUrl: env.TELEGRAM_PROXY_URL?.trim() || saved.telegram?.proxyUrl,
54
+ },
55
+ codexPath: env.CODEX_PATH ?? saved.codexPath,
56
+ });
57
+ if (!config.success) {
58
+ throw new Error(`配置无效:${[...new Set(config.error.issues.map((issue) => issue.path.join(".")))].join("、")};请运行 tellrun setup 或检查环境变量`);
59
+ }
60
+ return config.data;
61
+ }
62
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,141 @@
1
+ import { realpathSync, statSync } from "node:fs";
2
+ import { isAbsolute } from "node:path";
3
+ import { setTimeout } from "node:timers/promises";
4
+ /** 接收消息只保存必要状态;任务执行独立串行运行,控制命令始终可用。 */
5
+ export function createRelayService(options) {
6
+ let stopping = false;
7
+ /** 状态查询与历史结果共用面向用户的状态名称。 */
8
+ const statuses = {
9
+ queued: "等待开始",
10
+ dispatching: "正在连接 Agent",
11
+ running: "执行中",
12
+ cancelling: "正在停止",
13
+ completed: "已完成",
14
+ failed: "失败",
15
+ cancelled: "已停止",
16
+ interrupted: "执行状态待确认",
17
+ };
18
+ options.store.recoverTasks();
19
+ return {
20
+ /** 返回前保存消息和回复;重复事件直接忽略,不重新执行控制或任务。 */
21
+ async handleMessage(message) {
22
+ if (stopping)
23
+ throw new Error("服务正在停止,消息尚未接收");
24
+ options.store.accept(message, (channel) => {
25
+ /** 未指定目录时沿用服务启动目录,并随消息一同保存,后续可用 /cwd 切换。 */
26
+ if (!channel.cwd)
27
+ options.store.setSession(channel.id, realpathSync(process.cwd()));
28
+ const task = options.store.activeTask();
29
+ if (message.content.type === "command") {
30
+ switch (message.content.name) {
31
+ case "start":
32
+ case "help":
33
+ return "Tellrun 已连接。\n/cwd 绝对路径 — 切换工作目录(可选)\n普通文本 — 交给 Codex,后续消息沿用当前会话\n/new — 新建会话,保留目录\n/status — 查看状态\n/stop — 停止任务并暂停\n/resume — 确认后恢复接收任务\n/last — 查看最近结果\n当前一次处理一个任务;审批与结构化提问尚未接入,遇到此类请求会停止并提示。";
34
+ case "status":
35
+ return `服务:已连接\n${options.agent.name}:${options.agent.version}\n工作目录:${channel.cwd}\n会话:${channel.sessionId ? "已有上下文" : "新会话"}\n接收任务:${channel.paused ? "已暂停,使用 /resume 恢复" : "已启用"}\n任务:${task ? `#${task.id} ${statuses[task.status]}` : "空闲"}`;
36
+ case "cwd": {
37
+ if (!message.content.args)
38
+ return `当前目录:${channel.cwd}\n使用 /cwd 绝对路径 切换目录,目录变化会开始新会话。`;
39
+ if (task)
40
+ return "请等待当前任务结束,或先用 /stop 停止后再切换目录。";
41
+ if (!isAbsolute(message.content.args))
42
+ return "请提供绝对目录,例如 /cwd /Users/你的用户名/Code/项目名。";
43
+ let cwd;
44
+ try {
45
+ cwd = realpathSync(message.content.args);
46
+ if (!statSync(cwd).isDirectory())
47
+ return "指定路径不是目录。";
48
+ }
49
+ catch {
50
+ return "无法访问该目录,请检查路径是否存在及访问权限。";
51
+ }
52
+ if (cwd !== channel.cwd)
53
+ options.store.setSession(channel.id, cwd);
54
+ return `工作目录:${cwd}\n${channel.paused ? "当前已暂停,发送 /resume 后可提交任务。" : "现在可以发送消息给 Codex。"}`;
55
+ }
56
+ case "new":
57
+ if (task)
58
+ return "请等待当前任务结束,或先用 /stop 停止后再新建会话。";
59
+ options.store.setSession(channel.id, channel.cwd);
60
+ return `已开始新会话。\n工作目录:${channel.cwd}${channel.paused ? "\n当前已暂停,请发送 /resume。" : ""}`;
61
+ case "stop":
62
+ options.store.setPaused(channel.id, true);
63
+ if (!task || task.channelId !== channel.id)
64
+ return "已暂停接收任务,当前聊天没有执行中的任务。发送 /resume 可恢复。";
65
+ options.store.cancelTask(task.id);
66
+ if (task.status !== "queued")
67
+ options.agent.stop();
68
+ return `已请求停止任务 #${task.id},请等待最终状态。之后发送 /resume 可恢复接收任务。`;
69
+ case "resume":
70
+ if (task)
71
+ return "当前任务尚未结束,请等待最终状态后再恢复。";
72
+ options.store.setPaused(channel.id, false);
73
+ return "已恢复接收任务。之前中断的任务不会重新执行,请发送新的消息。";
74
+ case "last": {
75
+ const last = options.store.lastTask(channel.id);
76
+ return last
77
+ ? `任务 #${last.id} ${statuses[last.status]}\n${last.result ?? "尚无最终结果。"}`
78
+ : "当前聊天还没有任务记录。";
79
+ }
80
+ default:
81
+ return "暂不支持此命令,请使用 /help 查看可用操作。";
82
+ }
83
+ }
84
+ if (message.content.type === "unsupported")
85
+ return "当前仅支持文本消息,请使用 /help 查看可用操作。";
86
+ if (channel.paused)
87
+ return "当前已暂停。请检查上次任务结果,确认后发送 /resume,再提交新消息。";
88
+ if (task)
89
+ return `任务 #${task.id} 仍在处理,本条消息未提交。可用 /status 查看状态或 /stop 停止。`;
90
+ if (!message.content.text.trim())
91
+ return "请输入任务内容。";
92
+ return `已接收任务 #${options.store.createTask(channel, message.content.text).id}\n工作目录:${channel.cwd}\n可用 /status 查看状态或 /stop 停止。`;
93
+ });
94
+ },
95
+ /** 领取任务后再次检查目录;运行结果与最终回复在同一个快照中保存。 */
96
+ async run(source) {
97
+ while (!stopping) {
98
+ const task = options.store.claimTask(source);
99
+ if (!task) {
100
+ await setTimeout(250);
101
+ continue;
102
+ }
103
+ try {
104
+ if (realpathSync(task.cwd) !== task.cwd || !statSync(task.cwd).isDirectory())
105
+ throw new Error("目录已改变");
106
+ }
107
+ catch {
108
+ options.store.finishTask(task.id, {
109
+ status: "failed",
110
+ text: "工作目录不存在、已改变或无法访问,未调用 Agent。请重新设置 /cwd 后提交任务。",
111
+ });
112
+ continue;
113
+ }
114
+ try {
115
+ const result = await options.agent.run({
116
+ cwd: task.cwd,
117
+ prompt: task.prompt,
118
+ sessionId: task.sessionId,
119
+ onSession: (id) => options.store.recordSession(task.id, id),
120
+ onStarted: () => options.store.markRunning(task.id),
121
+ });
122
+ options.store.finishTask(task.id, result);
123
+ options.logger.info({ taskId: task.id, status: result.status }, "Agent 任务已结束");
124
+ }
125
+ catch (error) {
126
+ options.store.finishTask(task.id, {
127
+ status: "interrupted",
128
+ text: "运行环境异常,服务将停止。请检查工作目录与本地进程后再恢复。",
129
+ });
130
+ throw error;
131
+ }
132
+ }
133
+ },
134
+ /** 停止领取新任务;未派发记录保留,当前任务等待 Agent 确认退出。 */
135
+ stop() {
136
+ stopping = true;
137
+ options.agent.stop();
138
+ },
139
+ };
140
+ }
141
+ //# sourceMappingURL=relay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay.js","sourceRoot":"","sources":["../../src/core/relay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,187 @@
1
+ import { Agent } from "node:https";
2
+ import { setTimeout } from "node:timers/promises";
3
+ import { autoRetry } from "@grammyjs/auto-retry";
4
+ import { Bot, BotError, GrammyError, HttpError } from "grammy";
5
+ /** Telegram 连接器负责鉴权、消息转换与发送,业务逻辑交给统一处理入口。 */
6
+ export function createTelegramConnection(config, handleMessage, store, logger) {
7
+ /** 默认继承终端代理;显式配置使用优先级更高的小写变量,保留 NO_PROXY 规则。 */
8
+ const agent = new Agent({
9
+ keepAlive: true,
10
+ proxyEnv: config.proxyUrl === undefined
11
+ ? process.env
12
+ : config.proxyUrl
13
+ ? { ...process.env, https_proxy: config.proxyUrl }
14
+ : {},
15
+ });
16
+ const bot = new Bot(config.token, {
17
+ client: { timeoutSeconds: 35, baseFetchConfig: { agent } },
18
+ });
19
+ /** 只中断初始化和拉取;正在处理的消息由 start 等待完成。 */
20
+ const polling = new AbortController();
21
+ let started = false;
22
+ bot.api.config.use(autoRetry({ maxRetryAttempts: 2, maxDelaySeconds: 5, rethrowHttpErrors: true }));
23
+ /** 超时覆盖整次调用及重试;grammY 的旧 signal 类型与 Node 原生接口兼容。 */
24
+ bot.api.config.use((prev, method, payload, signal) => prev(method, payload, signal ??
25
+ AbortSignal.any([
26
+ AbortSignal.timeout(method === "getUpdates" ? 40_000 : 15_000),
27
+ ...(["getMe", "getWebhookInfo", "getUpdates"].includes(method) ? [polling.signal] : []),
28
+ ])));
29
+ /** 身份与私聊范围校验必须先于核心层调用。 */
30
+ bot.use(async (ctx, next) => {
31
+ if (ctx.chat?.type === "private" && ctx.from?.id === config.ownerId) {
32
+ await next();
33
+ }
34
+ });
35
+ bot.on("message", async (ctx) => {
36
+ const command = ctx.message.text === undefined
37
+ ? undefined
38
+ : ctx.message.entities?.find((entity) => entity.type === "bot_command" && entity.offset === 0);
39
+ const [name, target] = command
40
+ ? (ctx.message.text?.slice(1, command.length).split("@") ?? [])
41
+ : [];
42
+ if (target !== undefined && target.toLowerCase() !== ctx.me.username?.toLowerCase())
43
+ return;
44
+ await handleMessage({
45
+ channel: {
46
+ platform: "telegram",
47
+ accountId: String(ctx.me.id),
48
+ chatId: String(ctx.chat.id),
49
+ userId: String(ctx.from.id),
50
+ },
51
+ eventId: String(ctx.update.update_id),
52
+ content: command
53
+ ? {
54
+ type: "command",
55
+ name: name ?? "",
56
+ args: ctx.message.text?.slice(command.length).trim() ?? "",
57
+ }
58
+ : ctx.message.text !== undefined
59
+ ? { type: "text", text: ctx.message.text }
60
+ : { type: "unsupported" },
61
+ });
62
+ });
63
+ /** 原始网络错误可能带 Token,只记录类别和错误码。 */
64
+ function logFailure(error) {
65
+ let cause = error instanceof BotError ? error.error : error;
66
+ if (cause instanceof HttpError)
67
+ cause = cause.error;
68
+ logger.error({
69
+ updateId: error instanceof BotError ? error.ctx.update.update_id : undefined,
70
+ errorType: cause instanceof Error ? cause.name : "UnknownError",
71
+ errorCode: cause instanceof GrammyError
72
+ ? cause.error_code
73
+ : cause instanceof Error && "code" in cause && typeof cause.code === "string"
74
+ ? cause.code
75
+ : undefined,
76
+ }, cause instanceof GrammyError && cause.error_code === 409
77
+ ? "Telegram 轮询冲突,请检查其他实例或 Webhook"
78
+ : cause instanceof GrammyError && cause.error_code === 401
79
+ ? "Telegram 身份验证失败,请检查 Bot Token"
80
+ : "Telegram 连接或持久化处理失败,服务将停止");
81
+ }
82
+ return {
83
+ /** 核实机器人身份后才启动任务,初始化不消费 Telegram 消息。 */
84
+ async initialize() {
85
+ try {
86
+ bot.botInfo = await bot.api.getMe();
87
+ if (polling.signal.aborted)
88
+ return;
89
+ if ((await bot.api.getWebhookInfo()).url) {
90
+ logger.error("当前 Bot 已配置 Webhook,请先确认并手动移除后再启用长轮询");
91
+ throw new Error("Bot 已被 Webhook 占用");
92
+ }
93
+ return {
94
+ platform: "telegram",
95
+ accountId: String(bot.botInfo.id),
96
+ userId: String(config.ownerId),
97
+ };
98
+ }
99
+ catch (error) {
100
+ if (polling.signal.aborted && error instanceof HttpError)
101
+ return;
102
+ logFailure(error);
103
+ throw error;
104
+ }
105
+ },
106
+ /** 接收与发送独立运行,慢回复不会阻塞 /stop 的入站处理。 */
107
+ async start() {
108
+ started = true;
109
+ const workers = [];
110
+ try {
111
+ if (polling.signal.aborted)
112
+ return;
113
+ logger.info({ botId: bot.botInfo.id }, "Telegram 长轮询已启动");
114
+ workers.push((async () => {
115
+ /** 只有入站状态保存成功才推进确认位置;重投按已保存的事件标识去重。 */
116
+ let offset = 0;
117
+ while (!polling.signal.aborted) {
118
+ for (const update of await bot.api.getUpdates({
119
+ offset,
120
+ timeout: 30,
121
+ allowed_updates: ["message"],
122
+ })) {
123
+ if (polling.signal.aborted)
124
+ return;
125
+ await bot.handleUpdate(update);
126
+ offset = update.update_id + 1;
127
+ }
128
+ }
129
+ })(), (async () => {
130
+ while (!polling.signal.aborted) {
131
+ const reply = store.pendingReply(String(bot.botInfo.id), String(config.ownerId));
132
+ if (!reply) {
133
+ await setTimeout(250);
134
+ continue;
135
+ }
136
+ try {
137
+ await bot.api.sendMessage(reply.chatId, reply.text);
138
+ store.removeReply(reply.id);
139
+ }
140
+ catch (error) {
141
+ if (!(error instanceof HttpError || error instanceof GrammyError))
142
+ throw error;
143
+ if (error instanceof GrammyError && error.error_code === 401)
144
+ throw error;
145
+ const permanent = error instanceof GrammyError &&
146
+ error.error_code >= 400 &&
147
+ error.error_code < 500 &&
148
+ error.error_code !== 429;
149
+ if (permanent)
150
+ store.removeReply(reply.id);
151
+ else
152
+ store.retryReply(reply.id, error instanceof GrammyError && error.parameters.retry_after !== undefined
153
+ ? error.parameters.retry_after
154
+ : Math.min(60, 2 ** Math.min(reply.attempts, 6)));
155
+ logger.warn({ outboxId: reply.id, permanent, errorType: error.name }, permanent
156
+ ? "Telegram 永久拒绝发送,回复已移出队列;任务结果仍保留"
157
+ : "Telegram 回复发送失败,已保留并安排重试");
158
+ }
159
+ }
160
+ })());
161
+ await Promise.all(workers);
162
+ }
163
+ catch (error) {
164
+ if (polling.signal.aborted &&
165
+ error instanceof HttpError &&
166
+ error.error instanceof Error &&
167
+ error.error.name === "AbortError")
168
+ return;
169
+ logFailure(error);
170
+ throw error;
171
+ }
172
+ finally {
173
+ polling.abort();
174
+ await Promise.allSettled(workers);
175
+ agent.destroy();
176
+ started = false;
177
+ }
178
+ },
179
+ /** 停止拉取,不额外发送确认请求;未确认更新允许在重启后重投。 */
180
+ stop() {
181
+ polling.abort();
182
+ if (!started)
183
+ agent.destroy();
184
+ },
185
+ };
186
+ }
187
+ //# sourceMappingURL=telegram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../src/im/telegram.ts"],"names":[],"mappings":"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"}
package/dist/logger.js ADDED
@@ -0,0 +1,24 @@
1
+ import { pino } from "pino";
2
+ /** 创建结构化日志;调用方只记录标识和阶段,不传入配置、正文或原始 API 错误。 */
3
+ export function createLogger() {
4
+ return pino({
5
+ name: "tellrun",
6
+ level: "info",
7
+ redact: {
8
+ paths: [
9
+ "telegramToken",
10
+ "token",
11
+ "TELEGRAM_BOT_TOKEN",
12
+ "authorization",
13
+ "prompt",
14
+ "*.telegramToken",
15
+ "*.token",
16
+ "*.TELEGRAM_BOT_TOKEN",
17
+ "*.authorization",
18
+ "*.prompt",
19
+ ],
20
+ censor: "[已隐藏]",
21
+ },
22
+ });
23
+ }
24
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,8CAA8C;AAC9C,MAAM,UAAU,YAAY;IAC1B,OAAO,IAAI,CAAC;QACV,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,MAAM;QACb,MAAM,EAAE;YACN,KAAK,EAAE;gBACL,eAAe;gBACf,OAAO;gBACP,oBAAoB;gBACpB,eAAe;gBACf,QAAQ;gBACR,iBAAiB;gBACjB,SAAS;gBACT,sBAAsB;gBACtB,iBAAiB;gBACjB,UAAU;aACX;YACD,MAAM,EAAE,OAAO;SAChB;KACF,CAAC,CAAC;AACL,CAAC"}
package/dist/main.js ADDED
@@ -0,0 +1,75 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ import { createCodexAgent } from "./agents/codex.js";
4
+ import { loadConfig } from "./config.js";
5
+ import { createRelayService } from "./core/relay.js";
6
+ import { createTelegramConnection } from "./im/telegram.js";
7
+ import { createLogger } from "./logger.js";
8
+ import { openStore } from "./storage/store.js";
9
+ /** 启动日志在配置校验前可用,避免将无效配置直接输出。 */
10
+ const logger = createLogger();
11
+ let store;
12
+ let im;
13
+ let relay;
14
+ let running = [];
15
+ let phase = "配置加载";
16
+ let stopping = false;
17
+ /** 两种退出信号共用关停入口;主流程等待消息处理和 Agent 退出后释放状态锁。 */
18
+ function stop() {
19
+ if (stopping)
20
+ return;
21
+ stopping = true;
22
+ logger.info("正在停止服务");
23
+ im?.stop();
24
+ relay?.stop();
25
+ }
26
+ process.once("SIGINT", stop);
27
+ process.once("SIGTERM", stop);
28
+ try {
29
+ const config = loadConfig();
30
+ phase = "状态加载";
31
+ store = openStore();
32
+ phase = "Agent 可用性检查";
33
+ const agent = await createCodexAgent(config.codexPath);
34
+ logger.info({ agent: agent.name, version: agent.version }, "Agent CLI 可用");
35
+ if (!stopping) {
36
+ relay = createRelayService({ store, agent, logger });
37
+ im = createTelegramConnection(config.telegram, relay.handleMessage, store, logger);
38
+ phase = "IM 连接";
39
+ const source = await im.initialize();
40
+ if (source && !stopping) {
41
+ /** systemctl start 等待实际初始化成功,避免把进程创建误报为服务就绪。 */
42
+ if (process.env.NOTIFY_SOCKET) {
43
+ phase = "后台就绪通知";
44
+ await promisify(execFile)("systemd-notify", ["--ready", "--status=Telegram 已连接"], {
45
+ timeout: 5_000,
46
+ });
47
+ }
48
+ phase = "消息与任务处理";
49
+ running = [im.start(), relay.run(source)];
50
+ await Promise.all(running);
51
+ }
52
+ }
53
+ }
54
+ catch (error) {
55
+ process.exitCode = 1;
56
+ logger.fatal({
57
+ phase,
58
+ errorType: error instanceof Error ? error.name : "UnknownError",
59
+ errorCode: error instanceof Error && "code" in error && typeof error.code === "string"
60
+ ? error.code
61
+ : undefined,
62
+ }, (phase === "配置加载" || phase === "状态加载") && error instanceof Error
63
+ ? error.message
64
+ : "服务启动或运行失败");
65
+ }
66
+ finally {
67
+ im?.stop();
68
+ relay?.stop();
69
+ await Promise.allSettled(running);
70
+ store?.close();
71
+ process.removeListener("SIGINT", stop);
72
+ process.removeListener("SIGTERM", stop);
73
+ logger.info("Tellrun 已退出");
74
+ }
75
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { closeSync, fsyncSync, openSync, renameSync, rmSync, writeFileSync } from "node:fs";
3
+ import { dirname } from "node:path";
4
+ /** 配置和状态共用原子写入:同目录临时文件写完整并刷盘后,再替换目标文件。 */
5
+ export function writeJson(path, value) {
6
+ const temporary = `${path}.${process.pid}.${randomUUID()}.tmp`;
7
+ let descriptor;
8
+ try {
9
+ descriptor = openSync(temporary, "wx", 0o600);
10
+ writeFileSync(descriptor, `${JSON.stringify(value, null, 2)}\n`);
11
+ fsyncSync(descriptor);
12
+ closeSync(descriptor);
13
+ descriptor = undefined;
14
+ renameSync(temporary, path);
15
+ if (process.platform !== "win32") {
16
+ descriptor = openSync(dirname(path), "r");
17
+ fsyncSync(descriptor);
18
+ closeSync(descriptor);
19
+ descriptor = undefined;
20
+ }
21
+ }
22
+ finally {
23
+ if (descriptor !== undefined)
24
+ closeSync(descriptor);
25
+ rmSync(temporary, { force: true });
26
+ }
27
+ }
28
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/storage/json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC5F,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,0CAA0C;AAC1C,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,KAAc;IACpD,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,IAAI,UAAU,EAAE,MAAM,CAAC;IAC/D,IAAI,UAA8B,CAAC;IACnC,IAAI,CAAC;QACH,UAAU,GAAG,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAC9C,aAAa,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACjE,SAAS,CAAC,UAAU,CAAC,CAAC;QACtB,SAAS,CAAC,UAAU,CAAC,CAAC;QACtB,UAAU,GAAG,SAAS,CAAC;QACvB,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC5B,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACjC,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;YAC1C,SAAS,CAAC,UAAU,CAAC,CAAC;YACtB,SAAS,CAAC,UAAU,CAAC,CAAC;YACtB,UAAU,GAAG,SAAS,CAAC;QACzB,CAAC;IACH,CAAC;YAAS,CAAC;QACT,IAAI,UAAU,KAAK,SAAS;YAAE,SAAS,CAAC,UAAU,CAAC,CAAC;QACpD,MAAM,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACrC,CAAC;AACH,CAAC"}