@zythum02/fello-server 0.1.29 → 0.1.32

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.
Files changed (56) hide show
  1. package/README.md +16 -2
  2. package/out/renderer/assets/{_baseUniq-BApwm7pv.js → _baseUniq-DNNr8R6Z.js} +1 -1
  3. package/out/renderer/assets/{arc-yKenDsmO.js → arc-fZlBtxL9.js} +1 -1
  4. package/out/renderer/assets/{architectureDiagram-Q4EWVU46-C31yFVWH.js → architectureDiagram-Q4EWVU46-k4E5eOG6.js} +5 -5
  5. package/out/renderer/assets/{blockDiagram-DXYQGD6D-6liCvTXv.js → blockDiagram-DXYQGD6D-DUXfUO2U.js} +6 -6
  6. package/out/renderer/assets/{c4Diagram-AHTNJAMY-Co_b_6bH.js → c4Diagram-AHTNJAMY-Chff2Ong.js} +2 -2
  7. package/out/renderer/assets/{channel-Dc_jjyUr.js → channel-C3mo-Wfq.js} +1 -1
  8. package/out/renderer/assets/{chunk-4BX2VUAB-Cg18SQei.js → chunk-4BX2VUAB-DGQRb5sN.js} +1 -1
  9. package/out/renderer/assets/{chunk-4TB4RGXK-CvSqwINq.js → chunk-4TB4RGXK-BSCZx5Py.js} +5 -5
  10. package/out/renderer/assets/{chunk-55IACEB6-CfBiPWtx.js → chunk-55IACEB6-BVIv0C3q.js} +1 -1
  11. package/out/renderer/assets/{chunk-EDXVE4YY-DMjVfNdS.js → chunk-EDXVE4YY-DPmCmhx8.js} +1 -1
  12. package/out/renderer/assets/{chunk-FMBD7UC4-BbpFqyFG.js → chunk-FMBD7UC4-DM66-_hG.js} +1 -1
  13. package/out/renderer/assets/{chunk-OYMX7WX6-Cf724x--.js → chunk-OYMX7WX6-Tff_uZlx.js} +3 -3
  14. package/out/renderer/assets/{chunk-QZHKN3VN-4ZNIwknr.js → chunk-QZHKN3VN-C86eKqSd.js} +1 -1
  15. package/out/renderer/assets/{chunk-YZCP3GAM-D1j7xGGR.js → chunk-YZCP3GAM-CHuoIosP.js} +1 -1
  16. package/out/renderer/assets/{classDiagram-6PBFFD2Q-OFMeoPav.js → classDiagram-6PBFFD2Q-pm-iptmM.js} +6 -6
  17. package/out/renderer/assets/{classDiagram-v2-HSJHXN6E-OFMeoPav.js → classDiagram-v2-HSJHXN6E-pm-iptmM.js} +6 -6
  18. package/out/renderer/assets/{clone-Cm3RO2Zl.js → clone-5TzmfoWe.js} +1 -1
  19. package/out/renderer/assets/{cose-bilkent-S5V4N54A-lCfWcP6y.js → cose-bilkent-S5V4N54A-DVrDSw12.js} +1 -1
  20. package/out/renderer/assets/{dagre-KV5264BT-4I0h4wyh.js → dagre-KV5264BT-DdjpmydK.js} +6 -6
  21. package/out/renderer/assets/{diagram-5BDNPKRD-C1mEpAlt.js → diagram-5BDNPKRD-CdTSROj9.js} +6 -6
  22. package/out/renderer/assets/{diagram-G4DWMVQ6-C_g_DZm9.js → diagram-G4DWMVQ6-DQ1x-vhi.js} +6 -6
  23. package/out/renderer/assets/{diagram-MMDJMWI5-Di6wZV6-.js → diagram-MMDJMWI5-40ryNdvI.js} +5 -5
  24. package/out/renderer/assets/{diagram-TYMM5635-aF8hIDx1.js → diagram-TYMM5635-tf8FuJg1.js} +5 -5
  25. package/out/renderer/assets/{erDiagram-SMLLAGMA-Bk9QFZ27.js → erDiagram-SMLLAGMA-BciRZ0dO.js} +4 -4
  26. package/out/renderer/assets/{flowDiagram-DWJPFMVM-Dfg0LLup.js → flowDiagram-DWJPFMVM-CYDqfzx3.js} +6 -6
  27. package/out/renderer/assets/{ganttDiagram-T4ZO3ILL-lTjaJTs0.js → ganttDiagram-T4ZO3ILL-CRhxy6fZ.js} +2 -2
  28. package/out/renderer/assets/{gitGraphDiagram-UUTBAWPF-C74WBszH.js → gitGraphDiagram-UUTBAWPF-BadxOCq2.js} +6 -6
  29. package/out/renderer/assets/{graph-DGEX1eV1.js → graph-B3RLQ95r.js} +2 -2
  30. package/out/renderer/assets/{highlighted-body-OFNGDK62-DQWoSdTY.js → highlighted-body-OFNGDK62-CrGFRrSX.js} +1 -1
  31. package/out/renderer/assets/{index-BZzw3jIU.js → index-B1oSpSBX.js} +2137 -950
  32. package/out/renderer/assets/index-COLJTco3.css +382 -0
  33. package/out/renderer/assets/{infoDiagram-42DDH7IO-CR4ZLAM1.js → infoDiagram-42DDH7IO-DLMGtQF0.js} +4 -4
  34. package/out/renderer/assets/{ishikawaDiagram-UXIWVN3A-uXL-4FGw.js → ishikawaDiagram-UXIWVN3A-D8djsZeF.js} +1 -1
  35. package/out/renderer/assets/{journeyDiagram-VCZTEJTY-Ds2OL3Lo.js → journeyDiagram-VCZTEJTY-567Gpkxf.js} +4 -4
  36. package/out/renderer/assets/{kanban-definition-6JOO6SKY-CZ1CZVyP.js → kanban-definition-6JOO6SKY-DPjxCDrA.js} +2 -2
  37. package/out/renderer/assets/{layout-CNGveWdi.js → layout-CGQjv10p.js} +4 -4
  38. package/out/renderer/assets/{linear-CnHAiAJ3.js → linear-S4Y_UBCp.js} +1 -1
  39. package/out/renderer/assets/{min-D63AfN0e.js → min-DpKM6qkq.js} +2 -2
  40. package/out/renderer/assets/{mindmap-definition-QFDTVHPH-C3U3xkIJ.js → mindmap-definition-QFDTVHPH-BtxeumQc.js} +3 -3
  41. package/out/renderer/assets/{pieDiagram-DEJITSTG-C8AxK_-F.js → pieDiagram-DEJITSTG-n1UTGYDH.js} +6 -6
  42. package/out/renderer/assets/{quadrantDiagram-34T5L4WZ-BdiZmi7w.js → quadrantDiagram-34T5L4WZ-DXaOIoV-.js} +2 -2
  43. package/out/renderer/assets/{requirementDiagram-MS252O5E-BHIfl5Tz.js → requirementDiagram-MS252O5E-CTmWVt-P.js} +3 -3
  44. package/out/renderer/assets/{sankeyDiagram-XADWPNL6-SthTR8cL.js → sankeyDiagram-XADWPNL6-BXOndA46.js} +1 -1
  45. package/out/renderer/assets/{sequenceDiagram-FGHM5R23-COKEbCYM.js → sequenceDiagram-FGHM5R23-C5v5_yv_.js} +3 -3
  46. package/out/renderer/assets/{stateDiagram-FHFEXIEX-7zRGBf7O.js → stateDiagram-FHFEXIEX-D6Vd4_MM.js} +8 -8
  47. package/out/renderer/assets/{stateDiagram-v2-QKLJ7IA2-BqHJ_ZBX.js → stateDiagram-v2-QKLJ7IA2-De00f0TU.js} +4 -4
  48. package/out/renderer/assets/{timeline-definition-GMOUNBTQ-AvZAT5J-.js → timeline-definition-GMOUNBTQ-DxOCmdWf.js} +2 -2
  49. package/out/renderer/assets/{vennDiagram-DHZGUBPP-oSTndBDY.js → vennDiagram-DHZGUBPP-VNGucDZS.js} +1 -1
  50. package/out/renderer/assets/{wardley-RL74JXVD-C8hIuf19.js → wardley-RL74JXVD-BbxXQNlq.js} +3 -3
  51. package/out/renderer/assets/{wardleyDiagram-NUSXRM2D-Dv2kSOMM.js → wardleyDiagram-NUSXRM2D-BqldBvm5.js} +5 -5
  52. package/out/renderer/assets/{xychartDiagram-5P7HB3ND-J9z4uuMK.js → xychartDiagram-5P7HB3ND-BrCeeMZz.js} +2 -2
  53. package/out/renderer/index.html +2 -2
  54. package/out/server/main.js +210 -165
  55. package/package.json +1 -1
  56. package/out/renderer/assets/index-Cv3lJTlc.css +0 -382
@@ -3319,7 +3319,7 @@ import { createServer } from "http";
3319
3319
  import { WebSocketServer } from "ws";
3320
3320
  import { randomBytes as randomBytes2 } from "crypto";
3321
3321
  import { networkInterfaces } from "os";
3322
- import { dirname, join as join4 } from "path";
3322
+ import { dirname as dirname2, join as join5 } from "path";
3323
3323
  import { fileURLToPath } from "url";
3324
3324
  import { readFile as readFile4, stat as stat2 } from "fs/promises";
3325
3325
 
@@ -3389,6 +3389,146 @@ async function serveProjectFile(projectCwd, relativePath) {
3389
3389
  }
3390
3390
  }
3391
3391
 
3392
+ // src/backend/automation/store.ts
3393
+ import { join as join4, dirname } from "path";
3394
+ import { homedir as homedir2 } from "os";
3395
+ import {
3396
+ mkdirSync as mkdirSync3,
3397
+ writeFileSync as writeFileSync3,
3398
+ readFileSync as readFileSync3,
3399
+ readdirSync as readdirSync2,
3400
+ rmSync as rmSync3,
3401
+ existsSync as existsSync2,
3402
+ statSync as statSync2
3403
+ } from "fs";
3404
+ var AUTOMATIONS_DIR = join4(homedir2(), ".fello", "automations");
3405
+ mkdirSync3(AUTOMATIONS_DIR, { recursive: true });
3406
+ var store = {
3407
+ scheduleDir(scheduleId) {
3408
+ return join4(AUTOMATIONS_DIR, scheduleId);
3409
+ },
3410
+ scheduleConfigPath(scheduleId) {
3411
+ return join4(this.scheduleDir(scheduleId), "schedule.json");
3412
+ },
3413
+ tasksDir(scheduleId) {
3414
+ return join4(this.scheduleDir(scheduleId), "tasks");
3415
+ },
3416
+ taskDir(scheduleId, taskId) {
3417
+ return join4(this.tasksDir(scheduleId), taskId);
3418
+ },
3419
+ taskMetaPath(scheduleId, taskId) {
3420
+ return join4(this.taskDir(scheduleId, taskId), "task.json");
3421
+ },
3422
+ listSchedules() {
3423
+ if (!existsSync2(AUTOMATIONS_DIR)) return [];
3424
+ const dirs = readdirSync2(AUTOMATIONS_DIR);
3425
+ const list = [];
3426
+ for (const dir of dirs) {
3427
+ try {
3428
+ const raw = JSON.parse(readFileSync3(this.scheduleConfigPath(dir), "utf-8"));
3429
+ list.push(raw);
3430
+ } catch {
3431
+ }
3432
+ }
3433
+ list.sort((a, b) => b.updatedAt - a.updatedAt);
3434
+ return list;
3435
+ },
3436
+ getSchedule(scheduleId) {
3437
+ try {
3438
+ return JSON.parse(readFileSync3(this.scheduleConfigPath(scheduleId), "utf-8"));
3439
+ } catch {
3440
+ return null;
3441
+ }
3442
+ },
3443
+ saveSchedule(schedule) {
3444
+ const dir = this.scheduleDir(schedule.id);
3445
+ mkdirSync3(dir, { recursive: true });
3446
+ mkdirSync3(this.tasksDir(schedule.id), { recursive: true });
3447
+ writeFileSync3(this.scheduleConfigPath(schedule.id), JSON.stringify(schedule, null, 2));
3448
+ },
3449
+ deleteSchedule(scheduleId) {
3450
+ const dir = this.scheduleDir(scheduleId);
3451
+ if (existsSync2(dir)) {
3452
+ rmSync3(dir, { recursive: true, force: true });
3453
+ }
3454
+ },
3455
+ listTasks(scheduleId) {
3456
+ const dir = this.tasksDir(scheduleId);
3457
+ if (!existsSync2(dir)) return [];
3458
+ const dirs = readdirSync2(dir);
3459
+ const list = [];
3460
+ for (const d of dirs) {
3461
+ try {
3462
+ const raw = JSON.parse(readFileSync3(this.taskMetaPath(scheduleId, d), "utf-8"));
3463
+ list.push(raw);
3464
+ } catch {
3465
+ }
3466
+ }
3467
+ list.sort((a, b) => b.startedAt - a.startedAt);
3468
+ return list;
3469
+ },
3470
+ getTask(scheduleId, taskId) {
3471
+ try {
3472
+ return JSON.parse(readFileSync3(this.taskMetaPath(scheduleId, taskId), "utf-8"));
3473
+ } catch {
3474
+ return null;
3475
+ }
3476
+ },
3477
+ saveTask(scheduleId, task) {
3478
+ const dir = this.taskDir(scheduleId, task.id);
3479
+ mkdirSync3(dir, { recursive: true });
3480
+ writeFileSync3(this.taskMetaPath(scheduleId, task.id), JSON.stringify(task, null, 2));
3481
+ },
3482
+ deleteTask(scheduleId, taskId) {
3483
+ const dir = this.taskDir(scheduleId, taskId);
3484
+ if (existsSync2(dir)) {
3485
+ rmSync3(dir, { recursive: true, force: true });
3486
+ }
3487
+ },
3488
+ listTaskFiles(scheduleId, taskId) {
3489
+ const dir = this.taskDir(scheduleId, taskId);
3490
+ if (!existsSync2(dir)) return [];
3491
+ const entries = readdirSync2(dir);
3492
+ return entries.filter((f) => f !== "task.json").map((f) => {
3493
+ const fullPath = join4(dir, f);
3494
+ const s = statSync2(fullPath);
3495
+ if (s.isDirectory()) {
3496
+ return this._listDirRecursive(fullPath, f);
3497
+ }
3498
+ return f;
3499
+ }).flat().sort();
3500
+ },
3501
+ _listDirRecursive(dir, prefix) {
3502
+ const result = [];
3503
+ const entries = readdirSync2(dir);
3504
+ for (const entry of entries) {
3505
+ const full = join4(dir, entry);
3506
+ const s = statSync2(full);
3507
+ if (s.isDirectory()) {
3508
+ result.push(...this._listDirRecursive(full, join4(prefix, entry)));
3509
+ } else {
3510
+ result.push(join4(prefix, entry));
3511
+ }
3512
+ }
3513
+ return result;
3514
+ },
3515
+ readTaskFile(scheduleId, taskId, filePath, encoding) {
3516
+ const base = this.taskDir(scheduleId, taskId);
3517
+ const fullPath = join4(base, filePath);
3518
+ if (!fullPath.startsWith(base + "/") && fullPath !== base) throw new Error("Invalid file path");
3519
+ if (!existsSync2(fullPath)) throw new Error("File not found");
3520
+ if (encoding === "base64") return readFileSync3(fullPath).toString("base64");
3521
+ return readFileSync3(fullPath, "utf-8");
3522
+ },
3523
+ writeTaskFile(scheduleId, taskId, filePath, content) {
3524
+ const base = this.taskDir(scheduleId, taskId);
3525
+ const fullPath = join4(base, filePath);
3526
+ if (!fullPath.startsWith(base + "/") && fullPath !== base) throw new Error("Invalid file path");
3527
+ mkdirSync3(dirname(fullPath), { recursive: true });
3528
+ writeFileSync3(fullPath, content);
3529
+ }
3530
+ };
3531
+
3392
3532
  // src/backend/utils.ts
3393
3533
  import { relative as relative2, resolve as resolve3, isAbsolute as isAbsolute2 } from "path";
3394
3534
  function toPosixPath(p) {
@@ -3460,7 +3600,7 @@ function extractErrorMessage(error) {
3460
3600
 
3461
3601
  // src/backend/webui.ts
3462
3602
  import * as mimeTypes2 from "mime-types";
3463
- var __dirname = dirname(fileURLToPath(import.meta.url));
3603
+ var __dirname = dirname2(fileURLToPath(import.meta.url));
3464
3604
  var httpServer = null;
3465
3605
  var wss = null;
3466
3606
  var currentToken = null;
@@ -3573,17 +3713,33 @@ async function startWebUI(options) {
3573
3713
  res.end(result.body);
3574
3714
  return;
3575
3715
  }
3716
+ if (url.pathname.startsWith("/automation/")) {
3717
+ const pathParts = url.pathname.split("/");
3718
+ const scheduleId = pathParts[2] || "";
3719
+ const taskId = pathParts[4] || "";
3720
+ const relativePath = decodeURIComponent(pathParts.slice(5).join("/") || "");
3721
+ if (!scheduleId || pathParts[3] !== "task" || !taskId || !relativePath) {
3722
+ res.writeHead(400, { "Content-Type": "text/plain" });
3723
+ res.end("Bad Request");
3724
+ return;
3725
+ }
3726
+ const taskDir = store.taskDir(scheduleId, taskId);
3727
+ const result = await serveProjectFile(taskDir, relativePath);
3728
+ res.writeHead(result.status, { "Content-Type": result.mimeType });
3729
+ res.end(result.body);
3730
+ return;
3731
+ }
3576
3732
  try {
3577
3733
  const isFile = url.pathname !== "/" && !url.pathname.endsWith("/");
3578
3734
  let reqPath = url.pathname;
3579
3735
  if (!isFile) {
3580
3736
  reqPath = "/index.html";
3581
3737
  }
3582
- const baseDir = join4(__dirname, "../renderer");
3583
- let filePath = join4(baseDir, reqPath);
3738
+ const baseDir = join5(__dirname, "../renderer");
3739
+ let filePath = join5(baseDir, reqPath);
3584
3740
  let s = await stat2(filePath).catch(() => null);
3585
3741
  if (!s || s.isDirectory()) {
3586
- filePath = join4(baseDir, "index.html");
3742
+ filePath = join5(baseDir, "index.html");
3587
3743
  }
3588
3744
  const mime = mimeTypes2.lookup(filePath) || "application/octet-stream";
3589
3745
  const content = await readFile4(filePath);
@@ -3689,15 +3845,15 @@ function getWebUIUrl(addressInfo) {
3689
3845
 
3690
3846
  // src/backend/socket-server.ts
3691
3847
  import { createServer as createServer2 } from "http";
3692
- import { dirname as dirname2 } from "path";
3693
- import { mkdirSync as mkdirSync3, existsSync as existsSync2, unlinkSync } from "fs";
3848
+ import { dirname as dirname3 } from "path";
3849
+ import { mkdirSync as mkdirSync4, existsSync as existsSync3, unlinkSync } from "fs";
3694
3850
  function isWindowsPipePath(p) {
3695
3851
  return /^\\\\.\\pipe\\/i.test(p);
3696
3852
  }
3697
3853
  async function startSocketServer(socketPath) {
3698
3854
  if (!isWindowsPipePath(socketPath)) {
3699
- mkdirSync3(dirname2(socketPath), { recursive: true });
3700
- if (existsSync2(socketPath)) {
3855
+ mkdirSync4(dirname3(socketPath), { recursive: true });
3856
+ if (existsSync3(socketPath)) {
3701
3857
  unlinkSync(socketPath);
3702
3858
  }
3703
3859
  }
@@ -3750,7 +3906,7 @@ async function startSocketServer(socketPath) {
3750
3906
  server.close();
3751
3907
  server.closeAllConnections?.();
3752
3908
  if (!isWindowsPipePath(socketPath)) {
3753
- if (existsSync2(socketPath)) {
3909
+ if (existsSync3(socketPath)) {
3754
3910
  try {
3755
3911
  unlinkSync(socketPath);
3756
3912
  } catch {
@@ -3814,7 +3970,7 @@ var skillDetailSchema = z3.object({
3814
3970
 
3815
3971
  // src/backend/ilink/ilink-bridge.ts
3816
3972
  import { readFile as readFile5, writeFile as writeFile2, mkdir, rm } from "fs/promises";
3817
- import { join as join5 } from "path";
3973
+ import { join as join6 } from "path";
3818
3974
  import { randomUUID as randomUUID3 } from "crypto";
3819
3975
 
3820
3976
  // src/backend/ilink/ilink-crypto.ts
@@ -3990,10 +4146,10 @@ var ILinkClient = class {
3990
4146
  };
3991
4147
 
3992
4148
  // src/backend/ilink/ilink-bridge.ts
3993
- var ILINK_DIR = join5(FELLO_DIR, "ilink");
3994
- var CREDENTIALS_PATH = join5(ILINK_DIR, "credentials.json");
3995
- var CURSOR_PATH = join5(ILINK_DIR, "cursor.json");
3996
- var ACTIVE_SESSION_PATH = join5(ILINK_DIR, "active-session.json");
4149
+ var ILINK_DIR = join6(FELLO_DIR, "ilink");
4150
+ var CREDENTIALS_PATH = join6(ILINK_DIR, "credentials.json");
4151
+ var CURSOR_PATH = join6(ILINK_DIR, "cursor.json");
4152
+ var ACTIVE_SESSION_PATH = join6(ILINK_DIR, "active-session.json");
3997
4153
  async function ensureDir() {
3998
4154
  await mkdir(ILINK_DIR, { recursive: true });
3999
4155
  }
@@ -4429,145 +4585,6 @@ var ILinkBridge = class _ILinkBridge {
4429
4585
  }
4430
4586
  };
4431
4587
 
4432
- // src/backend/automation/store.ts
4433
- import { join as join6, dirname as dirname3 } from "path";
4434
- import { homedir as homedir2 } from "os";
4435
- import {
4436
- mkdirSync as mkdirSync4,
4437
- writeFileSync as writeFileSync3,
4438
- readFileSync as readFileSync3,
4439
- readdirSync as readdirSync2,
4440
- rmSync as rmSync3,
4441
- existsSync as existsSync3,
4442
- statSync as statSync2
4443
- } from "fs";
4444
- var AUTOMATIONS_DIR = join6(homedir2(), ".fello", "automations");
4445
- mkdirSync4(AUTOMATIONS_DIR, { recursive: true });
4446
- var store = {
4447
- scheduleDir(scheduleId) {
4448
- return join6(AUTOMATIONS_DIR, scheduleId);
4449
- },
4450
- scheduleConfigPath(scheduleId) {
4451
- return join6(this.scheduleDir(scheduleId), "schedule.json");
4452
- },
4453
- tasksDir(scheduleId) {
4454
- return join6(this.scheduleDir(scheduleId), "tasks");
4455
- },
4456
- taskDir(scheduleId, taskId) {
4457
- return join6(this.tasksDir(scheduleId), taskId);
4458
- },
4459
- taskMetaPath(scheduleId, taskId) {
4460
- return join6(this.taskDir(scheduleId, taskId), "task.json");
4461
- },
4462
- listSchedules() {
4463
- if (!existsSync3(AUTOMATIONS_DIR)) return [];
4464
- const dirs = readdirSync2(AUTOMATIONS_DIR);
4465
- const list = [];
4466
- for (const dir of dirs) {
4467
- try {
4468
- const raw = JSON.parse(readFileSync3(this.scheduleConfigPath(dir), "utf-8"));
4469
- list.push(raw);
4470
- } catch {
4471
- }
4472
- }
4473
- list.sort((a, b) => b.updatedAt - a.updatedAt);
4474
- return list;
4475
- },
4476
- getSchedule(scheduleId) {
4477
- try {
4478
- return JSON.parse(readFileSync3(this.scheduleConfigPath(scheduleId), "utf-8"));
4479
- } catch {
4480
- return null;
4481
- }
4482
- },
4483
- saveSchedule(schedule) {
4484
- const dir = this.scheduleDir(schedule.id);
4485
- mkdirSync4(dir, { recursive: true });
4486
- mkdirSync4(this.tasksDir(schedule.id), { recursive: true });
4487
- writeFileSync3(this.scheduleConfigPath(schedule.id), JSON.stringify(schedule, null, 2));
4488
- },
4489
- deleteSchedule(scheduleId) {
4490
- const dir = this.scheduleDir(scheduleId);
4491
- if (existsSync3(dir)) {
4492
- rmSync3(dir, { recursive: true, force: true });
4493
- }
4494
- },
4495
- listTasks(scheduleId) {
4496
- const dir = this.tasksDir(scheduleId);
4497
- if (!existsSync3(dir)) return [];
4498
- const dirs = readdirSync2(dir);
4499
- const list = [];
4500
- for (const d of dirs) {
4501
- try {
4502
- const raw = JSON.parse(readFileSync3(this.taskMetaPath(scheduleId, d), "utf-8"));
4503
- list.push(raw);
4504
- } catch {
4505
- }
4506
- }
4507
- list.sort((a, b) => b.startedAt - a.startedAt);
4508
- return list;
4509
- },
4510
- getTask(scheduleId, taskId) {
4511
- try {
4512
- return JSON.parse(readFileSync3(this.taskMetaPath(scheduleId, taskId), "utf-8"));
4513
- } catch {
4514
- return null;
4515
- }
4516
- },
4517
- saveTask(scheduleId, task) {
4518
- const dir = this.taskDir(scheduleId, task.id);
4519
- mkdirSync4(dir, { recursive: true });
4520
- writeFileSync3(this.taskMetaPath(scheduleId, task.id), JSON.stringify(task, null, 2));
4521
- },
4522
- deleteTask(scheduleId, taskId) {
4523
- const dir = this.taskDir(scheduleId, taskId);
4524
- if (existsSync3(dir)) {
4525
- rmSync3(dir, { recursive: true, force: true });
4526
- }
4527
- },
4528
- listTaskFiles(scheduleId, taskId) {
4529
- const dir = this.taskDir(scheduleId, taskId);
4530
- if (!existsSync3(dir)) return [];
4531
- const entries = readdirSync2(dir);
4532
- return entries.filter((f) => f !== "task.json").map((f) => {
4533
- const fullPath = join6(dir, f);
4534
- const s = statSync2(fullPath);
4535
- if (s.isDirectory()) {
4536
- return this._listDirRecursive(fullPath, f);
4537
- }
4538
- return f;
4539
- }).flat().sort();
4540
- },
4541
- _listDirRecursive(dir, prefix) {
4542
- const result = [];
4543
- const entries = readdirSync2(dir);
4544
- for (const entry of entries) {
4545
- const full = join6(dir, entry);
4546
- const s = statSync2(full);
4547
- if (s.isDirectory()) {
4548
- result.push(...this._listDirRecursive(full, join6(prefix, entry)));
4549
- } else {
4550
- result.push(join6(prefix, entry));
4551
- }
4552
- }
4553
- return result;
4554
- },
4555
- readTaskFile(scheduleId, taskId, filePath) {
4556
- const base = this.taskDir(scheduleId, taskId);
4557
- const fullPath = join6(base, filePath);
4558
- if (!fullPath.startsWith(base + "/") && fullPath !== base) throw new Error("Invalid file path");
4559
- if (!existsSync3(fullPath)) throw new Error("File not found");
4560
- return readFileSync3(fullPath, "utf-8");
4561
- },
4562
- writeTaskFile(scheduleId, taskId, filePath, content) {
4563
- const base = this.taskDir(scheduleId, taskId);
4564
- const fullPath = join6(base, filePath);
4565
- if (!fullPath.startsWith(base + "/") && fullPath !== base) throw new Error("Invalid file path");
4566
- mkdirSync4(dirname3(fullPath), { recursive: true });
4567
- writeFileSync3(fullPath, content);
4568
- }
4569
- };
4570
-
4571
4588
  // src/backend/automation/scheduler.ts
4572
4589
  import { CronJob } from "cron";
4573
4590
 
@@ -4828,7 +4845,11 @@ async function setupSkillsServer(taskDir) {
4828
4845
  const socketPath = join8(TEMP_DIR, `auto-${randomUUID4()}.socket`);
4829
4846
  const server = await startSocketServer(socketPath);
4830
4847
  server.registry("skills/catalog", async () => {
4831
- return getSkillsCatalog({ projectRoot: taskDir }).map(({ id, name, description }) => ({ id, name, description }));
4848
+ return getSkillsCatalog({ projectRoot: taskDir }).map(({ id, name, description }) => ({
4849
+ id,
4850
+ name,
4851
+ description
4852
+ }));
4832
4853
  });
4833
4854
  server.registry("skills/detail", async (payload) => {
4834
4855
  const { id } = payload;
@@ -4849,9 +4870,18 @@ async function setupSkillsServer(taskDir) {
4849
4870
  supportingFiles = listSkillFiles(skill.id, { projectRoot: taskDir });
4850
4871
  } catch {
4851
4872
  }
4852
- return { id: skill.id, name: skill.name, description: skill.description, instructions: body, root_path: skillDir, supporting_files: supportingFiles };
4873
+ return {
4874
+ id: skill.id,
4875
+ name: skill.name,
4876
+ description: skill.description,
4877
+ instructions: body,
4878
+ root_path: skillDir,
4879
+ supporting_files: supportingFiles
4880
+ };
4853
4881
  });
4854
- const catalogData = getSkillsCatalog({ projectRoot: taskDir }).map(({ id, name, description }) => ({ id, name, description }));
4882
+ const catalogData = getSkillsCatalog({ projectRoot: taskDir }).map(
4883
+ ({ id, name, description }) => ({ id, name, description })
4884
+ );
4855
4885
  const catalogFile = join8(TEMP_DIR, `auto-catalog-${randomUUID4()}.json`);
4856
4886
  fs2.writeFileSync(catalogFile, JSON.stringify(catalogData), "utf8");
4857
4887
  const mcpServer = {
@@ -4879,7 +4909,13 @@ async function executeTask(scheduleId) {
4879
4909
  runningTasks.add(scheduleId);
4880
4910
  const taskId = String(Date.now());
4881
4911
  const startedAt = Date.now();
4882
- const task = { id: taskId, scheduleId, startedAt, completedAt: null, status: "running" };
4912
+ const task = {
4913
+ id: taskId,
4914
+ scheduleId,
4915
+ startedAt,
4916
+ completedAt: null,
4917
+ status: "running"
4918
+ };
4883
4919
  store.saveTask(scheduleId, task);
4884
4920
  sendEvent?.("task-update", { scheduleId, task });
4885
4921
  const notifications = [];
@@ -4893,7 +4929,10 @@ async function executeTask(scheduleId) {
4893
4929
  ...notification,
4894
4930
  update: {
4895
4931
  ...notification.update,
4896
- _meta: { ...notification.update?._meta, fello: { receivedAt: Date.now(), displayId: `auto-${notifications.length}` } }
4932
+ _meta: {
4933
+ ...notification.update?._meta,
4934
+ fello: { receivedAt: Date.now(), displayId: `auto-${notifications.length}` }
4935
+ }
4897
4936
  }
4898
4937
  });
4899
4938
  },
@@ -4917,7 +4956,12 @@ async function executeTask(scheduleId) {
4917
4956
  const promptContent = [{ type: "text", text: schedule.prompt }];
4918
4957
  await bridge.sendPrompt({ sessionId, prompt: promptContent });
4919
4958
  const messages = reduceNotificationsToMessages(notifications);
4920
- store.writeTaskFile(scheduleId, taskId, "README.md", generateReadme(schedule, messages, startedAt));
4959
+ store.writeTaskFile(
4960
+ scheduleId,
4961
+ taskId,
4962
+ "README.md",
4963
+ generateReadme(schedule, messages, startedAt)
4964
+ );
4921
4965
  store.writeTaskFile(scheduleId, taskId, "conversation.json", JSON.stringify(messages, null, 2));
4922
4966
  await bridge.kill();
4923
4967
  skillsServer?.stop();
@@ -5002,7 +5046,8 @@ function reduceNotificationsToMessages(notifications) {
5002
5046
  function generateReadme(schedule, messages, startedAt) {
5003
5047
  const lines = [];
5004
5048
  lines.push(`# ${schedule.name}`);
5005
- lines.push(`> Run at ${new Date(startedAt).toLocaleString()}`);
5049
+ const locale = storageOps.getSettings().i18n?.language;
5050
+ lines.push(`> Run at ${new Date(startedAt).toLocaleString(locale)}`);
5006
5051
  lines.push("");
5007
5052
  for (const msg of messages) {
5008
5053
  if (msg.role === "user" || msg.role === "assistant") {
@@ -5046,7 +5091,7 @@ function scheduleCron(schedule) {
5046
5091
  cronJob.start();
5047
5092
  const next = getNextRun(schedule);
5048
5093
  console.log(
5049
- `[Automation] Scheduled "${schedule.name}" (${schedule.cron.expr}) next: ${next ? new Date(next).toLocaleString() : "?"}`
5094
+ `[Automation] Scheduled "${schedule.name}" (${schedule.cron.expr}) next: ${next ? new Date(next).toLocaleString(storageOps.getSettings().i18n?.language) : "?"}`
5050
5095
  );
5051
5096
  } catch (err) {
5052
5097
  console.error(`[Automation] Failed to schedule "${schedule.name}":`, err);
@@ -7465,8 +7510,8 @@ var backendHandlers = {
7465
7510
  async getTaskFiles({ scheduleId, taskId }) {
7466
7511
  return store.listTaskFiles(scheduleId, taskId);
7467
7512
  },
7468
- async readTaskFile({ scheduleId, taskId, filePath }) {
7469
- return store.readTaskFile(scheduleId, taskId, filePath);
7513
+ async readTaskFile({ scheduleId, taskId, filePath, encoding }) {
7514
+ return store.readTaskFile(scheduleId, taskId, filePath, encoding);
7470
7515
  },
7471
7516
  async getTaskFileSystemPath({ scheduleId, taskId, filePath }) {
7472
7517
  const base = store.taskDir(scheduleId, taskId);
@@ -7480,7 +7525,7 @@ var backendHandlers = {
7480
7525
  };
7481
7526
 
7482
7527
  // package.json
7483
- var version = "0.1.29";
7528
+ var version = "0.1.32";
7484
7529
 
7485
7530
  // src/server/main.ts
7486
7531
  var port;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zythum02/fello-server",
3
- "version": "0.1.29",
3
+ "version": "0.1.32",
4
4
  "description": "Fello Server — standalone headless AI agent server",
5
5
  "type": "module",
6
6
  "bin": {